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:
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl42
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl8
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl5
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl16
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl58
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c3
8 files changed, 102 insertions, 45 deletions
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 deedde64194..3560ae62a84 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -74,34 +74,36 @@ vec3 F_color_blend(float eta, float fresnel, vec3 f0_color)
return mix(f0_color, vec3(1.0), fac);
}
-/* Fresnel */
-vec3 F_schlick(vec3 f0, float cos_theta)
-{
- float fac = 1.0 - cos_theta;
- float fac2 = fac * fac;
- fac = fac2 * fac2 * fac;
-
- /* Unreal specular matching : if specular color is below 2% intensity,
- * (using green channel for intensity) treat as shadowning */
- return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * fac + (1.0 - fac) * f0;
-}
-
-/* Fresnel approximation for LTC area lights (not MRP) */
-vec3 F_area(vec3 f0, vec3 f90, vec2 lut)
+/* Fresnel split-sum approximation. */
+vec3 F_brdf_single_scatter(vec3 f0, vec3 f90, vec2 lut)
{
/* Unreal specular matching : if specular color is below 2% intensity,
* treat as shadowning */
- return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0;
+ return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * abs(f90) + lut.x * f0;
}
-/* Fresnel approximation for IBL */
-vec3 F_ibl(vec3 f0, vec3 f90, vec2 lut)
+/* Multi-scattering brdf approximation from :
+ * "A Multiple-Scattering Microfacet Model for Real-Time Image-based Lighting"
+ * by Carmelo J. Fdez-Agüera. */
+vec3 F_brdf_multi_scatter(vec3 f0, vec3 f90, vec2 lut)
{
- /* Unreal specular matching : if specular color is below 2% intensity,
- * treat as shadowning */
- return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0;
+ vec3 FssEss = F_brdf_single_scatter(f0, f90, lut);
+ /* Hack to avoid many more shader variations. */
+ if (f90.g < 0.0) {
+ return FssEss;
+ }
+
+ float Ess = lut.x + lut.y;
+ float Ems = 1.0 - Ess;
+ vec3 Favg = f0 + (1.0 - f0) / 21.0;
+ vec3 Fms = FssEss * Favg / (1.0 - (1.0 - Ess) * Favg);
+ /* We don't do anything special for diffuse surfaces because the principle bsdf
+ * does not care about energy conservation of the specular layer for dielectrics. */
+ return FssEss + Fms * Ems;
}
+#define F_brdf(f0, f90, lut) F_brdf_multi_scatter(f0, f90, lut)
+
/* GGX */
float D_ggx_opti(float NH, float a2)
{
diff --git a/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl
index bf33caf9854..613b48ff9b8 100644
--- a/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl
@@ -250,12 +250,12 @@ void CLOSURE_NAME(vec3 N
# ifdef CLOSURE_GLOSSY
vec2 brdf_lut_lights = texture(utilTex, vec3(lut_uv, 1.0)).ba;
- out_spec *= F_area(f0, f90, brdf_lut_lights.xy);
+ out_spec *= F_brdf(f0, f90, brdf_lut_lights.xy);
# endif
# ifdef CLOSURE_CLEARCOAT
vec2 brdf_lut_lights_clear = texture(utilTex, vec3(lut_uv_clear, 1.0)).ba;
- out_spec_clear *= F_area(vec3(0.04), vec3(1.0), brdf_lut_lights_clear.xy);
+ out_spec_clear *= F_brdf(vec3(0.04), vec3(1.0), brdf_lut_lights_clear.xy);
out_spec += out_spec_clear * C_intensity;
# endif
@@ -449,7 +449,7 @@ void CLOSURE_NAME(vec3 N
/* This factor is outputted to be used by SSR in order
* to match the intensity of the regular reflections. */
- ssr_spec = F_ibl(f0, f90, brdf_lut);
+ ssr_spec = F_brdf(f0, f90, brdf_lut);
float spec_occlu = specular_occlusion(NV, final_ao, roughness);
/* The SSR pass recompute the occlusion to not apply it to the SSR */
@@ -470,7 +470,7 @@ void CLOSURE_NAME(vec3 N
NV = dot(C_N, V);
vec2 C_uv = lut_coords(NV, C_roughness);
vec2 C_brdf_lut = texture(utilTex, vec3(C_uv, 1.0)).rg;
- vec3 C_fresnel = F_ibl(vec3(0.04), vec3(1.0), C_brdf_lut) *
+ vec3 C_fresnel = F_brdf(vec3(0.04), vec3(1.0), C_brdf_lut) *
specular_occlusion(NV, final_ao, C_roughness);
out_spec += C_spec_accum.rgb * C_fresnel * C_intensity;
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl
index e1137d9d0e7..8131958313b 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl
@@ -5,11 +5,12 @@ void node_bsdf_anisotropic(vec4 color,
float rotation,
vec3 N,
vec3 T,
+ float use_multiscatter,
out Closure result)
{
- node_bsdf_glossy(color, roughness, N, -1, result);
+ node_bsdf_glossy(color, roughness, N, -1, use_multiscatter, result);
}
#else
/* Stub anisotropic because it is not compatible with volumetrics. */
-# define node_bsdf_anisotropic(a, b, c, d, e, f, g) (g = CLOSURE_DEFAULT)
+# define node_bsdf_anisotropic(a, b, c, d, e, f, g, result) (result = CLOSURE_DEFAULT)
#endif
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 5ea22f3e0b4..36675cf720d 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
@@ -1,10 +1,18 @@
#ifndef VOLUMETRICS
-void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Closure result)
+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), vec3(1.0), int(ssr_id), roughness, 1.0, true, 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;
result = CLOSURE_DEFAULT;
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) * color.rgb;
@@ -12,5 +20,5 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo
}
#else
/* Stub glossy because it is not compatible with volumetrics. */
-# define node_bsdf_glossy(a, b, c, d, e) (e = CLOSURE_DEFAULT)
+# define node_bsdf_glossy(a, b, c, d, e, result) (result = CLOSURE_DEFAULT)
#endif
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 f7803155934..3fc40fd88e5 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
@@ -60,6 +60,7 @@ void node_bsdf_principled(vec4 base_color,
vec3 CN,
vec3 T,
vec3 I,
+ float use_multiscatter,
float ssr_id,
float sss_id,
vec3 sss_scale,
@@ -107,7 +108,9 @@ void node_bsdf_principled(vec4 base_color,
eevee_closure_principled(N,
mixed_ss_base_color,
f0,
- f90,
+ /* 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,
@@ -168,6 +171,7 @@ void node_bsdf_principled_dielectric(vec4 base_color,
vec3 CN,
vec3 T,
vec3 I,
+ float use_multiscatter,
float ssr_id,
float sss_id,
vec3 sss_scale,
@@ -188,8 +192,19 @@ void node_bsdf_principled_dielectric(vec4 base_color,
float NV = dot(N, cameraVec);
principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
- eevee_closure_default(
- N, diffuse, f0, f90, int(ssr_id), roughness, 1.0, true, out_diff, out_spec, ssr_spec);
+ 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);
result = CLOSURE_DEFAULT;
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
@@ -226,6 +241,7 @@ void node_bsdf_principled_metallic(vec4 base_color,
vec3 CN,
vec3 T,
vec3 I,
+ float use_multiscatter,
float ssr_id,
float sss_id,
vec3 sss_scale,
@@ -236,8 +252,17 @@ void node_bsdf_principled_metallic(vec4 base_color,
vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
- eevee_closure_glossy(
- N, base_color.rgb, f90, int(ssr_id), roughness, 1.0, true, out_spec, ssr_spec);
+ 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);
result = CLOSURE_DEFAULT;
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
@@ -272,6 +297,7 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
vec3 CN,
vec3 T,
vec3 I,
+ float use_multiscatter,
float ssr_id,
float sss_id,
vec3 sss_scale,
@@ -284,7 +310,9 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
eevee_closure_clearcoat(N,
base_color.rgb,
- f90,
+ /* 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,
@@ -331,6 +359,7 @@ void node_bsdf_principled_subsurface(vec4 base_color,
vec3 CN,
vec3 T,
vec3 I,
+ float use_multiscatter,
float ssr_id,
float sss_id,
vec3 sss_scale,
@@ -357,7 +386,9 @@ void node_bsdf_principled_subsurface(vec4 base_color,
eevee_closure_skin(N,
mixed_ss_base_color,
f0,
- f90,
+ /* 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,
@@ -405,6 +436,7 @@ void node_bsdf_principled_glass(vec4 base_color,
vec3 CN,
vec3 T,
vec3 I,
+ float use_multiscatter,
float ssr_id,
float sss_id,
vec3 sss_scale,
@@ -450,11 +482,11 @@ void node_bsdf_principled_glass(vec4 base_color,
#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, 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, 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, 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, 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, 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, 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, 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)
/* clang-format on */
#endif
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
index b0e17ed7716..7ce085d2c82 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
@@ -53,7 +53,10 @@ static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY);
- return GPU_stack_link(mat, node, "node_bsdf_anisotropic", in, out);
+ float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
+
+ return GPU_stack_link(
+ mat, node, "node_bsdf_anisotropic", in, out, GPU_constant(&use_multi_scatter));
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
index 2bbd260fe0e..13b1b21c7fc 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
@@ -54,7 +54,15 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY);
- return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out, GPU_constant(&node->ssr_id));
+ float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
+
+ return GPU_stack_link(mat,
+ node,
+ "node_bsdf_glossy",
+ in,
+ out,
+ GPU_constant(&use_multi_scatter),
+ GPU_constant(&node->ssr_id));
}
/* node type definition */
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 ccc5198832a..b9f0e793a61 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
@@ -172,6 +172,8 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
flag |= GPU_MATFLAG_SSS;
}
+ float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
+
GPU_material_flag_set(mat, flag);
return GPU_stack_link(mat,
@@ -180,6 +182,7 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
in,
out,
GPU_builtin(GPU_VIEW_POSITION),
+ GPU_constant(&use_multi_scatter),
GPU_constant(&node->ssr_id),
GPU_constant(&node->sss_id),
sss_scale);