Parcourir la source

Implement Blinn-Phong model and material
It's very similar to the Phong model so we only need to pass a parameter to the phong_model shader

Maugre il y a 4 ans
Parent
commit
e56e219515
3 fichiers modifiés avec 56 ajouts et 6 suppressions
  1. 10 0
      material/standard.go
  2. 23 3
      renderer/shaders/include/phong_model.glsl
  3. 23 3
      renderer/shaders/sources.go

+ 10 - 0
material/standard.go

@@ -38,6 +38,16 @@ func NewStandard(color *math32.Color) *Standard {
 	return ms
 }
 
+// NewBlinnPhong creates and returns a pointer to a new Standard material using Blinn-Phong model
+// It is very close to Standard (Phong) model so we need only pass a parameter
+func NewBlinnPhong(color *math32.Color) *Standard {
+
+	ms := new(Standard)
+	ms.Init("standard", color)
+	ms.ShaderDefines.Set("BLINN", "true")
+	return ms
+}
+
 // Init initializes the material setting the specified shader and color
 // It is used mainly when the material is embedded in another type
 func (ms *Standard) Init(shader string, color *math32.Color) {

+ 23 - 3
renderer/shaders/include/phong_model.glsl

@@ -28,6 +28,8 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     bool noLights = true;
     const float EPS = 0.00001;
 
+    float specular;
+
 #if AMB_LIGHTS>0
     noLights = false;
     // Ambient lights
@@ -44,7 +46,13 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
         float dotNormal = dot(lightDirection, normal); // Dot product between light direction and fragment normal
         if (dotNormal > EPS) { // If the fragment is lit
             diffuseTotal += DirLightColor(i) * matDiffuse * dotNormal;
-            specularTotal += DirLightColor(i) * MatSpecularColor * pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+
+#ifdef BLINN
+            specular = pow(max(dot(normal, normalize(lightDirection + camDir)), 0.0), MatShininess);
+#else
+            specular = pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+#endif
+            specularTotal += DirLightColor(i) * MatSpecularColor * specular;
         }
     }
 #endif
@@ -61,7 +69,13 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
             float attenuation = 1.0 / (1.0 + lightDistance * (PointLightLinearDecay(i) + PointLightQuadraticDecay(i) * lightDistance));
             vec3 attenuatedColor = PointLightColor(i) * attenuation;
             diffuseTotal += attenuatedColor * matDiffuse * dotNormal;
-            specularTotal += attenuatedColor * MatSpecularColor * pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+
+#ifdef BLINN
+            specular = pow(max(dot(normal, normalize(lightDirection + camDir)), 0.0), MatShininess);
+#else
+            specular = pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+#endif
+            specularTotal += attenuatedColor * MatSpecularColor * specular;
         }
     }
 #endif
@@ -83,7 +97,13 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
                 float spotFactor = pow(angleDot, SpotLightAngularDecay(i));
                 vec3 attenuatedColor = SpotLightColor(i) * attenuation * spotFactor;
                 diffuseTotal += attenuatedColor * matDiffuse * dotNormal;
-                specularTotal += attenuatedColor * MatSpecularColor * pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+
+#ifdef BLINN
+                specular = pow(max(dot(normal, normalize(lightDirection + camDir)), 0.0), MatShininess);
+#else
+                specular = pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+#endif
+                specularTotal += attenuatedColor * MatSpecularColor * specular;
             }
         }
     }

+ 23 - 3
renderer/shaders/sources.go

@@ -192,6 +192,8 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     bool noLights = true;
     const float EPS = 0.00001;
 
+    float specular;
+
 #if AMB_LIGHTS>0
     noLights = false;
     // Ambient lights
@@ -208,7 +210,13 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
         float dotNormal = dot(lightDirection, normal); // Dot product between light direction and fragment normal
         if (dotNormal > EPS) { // If the fragment is lit
             diffuseTotal += DirLightColor(i) * matDiffuse * dotNormal;
-            specularTotal += DirLightColor(i) * MatSpecularColor * pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+
+#ifdef BLINN
+            specular = pow(max(dot(normal, normalize(lightDirection + camDir)), 0.0), MatShininess);
+#else
+            specular = pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+#endif
+            specularTotal += DirLightColor(i) * MatSpecularColor * specular;
         }
     }
 #endif
@@ -225,7 +233,13 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
             float attenuation = 1.0 / (1.0 + lightDistance * (PointLightLinearDecay(i) + PointLightQuadraticDecay(i) * lightDistance));
             vec3 attenuatedColor = PointLightColor(i) * attenuation;
             diffuseTotal += attenuatedColor * matDiffuse * dotNormal;
-            specularTotal += attenuatedColor * MatSpecularColor * pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+
+#ifdef BLINN
+            specular = pow(max(dot(normal, normalize(lightDirection + camDir)), 0.0), MatShininess);
+#else
+            specular = pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+#endif
+            specularTotal += attenuatedColor * MatSpecularColor * specular;
         }
     }
 #endif
@@ -247,7 +261,13 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
                 float spotFactor = pow(angleDot, SpotLightAngularDecay(i));
                 vec3 attenuatedColor = SpotLightColor(i) * attenuation * spotFactor;
                 diffuseTotal += attenuatedColor * matDiffuse * dotNormal;
-                specularTotal += attenuatedColor * MatSpecularColor * pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+
+#ifdef BLINN
+                specular = pow(max(dot(normal, normalize(lightDirection + camDir)), 0.0), MatShininess);
+#else
+                specular = pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
+#endif
+                specularTotal += attenuatedColor * MatSpecularColor * specular;
             }
         }
     }