Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-08-08 19:34:25 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-08-08 22:27:26 +0300
commitcac43e1765ab128880bd410d3b8387dc7143f740 (patch)
tree85277c7c6230bda86381266406e46ca85e3a78f0 /source/blender/gpu/shaders
parent26d46d00cfa73efe8e434796634dd23e76abbf19 (diff)
Eevee: Use "constant folding" for the principle shader
This is more like a static optimisation when some parameters are set to 1.0 or 0.0. In theses case we use a more optimized version of the node. This also revisit the transmission parameter behaviour to make it closer to cycles.
Diffstat (limited to 'source/blender/gpu/shaders')
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl183
1 files changed, 152 insertions, 31 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 808d2f73659..c9564a21d15 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1069,11 +1069,11 @@ 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);
+ vec3 tmp_col = mix(vec3(1.0), tint, specular_tint);
+ f0 = mix((0.08 * specular_fac) * tmp_col, basecol, metallic);
+ diffuse = basecol * (1.0 - metallic);
}
#ifndef VOLUMETRICS
@@ -1126,52 +1126,142 @@ void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure r
node_bsdf_diffuse(color, 0.0, N, result);
}
-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, float ssr_id,
- float sss_id, vec3 sss_scale, out Closure result)
+void node_bsdf_principled(
+ 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, float ssr_id,
+ float sss_id, vec3 sss_scale, out Closure result)
{
+ ior = max(ior, 1e-5);
metallic = saturate(metallic);
transmission = saturate(transmission);
+ float dielectric = 1.0 - metallic;
+ transmission *= dielectric;
+ subsurface_color *= dielectric;
vec3 diffuse, f0, out_diff, out_spec, out_trans, out_refr, ssr_spec;
convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
- transmission *= 1.0 - metallic;
- subsurface *= 1.0 - metallic;
-
- clearcoat *= 0.25;
- clearcoat *= 1.0 - transmission;
+ /* Far from being accurate, but 2 glossy evaluation is too expensive.
+ * Most noticeable difference is at grazing angles since the bsdf lut
+ * f0 color interpolation is done on top of this interpolation. */
+ vec3 f0_glass = mix(vec3(1.0), base_color.rgb, specular_tint);
+ float fresnel = F_eta(ior, dot(N, cameraVec));
+ vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel;
+ f0 = mix(f0, spec_col, transmission);
vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
-#ifdef USE_SSS
- diffuse = vec3(0.0);
-#else
- diffuse = mixed_ss_base_color;
-#endif
-
- f0 = mix(f0, vec3(1.0), transmission);
-
float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface;
eevee_closure_principled(N, mixed_ss_base_color, f0, int(ssr_id), roughness,
- CN, clearcoat, clearcoat_roughness, 1.0, sss_scalef, ior,
+ CN, clearcoat * 0.25, clearcoat_roughness, 1.0, sss_scalef, ior,
out_diff, out_trans, out_spec, out_refr, ssr_spec);
vec3 refr_color = base_color.rgb;
refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission event */
+ out_refr *= refr_color * (1.0 - fresnel) * transmission;
- float fresnel = F_eta(ior, dot(N, cameraVec));
- vec3 refr_spec_color = base_color.rgb * fresnel;
- /* This bit maybe innacurate. */
- out_refr = out_refr * refr_color * (1.0 - fresnel) + out_spec * refr_spec_color;
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.radiance = out_spec + out_refr;
+#ifndef USE_SSS
+ result.radiance += (out_diff + out_trans) * mixed_ss_base_color * (1.0 - transmission);
+#endif
+ result.ssr_data = vec4(ssr_spec, roughness);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = int(ssr_id);
+#ifdef USE_SSS
+ result.sss_data.a = sss_scalef;
+ result.sss_data.rgb = out_diff + out_trans;
+# ifdef USE_SSS_ALBEDO
+ result.sss_albedo.rgb = mixed_ss_base_color;
+# else
+ result.sss_data.rgb *= mixed_ss_base_color;
+# endif
+ result.sss_data.rgb *= (1.0 - transmission);
+#endif
+}
+
+void node_bsdf_principled_dielectric(
+ 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, float ssr_id,
+ float sss_id, vec3 sss_scale, out Closure result)
+{
+ metallic = saturate(metallic);
+ float dielectric = 1.0 - metallic;
+
+ vec3 diffuse, f0, out_diff, out_spec, ssr_spec;
+ convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
- ssr_spec = mix(ssr_spec, refr_spec_color, transmission);
+ eevee_closure_default(N, diffuse, f0, int(ssr_id), roughness, 1.0, out_diff, out_spec, ssr_spec);
vec3 vN = normalize(mat3(ViewMatrix) * N);
result = CLOSURE_DEFAULT;
result.radiance = out_spec + out_diff * diffuse;
- result.radiance = mix(result.radiance, out_refr, transmission);
+ result.ssr_data = vec4(ssr_spec, roughness);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = int(ssr_id);
+}
+
+void node_bsdf_principled_metallic(
+ 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, float ssr_id,
+ float sss_id, vec3 sss_scale, out Closure result)
+{
+ vec3 out_spec, ssr_spec;
+
+ eevee_closure_glossy(N, base_color.rgb, int(ssr_id), roughness, 1.0, out_spec, ssr_spec);
+
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.radiance = out_spec;
+ result.ssr_data = vec4(ssr_spec, roughness);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = int(ssr_id);
+}
+
+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, float ssr_id,
+ float sss_id, vec3 sss_scale, out Closure result)
+{
+ vec3 out_spec, ssr_spec;
+
+ eevee_closure_clearcoat(N, base_color.rgb, int(ssr_id), roughness, CN, clearcoat * 0.25, clearcoat_roughness,
+ 1.0, out_spec, ssr_spec);
+
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.radiance = out_spec;
+ result.ssr_data = vec4(ssr_spec, roughness);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = int(ssr_id);
+}
+
+void node_bsdf_principled_subsurface(
+ 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, float ssr_id,
+ float sss_id, vec3 sss_scale, out Closure result)
+{
+ metallic = saturate(metallic);
+
+ vec3 diffuse, f0, out_diff, out_spec, out_trans, ssr_spec;
+ convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
+
+ subsurface_color = subsurface_color * (1.0 - metallic);
+ vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
+ float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface;
+
+ eevee_closure_skin(N, mixed_ss_base_color, f0, int(ssr_id), roughness, 1.0, sss_scalef,
+ out_diff, out_trans, out_spec, ssr_spec);
+
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.radiance = out_spec;
result.ssr_data = vec4(ssr_spec, roughness);
result.ssr_normal = normal_encode(vN, viewCameraVec);
result.ssr_id = int(ssr_id);
@@ -1183,10 +1273,41 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs
# else
result.sss_data.rgb *= mixed_ss_base_color;
# endif
- result.sss_data.rgb *= (1.0 - transmission);
+#else
+ result.radiance += (out_diff + out_trans) * mixed_ss_base_color;
#endif
}
+void node_bsdf_principled_glass(
+ 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, float ssr_id,
+ float sss_id, vec3 sss_scale, out Closure result)
+{
+ ior = max(ior, 1e-5);
+
+ vec3 f0, out_spec, out_refr, ssr_spec;
+ f0 = mix(vec3(1.0), base_color.rgb, specular_tint);
+
+ eevee_closure_glass(N, vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec);
+
+ vec3 refr_color = base_color.rgb;
+ refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission events */
+ out_refr *= refr_color;
+
+ float fresnel = F_eta(ior, dot(N, cameraVec));
+ vec3 spec_col = F_color_blend(ior, fresnel, f0);
+ out_spec *= spec_col;
+ ssr_spec *= spec_col * fresnel;
+
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.radiance = mix(out_refr, out_spec, fresnel);
+ result.ssr_data = vec4(ssr_spec, roughness);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = int(ssr_id);
+}
+
void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
{
node_bsdf_diffuse(color, 0.0, -N, result);
@@ -1220,13 +1341,13 @@ void node_subsurface_scattering(
result.sss_data.a = scale;
eevee_closure_subsurface(N, color.rgb, 1.0, scale, out_diff, out_trans);
result.sss_data.rgb = out_diff + out_trans;
-#ifdef USE_SSS_ALBEDO
+# ifdef USE_SSS_ALBEDO
/* Not perfect for texture_blur not exaclty equal to 0.0 or 1.0. */
result.sss_albedo.rgb = mix(color.rgb, vec3(1.0), texture_blur);
result.sss_data.rgb *= mix(vec3(1.0), color.rgb, texture_blur);
-#else
+# else
result.sss_data.rgb *= color.rgb;
-#endif
+# endif
#else
node_bsdf_diffuse(color, 0.0, N, result);
#endif