[Bf-blender-cvs] [50dc534] strand_gpu: Implementation of the Kajiya-Kay shading model for hair strands.

Lukas Tönne noreply at git.blender.org
Thu Jul 7 11:22:34 CEST 2016


Commit: 50dc534f0e35c874cb774c2c6745d56dbfdd889a
Author: Lukas Tönne
Date:   Thu Jul 7 11:17:11 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rB50dc534f0e35c874cb774c2c6745d56dbfdd889a

Implementation of the Kajiya-Kay shading model for hair strands.

This is a common simple shading model defined by Kajiya and Kay in
"Rendering fur with three dimensional textures." (1989)

This model in particular defines specular highlights for reflective
thin cylinders (strands), which gives a much more hair-like appearance
in the viewport. More advanced models (Marschner et. al.) improve this
further, in particular the diffuse term.

===================================================================

M	source/blender/gpu/shaders/gpu_shader_strand_frag.glsl
M	source/blender/gpu/shaders/gpu_shader_strand_geom.glsl
M	source/blender/gpu/shaders/gpu_shader_strand_vert.glsl

===================================================================

diff --git a/source/blender/gpu/shaders/gpu_shader_strand_frag.glsl b/source/blender/gpu/shaders/gpu_shader_strand_frag.glsl
index 510dd1d..c568fca 100644
--- a/source/blender/gpu/shaders/gpu_shader_strand_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_strand_frag.glsl
@@ -1,5 +1,10 @@
 #define NUM_LIGHTS 3
 
+/* Classic Blender particle hair with tangent as normal (just for comparison) */
+//#define SHADING_CLASSIC_BLENDER
+/* Kajiya-Kay model with a diffuse component and main specular highlights */
+#define SHADING_KAJIYA
+
 in vec3 fPosition;
 in vec3 fTangent;
 in vec3 fColor;
@@ -8,11 +13,17 @@ out vec4 outColor;
 
 void main()
 {
-	/* XXX classic Blender hair normal == crap */
+#ifdef SHADING_CLASSIC_BLENDER
 	vec3 N = normalize(fTangent);
+#endif
+#ifdef SHADING_KAJIYA
+	vec3 T = normalize(fTangent);
+#endif 
 
 	/* view vector computation, depends on orthographics or perspective */
 	vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(fPosition) : vec3(0.0, 0.0, -1.0);
+	float cosine_eye = dot(T, V);
+	float sine_eye = sqrt(1.0 - cosine_eye*cosine_eye);
 
 	vec3 L_diffuse = vec3(0.0);
 	vec3 L_specular = vec3(0.0);
@@ -48,6 +59,7 @@ void main()
 			             gl_LightSource[i].quadraticAttenuation * distance * distance;
 		}
 
+#ifdef SHADING_CLASSIC_BLENDER
 		/* diffuse light */
 		vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
 		float diffuse_bsdf = max(dot(N, light_direction), 0.0);
@@ -56,19 +68,32 @@ void main()
 		/* specular light */
 		vec3 light_specular = gl_LightSource[i].specular.rgb;
 		vec3 H = normalize(light_direction - V);
-
 		float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
 		L_specular += light_specular * specular_bsdf * intensity;
+#endif
+#ifdef SHADING_KAJIYA
+		float cosine_light = dot(T, light_direction);
+		float sine_light = sqrt(1.0 - cosine_light*cosine_light);
+
+		/* diffuse light */
+		vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
+		float diffuse_bsdf = sine_light;
+		L_diffuse += light_diffuse * diffuse_bsdf * intensity;
+
+		/* specular light */
+		vec3 light_specular = gl_LightSource[i].specular.rgb;
+		float specular_bsdf = pow(abs(cosine_light)*abs(cosine_eye) + sine_light*sine_eye, gl_FrontMaterial.shininess);
+		L_specular += light_specular * specular_bsdf * intensity;
+#endif 
 	}
 
 	/* sum lighting */
 	
-	vec3 L = gl_FrontLightModelProduct.sceneColor.rgb;
-	//L += L_diffuse * gl_FrontMaterial.diffuse.rgb;
-	//L += L_specular * gl_FrontMaterial.specular.rgb;
-	//float alpha = gl_FrontMaterial.diffuse.a;
-	L += L_diffuse * fColor.rgb;
-	float alpha = 1.0;
+	vec3 L = vec3(0.0, 0.0, 0.0);
+	L += gl_FrontLightModelProduct.sceneColor.rgb;
+	L += L_diffuse * gl_FrontMaterial.diffuse.rgb;
+	L += L_specular * gl_FrontMaterial.specular.rgb;
+	float alpha = gl_FrontMaterial.diffuse.a;
 
 	/* write out fragment color */
 	outColor = vec4(L, alpha);
diff --git a/source/blender/gpu/shaders/gpu_shader_strand_geom.glsl b/source/blender/gpu/shaders/gpu_shader_strand_geom.glsl
index eb5b5a4..62d66bf 100644
--- a/source/blender/gpu/shaders/gpu_shader_strand_geom.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_strand_geom.glsl
@@ -24,7 +24,7 @@ void emit_vertex(in vec3 location, in vec3 tangent)
 {
 	gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(location, 1.0);
 	fPosition = (gl_ModelViewMatrix * vec4(location, 1.0)).xyz;
-	fTangent = (gl_ModelViewMatrix * vec4(tangent, 0.0)).xyz;
+	fTangent = gl_NormalMatrix * tangent;
 	fColor = vColor[0];
 	//fColor = vec3(float(i)/float(num_verts-1), 1.0-float(i)/float(num_verts-1), 0.0);
 	//fColor = vec3(float(t[0]), 0.0, 0.0);
diff --git a/source/blender/gpu/shaders/gpu_shader_strand_vert.glsl b/source/blender/gpu/shaders/gpu_shader_strand_vert.glsl
index 8a1e623..f40c15e 100644
--- a/source/blender/gpu/shaders/gpu_shader_strand_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_strand_vert.glsl
@@ -13,5 +13,5 @@ void main()
 	v_control_index = control_index;
 	v_control_weight = control_weight;
 	
-	vColor = vec3(1.0, 0.0, 1.0);
+	vColor = vec3(1.0, 1.0, 1.0);
 }




More information about the Bf-blender-cvs mailing list