[Bf-blender-cvs] [20eb199] strand_gpu: Fragment shader emulation of the current particle hair shading method.
Lukas Tönne
noreply at git.blender.org
Thu Jul 7 09:38:40 CEST 2016
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();
}
More information about the Bf-blender-cvs
mailing list