Commit: 08310996645f0afb5d1d6ecd4c6b41a2ab22cd89
Author: Clément Foucault
Date:   Fri Jun 30 14:12:25 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB08310996645f0afb5d1d6ecd4c6b41a2ab22cd89

Eevee: Principled BSDF: add support for specular tint + optimisation

Only use clearcoat version if there is something linked or if the clearcoat 
value is not 0.

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

M       source/blender/gpu/shaders/gpu_shader_material.glsl
M       source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c

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

diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl 
b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 2633c2965b1..0c36d6ca618 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2573,13 +2573,41 @@ vec3 rotate_vector(vec3 p, vec3 n, float theta) {
               );
 }
 
-void convert_metallic_to_specular(vec4 basecol, float metallic, float 
specular_fac, out vec4 diffuse, out vec4 f0)
+void prepare_tangent(
+        float anisotropic, float anisotropic_rotation, float roughness, vec3 
N, vec3 T,
+        out vec3 X, out vec3 Y, out float ax, out float ay)
 {
-       vec4 dielectric = vec4(0.034) * specular_fac * 2.0;
-       diffuse = mix(basecol, vec4(0.0), metallic);
+       /* rotate tangent */
+       if (anisotropic_rotation != 0.0) {
+               T = rotate_vector(T, N, anisotropic_rotation * 2.0 * M_PI);
+       }
+
+       Y = normalize(cross(T, N));
+
+       float aspect = sqrt(1.0 - anisotropic * 0.9);
+       float a = sqr(roughness);
+       ax = max(0.001, a / aspect);
+       ay = max(0.001, a * aspect);
+}
+
+void convert_metallic_to_specular(vec3 basecol, float metallic, float 
specular_fac, out vec3 diffuse, out vec3 f0)
+{
+       vec3 dielectric = vec3(0.034) * specular_fac * 2.0;
+       diffuse = mix(basecol, vec3(0.0), metallic);
        f0 = mix(dielectric, basecol, metallic);
 }
 
+void convert_metallic_to_specular_tinted(
+        vec3 basecol, float metallic, float specular_fac, float specular_tint,
+        out vec3 diffuse, out vec3 f0)
+{
+       vec3 dielectric = vec3(0.034) * specular_fac * 2.0;
+       float lum = dot(basecol, vec3(0.3, 0.6, 0.1)); /* luminance approx. */
+       vec3 tint = lum > 0 ? basecol / lum : vec3(1.0); /* normalize lum. to 
isolate hue+sat */
+       f0 = mix(dielectric * mix(vec3(1.0), tint, specular_tint), basecol, 
metallic);
+       diffuse = mix(basecol, vec3(0.0), metallic);
+}
+
 /*********** NEW SHADER NODES ***************/
 
 #define NUM_LIGHTS 3
