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>2020-09-19 01:06:45 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-09-19 01:09:51 +0300
commit6f3c279d9e7082b963f3ca758f6ba0561c4bcc9c (patch)
tree1ea2b44e57e192dd9a23223d605d1244734bff9e /source/blender/gpu/shaders
parentaa2e978bd8b47dbc06826698b07d850cdd499568 (diff)
EEVEE: Add support for GGX Multi-scatter
Based on http://jcgt.org/published/0008/01/03/ This is a simple trick that does *not* have a huge performance impact but does work pretty well. It just modifies the Fresnel term to account for the multibounce energy loss (coloration). However this makes the shader variations count double. To avoid this we use a uniform and pass the multiscatter use flag inside the sign of f90. This is a bit hacky but avoids many code duplication. This uses the simplification proposed by McAuley in A Journey Through Implementing Multiscattering BRDFs and Area Lights This does not handle area light differently than the IBL case but that's already an issue in current implementation. This is related to T68460. Reviewed By: brecht Differential Revision: https://developer.blender.org/D8912
Diffstat (limited to 'source/blender/gpu/shaders')
-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
3 files changed, 60 insertions, 19 deletions
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