Selaa lähdekoodia

Make Phong the Standard material.
Fix post-interpolation normal shrinkage.
Fix point shader to be independent of near plane depth.
Clean up material package.

Daniel Salvadori 6 vuotta sitten
vanhempi
commit
973727e925

+ 7 - 0
graphic/points.go

@@ -15,6 +15,7 @@ import (
 type Points struct {
 	Graphic             // Embedded graphic
 	uniMVPm gls.Uniform // Model view projection matrix uniform location cache
+	uniMVm  gls.Uniform // Model view matrix uniform location cache
 }
 
 // NewPoints creates and returns a graphic points object with the specified
@@ -27,6 +28,7 @@ func NewPoints(igeom geometry.IGeometry, imat material.IMaterial) *Points {
 		p.AddMaterial(p, imat, 0, 0)
 	}
 	p.uniMVPm.Init("MVP")
+	p.uniMVm.Init("MV")
 	return p
 }
 
@@ -37,4 +39,9 @@ func (p *Points) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
 	mvpm := p.ModelViewProjectionMatrix()
 	location := p.uniMVPm.Location(gs)
 	gs.UniformMatrix4fv(location, 1, false, &mvpm[0])
+
+	// Transfer model view matrix uniform
+	mvm := p.ModelViewMatrix()
+	location = p.uniMVm.Location(gs)
+	gs.UniformMatrix4fv(location, 1, false, &mvm[0])
 }

+ 0 - 1
graphic/skybox.go