@@ -2656,50 +2684,10 @@ void node_bsdf_principled(vec4 base_color, float 
subsurface, vec3 subsurface_rad
        float specular_tint, float roughness, float anisotropic, float 
anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
        float clearcoat_roughness, float ior, float transmission, float 
transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
 {
-       /* rotate tangent */
-       if (anisotropic_rotation != 0.0) {
-               T = rotate_vector(T, N, anisotropic_rotation * 2.0 * M_PI);
-       }
-
-       /* calculate the tangent and bitangent */
-       vec3 Y = T;
-       vec3 X = normalize(cross(Y, N));
-
-       float aspect = sqrt(1.0 - anisotropic * 0.9);
-       float a = sqr(roughness);
-       float ax = max(0.001, a / aspect);
-       float ay = max(0.001, a * aspect);
+       vec3 X, Y;
+       float ax, ay;
+       prepare_tangent(anisotropic, anisotropic_rotation, roughness, N, T, X, 
Y, ax, ay);
 
-#ifdef EEVEE_ENGINE
-       vec4 diffuse, f0;
-       convert_metallic_to_specular(base_color, metallic, specular, diffuse, 
f0);
-
-       /* Original value is 0.25 but this one seems to fit cycles better */
-       clearcoat *= 0.5;
-
-#if 0 /* Wait until temporal AA (aka. denoising) */
-       /* Distribute N in anisotropy direction. */
-       vec4 surface_color = vec4(0.0);
-       for (float i = 0.0; i < 5.0; ++i) {
-               vec4 rand = texture(utilTex, vec3((gl_FragCoord.xy + i) / 
LUT_SIZE, 2.0));
-
-               float tmp = sqrt( rand.x / (1.0 - rand.x) );
-               float x = (ax > ay ? ax : 0.0) * tmp * rand.z;
-               float y = (ay > ax ? ay : 0.0) * tmp * rand.w;
-               vec3 Ht = normalize(vec3(x, y, 1.0));
-               N = tangent_to_world(Ht, N, Y, X);
-
-               if (dot(N, cameraVec) > 0) {
-                       surface_color.rgb += eevee_surface_clearcoat_lit(N, 
diffuse.rgb, f0.rgb, sqrt(min(ax, ay)), CN, clearcoat, clearcoat_roughness, 
1.0);
-                       surface_color.a += 1.0;
-               }
-       }
-       result = vec4(surface_color.rgb / surface_color.a, 1.0);
-#else
-       result = vec4(eevee_surface_clearcoat_lit(N, diffuse.rgb, f0.rgb, 
sqrt(min(ax, ay)), CN, clearcoat * 0.5, clearcoat_roughness, 1.0), 1.0);
-#endif
-
-#else
        /* ambient light */
        // TODO: set ambient light to an appropriate value
        vec3 L = vec3(mix(0.1, 0.03, metallic)) * base_color.rgb;
@@ -2786,6 +2774,64 @@ void node_bsdf_principled(vec4 base_color, float 
subsurface, vec3 subsurface_rad
        }
 
        result = vec4(L, 1.0);
+}
+
+void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 
subsurface_radius, vec4 subsurface_color, float metallic, float specular,
+       float specular_tint, float roughness, float anisotropic, float 
anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
+       float clearcoat_roughness, float ior, float transmission, float 
transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
+{
+#ifdef EEVEE_ENGINE
+       vec3 diffuse, f0;
+       convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, 
specular_tint, diffuse, f0);
+
+       result = vec4(eevee_surface_lit(N, diffuse, f0, roughness, 1.0), 1.0);
+#else
+       node_bsdf_principled(base_color, subsurface, subsurface_radius, 
subsurface_color, metallic, specular,
+               specular_tint, roughness, anisotropic, anisotropic_rotation, 
sheen, sheen_tint, clearcoat,
+               clearcoat_roughness, ior, transmission, transmission_roughness, 
N, CN, T, I, result);
+#endif
+}
+
+void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 
subsurface_radius, vec4 subsurface_color, float metallic, float specular,
+       float specular_tint, float roughness, float anisotropic, float 
anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
+       float clearcoat_roughness, float ior, float transmission, float 
transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
+{
+#ifdef EEVEE_ENGINE
+       vec3 diffuse, f0;
+       convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, 
specular_tint, diffuse, f0);
+
+       clearcoat *= 0.25;
+#if 0 /* Wait until temporal AA (aka. denoising) */
+
+       vec3 X, Y;
+       float ax, ay;
+       prepare_tangent(anisotropic, anisotropic_rotation, roughness, N, T, X, 
Y, ax, ay);
+
+       /* Distribute N in anisotropy direction. */
+       vec4 surface_color = vec4(0.0);
+       for (float i = 0.0; i < 5.0; ++i) {
+               vec4 rand = texture(utilTex, vec3((gl_FragCoord.xy + i) / 
LUT_SIZE, 2.0));
+
+               float tmp = sqrt( rand.x / (1.0 - rand.x) );
+               float x = (ax > ay ? ax : 0.0) * tmp * rand.z;
+               float y = (ay > ax ? ay : 0.0) * tmp * rand.w;
+               vec3 Ht = normalize(vec3(x, y, 1.0));
+               N = tangent_to_world(Ht, N, Y, X);
+
+               if (dot(N, cameraVec) > 0) {
+                       surface_color.rgb += eevee_surface_clearcoat_lit(N, 
diffuse, f0, sqrt(min(ax, ay)), CN, clearcoat, clearcoat_roughness, 1.0);
+                       surface_color.a += 1.0;
+               }
+       }
+       result = vec4(surface_color.rgb / surface_color.a, 1.0);
+#else
+       result = vec4(eevee_surface_clearcoat_lit(N, diffuse, f0, roughness, 
CN, clearcoat, clearcoat_roughness, 1.0), 1.0);
+#endif
+
+#else
+       node_bsdf_principled(base_color, subsurface, subsurface_radius, 
subsurface_color, metallic, specular,
+               specular_tint, roughness, anisotropic, anisotropic_rotation, 
sheen, sheen_tint, clearcoat,
+               clearcoat_roughness, ior, transmission, transmission_roughness, 
N, CN, T, I, result);
 #endif
 }
 
@@ -3885,10 +3931,10 @@ void node_eevee_metallic(
         float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
         float occlusion, out vec4 result)
 {
-       vec4 diffuse, f0;
-       convert_metallic_to_specular(basecol, metallic, specular, diffuse, f0);
+       vec3 diffuse, f0;
+       convert_metallic_to_specular(basecol.rgb, metallic, specular, diffuse, 
f0);
 
-       result = vec4(eevee_surface_lit(normal, diffuse.rgb, f0.rgb, roughness, 
occlusion) + emissive.rgb, 1.0 - transp);
+       result = vec4(eevee_surface_lit(normal, diffuse, f0, roughness, 
occlusion) + emissive.rgb, 1.0 - transp);
 }
 
 void node_eevee_specular(
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c 
b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
index c3940573a29..7e90397dc50 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
@@ -98,7 +98,13 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, 
bNode *UNUSED(node)
                        &in[19].link);
        }
 
-       return GPU_stack_link(mat, "node_bsdf_principled", in, out, 
GPU_builtin(GPU_VIEW_POSITION));
+       /* Only use complex versions when needed. */
+       if (!in[12].link && (in[12].vec[0] == 0.0f)) {
+               return GPU_stack_link(mat, "node_bsdf_principled_simple", in, 
out, GPU_builtin(GPU_VIEW_POSITION));
+       }
+       else {
+               return GPU_stack_link(mat, "node_bsdf_principled_clearcoat", 
in, out, GPU_builtin(GPU_VIEW_POSITION));
+       }
 }
 
 static void node_shader_update_principled(bNodeTree *UNUSED(ntree), bNode 
*node)

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

Reply via email to