diff options
8 files changed, 21 insertions, 9 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl index 1f2f7cb65cc..696e5d4c97b 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl @@ -112,6 +112,7 @@ GlobalData init_globals(void) surf.N = -surf.N; } # ifdef HAIR_SHADER + vec3 V = cameraVec(surf.P); /* Shade as a cylinder. */ vec3 B = normalize(cross(worldNormal, hairTangent)); float cos_theta; @@ -125,7 +126,10 @@ GlobalData init_globals(void) } float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta)); surf.N = safe_normalize(worldNormal * sin_theta + B * cos_theta); - surf.T = hairTangent; + surf.curve_T = -hairTangent; + /* Costly, but follows cycles per pixel tangent space (not following curve shape). */ + surf.curve_B = cross(V, surf.curve_T); + surf.curve_N = safe_normalize(cross(surf.curve_T, surf.curve_B)); surf.is_strand = true; surf.hair_time = hairTime; surf.hair_thickness = hairThickness; @@ -134,7 +138,7 @@ GlobalData init_globals(void) surf.barycentric_coords = hair_resolve_barycentric(hairBary); # endif # else - surf.T = vec3(0.0); + surf.curve_T = surf.curve_B = surf.curve_N = vec3(0.0); surf.is_strand = false; surf.hair_time = 0.0; surf.hair_thickness = 0.0; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl index 11f93ad0d14..708bd153e84 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl @@ -18,7 +18,7 @@ void main() ViewMatrixInverse[3].xyz, ViewMatrixInverse[2].xyz, interp.P, - T, + interp.curves_tangent, interp.curves_binormal, interp.curves_time, interp.curves_thickness, diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl index 0d8644c9901..30b48edaa78 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl @@ -42,6 +42,12 @@ void init_globals_curves() float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta)); g_data.N = normalize(interp.N * sin_theta + interp.curves_binormal * cos_theta); + /* Costly, but follows cycles per pixel tangent space (not following curve shape). */ + vec3 V = cameraVec(g_data.P); + g_data.curve_T = -interp.curves_tangent; + g_data.curve_B = cross(V, g_data.curve_T); + g_data.curve_N = safe_normalize(cross(g_data.curve_T, g_data.curve_B)); + g_data.is_strand = true; g_data.hair_time = interp.curves_time; g_data.hair_thickness = interp.curves_thickness; @@ -94,6 +100,7 @@ void init_interface() interp.P = vec3(0.0); interp.N = vec3(0.0); interp.barycentric_coords = vec2(0.0); + interp.curves_tangent = vec3(0.0); interp.curves_binormal = vec3(0.0); interp.curves_time = 0.0; interp.curves_time_width = 0.0; diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh index e829a41d682..4d6895bcde0 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh @@ -54,6 +54,7 @@ GPU_SHADER_INTERFACE_INFO(eevee_surf_iface, "interp") .smooth(Type::VEC3, "P") .smooth(Type::VEC3, "N") .smooth(Type::VEC2, "barycentric_coords") + .smooth(Type::VEC3, "curves_tangent") .smooth(Type::VEC3, "curves_binormal") .smooth(Type::FLOAT, "curves_time") .smooth(Type::FLOAT, "curves_time_width") diff --git a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl index 5c97eada77d..6091a5c834a 100644 --- a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl +++ b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl @@ -191,8 +191,8 @@ struct GlobalData { vec3 N; /** Geometric Normal. */ vec3 Ng; - /** Surface default Tangent. */ - vec3 T; + /** Curve Tangent Space. */ + vec3 curve_T, curve_B, curve_N; /** Barycentric coordinates. */ vec2 barycentric_coords; vec3 barycentric_dists; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl index 5e86a4577ee..4c9ff31622f 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl @@ -18,7 +18,7 @@ void node_geometry(vec3 orco, true_normal = g_data.Ng; if (g_data.is_strand) { - tangent = g_data.T; + tangent = g_data.curve_T; } else { tangent_orco_z(orco, orco); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl index 7bf8795495a..b24f9ab65f0 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl @@ -40,7 +40,7 @@ void node_bsdf_hair_principled(vec4 color, hair_data.color = color.rgb; hair_data.offset = offset; hair_data.roughness = vec2(0.0); - hair_data.T = g_data.T; + hair_data.T = g_data.curve_B; result = closure_eval(hair_data); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl index a8b4b039370..2d5114c3bad 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl @@ -5,14 +5,14 @@ void node_hair_info(float hair_length, out float intercept, out float out_length, out float thickness, - out vec3 tangent, + out vec3 normal, out float random) { is_strand = float(g_data.is_strand); intercept = g_data.hair_time; thickness = g_data.hair_thickness; out_length = hair_length; - tangent = g_data.T; + normal = g_data.curve_N; /* TODO: could be precomputed per strand instead. */ random = wang_hash_noise(uint(g_data.hair_strand_id)); } |