Eevee / Workbench: Fix hair normals
authorClément Foucault <foucault.clem@gmail.com>
Fri, 17 May 2019 16:17:14 +0000 (18:17 +0200)
committerClément Foucault <foucault.clem@gmail.com>
Fri, 17 May 2019 16:17:23 +0000 (18:17 +0200)
Hair normals were not behaving correctly. This corrects their looks and
fix the node shader geometry that was showing the flat normal.

source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
source/blender/draw/modes/shaders/common_hair_lib.glsl
source/blender/gpu/shaders/gpu_shader_material.glsl
source/blender/nodes/shader/nodes/node_shader_geometry.c

index 0a2785b..2b9a325 100644 (file)
@@ -47,9 +47,7 @@ void main()
                               hairTime,
                               hairThickness,
                               hairThickTime);
-
-  hairTangent = normalize(hairTangent);
-  worldNormal = cross(binor, hairTangent);
+  worldNormal = cross(hairTangent, binor);
   worldPosition = pos;
 #else
   worldPosition = point_object_to_world(pos);
index 5d41539..7872c13 100644 (file)
@@ -46,12 +46,11 @@ vec3 srgb_to_linear_attr(vec3 c)
 vec3 workbench_hair_hair_normal(vec3 tan, vec3 binor, float rand)
 {
   /* To "simulate" anisotropic shading, randomize hair normal per strand. */
-  tan = normalize(tan);
-  vec3 nor = normalize(cross(binor, tan));
-  // nor = normalize(mix(nor, -tan, rand * 0.1));
-  // float cos_theta = (rand * 2.0 - 1.0) * 0.2;
-  // float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta));
-  // nor = nor * sin_theta + binor * cos_theta;
+  vec3 nor = cross(tan, binor);
+  nor = normalize(mix(nor, -tan, rand * 0.1));
+  float cos_theta = (rand * 2.0 - 1.0) * 0.2;
+  float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta));
+  nor = nor * sin_theta + binor * cos_theta;
   return nor;
 }
 
index 1c0a31c..f9c3df3 100644 (file)
@@ -160,9 +160,9 @@ void hair_get_pos_tan_binor_time(bool is_persp,
   }
 
   wpos = (hairDupliMatrix * vec4(wpos, 1.0)).xyz;
-  wtan = mat3(hairDupliMatrix) * wtan;
+  wtan = -normalize(mat3(hairDupliMatrix) * wtan);
 
-  vec3 camera_vec = (is_persp) ? wpos - camera_pos : -camera_z;
+  vec3 camera_vec = (is_persp) ? camera_pos - wpos : camera_z;
   wbinor = normalize(cross(camera_vec, wtan));
 
   thickness = hair_shaperadius(hairRadShape, hairRadRoot, hairRadTip, time);
index 94770aa..b94a7d6 100644 (file)
@@ -2038,7 +2038,7 @@ void node_geometry(vec3 I,
 
   position = worldPosition;
 #  ifndef VOLUMETRICS
-  normal = normalize(gl_FrontFacing ? worldNormal : -worldNormal);
+  normal = normalize(N);
   vec3 B = dFdx(worldPosition);
   vec3 T = dFdy(worldPosition);
   true_normal = normalize(cross(B, T));
index 6f97efe..df9a8ac 100644 (file)
@@ -51,7 +51,7 @@ static int node_shader_gpu_geometry(GPUMaterial *mat,
                         in,
                         out,
                         GPU_builtin(GPU_VIEW_POSITION),
-                        GPU_builtin(GPU_VIEW_NORMAL),
+                        GPU_builtin(GPU_WORLD_NORMAL),
                         GPU_attribute(CD_ORCO, ""),
                         GPU_builtin(GPU_OBJECT_MATRIX),
                         GPU_builtin(GPU_INVERSE_VIEW_MATRIX),