Commit: 20eb1992851fcf01be5c31866c902dc11d9c1196
Author: Lukas Tönne
Date:   Thu Jul 7 09:30:32 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rB20eb1992851fcf01be5c31866c902dc11d9c1196

Fragment shader emulation of the current particle hair shading method.

This is a terrible shading method, using the curve tangent as a "normal" vector.
With the old particle hair this was a compromise, because line drawing does not
support nicer shading in the fixed-function pipeline. With GLSL shaders this
is just a quick starting point, and useful for comparison with the old shading.

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

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

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

diff --git a/source/blender/gpu/shaders/gpu_shader_strand_frag.glsl 
b/source/blender/gpu/shaders/gpu_shader_strand_frag.glsl
index 164320b..510dd1d 100644
--- a/source/blender/gpu/shaders/gpu_shader_strand_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_strand_frag.glsl
@@ -1,8 +1,75 @@
+#define NUM_LIGHTS 3
+
+in vec3 fPosition;
+in vec3 fTangent;
 in vec3 fColor;
 
 out vec4 outColor;
 
 void main()
 {
-       outColor = vec4(fColor, 1.0);
+       /* XXX classic Blender hair normal == crap */
+       vec3 N = normalize(fTangent);
+
+       /* 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);
+
+       vec3 L_diffuse = vec3(0.0);
+       vec3 L_specular = vec3(0.0);
+       for (int i = 0; i < NUM_LIGHTS; i++) {
+               /* todo: this is a slow check for disabled lights */
+               if (gl_LightSource[i].specular.a == 0.0)
+                       continue;
+
+               float intensity = 1.0;
+               vec3 light_direction;
+
+               if (gl_LightSource[i].position.w == 0.0) {
+                       /* directional light */
+                       light_direction = gl_LightSource[i].position.xyz;
+               }
+               else {
+                       /* point light */
+                       vec3 d = gl_LightSource[i].position.xyz - fPosition;
+                       light_direction = normalize(d);
+
+                       /* spot light cone */
+                       if (gl_LightSource[i].spotCutoff < 90.0) {
+                               float cosine = max(dot(light_direction, 
-gl_LightSource[i].spotDirection), 0.0);
+                               intensity = pow(cosine, 
gl_LightSource[i].spotExponent);
+                               intensity *= 
step(gl_LightSource[i].spotCosCutoff, cosine);
+                       }
+
+                       /* falloff */
+                       float distance = length(d);
+
+                       intensity /= gl_LightSource[i].constantAttenuation +
+                                    gl_LightSource[i].linearAttenuation * 
distance +
+                                    gl_LightSource[i].quadraticAttenuation * 
distance * distance;
+               }
+
+               /* diffuse light */
+               vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
+               float diffuse_bsdf = max(dot(N, light_direction), 0.0);
+               L_diffuse += light_diffuse * diffuse_bsdf * intensity;
+
+               /* 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;
+       }
+
+       /* 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;
+
+       /* 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 a02760b..eb5b5a4 100644
--- a/source/blender/gpu/shaders/gpu_shader_strand_geom.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_strand_geom.glsl
@@ -8,6 +8,8 @@ in vec3 vColor[];
 in uvec4 v_control_index[];
 in vec4 v_control_weight[];
 
+out vec3 fPosition;
+out vec3 fTangent;
 out vec3 fColor;
 
 uniform usamplerBuffer control_curves;
@@ -18,20 +20,20 @@ bool is_valid_index(uint index)
        return index < uint(0xFFFFFFFF);
 }
 
-void emit_vertex(in vec4 loc)
+void emit_vertex(in vec3 location, in vec3 tangent)
 {
-       gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(loc.xyz, 
1.0);
+       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;
+       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);
        EmitVertex();
 }
 
 void main()
 {
-       fColor = vColor[0];
-       
-       vec4 root = gl_in[0].gl_Position;
-       
-       emit_vertex(root);
-       
+       vec3 root = gl_in[0].gl_Position.xyz;
        
        int index[4] = int[4](int(v_control_index[0].x),
                              int(v_control_index[0].y),
@@ -49,8 +51,8 @@ void main()
        int cvert_begin[4];
        int num_cverts[4];
        float fnum_verts = 0.0;
-       vec4 croot[4];
-       vec4 offset[4];
+       vec3 croot[4];
+       vec3 offset[4];
        for (int k = 0; k < 4; ++k) {
                uvec4 curve = texelFetch(control_curves, index[k]);
                cvert_begin[k] = int(curve.x);
@@ -58,7 +60,7 @@ void main()
                
                fnum_verts += weight[k] * float(num_cverts[k]);
                
-               croot[k] = texelFetch(control_points, cvert_begin[k]);
+               croot[k] = texelFetch(control_points, cvert_begin[k]).xyz;
                offset[k] = root - croot[k];
        }
        int num_verts = max(int(ceil(fnum_verts)), 2);
@@ -68,12 +70,11 @@ void main()
                dt[k] = float(num_cverts[k] - 1) / float(num_verts - 1);
        }
 
-       //fColor = vec3(0.0, 1.0, 0.0);
-       emit_vertex(root);
-
+       vec3 loc = root;
+       vec3 tangent;
        float t[4] = float[4](dt[0], dt[1], dt[2], dt[3]);
        for (int i = 1; i < num_verts; ++i) {
-               vec4 loc = vec4(0.0, 0.0, 0.0, 1.0);
+               vec3 next_loc = vec3(0.0, 0.0, 0.0);
 
                for (int k = 0; k < 4; ++k) {
                        if (!valid[k])
@@ -83,18 +84,20 @@ void main()
                        int ci1 = ci0 + 1;
                        float lambda = t[k] - floor(t[k]);
                        /* XXX could use texture filtering to do this for us? */
-                       vec4 cloc0 = texelFetch(control_points, cvert_begin[k] 
+ ci0);
-                       vec4 cloc1 = texelFetch(control_points, cvert_begin[k] 
+ ci1);
-                       vec4 cloc = mix(cloc0, cloc1, lambda) + offset[k];
+                       vec3 next_cloc0 = texelFetch(control_points, 
cvert_begin[k] + ci0).xyz;
+                       vec3 next_cloc1 = texelFetch(control_points, 
cvert_begin[k] + ci1).xyz;
+                       vec3 next_cloc = mix(next_cloc0, next_cloc1, lambda) + 
offset[k];
                        
-                       loc += weight[k] * cloc;
+                       next_loc += weight[k] * next_cloc;
                        t[k] += dt[k];
                }
 
-               //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);
-               emit_vertex(loc);
+               tangent = next_loc - loc;
+               emit_vertex(loc, tangent);
+               loc = next_loc;
        }
+       /* last vertex */
+       emit_vertex(loc, tangent);
        
        EndPrimitive();
 }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to