@@ -46,7 +46,6 @@ func NewSkybox(data SkyboxData) (*Skybox, error) {
 		matFace.AddTexture(tex)
 		matFace.SetSide(material.SideBack)
 		matFace.SetUseLights(material.UseLightNone)
-		matFace.SetEmissiveColor(&math32.Color{1, 1, 1})
 
 		// Disable writes to the depth buffer (call glDepthMask(GL_FALSE)).
 		// This will cause every other object to draw over the skybox, making it always appear behind everything else.

+ 1 - 1
loader/collada/material.go

@@ -163,7 +163,7 @@ func (d *Decoder) newLambertMaterial(se *Lambert) (material.IMaterial, error) {
 func (d *Decoder) newPhongMaterial(se *Phong) (material.IMaterial, error) {
 
 	// Creates material with default color
-	m := material.NewPhong(&math32.Color{0.5, 0.5, 0.5})
+	m := material.NewStandard(&math32.Color{0.5, 0.5, 0.5})
 
 	// If "diffuse" is Color set its value in the material
 	_, ok := se.Diffuse.(*Color)

+ 9 - 32
loader/gltf/khr_materials_common.go

@@ -22,13 +22,6 @@ func (g *GLTF) loadMaterialCommon(ext interface{}) (material.IMaterial, error) {
 		doubleSided = val.(bool)
 	}
 
-	// Technique
-	technique := ""
-	val, ok = m["technique"]
-	if ok {
-		technique = val.(string)
-	}
-
 	// Transparent
 	transparent := false
 	val, ok = m["transparent"]
@@ -120,33 +113,17 @@ func (g *GLTF) loadMaterialCommon(ext interface{}) (material.IMaterial, error) {
 	//log.Error("shininess:%v", shininess)
 	//log.Error("transparency:%v", transparency)
 
-	var imat material.IMaterial
-	if technique == "PHONG" {
-		pm := material.NewPhong(&math32.Color{diffuse[0], diffuse[1], diffuse[2]})
-		pm.SetAmbientColor(&math32.Color{ambient[0], ambient[1], ambient[2]})
-		pm.SetEmissiveColor(&math32.Color{emission[0], emission[1], emission[2]})
-		pm.SetSpecularColor(&math32.Color{specular[0], specular[1], specular[2]})
-		pm.SetShininess(shininess)
-		pm.SetOpacity(transparency)
-		if texDiffuse != nil {
-			pm.AddTexture(texDiffuse)
-		}
-		imat = pm
-	} else {
-		sm := material.NewStandard(&math32.Color{diffuse[0], diffuse[1], diffuse[2]})
-		sm.SetAmbientColor(&math32.Color{ambient[0], ambient[1], ambient[2]})
-		sm.SetEmissiveColor(&math32.Color{emission[0], emission[1], emission[2]})
-		sm.SetSpecularColor(&math32.Color{specular[0], specular[1], specular[2]})
-		sm.SetShininess(shininess)
-		sm.SetOpacity(transparency)
-		if texDiffuse != nil {
-			sm.AddTexture(texDiffuse)
-		}
-		imat = sm
+	mat := material.NewStandard(&math32.Color{diffuse[0], diffuse[1], diffuse[2]})
+	mat.SetAmbientColor(&math32.Color{ambient[0], ambient[1], ambient[2]})
+	mat.SetEmissiveColor(&math32.Color{emission[0], emission[1], emission[2]})
+	mat.SetSpecularColor(&math32.Color{specular[0], specular[1], specular[2]})
+	mat.SetShininess(shininess)
+	mat.SetOpacity(transparency)
+	if texDiffuse != nil {
+		mat.AddTexture(texDiffuse)
 	}
 
 	// Double Sided
-	mat := imat.GetMaterial()
 	if doubleSided {
 		mat.SetSide(material.SideDouble)
 	} else {
@@ -159,5 +136,5 @@ func (g *GLTF) loadMaterialCommon(ext interface{}) (material.IMaterial, error) {
 	} else {
 		mat.SetDepthMask(false)
 	}
-	return imat, nil
+	return mat, nil
 }

+ 2 - 2
loader/obj/obj.go

@@ -257,7 +257,7 @@ func (dec *Decoder) NewMesh(obj *Object) (*graphic.Mesh, error) {
 		}
 
 		// Creates material for mesh
-		mat := material.NewPhong(&matDesc.Diffuse)
+		mat := material.NewStandard(&matDesc.Diffuse)
 		ambientColor := mat.AmbientColor()
 		mat.SetAmbientColor(ambientColor.Multiply(&matDesc.Ambient))
 		mat.SetSpecularColor(&matDesc.Specular)
@@ -292,7 +292,7 @@ func (dec *Decoder) NewMesh(obj *Object) (*graphic.Mesh, error) {
 		}
 
 		// Creates material for mesh
-		matGroup := material.NewPhong(&matDesc.Diffuse)
+		matGroup := material.NewStandard(&matDesc.Diffuse)
 		ambientColor := matGroup.AmbientColor()
 		matGroup.SetAmbientColor(ambientColor.Multiply(&matDesc.Ambient))
 		matGroup.SetSpecularColor(&matDesc.Specular)

+ 0 - 12
material/logger.go

@@ -1,12 +0,0 @@
-// Copyright 2016 The G3N Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package material
-
-import (
-	"github.com/g3n/engine/util/logger"
-)
-
-// Package logger
-var log = logger.New("MATERIAL", logger.Default)

+ 47 - 41
material/material.go

@@ -2,41 +2,46 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package material contains several types of materials which
-// can be used to set the appearance of graphic object
+// Package material contains virtual materials which
+// specify the appearance of graphic objects.
 package material
 
 import (
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/texture"
+	"github.com/g3n/engine/util/logger"
 )
 
-// Side represents the material's visible side(s)
+// Package logger
+var log = logger.New("MATERIAL", logger.Default)
+
+// Side represents the material's visible side(s).
 type Side int
 
 // The face side(s) to be rendered. The non-rendered side will be culled to improve performance.
 const (
-	SideFront  Side = 0
-	SideBack   Side = 1
-	SideDouble Side = 2
+	SideFront = Side(iota)
+	SideBack
+	SideDouble
 )
 
-// Blending
+// Blending specifies the blending mode.
 type Blending int
 
-// The various blending types
+// The various blending types.
 const (
-	BlendingNone        Blending = 0
-	BlendingNormal      Blending = 1
-	BlendingAdditive    Blending = 2
-	BlendingSubtractive Blending = 3
-	BlendingMultiply    Blending = 4
-	BlendingCustom      Blending = 5
+	BlendNone = Blending(iota)
+	BlendNormal
+	BlendAdditive
+	BlendSubtractive
+	BlendMultiply
+	BlendCustom
 )
 
-// UseLights flags
+// UseLights is a bitmask that specifies which types of lights affect the material.
 type UseLights int
 
+// The possible UseLights values.
 const (
 	UseLightNone        UseLights = 0x00
 	UseLightAmbient     UseLights = 0x01
@@ -62,12 +67,12 @@ type Material struct {
 	shaderUnique  bool              // shader has only one instance (does not depend on lights or textures)
 	ShaderDefines gls.ShaderDefines // shader defines
 
-	uselights   UseLights            // Which light types to consider
-	sidevis     Side                 // Face side(s) visibility
+	side        Side                 // Face side(s) visibility
 	blending    Blending             // Blending mode
+	useLights   UseLights            // Which light types to consider
 	transparent bool                 // Whether at all transparent
 	wireframe   bool                 // Whether to render only the wireframe
-	lineWidth   float32              // Line width for lines and mesh wireframe
+	lineWidth   float32              // Line width for lines and wireframe
 	textures    []*texture.Texture2D // List of textures
 
 	polyOffsetFactor float32 // polygon offset factor
@@ -77,13 +82,15 @@ type Material struct {
 	depthTest bool   // Enable depth buffer test
 	depthFunc uint32 // Active depth test function
 
-	// Equations used for custom blending (when blending=BlendingCustom) // TODO implement methods
-	blendRGB      uint32 // separate blend equation for RGB
-	blendAlpha    uint32 // separate blend equation for Alpha
-	blendSrcRGB   uint32 // separate blend func source RGB
-	blendDstRGB   uint32 // separate blend func dest RGB
-	blendSrcAlpha uint32 // separate blend func source Alpha
-	blendDstAlpha uint32 // separate blend func dest Alpha
+	// TODO stencil properties
+
+	// Equations used for custom blending (when blending=BlendCustom) // TODO implement methods
+	blendRGB      uint32 // separate blending equation for RGB
+	blendAlpha    uint32 // separate blending equation for Alpha
+	blendSrcRGB   uint32 // separate blending func source RGB
+	blendDstRGB   uint32 // separate blending func dest RGB
+	blendSrcAlpha uint32 // separate blending func source Alpha
+	blendDstAlpha uint32 // separate blending func dest Alpha
 }
 
 // NewMaterial creates and returns a pointer to a new Material.
@@ -97,14 +104,14 @@ func NewMaterial() *Material {
 func (mat *Material) Init() *Material {
 
 	mat.refcount = 1
-	mat.uselights = UseLightAll
-	mat.sidevis = SideFront
+	mat.useLights = UseLightAll
+	mat.side = SideFront
 	mat.transparent = false
 	mat.wireframe = false
 	mat.depthMask = true
 	mat.depthFunc = gls.LEQUAL
 	mat.depthTest = true
-	mat.blending = BlendingNormal
+	mat.blending = BlendNormal
 	mat.lineWidth = 1.0
 	mat.polyOffsetFactor = 0
 	mat.polyOffsetUnits = 0
@@ -180,25 +187,25 @@ func (mat *Material) ShaderUnique() bool {
 // By default the material will use all lights
 func (mat *Material) SetUseLights(lights UseLights) {
 
-	mat.uselights = lights
+	mat.useLights = lights
 }
 
 // UseLights returns the current use lights bitmask
 func (mat *Material) UseLights() UseLights {
 
-	return mat.uselights
+	return mat.useLights
 }
 
 // SetSide sets the visible side(s) (SideFront | SideBack | SideDouble)
 func (mat *Material) SetSide(side Side) {
 
-	mat.sidevis = side
+	mat.side = side
 }
 
 // Side returns the current side visibility for this material
 func (mat *Material) Side() Side {
 
-	return mat.sidevis
+	return mat.side
 }
 
 // SetTransparent sets whether this material is transparent.
@@ -207,7 +214,7 @@ func (mat *Material) SetTransparent(state bool) {
 	mat.transparent = state
 }
 
-// Transparent returns whether this material is transparent.
+// Transparent returns whether this material has been set as transparent.
 func (mat *Material) Transparent() bool {
 
 	return mat.transparent
@@ -260,7 +267,7 @@ func (mat *Material) SetPolygonOffset(factor, units float32) {
 func (mat *Material) RenderSetup(gs *gls.GLS) {
 
 	// Sets triangle side view mode
-	switch mat.sidevis {
+	switch mat.side {
 	case SideFront:
 		gs.Enable(gls.CULL_FACE)
 		gs.FrontFace(gls.CCW)
@@ -294,27 +301,27 @@ func (mat *Material) RenderSetup(gs *gls.GLS) {
 
 	// Sets blending
 	switch mat.blending {
-	case BlendingNone:
+	case BlendNone:
 		gs.Disable(gls.BLEND)
-	case BlendingNormal:
+	case BlendNormal:
 		gs.Enable(gls.BLEND)
 		gs.BlendEquation(gls.FUNC_ADD)
 		gs.BlendFunc(gls.SRC_ALPHA, gls.ONE_MINUS_SRC_ALPHA)
-	case BlendingAdditive:
+	case BlendAdditive:
 		gs.Enable(gls.BLEND)
 		gs.BlendEquation(gls.FUNC_ADD)
 		gs.BlendFunc(gls.SRC_ALPHA, gls.ONE)
-	case BlendingSubtractive:
+	case BlendSubtractive:
 		gs.Enable(gls.BLEND)
 		gs.BlendEquation(gls.FUNC_ADD)
 		gs.BlendFunc(gls.ZERO, gls.ONE_MINUS_SRC_COLOR)
 		break
-	case BlendingMultiply:
+	case BlendMultiply:
 		gs.Enable(gls.BLEND)
 		gs.BlendEquation(gls.FUNC_ADD)
 		gs.BlendFunc(gls.ZERO, gls.SRC_COLOR)
 		break
-	case BlendingCustom:
+	case BlendCustom:
 		gs.BlendEquationSeparate(mat.blendRGB, mat.blendAlpha)
 		gs.BlendFuncSeparate(mat.blendSrcRGB, mat.blendDstRGB, mat.blendSrcAlpha, mat.blendDstAlpha)
 		break
@@ -350,7 +357,6 @@ func (mat *Material) RemoveTexture(tex *texture.Texture2D) {
 			break
 		}
 	}
-
 }
 
 // HasTexture checks if the material contains the specified texture

+ 0 - 29
material/pbr.txt

@@ -1,29 +0,0 @@
-Physically Based Rendering/Shading
-----------------------------------
-
-https://www.marmoset.co/posts/basic-theory-of-physically-based-rendering/
-
-- albedo: a color which describes the fractions of various colors of light
-  that will scatter back out of a surface.
-  “Diffuse color” is a phrase sometimes used synonymously.
-
-- Reflection
-- Diffusion
-- Energy conservation:
-    - Reflection and diffusion are mutually exclusive.
-- Fresnel
-    - Differing reflectivity that occurs at diffent angles
-- Microsurface
-    - Gloss, smoothness, roughness.
-
-- BRDF - Bidirectional Reflectance Distribution Function.
-    -   Function of View and Light direction - f(l, v)
-    -   For a ray of incoming light from a given direction
-        the BRDF function gives the distribution of outgoing light
-        in all directions.
-    -   For a given view direction, the BRDF gives the relative 
-        contribution of each incoming direction.
-    -   The BRDF varies by light wavelength
-
-
-

+ 0 - 23
material/phong.go

@@ -1,23 +0,0 @@
-// Copyright 2016 The G3N Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package material
-
-import (
-	"github.com/g3n/engine/math32"
-)
-
-// Phong material is identical to the Standard material but
-// the calculation of the lighting model is done in the fragment shader.
-type Phong struct {
-	Standard // Embedded standard material
-}
-
-// NewPhong creates and returns a pointer to a new phong material
-func NewPhong(color *math32.Color) *Phong {
-
-	pm := new(Phong)
-	pm.Standard.Init("phong", color)
-	return pm
-}

+ 0 - 5
renderer/shaders/basic_fragment.glsl

@@ -1,7 +1,3 @@
-//
-// Fragment Shader template
-//
-
 precision highp float;
 
 in vec3 Color;
@@ -11,4 +7,3 @@ void main() {
 
     FragColor = vec4(Color, 1.0);
 }
-

+ 0 - 5
renderer/shaders/basic_vertex.glsl

@@ -1,6 +1,3 @@
-//
-// Vertex shader basic
-//
 #include <attributes>
 
 // Model uniforms
@@ -14,5 +11,3 @@ void main() {
     Color = VertexColor;
     gl_Position = MVP * vec4(VertexPosition, 1.0);
 }
-
-

+ 0 - 1
renderer/shaders/include/lights.glsl

@@ -37,4 +37,3 @@
     #define SpotLightLinearDecay(a)		SpotLight[5*a+3].z
     #define SpotLightQuadraticDecay(a)	SpotLight[5*a+4].x
 #endif
-

+ 2 - 1
renderer/shaders/include/material.glsl

@@ -24,6 +24,7 @@ uniform vec3 Material[6];
     #define MatTexRepeat(a)		MatTexinfo[(3*a)+1]
     #define MatTexFlipY(a)		bool(MatTexinfo[(3*a)+2].x)
     #define MatTexVisible(a)	bool(MatTexinfo[(3*a)+2].y)
+    #define MatTex(a)           MatTexture[a]
 
 // GLSL 3.30 does not allow indexing texture sampler with non constant values.
 // This function is used to mix the texture with the specified index with the material color.
@@ -32,7 +33,7 @@ uniform vec3 Material[6];
 // vec4 texMixed
 vec4 MIX_TEXTURE(vec4 texMixed, vec2 FragTexcoord, int i) {
     if (MatTexVisible(i)) {
-        vec4 texColor = texture(MatTexture[i], FragTexcoord * MatTexRepeat(i) + MatTexOffset(i));
+        vec4 texColor = texture(MatTex(i), FragTexcoord * MatTexRepeat(i) + MatTexOffset(i));
         if (i == 0) {
             texMixed = texColor;
         } else {

+ 9 - 1
renderer/shaders/include/phong_model.glsl

@@ -25,7 +25,10 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     vec3 diffuseTotal  = vec3(0.0);
     vec3 specularTotal = vec3(0.0);
 
+    bool noLights = true;
+
 #if AMB_LIGHTS>0
+    noLights = false;
     // Ambient lights
     for (int i = 0; i < AMB_LIGHTS; ++i) {
         ambientTotal += AmbientLightColor[i] * matAmbient;
@@ -33,6 +36,7 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
 #endif
 
 #if DIR_LIGHTS>0
+    noLights = false;
     // Directional lights
     for (int i = 0; i < DIR_LIGHTS; ++i) {
         vec3 lightDirection = normalize(DirLightPosition(i)); // Vector from fragment to light source
@@ -45,6 +49,7 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
 #endif
 
 #if POINT_LIGHTS>0
+    noLights = false;
     // Point lights
     for (int i = 0; i < POINT_LIGHTS; ++i) {
         vec3 lightDirection = PointLightPosition(i) - vec3(position); // Vector from fragment to light source
@@ -61,6 +66,7 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
 #endif
 
 #if SPOT_LIGHTS>0
+    noLights = false;
     for (int i = 0; i < SPOT_LIGHTS; ++i) {
         // Calculates the direction and distance from the current vertex to this spot light.
         vec3 lightDirection = SpotLightPosition(i) - vec3(position); // Vector from fragment to light source
@@ -81,7 +87,9 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
         }
     }
 #endif
-
+    if (noLights) {
+        diffuseTotal = matDiffuse;
+    }
     // Sets output colors
     ambdiff = ambientTotal + MatEmissiveColor + diffuseTotal;
     spec = specularTotal;

+ 0 - 5
renderer/shaders/panel_fragment.glsl

@@ -1,7 +1,3 @@
-//
-// Fragment Shader template
-//
-
 precision highp float;
 
 // Texture uniforms
@@ -124,4 +120,3 @@ void main() {
     // Fragment is in margins area (always transparent)
     FragColor = vec4(1,1,1,0);
 }
-

+ 0 - 4
renderer/shaders/panel_vertex.glsl

@@ -1,6 +1,3 @@
-//
-// Vertex shader panel
-//
 #include <attributes>
 
 // Model uniforms
@@ -21,4 +18,3 @@ void main() {
     vec4 pos = vec4(VertexPosition.xyz, 1);
     gl_Position = ModelMatrix * pos;
 }
-

+ 0 - 52
renderer/shaders/phong_fragment.glsl

@@ -1,52 +0,0 @@
-//
-// Fragment Shader template
-//
-
-precision highp float;
-
-// Inputs from vertex shader
-in vec4 Position;       // Vertex position in camera coordinates.
-in vec3 Normal;         // Vertex normal in camera coordinates.
-in vec3 CamDir;         // Direction from vertex to camera
-in vec2 FragTexcoord;
-
-#include <lights>
-#include <material>
-#include <phong_model>
-
-// Final fragment color
-out vec4 FragColor;
-
-void main() {
-
-    // Mix material color with textures colors
-    vec4 texMixed = vec4(1);
-    #if MAT_TEXTURES==1
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 0);
-    #elif MAT_TEXTURES==2
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 0);
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 1);
-    #elif MAT_TEXTURES==3
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 0);
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 1);
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 2);
-    #endif
-
-    // Combine material with texture colors
-    vec4 matDiffuse = vec4(MatDiffuseColor, MatOpacity) * texMixed;
-    vec4 matAmbient = vec4(MatAmbientColor, MatOpacity) * texMixed;
-
-    // Inverts the fragment normal if not FrontFacing
-    vec3 fragNormal = Normal;
-    if (!gl_FrontFacing) {
-        fragNormal = -fragNormal;
-    }
-
-    // Calculates the Ambient+Diffuse and Specular colors for this fragment using the Phong model.
-    vec3 Ambdiff, Spec;
-    phongModel(Position, fragNormal, CamDir, vec3(matAmbient), vec3(matDiffuse), Ambdiff, Spec);
-
-    // Final fragment color
-    FragColor = min(vec4(Ambdiff + Spec, matDiffuse.a), vec4(1.0));
-}
-

+ 0 - 48
renderer/shaders/phong_vertex.glsl

@@ -1,48 +0,0 @@
-//
-// Vertex Shader
-//
-#include <attributes>
-
-// Model uniforms
-uniform mat4 ModelViewMatrix;
-uniform mat3 NormalMatrix;
-uniform mat4 MVP;
-
-#include <material>
-#include <morphtarget_vertex_declaration>
-#include <bones_vertex_declaration>
-
-// Output variables for Fragment shader
-out vec4 Position;
-out vec3 Normal;
-out vec3 CamDir;
-out vec2 FragTexcoord;
-
-void main() {
-
-    // Transform this vertex position to camera coordinates.
-    Position = ModelViewMatrix * vec4(VertexPosition, 1.0);
-
-    // Transform this vertex normal to camera coordinates.
-    Normal = normalize(NormalMatrix * VertexNormal);
-
-    // Calculate the direction vector from the vertex to the camera
-    // The camera is at 0,0,0
-    CamDir = normalize(-Position.xyz);
-
-    // Flips texture coordinate Y if requested.
-    vec2 texcoord = VertexTexcoord;
-#if MAT_TEXTURES>0
-    if (MatTexFlipY(0)) {
-        texcoord.y = 1.0 - texcoord.y;
-    }
-#endif
-    FragTexcoord = texcoord;
-    vec3 vPosition = VertexPosition;
-    mat4 finalWorld = mat4(1.0);
-    #include <morphtarget_vertex>
-    #include <bones_vertex>
-
-    gl_Position = MVP * finalWorld * vec4(vPosition, 1.0);
-}
-

+ 0 - 2
renderer/shaders/physical_fragment.glsl

@@ -411,5 +411,3 @@ void main() {
     // Final fragment color
     FragColor = vec4(pow(color,vec3(1.0/2.2)), baseColor.a);
 }
-
-

+ 0 - 2
renderer/shaders/physical_vertex.glsl

@@ -41,5 +41,3 @@ void main() {
     gl_Position = MVP * finalWorld * vec4(vPosition, 1.0);
 
 }
-
-

+ 0 - 1
renderer/shaders/point_fragment.glsl

@@ -45,4 +45,3 @@ void main() {
     // Generates final color
     FragColor = min(vec4(Color, MatOpacity) * texMixed, vec4(1));
 }
-

+ 3 - 1
renderer/shaders/point_vertex.glsl

@@ -2,6 +2,7 @@
 
 // Model uniforms
 uniform mat4 MVP;
+uniform mat4 MV;
 
 // Material uniforms
 #include <material>
@@ -22,7 +23,8 @@ void main() {
     gl_Position = pos;
 
     // Sets the size of the rasterized point decreasing with distance
-    gl_PointSize = (1.0 - pos.z / pos.w) * MatPointSize;
+    vec4 posMV = MV * vec4(VertexPosition, 1.0);
+    gl_PointSize = MatPointSize / -posMV.z;
 
     // Outputs color
     Color = MatEmissiveColor;

+ 55 - 185
renderer/shaders/sources.go

@@ -97,7 +97,6 @@ const include_lights_source = `//
     #define SpotLightLinearDecay(a)		SpotLight[5*a+3].z
     #define SpotLightQuadraticDecay(a)	SpotLight[5*a+4].x
 #endif
-
 `
 
 const include_material_source = `//
@@ -126,6 +125,7 @@ uniform vec3 Material[6];
     #define MatTexRepeat(a)		MatTexinfo[(3*a)+1]
     #define MatTexFlipY(a)		bool(MatTexinfo[(3*a)+2].x)
     #define MatTexVisible(a)	bool(MatTexinfo[(3*a)+2].y)
+    #define MatTex(a)           MatTexture[a]
 
 // GLSL 3.30 does not allow indexing texture sampler with non constant values.
 // This function is used to mix the texture with the specified index with the material color.
@@ -134,7 +134,7 @@ uniform vec3 Material[6];
 // vec4 texMixed
 vec4 MIX_TEXTURE(vec4 texMixed, vec2 FragTexcoord, int i) {
     if (MatTexVisible(i)) {
-        vec4 texColor = texture(MatTexture[i], FragTexcoord * MatTexRepeat(i) + MatTexOffset(i));
+        vec4 texColor = texture(MatTex(i), FragTexcoord * MatTexRepeat(i) + MatTexOffset(i));
         if (i == 0) {
             texMixed = texColor;
         } else {
@@ -206,7 +206,10 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     vec3 diffuseTotal  = vec3(0.0);
     vec3 specularTotal = vec3(0.0);
 
+    bool noLights = true;
+
 #if AMB_LIGHTS>0
+    noLights = false;
     // Ambient lights
     for (int i = 0; i < AMB_LIGHTS; ++i) {
         ambientTotal += AmbientLightColor[i] * matAmbient;
@@ -214,6 +217,7 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
 #endif
 
 #if DIR_LIGHTS>0
+    noLights = false;
     // Directional lights
     for (int i = 0; i < DIR_LIGHTS; ++i) {
         vec3 lightDirection = normalize(DirLightPosition(i)); // Vector from fragment to light source
@@ -226,6 +230,7 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
 #endif
 
 #if POINT_LIGHTS>0
+    noLights = false;
     // Point lights
     for (int i = 0; i < POINT_LIGHTS; ++i) {
         vec3 lightDirection = PointLightPosition(i) - vec3(position); // Vector from fragment to light source
@@ -242,6 +247,7 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
 #endif
 
 #if SPOT_LIGHTS>0
+    noLights = false;
     for (int i = 0; i < SPOT_LIGHTS; ++i) {
         // Calculates the direction and distance from the current vertex to this spot light.
         vec3 lightDirection = SpotLightPosition(i) - vec3(position); // Vector from fragment to light source
@@ -262,18 +268,16 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
         }
     }
 #endif
-
+    if (noLights) {
+        diffuseTotal = matDiffuse;
+    }
     // Sets output colors
     ambdiff = ambientTotal + MatEmissiveColor + diffuseTotal;
     spec = specularTotal;
 }
 `
 
-const basic_fragment_source = `//
-// Fragment Shader template
-//
-
-precision highp float;
+const basic_fragment_source = `precision highp float;
 
 in vec3 Color;
 out vec4 FragColor;
@@ -282,13 +286,9 @@ void main() {
 
     FragColor = vec4(Color, 1.0);
 }
-
 `
 
-const basic_vertex_source = `//
-// Vertex shader basic
-//
-#include <attributes>
+const basic_vertex_source = `#include <attributes>
 
 // Model uniforms
 uniform mat4 MVP;
@@ -301,15 +301,9 @@ void main() {
     Color = VertexColor;
     gl_Position = MVP * vec4(VertexPosition, 1.0);
 }
-
-
 `
 
-const panel_fragment_source = `//
-// Fragment Shader template
-//
-
-precision highp float;
+const panel_fragment_source = `precision highp float;
 
 // Texture uniforms
 uniform sampler2D	MatTexture;
@@ -431,13 +425,9 @@ void main() {
     // Fragment is in margins area (always transparent)
     FragColor = vec4(1,1,1,0);
 }
-
 `
 
-const panel_vertex_source = `//
-// Vertex shader panel
-//
-#include <attributes>
+const panel_vertex_source = `#include <attributes>
 
 // Model uniforms
 uniform mat4 ModelMatrix;
@@ -457,111 +447,6 @@ void main() {
     vec4 pos = vec4(VertexPosition.xyz, 1);
     gl_Position = ModelMatrix * pos;
 }
-
-`
-
-const phong_fragment_source = `//
-// Fragment Shader template
-//
-
-precision highp float;
-
-// Inputs from vertex shader
-in vec4 Position;       // Vertex position in camera coordinates.
-in vec3 Normal;         // Vertex normal in camera coordinates.
-in vec3 CamDir;         // Direction from vertex to camera
-in vec2 FragTexcoord;
-
-#include <lights>
-#include <material>
-#include <phong_model>
-
-// Final fragment color
-out vec4 FragColor;
-
-void main() {
-
-    // Mix material color with textures colors
-    vec4 texMixed = vec4(1);
-    #if MAT_TEXTURES==1
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 0);
-    #elif MAT_TEXTURES==2
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 0);
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 1);
-    #elif MAT_TEXTURES==3
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 0);
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 1);
-        texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 2);
-    #endif
-
-    // Combine material with texture colors
-    vec4 matDiffuse = vec4(MatDiffuseColor, MatOpacity) * texMixed;
-    vec4 matAmbient = vec4(MatAmbientColor, MatOpacity) * texMixed;
-
-    // Inverts the fragment normal if not FrontFacing
-    vec3 fragNormal = Normal;
-    if (!gl_FrontFacing) {
-        fragNormal = -fragNormal;
-    }
-
-    // Calculates the Ambient+Diffuse and Specular colors for this fragment using the Phong model.
-    vec3 Ambdiff, Spec;
-    phongModel(Position, fragNormal, CamDir, vec3(matAmbient), vec3(matDiffuse), Ambdiff, Spec);
-
-    // Final fragment color
-    FragColor = min(vec4(Ambdiff + Spec, matDiffuse.a), vec4(1.0));
-}
-
-`
-
-const phong_vertex_source = `//
-// Vertex Shader
-//
-#include <attributes>
-
-// Model uniforms
-uniform mat4 ModelViewMatrix;
-uniform mat3 NormalMatrix;
-uniform mat4 MVP;
-
-#include <material>
-#include <morphtarget_vertex_declaration>
-#include <bones_vertex_declaration>
-
-// Output variables for Fragment shader
-out vec4 Position;
-out vec3 Normal;
-out vec3 CamDir;
-out vec2 FragTexcoord;
-
-void main() {
-
-    // Transform this vertex position to camera coordinates.
-    Position = ModelViewMatrix * vec4(VertexPosition, 1.0);
-
-    // Transform this vertex normal to camera coordinates.
-    Normal = normalize(NormalMatrix * VertexNormal);
-
-    // Calculate the direction vector from the vertex to the camera
-    // The camera is at 0,0,0
-    CamDir = normalize(-Position.xyz);
-
-    // Flips texture coordinate Y if requested.
-    vec2 texcoord = VertexTexcoord;
-#if MAT_TEXTURES>0
-    if (MatTexFlipY(0)) {
-        texcoord.y = 1.0 - texcoord.y;
-    }
-#endif
-    FragTexcoord = texcoord;
-    vec3 vPosition = VertexPosition;
-    mat4 finalWorld = mat4(1.0);
-    #include <morphtarget_vertex>
-    #include <bones_vertex>
-
-    gl_Position = MVP * finalWorld * vec4(vPosition, 1.0);
-}
-
 `
 
 const physical_fragment_source = `//
@@ -977,8 +862,6 @@ void main() {
     // Final fragment color
     FragColor = vec4(pow(color,vec3(1.0/2.2)), baseColor.a);
 }
-
-
 `
 
 const physical_vertex_source = `//
@@ -1024,8 +907,6 @@ void main() {
     gl_Position = MVP * finalWorld * vec4(vPosition, 1.0);
 
 }
-
-
 `
 
 const point_fragment_source = `precision highp float;
@@ -1075,13 +956,13 @@ void main() {
     // Generates final color
     FragColor = min(vec4(Color, MatOpacity) * texMixed, vec4(1));
 }
-
 `
 
 const point_vertex_source = `#include <attributes>
 
 // Model uniforms
 uniform mat4 MVP;
+uniform mat4 MV;
 
 // Material uniforms
 #include <material>
@@ -1102,7 +983,8 @@ void main() {
     gl_Position = pos;
 
     // Sets the size of the rasterized point decreasing with distance
-    gl_PointSize = (1.0 - pos.z / pos.w) * MatPointSize;
+    vec4 posMV = MV * vec4(VertexPosition, 1.0);
+    gl_PointSize = MatPointSize / -posMV.z;
 
     // Outputs color
     Color = MatEmissiveColor;
@@ -1110,25 +992,21 @@ void main() {
 
 `
 
-const standard_fragment_source = `//
-// Fragment Shader template
-//
+const standard_fragment_source = `precision highp float;
 
-precision highp float;
+// Inputs from vertex shader
+in vec4 Position;     // Fragment position in camera coordinates
+in vec3 Normal;       // Interpolated fragment normal in camera coordinates
+in vec3 CamDir;       // Direction from fragment to camera
+in vec2 FragTexcoord; // Fragment texture coordinates
 
+#include <lights>
 #include <material>
+#include <phong_model>
 
-// Inputs from Vertex shader
-in vec3 ColorFrontAmbdiff;
-in vec3 ColorFrontSpec;
-in vec3 ColorBackAmbdiff;
-in vec3 ColorBackSpec;
-in vec2 FragTexcoord;
-
-// Output
+// Final fragment color
 out vec4 FragColor;
 
-
 void main() {
 
     // Mix material color with textures colors
@@ -1144,63 +1022,59 @@ void main() {
         texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 2);
     #endif
 
-    vec4 colorAmbDiff;
-    vec4 colorSpec;
-    if (gl_FrontFacing) {
-        colorAmbDiff = vec4(ColorFrontAmbdiff, MatOpacity);
-        colorSpec = vec4(ColorFrontSpec, 0);
-    } else {
-        colorAmbDiff = vec4(ColorBackAmbdiff, MatOpacity);
-        colorSpec = vec4(ColorBackSpec, 0);
+    // Combine material with texture colors
+    vec4 matDiffuse = vec4(MatDiffuseColor, MatOpacity) * texMixed;
+    vec4 matAmbient = vec4(MatAmbientColor, MatOpacity) * texMixed;
+
+    // Normalize interpolated normal as it may have shrinked
+    vec3 fragNormal = normalize(Normal);
+
+    // Invert the fragment normal if not FrontFacing
+    if (!gl_FrontFacing) {
+        fragNormal = -fragNormal;
     }
-    FragColor = min(colorAmbDiff * texMixed + colorSpec, vec4(1));
-}
 
+    // Calculates the Ambient+Diffuse and Specular colors for this fragment using the Phong model.
+    vec3 Ambdiff, Spec;
+    phongModel(Position, fragNormal, CamDir, vec3(matAmbient), vec3(matDiffuse), Ambdiff, Spec);
+
+    // Final fragment color
+    FragColor = min(vec4(Ambdiff + Spec, matDiffuse.a), vec4(1.0));
+}
 `
 
-const standard_vertex_source = `//
-// Vertex shader standard
-//
-#include <attributes>
+const standard_vertex_source = `#include <attributes>
 
 // Model uniforms
 uniform mat4 ModelViewMatrix;
 uniform mat3 NormalMatrix;
 uniform mat4 MVP;
 
-#include <lights>
 #include <material>
-#include <phong_model>
 #include <morphtarget_vertex_declaration>
 #include <bones_vertex_declaration>
 
-// Outputs for the fragment shader.
-out vec3 ColorFrontAmbdiff;
-out vec3 ColorFrontSpec;
-out vec3 ColorBackAmbdiff;
-out vec3 ColorBackSpec;
+// Output variables for Fragment shader
+out vec4 Position;
+out vec3 Normal;
+out vec3 CamDir;
 out vec2 FragTexcoord;
 
 void main() {
 
-    // Transform this vertex normal to camera coordinates.
-    vec3 Normal = normalize(NormalMatrix * VertexNormal);
+    // Transform this vertex position to camera coordinates.
+    Position = ModelViewMatrix * vec4(VertexPosition, 1.0);
 
-    // Calculate this vertex position in camera coordinates
-    vec4 Position = ModelViewMatrix * vec4(VertexPosition, 1.0);
+    // Transform this vertex normal to camera coordinates.
+    Normal = normalize(NormalMatrix * VertexNormal);
 
     // Calculate the direction vector from the vertex to the camera
     // The camera is at 0,0,0
-    vec3 camDir = normalize(-Position.xyz);
-
-    // Calculates the vertex Ambient+Diffuse and Specular colors using the Phong model
-    // for the front and back
-    phongModel(Position,  Normal, camDir, MatAmbientColor, MatDiffuseColor, ColorFrontAmbdiff, ColorFrontSpec);
-    phongModel(Position, -Normal, camDir, MatAmbientColor, MatDiffuseColor, ColorBackAmbdiff, ColorBackSpec);
+    CamDir = normalize(-Position.xyz);
 
     vec2 texcoord = VertexTexcoord;
 #if MAT_TEXTURES > 0
-    // Flips texture coordinate Y if requested.
+    // Flip texture coordinate Y if requested.
     if (MatTexFlipY(0)) {
         texcoord.y = 1.0 - texcoord.y;
     }
@@ -1213,7 +1087,6 @@ void main() {
 
     gl_Position = MVP * finalWorld * vec4(vPosition, 1.0);
 }
-
 `
 
 // Maps include name with its source code
@@ -1238,8 +1111,6 @@ var shaderMap = map[string]string{
 	"basic_vertex":      basic_vertex_source,
 	"panel_fragment":    panel_fragment_source,
 	"panel_vertex":      panel_vertex_source,
-	"phong_fragment":    phong_fragment_source,
-	"phong_vertex":      phong_vertex_source,
 	"physical_fragment": physical_fragment_source,
 	"physical_vertex":   physical_vertex_source,
 	"point_fragment":    point_fragment_source,
@@ -1253,7 +1124,6 @@ var programMap = map[string]ProgramInfo{
 
 	"basic":    {"basic_vertex", "basic_fragment", ""},
 	"panel":    {"panel_vertex", "panel_fragment", ""},
-	"phong":    {"phong_vertex", "phong_fragment", ""},
 	"physical": {"physical_vertex", "physical_fragment", ""},
 	"point":    {"point_vertex", "point_fragment", ""},
 	"standard": {"standard_vertex", "standard_fragment", ""},

+ 26 - 23
renderer/shaders/standard_fragment.glsl

@@ -1,22 +1,18 @@
-//
-// Fragment Shader template
-//
-
 precision highp float;
 
-#include <material>
+// Inputs from vertex shader
+in vec4 Position;     // Fragment position in camera coordinates
+in vec3 Normal;       // Interpolated fragment normal in camera coordinates
+in vec3 CamDir;       // Direction from fragment to camera
+in vec2 FragTexcoord; // Fragment texture coordinates
 
-// Inputs from Vertex shader
-in vec3 ColorFrontAmbdiff;
-in vec3 ColorFrontSpec;
-in vec3 ColorBackAmbdiff;
-in vec3 ColorBackSpec;
-in vec2 FragTexcoord;
+#include <lights>
+#include <material>
+#include <phong_model>
 
-// Output
+// Final fragment color
 out vec4 FragColor;
 
-
 void main() {
 
     // Mix material color with textures colors
@@ -32,15 +28,22 @@ void main() {
         texMixed = MIX_TEXTURE(texMixed, FragTexcoord, 2);
     #endif
 
-    vec4 colorAmbDiff;
-    vec4 colorSpec;
-    if (gl_FrontFacing) {
-        colorAmbDiff = vec4(ColorFrontAmbdiff, MatOpacity);
-        colorSpec = vec4(ColorFrontSpec, 0);
-    } else {
-        colorAmbDiff = vec4(ColorBackAmbdiff, MatOpacity);
-        colorSpec = vec4(ColorBackSpec, 0);
+    // Combine material with texture colors
+    vec4 matDiffuse = vec4(MatDiffuseColor, MatOpacity) * texMixed;
+    vec4 matAmbient = vec4(MatAmbientColor, MatOpacity) * texMixed;
+
+    // Normalize interpolated normal as it may have shrinked
+    vec3 fragNormal = normalize(Normal);
+
+    // Invert the fragment normal if not FrontFacing
+    if (!gl_FrontFacing) {
+        fragNormal = -fragNormal;
     }
-    FragColor = min(colorAmbDiff * texMixed + colorSpec, vec4(1));
-}
 
+    // Calculates the Ambient+Diffuse and Specular colors for this fragment using the Phong model.
+    vec3 Ambdiff, Spec;
+    phongModel(Position, fragNormal, CamDir, vec3(matAmbient), vec3(matDiffuse), Ambdiff, Spec);
+
+    // Final fragment color
+    FragColor = min(vec4(Ambdiff + Spec, matDiffuse.a), vec4(1.0));
+}

+ 12 - 24
renderer/shaders/standard_vertex.glsl

@@ -1,6 +1,3 @@
-//
-// Vertex shader standard
-//
 #include <attributes>
 
 // Model uniforms
@@ -8,39 +5,30 @@ uniform mat4 ModelViewMatrix;
 uniform mat3 NormalMatrix;
 uniform mat4 MVP;
 
-#include <lights>
 #include <material>
-#include <phong_model>
 #include <morphtarget_vertex_declaration>
 #include <bones_vertex_declaration>
 
-// Outputs for the fragment shader.
-out vec3 ColorFrontAmbdiff;
-out vec3 ColorFrontSpec;
-out vec3 ColorBackAmbdiff;
-out vec3 ColorBackSpec;
+// Output variables for Fragment shader
+out vec4 Position;
+out vec3 Normal;
+out vec3 CamDir;
 out vec2 FragTexcoord;
 
 void main() {
 
-    // Transform this vertex normal to camera coordinates.
-    vec3 Normal = normalize(NormalMatrix * VertexNormal);
+    // Transform vertex position to camera coordinates
+    Position = ModelViewMatrix * vec4(VertexPosition, 1.0);
 
-    // Calculate this vertex position in camera coordinates
-    vec4 Position = ModelViewMatrix * vec4(VertexPosition, 1.0);
+    // Transform vertex normal to camera coordinates
+    Normal = normalize(NormalMatrix * VertexNormal);
 
-    // Calculate the direction vector from the vertex to the camera
-    // The camera is at 0,0,0
-    vec3 camDir = normalize(-Position.xyz);
-
-    // Calculates the vertex Ambient+Diffuse and Specular colors using the Phong model
-    // for the front and back
-    phongModel(Position,  Normal, camDir, MatAmbientColor, MatDiffuseColor, ColorFrontAmbdiff, ColorFrontSpec);
-    phongModel(Position, -Normal, camDir, MatAmbientColor, MatDiffuseColor, ColorBackAmbdiff, ColorBackSpec);
+    // Calculate the direction vector from the vertex to the camera (origin)
+    CamDir = normalize(-Position.xyz);
 
     vec2 texcoord = VertexTexcoord;
 #if MAT_TEXTURES > 0
-    // Flips texture coordinate Y if requested.
+    // Flip texture coordinate Y if requested.
     if (MatTexFlipY(0)) {
         texcoord.y = 1.0 - texcoord.y;
     }
@@ -51,6 +39,6 @@ void main() {
     #include <morphtarget_vertex>
     #include <bones_vertex>
 
+    // Output projected and transformed vertex position
     gl_Position = MVP * finalWorld * vec4(vPosition, 1.0);
 }
-