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>2021-02-13 20:43:09 +0300
committerClément Foucault <foucault.clem@gmail.com>2021-02-13 20:43:09 +0300
commit7f7e6830991bf66e285fb54cdbae6c6618ed7afa (patch)
treeaccbf8b2f2ab68452ee8e2dfa58bf2477abe6294 /source/blender/gpu
parent40aadd894016f6ad6a1cde3d60b63ba47a72ec6c (diff)
EEVEE: Refactor closure_lit_lib.glsl
This refactor was needed for some reasons: - closure_lit_lib.glsl was unreadable and could not be easily extended to use new features. - It was generating ~5K LOC for any shader. Slowing down compilation. - Some calculations were incorrect and BSDF/Closure code had lots of workaround/hacks. What this refactor does: - Add some macros to define the light object loops / eval. - Clear separation between each closures which now have separate files. Each closure implements the eval functions. - Make principled BSDF a bit more correct in some cases (specular coloring, mix between glass and opaque). - The BSDF term are applied outside of the eval function and on the whole lighting (was separated for lights before). - Make light iteration last to avoid carrying more data than needed. - Makes sure that all inputs are within correct ranges before evaluating the closures (use `safe_normalize` on normals). - Making each BSDF isolated means that we might carry duplicated data (normals for instance) but this should be optimized by compilers. - Makes Translucent BSDF its own closure type to avoid having to disable raytraced shadows using hacks. - Separate transmission roughness is now working on Principled BSDF. - Makes principled shader variations using constants. Removing a lot of duplicated code. This needed `const` keyword detection in `gpu_material_library.c`. - SSR/SSS masking and data loading is a bit more consistent and defined outside of closure eval. The loading functions will act as accumulator if the lighting is not to be separated. - SSR pass now do a full deferred lighting evaluation, including lights, in order to avoid interference with the closure eval code. However, it seems that the cost of having a global SSR toggle uniform is making the surface shader more expensive (which is already the case, by the way). - Principle fully black specular tint now returns black instead of white. - This fixed some artifact issue on my AMD computer on normal surfaces (which might have been some uninitialized variables). - This touched the Ambient Occlusion because it needs to be evaluated for each closure. But to avoid the cost of this, we use another approach to just pass the result of the occlusion on interpolated normals and modify it using the bent normal for each Closure. This tends to reduce shadowing. I'm still looking into improving this but this is out of the scope of this patch. - Performance might be a bit worse with this patch since it is more oriented towards code modularity. But not by a lot. Render tests needs to be updated after this. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D10390 # Conflicts: # source/blender/draw/engines/eevee/eevee_shaders.c # source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl # source/blender/draw/intern/shaders/common_math_lib.glsl
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/intern/gpu_material_library.c4
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl23
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl82
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl53
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl37
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl574
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl29
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl32
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl16
10 files changed, 332 insertions, 520 deletions
diff --git a/source/blender/gpu/intern/gpu_material_library.c b/source/blender/gpu/intern/gpu_material_library.c
index 496988c4ba9..64cd375d466 100644
--- a/source/blender/gpu/intern/gpu_material_library.c
+++ b/source/blender/gpu/intern/gpu_material_library.c
@@ -755,6 +755,10 @@ static void gpu_parse_material_library(GHash *hash, GPUMaterialLibrary *library)
/* get parameters */
while (*code && *code != ')') {
+ if (BLI_str_startswith(code, "const ")) {
+ code = gpu_str_skip_token(code, NULL, 0);
+ }
+
/* test if it's an input or output */
qual = FUNCTION_QUAL_IN;
if (BLI_str_startswith(code, "out ")) {
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
index eea8d19efce..d718cc3f4fe 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
@@ -4,7 +4,7 @@ void node_ambient_occlusion(
{
vec3 bent_normal;
vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
- result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal);
+ result_ao = occlusion_compute(normalize(normal), viewPosition, rand, bent_normal);
result_color = result_ao * color;
}
#else
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl
index d7b6143d2a1..01a16e194ca 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl
@@ -1,12 +1,27 @@
#ifndef VOLUMETRICS
+
+CLOSURE_EVAL_FUNCTION_DECLARE_1(node_bsdf_diffuse, Diffuse)
+
void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
{
- N = normalize(N);
+ CLOSURE_VARS_DECLARE_1(Diffuse);
+
+ in_Diffuse_0.N = N; /* Normalized during eval. */
+ in_Diffuse_0.albedo = color.rgb;
+
+ CLOSURE_EVAL_FUNCTION_1(node_bsdf_diffuse, Diffuse);
+
result = CLOSURE_DEFAULT;
- eevee_closure_diffuse(N, color.rgb, 1.0, true, result.radiance);
- result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb);
- closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result);
+
+ out_Diffuse_0.radiance = render_pass_diffuse_mask(vec3(1.0), out_Diffuse_0.radiance);
+ out_Diffuse_0.radiance *= color.rgb;
+
+ result.radiance = out_Diffuse_0.radiance;
+
+ /* TODO(fclem) Try to not use this. */
+ closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result);
}
+
#else
/* Stub diffuse because it is not compatible with volumetrics. */
# define node_bsdf_diffuse(a, b, c, d) (d = CLOSURE_DEFAULT)
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
index 443bab7529b..429c4ed41ac 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
@@ -1,4 +1,7 @@
#ifndef VOLUMETRICS
+
+CLOSURE_EVAL_FUNCTION_DECLARE_3(node_eevee_specular, Diffuse, Glossy, Glossy)
+
void node_eevee_specular(vec4 diffuse,
vec4 specular,
float roughness,
@@ -12,34 +15,63 @@ void node_eevee_specular(vec4 diffuse,
float ssr_id,
out Closure result)
{
- normal = normalize(normal);
-
- vec3 out_diff, out_spec, ssr_spec;
- eevee_closure_default_clearcoat(normal,
- diffuse.rgb,
- specular.rgb,
- vec3(1.0),
- int(ssr_id),
- roughness,
- clearcoat_normal,
- clearcoat * 0.25,
- clearcoat_roughness,
- occlusion,
- true,
- out_diff,
- out_spec,
- ssr_spec);
-
- float alpha = 1.0 - transp;
+ CLOSURE_VARS_DECLARE_3(Diffuse, Glossy, Glossy);
+
+ in_common.occlusion = occlusion;
+
+ in_Diffuse_0.N = normal; /* Normalized during eval. */
+ in_Diffuse_0.albedo = diffuse.rgb;
+
+ in_Glossy_1.N = normal; /* Normalized during eval. */
+ in_Glossy_1.roughness = roughness;
+
+ in_Glossy_2.N = clearcoat_normal; /* Normalized during eval. */
+ in_Glossy_2.roughness = clearcoat_roughness;
+
+ CLOSURE_EVAL_FUNCTION_3(node_eevee_specular, Diffuse, Glossy, Glossy);
+
result = CLOSURE_DEFAULT;
- result.radiance = render_pass_diffuse_mask(diffuse.rgb, out_diff * diffuse.rgb);
- result.radiance += render_pass_glossy_mask(vec3(1.0), out_spec);
- result.radiance += render_pass_emission_mask(emissive.rgb);
- result.radiance *= alpha;
- result.transmittance = vec3(transp);
- closure_load_ssr_data(ssr_spec * alpha, roughness, normal, viewCameraVec, int(ssr_id), result);
+ {
+ /* Diffuse. */
+ out_Diffuse_0.radiance = render_pass_diffuse_mask(vec3(1), out_Diffuse_0.radiance);
+ out_Diffuse_0.radiance *= in_Diffuse_0.albedo;
+ result += out_Diffuse_0.radiance;
+ }
+ {
+ /* Glossy. */
+ float NV = dot(in_Glossy_1.N, cameraVec);
+ vec2 split_sum = brdf_lut(NV, in_Glossy_1.roughness);
+ vec3 brdf = F_brdf_single_scatter(specular.rgb, vec3(1.0), split_sum);
+
+ out_Glossy_1.radiance = closure_mask_ssr_radiance(out_Glossy_1.radiance, ssr_id);
+ out_Glossy_1.radiance *= brdf;
+ out_Glossy_1.radiance = render_pass_glossy_mask(spec_color, out_Glossy_1.radiance);
+ closure_load_ssr_data(
+ out_Glossy_1.radiance, in_Glossy_1.roughness, in_Glossy_1.N, ssr_id, result);
+ }
+ {
+ /* Clearcoat. */
+ float NV = dot(in_Glossy_2.N, cameraVec);
+ vec2 split_sum = brdf_lut(NV, in_Glossy_2.roughness);
+ vec3 brdf = F_brdf_single_scatter(vec3(0.04), vec3(1.0), split_sum);
+
+ out_Glossy_2.radiance *= brdf * clearcoat * 0.25;
+ out_Glossy_2.radiance = render_pass_glossy_mask(vec3(1), out_Glossy_2.radiance);
+ result.radiance += out_Glossy_2.radiance;
+ }
+ {
+ /* Emission. */
+ vec3 out_emission_radiance = render_pass_emission_mask(emission.rgb);
+ result.radiance += out_emission_radiance;
+ }
+
+ float trans = 1.0 - trans;
+ result.transmittance = vec3(trans);
+ result.radiance *= alpha;
+ result.ssr_data.rgb *= alpha;
}
+
#else
/* Stub specular because it is not compatible with volumetrics. */
# define node_eevee_specular(a, b, c, d, e, f, g, h, i, j, k, result) (result = CLOSURE_DEFAULT)
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl
index c328b4800bc..ba02ae6d886 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl
@@ -1,4 +1,7 @@
#ifndef VOLUMETRICS
+
+CLOSURE_EVAL_FUNCTION_DECLARE_2(node_bsdf_glass, Glossy, Refraction)
+
void node_bsdf_glass(vec4 color,
float roughness,
float ior,
@@ -7,32 +10,38 @@ void node_bsdf_glass(vec4 color,
float ssr_id,
out Closure result)
{
- N = normalize(N);
- vec3 out_spec, out_refr, ssr_spec;
- vec3 refr_color = (refractionDepth > 0.0) ? color.rgb * color.rgb :
- color.rgb; /* Simulate 2 transmission event */
- eevee_closure_glass(N,
- vec3(1.0),
- /* HACK: Pass the multiscatter flag as the sign to not add closure
- * variations or increase register usage. */
- (use_multiscatter != 0.0) ? vec3(1.0) : -vec3(1.0),
- int(ssr_id),
- roughness,
- 1.0,
- ior,
- true,
- out_spec,
- out_refr,
- ssr_spec);
- float fresnel = F_eta(ior, dot(N, cameraVec));
- vec3 vN = mat3(ViewMatrix) * N;
+ CLOSURE_VARS_DECLARE_2(Glossy, Refraction);
+
+ in_Glossy_0.N = N; /* Normalized during eval. */
+ in_Glossy_0.roughness = roughness;
+
+ in_Refraction_1.N = N; /* Normalized during eval. */
+ in_Refraction_1.roughness = roughness;
+ in_Refraction_1.ior = ior;
+
+ CLOSURE_EVAL_FUNCTION_2(node_bsdf_glass, Glossy, Refraction);
+
result = CLOSURE_DEFAULT;
- result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color) * (1.0 - fresnel);
- result.radiance += render_pass_glossy_mask(color.rgb, out_spec * color.rgb) * fresnel;
+ float fresnel = F_eta(in_Refraction_1.ior, dot(in_Glossy_0.N, cameraVec));
+
+ vec2 split_sum = brdf_lut(dot(in_Glossy_0.N, cameraVec), in_Glossy_0.roughness);
+ vec3 brdf = (use_multiscatter != 0.0) ? F_brdf_multi_scatter(vec3(1.0), vec3(1.0), split_sum) :
+ F_brdf_single_scatter(vec3(1.0), vec3(1.0), split_sum);
+ out_Glossy_0.radiance = closure_mask_ssr_radiance(out_Glossy_0.radiance, ssr_id);
+ out_Glossy_0.radiance *= brdf;
+ out_Glossy_0.radiance = render_pass_glossy_mask(vec3(1.0), out_Glossy_0.radiance);
+ out_Glossy_0.radiance *= color.rgb * fresnel;
closure_load_ssr_data(
- ssr_spec * color.rgb * fresnel, roughness, N, viewCameraVec, int(ssr_id), result);
+ out_Glossy_0.radiance, in_Glossy_0.roughness, in_Glossy_0.N, ssr_id, result);
+
+ out_Refraction_1.radiance = render_pass_glossy_mask(vec3(1.0), out_Refraction_1.radiance);
+ out_Refraction_1.radiance *= color.rgb * (1.0 - fresnel);
+ /* Simulate 2nd absorption event. */
+ out_Refraction_1.radiance *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0);
+ result.radiance += out_Refraction_1.radiance;
}
+
#else
/* Stub glass because it is not compatible with volumetrics. */
# define node_bsdf_glass(a, b, c, d, e, f, result) (result = CLOSURE_DEFAULT)
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
index 36675cf720d..ca7c3749597 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
@@ -1,23 +1,32 @@
#ifndef VOLUMETRICS
+
+CLOSURE_EVAL_FUNCTION_DECLARE_1(node_bsdf_glossy, Glossy)
+
void node_bsdf_glossy(
vec4 color, float roughness, vec3 N, float use_multiscatter, float ssr_id, out Closure result)
{
- N = normalize(N);
- vec3 out_spec, ssr_spec;
- eevee_closure_glossy(N,
- vec3(1.0),
- use_multiscatter != 0.0 ? vec3(1.0) : vec3(-1.0), /* HACK */
- int(ssr_id),
- roughness,
- 1.0,
- true,
- out_spec,
- ssr_spec);
- vec3 vN = mat3(ViewMatrix) * N;
+ bool do_ssr = (ssrToggle && int(ssr_id) == outputSsrId);
+
+ CLOSURE_VARS_DECLARE_1(Glossy);
+
+ in_Glossy_0.N = N; /* Normalized during eval. */
+ in_Glossy_0.roughness = roughness;
+
+ CLOSURE_EVAL_FUNCTION_1(node_bsdf_glossy, Glossy);
+
result = CLOSURE_DEFAULT;
- result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) * color.rgb;
- closure_load_ssr_data(ssr_spec * color.rgb, roughness, N, viewCameraVec, int(ssr_id), result);
+
+ vec2 split_sum = brdf_lut(dot(in_Glossy_0.N, cameraVec), in_Glossy_0.roughness);
+ vec3 brdf = (use_multiscatter != 0.0) ? F_brdf_multi_scatter(vec3(1.0), vec3(1.0), split_sum) :
+ F_brdf_single_scatter(vec3(1.0), vec3(1.0), split_sum);
+ out_Glossy_0.radiance = closure_mask_ssr_radiance(out_Glossy_0.radiance, ssr_id);
+ out_Glossy_0.radiance *= brdf;
+ out_Glossy_0.radiance = render_pass_glossy_mask(vec3(1.0), out_Glossy_0.radiance);
+ out_Glossy_0.radiance *= color.rgb;
+ closure_load_ssr_data(
+ out_Glossy_0.radiance, in_Glossy_0.roughness, in_Glossy_0.N, ssr_id, result);
}
+
#else
/* Stub glossy because it is not compatible with volumetrics. */
# define node_bsdf_glossy(a, b, c, d, e, result) (result = CLOSURE_DEFAULT)
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
index 3bd578e1ffc..15958dcf65e 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
@@ -1,41 +1,20 @@
#ifndef VOLUMETRICS
vec3 tint_from_color(vec3 color)
{
- float lum = dot(color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */
- return (lum > 0) ? color / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */
+ float lum = dot(color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */
+ return (lum > 0.0) ? color / lum : vec3(0.0); /* normalize lum. to isolate hue+sat */
}
-void convert_metallic_to_specular_tinted(vec3 basecol,
- vec3 basecol_tint,
- float metallic,
- float specular_fac,
- float specular_tint,
- out vec3 diffuse,
- out vec3 f0)
-{
- vec3 tmp_col = mix(vec3(1.0), basecol_tint, specular_tint);
- f0 = mix((0.08 * specular_fac) * tmp_col, basecol, metallic);
- diffuse = basecol * (1.0 - metallic);
-}
-
-/* Output sheen is to be multiplied by sheen_color. */
-void principled_sheen(float NV,
- vec3 basecol_tint,
- float sheen,
- float sheen_tint,
- out float out_sheen,
- out vec3 sheen_color)
+float principled_sheen(float NV)
{
float f = 1.0 - NV;
- /* Temporary fix for T59784. Normal map seems to contain NaNs for tangent space normal maps,
- * therefore we need to clamp value. */
- f = clamp(f, 0.0, 1.0);
/* Empirical approximation (manual curve fitting). Can be refined. */
- out_sheen = f * f * f * 0.077 + f * 0.01 + 0.00026;
-
- sheen_color = sheen * mix(vec3(1.0), basecol_tint, sheen_tint);
+ float sheen = f * f * f * 0.077 + f * 0.01 + 0.00026;
+ return sheen;
}
+CLOSURE_EVAL_FUNCTION_DECLARE_4(node_bsdf_principled, Diffuse, Glossy, Glossy, Refraction)
+
void node_bsdf_principled(vec4 base_color,
float subsurface,
vec3 subsurface_radius,
@@ -59,434 +38,163 @@ void node_bsdf_principled(vec4 base_color,
vec3 N,
vec3 CN,
vec3 T,
- vec3 I,
- float use_multiscatter,
+ const float do_diffuse,
+ const float do_clearcoat,
+ const float do_refraction,
+ const float do_multiscatter,
float ssr_id,
float sss_id,
vec3 sss_scale,
out Closure result)
{
- N = normalize(N);
- ior = max(ior, 1e-5);
- metallic = saturate(metallic);
- transmission = saturate(transmission);
- float m_transmission = 1.0 - transmission;
-
- float dielectric = 1.0 - metallic;
- transmission *= dielectric;
- sheen *= dielectric;
- subsurface_color *= dielectric;
-
- vec3 diffuse, f0, out_diff, out_spec, out_refr, ssr_spec, sheen_color;
- float out_sheen;
- vec3 ctint = tint_from_color(base_color.rgb);
- convert_metallic_to_specular_tinted(
- base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
-
- float NV = dot(N, cameraVec);
- principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
-
- vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
-
- /* 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, NV);
- vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel;
- f0 = mix(f0, spec_col, transmission);
- f90 = mix(f90, spec_col, transmission);
-
- /* Really poor approximation but needed to workaround issues with renderpasses. */
- spec_col = mix(vec3(1.0), spec_col, transmission);
/* Match cycles. */
- spec_col += float(clearcoat > 1e-5);
-
- vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
-
- float sss_scalef = avg(sss_scale) * subsurface;
- eevee_closure_principled(N,
- mixed_ss_base_color,
- f0,
- /* HACK: Pass the multiscatter flag as the sign to not add closure
- * variations or increase register usage. */
- (use_multiscatter != 0.0) ? f90 : -f90,
- int(ssr_id),
- roughness,
- CN,
- clearcoat * 0.25,
- clearcoat_roughness,
- 1.0,
- sss_scalef,
- ior,
- true,
- out_diff,
- 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 */
- refr_color *= saturate(1.0 - fresnel) * transmission;
-
- sheen_color *= m_transmission;
- mixed_ss_base_color *= m_transmission;
-
- result = CLOSURE_DEFAULT;
- result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color);
- result.radiance += render_pass_glossy_mask(spec_col, out_spec);
- /* Coarse approx. */
- result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
- result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
- result.radiance *= alpha;
- closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
-
- mixed_ss_base_color *= alpha;
- closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result);
- result.transmittance = vec3(1.0 - alpha);
-}
-
-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,
- vec4 emission,
- float emission_strength,
- float alpha,
- vec3 N,
- vec3 CN,
- vec3 T,
- vec3 I,
- float use_multiscatter,
- float ssr_id,
- float sss_id,
- vec3 sss_scale,
- out Closure result)
-{
- N = normalize(N);
metallic = saturate(metallic);
- float dielectric = 1.0 - metallic;
-
- vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color;
- float out_sheen;
- vec3 ctint = tint_from_color(base_color.rgb);
- convert_metallic_to_specular_tinted(
- base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
-
- vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
-
- float NV = dot(N, cameraVec);
- principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
-
- eevee_closure_default(N,
- diffuse,
- f0,
- /* HACK: Pass the multiscatter flag as the sign to not add closure
- * variations or increase register usage. */
- (use_multiscatter != 0.0) ? f90 : -f90,
- int(ssr_id),
- roughness,
- 1.0,
- true,
- out_diff,
- out_spec,
- ssr_spec);
+ transmission = saturate(transmission);
+ float diffuse_weight = (1.0 - transmission) * (1.0 - metallic);
+ transmission *= (1.0 - metallic);
+ float specular_weight = (1.0 - transmission);
+ clearcoat = max(clearcoat, 0.0);
+ transmission_roughness = 1.0 - (1.0 - roughness) * (1.0 - transmission_roughness);
- result = CLOSURE_DEFAULT;
- result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
- result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
- result.radiance += render_pass_diffuse_mask(diffuse, out_diff * diffuse);
- result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
- result.radiance *= alpha;
- closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
+ CLOSURE_VARS_DECLARE_4(Diffuse, Glossy, Glossy, Refraction);
- result.transmittance = vec3(1.0 - alpha);
-}
+ in_Diffuse_0.N = N; /* Normalized during eval. */
+ in_Diffuse_0.albedo = mix(base_color.rgb, subsurface_color.rgb, subsurface);
-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,
- vec4 emission,
- float emission_strength,
- float alpha,
- vec3 N,
- vec3 CN,
- vec3 T,
- vec3 I,
- float use_multiscatter,
- float ssr_id,
- float sss_id,
- vec3 sss_scale,
- out Closure result)
-{
- N = normalize(N);
- vec3 out_spec, ssr_spec;
-
- vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
-
- eevee_closure_glossy(N,
- base_color.rgb,
- /* HACK: Pass the multiscatter flag as the sign to not add closure
- * variations or increase register usage. */
- (use_multiscatter != 0.0) ? f90 : -f90,
- int(ssr_id),
- roughness,
- 1.0,
- true,
- out_spec,
- ssr_spec);
+ in_Glossy_1.N = N; /* Normalized during eval. */
+ in_Glossy_1.roughness = roughness;
- result = CLOSURE_DEFAULT;
- result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
- result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
- result.radiance *= alpha;
- closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
+ in_Glossy_2.N = CN; /* Normalized during eval. */
+ in_Glossy_2.roughness = clearcoat_roughness;
- result.transmittance = vec3(1.0 - alpha);
-}
+ in_Refraction_3.N = N; /* Normalized during eval. */
+ in_Refraction_3.roughness = do_multiscatter != 0.0 ? roughness : transmission_roughness;
+ in_Refraction_3.ior = ior;
+
-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,
- vec4 emission,
- float emission_strength,
- float alpha,
- vec3 N,
- vec3 CN,
- vec3 T,
- vec3 I,
- float use_multiscatter,
- float ssr_id,
- float sss_id,
- vec3 sss_scale,
- out Closure result)
-{
- vec3 out_spec, ssr_spec;
- N = normalize(N);
-
- vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
-
- eevee_closure_clearcoat(N,
- base_color.rgb,
- /* HACK: Pass the multiscatter flag as the sign to not add closure
- * variations or increase register usage. */
- (use_multiscatter != 0.0) ? f90 : -f90,
- int(ssr_id),
- roughness,
- CN,
- clearcoat * 0.25,
- clearcoat_roughness,
- 1.0,
- true,
- out_spec,
- ssr_spec);
- /* Match cycles. */
- float spec_col = 1.0 + float(clearcoat > 1e-5);
+ CLOSURE_EVAL_FUNCTION_4(node_bsdf_principled, Diffuse, Glossy, Glossy, Refraction);
result = CLOSURE_DEFAULT;
- result.radiance = render_pass_glossy_mask(vec3(spec_col), out_spec);
- result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
- result.radiance *= alpha;
- closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
+ /* This will tag the whole eval for optimisation. */
+ if (do_diffuse == 0.0) {
+ out_Diffuse_0.radiance = vec3(0);
+ }
+ if (do_clearcoat == 0.0) {
+ out_Glossy_2.radiance = vec3(0);
+ }
+ if (do_refraction == 0.0) {
+ out_Refraction_3.radiance = vec3(0);
+ }
+
+ /* Glossy_1 will always be evaluated. */
+ float NV = dot(in_Glossy_1.N, cameraVec);
+
+ vec3 base_color_tint = tint_from_color(base_color.rgb);
+
+ /* TODO(fclem) This isn't good for rough glass using multiscatter (since the fresnel is applied
+ * on each microfacet in cycles). */
+ float fresnel = F_eta(in_Refraction_3.ior, NV);
+
+ {
+ /* Glossy reflections.
+ * Separate Glass reflections and main specular reflections to match Cycles renderpasses. */
+ out_Glossy_1.radiance = closure_mask_ssr_radiance(out_Glossy_1.radiance, ssr_id);
+
+ vec2 split_sum = brdf_lut(NV, roughness);
+
+ vec3 glossy_radiance_final = vec3(0.0);
+ if (transmission > 1e-5) {
+ /* Glass Reflection: Reuse radiance from Glossy1. */
+ vec3 out_glass_refl_radiance = out_Glossy_1.radiance;
+
+ /* Poor approximation since we baked the LUT using a fixed IOR. */
+ vec3 f0 = mix(vec3(1.0), base_color.rgb, specular_tint);
+ vec3 f90 = vec3(1);
+
+ vec3 brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(f0, f90, split_sum) :
+ F_brdf_single_scatter(f0, f90, split_sum);
+
+ out_glass_refl_radiance *= brdf;
+ out_glass_refl_radiance = render_pass_glossy_mask(vec3(1), out_glass_refl_radiance);
+ out_glass_refl_radiance *= fresnel * transmission;
+ glossy_radiance_final += out_glass_refl_radiance;
+ }
+ if (specular_weight > 1e-5) {
+ vec3 dielectric_f0_color = mix(vec3(1.0), base_color_tint, specular_tint);
+ vec3 metallic_f0_color = base_color.rgb;
+ vec3 f0 = mix((0.08 * specular) * dielectric_f0_color, metallic_f0_color, metallic);
+ /* Cycles does this blending using the microfacet fresnel factor. However, our fresnel
+ * is already baked inside the split sum LUT. We approximate using by modifying the
+ * changing the f90 color directly in a non linear fashion. */
+ vec3 f90 = mix(f0, vec3(1), fast_sqrt(specular));
+
+ vec3 brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(f0, f90, split_sum) :
+ F_brdf_single_scatter(f0, f90, split_sum);
+
+ out_Glossy_1.radiance *= brdf;
+ out_Glossy_1.radiance = render_pass_glossy_mask(vec3(1), out_Glossy_1.radiance);
+ out_Glossy_1.radiance *= specular_weight;
+ glossy_radiance_final += out_Glossy_1.radiance;
+ }
+
+ closure_load_ssr_data(
+ glossy_radiance_final, in_Glossy_1.roughness, in_Glossy_1.N, ssr_id, result);
+ }
+
+ if (diffuse_weight > 1e-5) {
+ /* Mask over all diffuse radiance. */
+ out_Diffuse_0.radiance *= diffuse_weight;
+
+ /* Sheen Coarse approximation: We reuse the diffuse radiance and just scale it. */
+ vec3 sheen_color = mix(vec3(1), base_color_tint, sheen_tint);
+ vec3 out_sheen_radiance = out_Diffuse_0.radiance * principled_sheen(NV);
+ out_sheen_radiance = render_pass_diffuse_mask(vec3(1), out_sheen_radiance);
+ out_sheen_radiance *= sheen * sheen_color;
+ result.radiance += out_sheen_radiance;
+
+ /* Diffuse / Subsurface. */
+ float scale = avg(sss_scale) * subsurface;
+ closure_load_sss_data(scale, out_Diffuse_0.radiance, in_Diffuse_0.albedo, int(sss_id), result);
+ }
+
+ if (transmission > 1e-5) {
+ /* TODO(fclem) This could be going to a transmission render pass instead. */
+ out_Refraction_3.radiance = render_pass_glossy_mask(vec3(1), out_Refraction_3.radiance);
+ out_Refraction_3.radiance *= base_color.rgb;
+ /* Simulate 2nd transmission event. */
+ out_Refraction_3.radiance *= (refractionDepth > 0.0) ? base_color.rgb : vec3(1);
+ out_Refraction_3.radiance *= (1.0 - fresnel) * transmission;
+ result.radiance += out_Refraction_3.radiance;
+ }
+
+ if (clearcoat > 1e-5) {
+ float NV = dot(in_Glossy_2.N, cameraVec);
+ vec2 split_sum = brdf_lut(NV, in_Glossy_2.roughness);
+ vec3 brdf = F_brdf_single_scatter(vec3(0.04), vec3(1.0), split_sum);
+
+ out_Glossy_2.radiance *= brdf * clearcoat * 0.25;
+ out_Glossy_2.radiance = render_pass_glossy_mask(vec3(1), out_Glossy_2.radiance);
+ result.radiance += out_Glossy_2.radiance;
+ }
+
+ {
+ vec3 out_emission_radiance = render_pass_emission_mask(emission.rgb);
+ out_emission_radiance *= emission_strength;
+ result.radiance += out_emission_radiance;
+ }
result.transmittance = vec3(1.0 - alpha);
-}
-
-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,
- vec4 emission,
- float emission_strength,
- float alpha,
- vec3 N,
- vec3 CN,
- vec3 T,
- vec3 I,
- float use_multiscatter,
- float ssr_id,
- float sss_id,
- vec3 sss_scale,
- out Closure result)
-{
- metallic = saturate(metallic);
- N = normalize(N);
-
- vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color;
- float out_sheen;
- vec3 ctint = tint_from_color(base_color.rgb);
- convert_metallic_to_specular_tinted(
- base_color.rgb, ctint, 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 = avg(sss_scale) * subsurface;
-
- float NV = dot(N, cameraVec);
- principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
-
- vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
-
- eevee_closure_skin(N,
- mixed_ss_base_color,
- f0,
- /* HACK: Pass the multiscatter flag as the sign to not add closure variations
- * or increase register usage. */
- (use_multiscatter != 0.0) ? f90 : -f90,
- int(ssr_id),
- roughness,
- 1.0,
- sss_scalef,
- true,
- out_diff,
- out_spec,
- ssr_spec);
-
- result = CLOSURE_DEFAULT;
- result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
- result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
- result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
result.radiance *= alpha;
-
- closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
-
- mixed_ss_base_color *= alpha;
- closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result);
-
- result.transmittance = vec3(1.0 - alpha);
+ result.ssr_data.rgb *= alpha;
+# ifdef USE_SSS
+ result.sss_irradiance *= alpha;
+# 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,
- vec4 emission,
- float emission_strength,
- float alpha,
- vec3 N,
- vec3 CN,
- vec3 T,
- vec3 I,
- float use_multiscatter,
- float ssr_id,
- float sss_id,
- vec3 sss_scale,
- out Closure result)
-{
- ior = max(ior, 1e-5);
- N = normalize(N);
-
- 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),
- vec3((use_multiscatter != 0.0) ? 1.0 : -1.0),
- int(ssr_id),
- roughness,
- 1.0,
- ior,
- true,
- 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 */
-
- float fresnel = F_eta(ior, dot(N, cameraVec));
- vec3 spec_col = F_color_blend(ior, fresnel, f0);
- spec_col *= fresnel;
- refr_color *= (1.0 - fresnel);
-
- ssr_spec *= spec_col;
-
- result = CLOSURE_DEFAULT;
- result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color);
- result.radiance += render_pass_glossy_mask(spec_col, out_spec * spec_col);
- result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
- result.radiance *= alpha;
- closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
- result.transmittance = vec3(1.0 - alpha);
-}
#else
/* clang-format off */
/* Stub principled because it is not compatible with volumetrics. */
-# define node_bsdf_principled(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, result) (result = CLOSURE_DEFAULT)
-# define node_bsdf_principled_dielectric(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, result) (result = CLOSURE_DEFAULT)
-# define node_bsdf_principled_metallic(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, result) (result = CLOSURE_DEFAULT)
-# define node_bsdf_principled_clearcoat(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, result) (result = CLOSURE_DEFAULT)
-# define node_bsdf_principled_subsurface(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, result) (result = CLOSURE_DEFAULT)
-# define node_bsdf_principled_glass(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, result) (result = CLOSURE_DEFAULT)
+# define node_bsdf_principled(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, cc, dd, result) (result = CLOSURE_DEFAULT)
/* clang-format on */
#endif
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl
index cd043020a7f..db820efa42e 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl
@@ -1,15 +1,30 @@
#ifndef VOLUMETRICS
+
+CLOSURE_EVAL_FUNCTION_DECLARE_1(node_bsdf_refraction, Refraction)
+
void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result)
{
- N = normalize(N);
- vec3 out_refr;
- color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */
- eevee_closure_refraction(N, roughness, ior, true, out_refr);
- vec3 vN = mat3(ViewMatrix) * N;
+ CLOSURE_VARS_DECLARE_1(Refraction);
+
+ in_Refraction_0.N = N; /* Normalized during eval. */
+ in_Refraction_0.roughness = roughness;
+ in_Refraction_0.ior = ior;
+
+ CLOSURE_EVAL_FUNCTION_1(node_bsdf_refraction, Refraction);
+
result = CLOSURE_DEFAULT;
- result.ssr_normal = normal_encode(vN, viewCameraVec);
- result.radiance = render_pass_glossy_mask(color.rgb, out_refr * color.rgb);
+
+ out_Refraction_0.radiance = render_pass_glossy_mask(vec3(1.0), out_Refraction_0.radiance);
+ out_Refraction_0.radiance *= color.rgb;
+ /* Simulate 2nd absorption event. */
+ out_Refraction_0.radiance *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0);
+
+ result.radiance = out_Refraction_0.radiance;
+
+ /* TODO(fclem) Try to not use this. */
+ result.ssr_normal = normal_encode(mat3(ViewMatrix) * in_Refraction_0.N, viewCameraVec);
}
+
#else
/* Stub refraction because it is not compatible with volumetrics. */
# define node_bsdf_refraction(a, b, c, d, e) (e = CLOSURE_DEFAULT)
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
index c13b55513da..5a68f802659 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
@@ -1,4 +1,7 @@
#ifndef VOLUMETRICS
+
+CLOSURE_EVAL_FUNCTION_DECLARE_1(node_subsurface_scattering, Diffuse)
+
void node_subsurface_scattering(vec4 color,
float scale,
vec3 radius,
@@ -8,20 +11,29 @@ void node_subsurface_scattering(vec4 color,
float sss_id,
out Closure result)
{
- N = normalize(N);
- vec3 out_diff;
- vec3 vN = mat3(ViewMatrix) * N;
+ CLOSURE_VARS_DECLARE_1(Diffuse);
+
+ in_Diffuse_0.N = N; /* Normalized during eval. */
+ in_Diffuse_0.albedo = color.rgb;
+
+ CLOSURE_EVAL_FUNCTION_1(node_subsurface_scattering, Diffuse);
+
result = CLOSURE_DEFAULT;
- closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result);
- eevee_closure_subsurface(N, color.rgb, 1.0, scale, true, out_diff);
+ /* Not perfect for texture_blur values between 0.0 and 1.0.
+ * Interpolate between separated color and color applied on irradiance. */
+ float one_minus_texture_blur = 1.0 - texture_blur;
+ vec3 sss_albedo = color.rgb * texture_blur + one_minus_texture_blur;
+ vec3 radiance_tint = color.rgb * one_minus_texture_blur + texture_blur;
+ /* Consider output radiance as irradiance. */
+ out_Diffuse_0.radiance *= radiance_tint;
+
+ closure_load_sss_data(scale, out_Diffuse_0.radiance, sss_albedo, int(sss_id), result);
- /* Not perfect for texture_blur not exactly equal to 0.0 or 1.0. */
- vec3 sss_albedo = mix(color.rgb, vec3(1.0), texture_blur);
- out_diff *= mix(vec3(1.0), color.rgb, texture_blur);
- result.radiance = render_pass_sss_mask(sss_albedo);
- closure_load_sss_data(scale, out_diff, sss_albedo, int(sss_id), result);
+ /* TODO(fclem) Try to not use this. */
+ closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result);
}
+
#else
/* Stub subsurface scattering because it is not compatible with volumetrics. */
# define node_subsurface_scattering(a, b, c, d, e, f, g, h) (h = CLOSURE_DEFAULT)
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl
index 79bfd9b24bb..80bd3941b22 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl
@@ -1,12 +1,20 @@
#ifndef VOLUMETRICS
+
+CLOSURE_EVAL_FUNCTION_DECLARE_1(node_bsdf_translucent, Translucent)
+
void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
{
- N = normalize(N);
+ CLOSURE_VARS_DECLARE_1(Translucent);
+
+ in_Translucent_0.N = -N; /* Normalized during eval. */
+
+ CLOSURE_EVAL_FUNCTION_1(node_bsdf_translucent, Translucent);
+
result = CLOSURE_DEFAULT;
- eevee_closure_diffuse(-N, color.rgb, 1.0, false, result.radiance);
- closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result);
- result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb);
+ closure_load_ssr_data(vec3(0.0), 0.0, -in_Translucent_0.N, -1.0, result);
+ result.radiance = render_pass_diffuse_mask(color.rgb, out_Translucent_0.radiance * color.rgb);
}
+
#else
/* Stub translucent because it is not compatible with volumetrics. */
# define node_bsdf_translucent(a, b, c) (c = CLOSURE_DEFAULT)