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