[Bf-blender-cvs] [cac43e1765a] blender2.8: Eevee: Use "constant folding" for the principle shader

Clément Foucault noreply at git.blender.org
Wed Aug 8 21:37:59 CEST 2018


Commit: cac43e1765ab128880bd410d3b8387dc7143f740
Author: Clément Foucault
Date:   Wed Aug 8 18:34:25 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBcac43e1765ab128880bd410d3b8387dc7143f740

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.

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

M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
M	source/blender/gpu/GPU_material.h
M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
M	source/blender/nodes/shader/nodes/node_shader_eevee_specular.c

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

diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 769ac11736d..cd6b5db5b56 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -405,7 +405,7 @@ static void add_standard_uniforms(
 		DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
 	}
 
-	if (use_ssrefraction) {
+	if (use_refract || use_ssrefraction) {
 		BLI_assert(refract_depth != NULL);
 		DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1);
 		DRW_shgroup_uniform_texture_ref(shgrp, "colorBuffer", &vedata->txl->refract_color);
@@ -563,6 +563,8 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E
 		        datatoc_lit_surface_frag_glsl,
 		        datatoc_lit_surface_frag_glsl,
 		        datatoc_lit_surface_frag_glsl,
+		        datatoc_lit_surface_frag_glsl,
+		        datatoc_lit_surface_frag_glsl,
 		        datatoc_volumetric_lib_glsl);
 
 		e_data.volume_shader_lib = BLI_string_joinN(
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index 8b232bf14a4..286f00783d9 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -548,6 +548,14 @@ float F_eta(float eta, float cos_theta)
 	return result;
 }
 
+/* Fresnel color blend base on fresnel factor */
+vec3 F_color_blend(float eta, float fresnel, vec3 f0_color)
+{
+	float f0 = F_eta(eta, 1.0);
+	float fac = saturate((fresnel - f0) / max(1e-8, 1.0 - f0));
+	return mix(f0_color, vec3(1.0), fac);
+}
+
 /* Fresnel */
 vec3 F_schlick(vec3 f0, float cos_theta)
 {
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index 22194c22f39..c2e45ebb879 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -54,6 +54,13 @@ uniform int hairThicknessRes = 1;
 	#define CLOSURE_SUBSURFACE
 #endif /* SURFACE_PRINCIPLED */
 
+#if !defined(SURFACE_CLEARCOAT) && !defined(CLOSURE_NAME)
+	#define SURFACE_CLEARCOAT
+	#define CLOSURE_NAME eevee_closure_clearcoat
+	#define CLOSURE_GLOSSY
+	#define CLOSURE_CLEARCOAT
+#endif /* SURFACE_CLEARCOAT */
+
 #if !defined(SURFACE_DIFFUSE) && !defined(CLOSURE_NAME)
 	#define SURFACE_DIFFUSE
 	#define CLOSURE_NAME eevee_closure_diffuse
@@ -67,6 +74,14 @@ uniform int hairThicknessRes = 1;
 	#define CLOSURE_SUBSURFACE
 #endif /* SURFACE_SUBSURFACE */
 
+#if !defined(SURFACE_SKIN) && !defined(CLOSURE_NAME)
+	#define SURFACE_SKIN
+	#define CLOSURE_NAME eevee_closure_skin
+	#define CLOSURE_DIFFUSE
+	#define CLOSURE_SUBSURFACE
+	#define CLOSURE_GLOSSY
+#endif /* SURFACE_SKIN */
+
 #if !defined(SURFACE_GLOSSY) && !defined(CLOSURE_NAME)
 	#define SURFACE_GLOSSY
 	#define CLOSURE_NAME eevee_closure_glossy
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index cc1150b6d77..9dcf308a414 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -128,6 +128,7 @@ typedef enum GPUMatFlag {
 	GPU_MATFLAG_DIFFUSE       = (1 << 0),
 	GPU_MATFLAG_GLOSSY        = (1 << 1),
 	GPU_MATFLAG_REFRACT       = (1 << 2),
+	GPU_MATFLAG_SSS           = (1 << 3),
 } GPUMatFlag;
 
 typedef enum GPUBlendMode {
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);
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list