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>2019-08-22 17:04:25 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-09-05 18:37:50 +0300
commitd8aaf25c23fa10ee121dc4fdd1cafe544bcca355 (patch)
treeb5a16157beac22e4b474c699c1ce25f3d8c5be51 /source/blender/draw/engines/eevee/shaders
parentca58936f2ff2b14a649722be20d98f8fa35831ff (diff)
Eevee: Shadow map refactor
Reviewed By: brecht Differential Revision: http://developer.blender.org/D5659
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders')
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl102
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl43
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl165
-rw-r--r--source/blender/draw/engines/eevee/shaders/lights_lib.glsl407
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl46
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl199
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_process_geom.glsl36
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_process_vert.glsl32
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl322
11 files changed, 383 insertions, 974 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 7f795eaac2b..98012aea303 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -56,12 +56,12 @@ struct LightData {
#endif
struct ShadowData {
- vec4 near_far_bias_exp;
- vec4 shadow_data_start_end;
+ vec4 near_far_bias_id;
vec4 contact_shadow_data;
};
struct ShadowCubeData {
+ mat4 shadowmat;
vec4 position;
};
@@ -69,22 +69,20 @@ struct ShadowCascadeData {
mat4 shadowmat[MAX_CASCADE_NUM];
vec4 split_start_distances;
vec4 split_end_distances;
+ vec4 shadow_vec_id;
};
/* convenience aliases */
-#define sh_near near_far_bias_exp.x
-#define sh_far near_far_bias_exp.y
-#define sh_bias near_far_bias_exp.z
-#define sh_exp near_far_bias_exp.w
-#define sh_bleed near_far_bias_exp.w
-#define sh_tex_start shadow_data_start_end.x
-#define sh_data_start shadow_data_start_end.y
-#define sh_multi_nbr shadow_data_start_end.z
-#define sh_blur shadow_data_start_end.w
+#define sh_near near_far_bias_id.x
+#define sh_far near_far_bias_id.y
+#define sh_bias near_far_bias_id.z
+#define sh_data_index near_far_bias_id.w
#define sh_contact_dist contact_shadow_data.x
#define sh_contact_offset contact_shadow_data.y
#define sh_contact_spread contact_shadow_data.z
#define sh_contact_thickness contact_shadow_data.w
+#define sh_shadow_vec shadow_vec_id.xyz
+#define sh_tex_index shadow_vec_id.w
/* ------- Convenience functions --------- */
@@ -777,10 +775,9 @@ struct Closure {
vec3 transmittance;
float holdout;
# ifdef USE_SSS
- vec4 sss_data;
-# ifdef USE_SSS_ALBEDO
+ vec3 sss_irradiance;
vec3 sss_albedo;
-# endif
+ float sss_radius;
# endif
vec4 ssr_data;
vec2 ssr_normal;
@@ -796,13 +793,8 @@ Closure nodetree_exec(void); /* Prototype */
# define CLOSURE_HOLDOUT_FLAG 4
# ifdef USE_SSS
-# ifdef USE_SSS_ALBEDO
-# define CLOSURE_DEFAULT \
- Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), 0)
-# else
-# define CLOSURE_DEFAULT \
- Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec4(0.0), vec2(0.0), 0)
-# endif
+# define CLOSURE_DEFAULT \
+ Closure(vec3(0.0), vec3(0.0), 0.0, vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0)
# else
# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0)
# endif
@@ -823,30 +815,22 @@ void closure_load_ssr_data(
}
}
-# ifdef USE_SSS
-void closure_load_sss_data(float radius,
- vec3 sss_radiance,
-# ifdef USE_SSS_ALBEDO
- vec3 sss_albedo,
-# endif
- int sss_id,
- inout Closure cl)
+void closure_load_sss_data(
+ float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl)
{
+# ifdef USE_SSS
if (sss_id == outputSssId) {
- cl.sss_data = vec4(sss_radiance, radius);
-# ifdef USE_SSS_ALBEDO
+ cl.sss_irradiance = sss_irradiance;
+ cl.sss_radius = radius;
cl.sss_albedo = sss_albedo;
-# endif
cl.flag |= CLOSURE_SSS_FLAG;
}
- else {
- cl.radiance += sss_radiance;
-# ifdef USE_SSS_ALBEDO
- cl.radiance += sss_radiance * sss_albedo;
-# endif
+ else
+# endif
+ {
+ cl.radiance += sss_irradiance * sss_albedo;
}
}
-# endif
Closure closure_mix(Closure cl1, Closure cl2, float fac)
{
@@ -862,13 +846,11 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
# ifdef USE_SSS
- cl.sss_data = mix(cl1.sss_data, cl2.sss_data, fac);
+ cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac);
bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
- /* It also does not make sense to mix SSS radius or albedo. */
- cl.sss_data.w = (use_cl1_sss) ? cl1.sss_data.w : cl2.sss_data.w;
-# ifdef USE_SSS_ALBEDO
- cl.sss_albedo = (use_cl1_sss) ? cl1.sss_albedo : cl2.sss_albedo;
-# endif
+ /* It also does not make sense to mix SSS radius or irradiance. */
+ cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
+ cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
# endif
return cl;
}
@@ -887,13 +869,11 @@ Closure closure_add(Closure cl1, Closure cl2)
cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
# ifdef USE_SSS
- cl.sss_data = cl1.sss_data + cl2.sss_data;
+ cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo;
bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
- /* It also does not make sense to mix SSS radius or albedo. */
- cl.sss_data.w = (use_cl1_sss) ? cl1.sss_data.w : cl2.sss_data.w;
-# ifdef USE_SSS_ALBEDO
- cl.sss_albedo = (use_cl1_sss) ? cl1.sss_albedo : cl2.sss_albedo;
-# endif
+ /* It also does not make sense to mix SSS radius or irradiance. */
+ cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
+ cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
# endif
return cl;
}
@@ -914,10 +894,9 @@ layout(location = 0) out vec4 outRadiance;
layout(location = 1) out vec2 ssrNormals;
layout(location = 2) out vec4 ssrData;
# ifdef USE_SSS
-layout(location = 3) out vec4 sssData;
-# ifdef USE_SSS_ALBEDO
-layout(location = 4) out vec4 sssAlbedo;
-# endif
+layout(location = 3) out vec3 sssIrradiance;
+layout(location = 4) out float sssRadius;
+layout(location = 5) out vec3 sssAlbedo;
# endif
# else /* USE_ALPHA_BLEND */
/* Use dual source blending to be able to make a whole range of effects. */
@@ -953,10 +932,9 @@ void main()
ssrNormals = cl.ssr_normal;
ssrData = cl.ssr_data;
# ifdef USE_SSS
- sssData = cl.sss_data;
-# ifdef USE_SSS_ALBEDO
- sssAlbedo = cl.sss_albedo.rgbb;
-# endif
+ sssIrradiance = cl.sss_irradiance;
+ sssRadius = cl.sss_radius;
+ sssAlbedo = cl.sss_albedo;
# endif
# endif
@@ -964,6 +942,8 @@ void main()
# ifdef USE_SSS
float fac = float(!sssToggle);
+ /* TODO(fclem) we shouldn't need this.
+ * Just disable USE_SSS when USE_REFRACTION is enabled. */
# ifdef USE_REFRACTION
/* SSRefraction pass is done after the SSS pass.
* In order to not loose the diffuse light totally we
@@ -971,11 +951,7 @@ void main()
fac = 1.0;
# endif
-# ifdef USE_SSS_ALBEDO
- outRadiance.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * fac;
-# else
- outRadiance.rgb += cl.sss_data.rgb * fac;
-# endif
+ outRadiance.rgb += cl.sss_irradiance.rgb * cl.sss_albedo.rgb * fac;
# endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
index 1f60661d234..ca06d458f6e 100644
--- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
@@ -31,7 +31,7 @@ Closure nodetree_exec(void)
vec3 f0 = mix(dielectric, basecol, metallic);
vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
vec3 out_diff, out_spec, ssr_spec;
- eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, out_diff, out_spec, ssr_spec);
+ eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, true, out_diff, out_spec, ssr_spec);
Closure cl = CLOSURE_DEFAULT;
cl.radiance = out_spec + out_diff * albedo;
diff --git a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
index 4260c601543..1241cf0e387 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
@@ -10,7 +10,8 @@ layout(std140) uniform sssProfile
};
uniform sampler2D depthBuffer;
-uniform sampler2D sssData;
+uniform sampler2D sssIrradiance;
+uniform sampler2D sssRadius;
uniform sampler2D sssAlbedo;
#ifndef UTIL_TEX
@@ -19,9 +20,12 @@ uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
-layout(location = 0) out vec4 FragColor;
#ifdef RESULT_ACCUM
+/* Render Passes Accumulation */
+layout(location = 0) out vec4 sssDirect;
layout(location = 1) out vec4 sssColor;
+#else
+layout(location = 0) out vec4 sssRadiance;
#endif
float get_view_z_from_depth(float depth)
@@ -43,7 +47,8 @@ void main(void)
{
vec2 pixel_size = 1.0 / vec2(textureSize(depthBuffer, 0).xy); /* TODO precompute */
vec2 uvs = gl_FragCoord.xy * pixel_size;
- vec4 sss_data = texture(sssData, uvs).rgba;
+ vec3 sss_irradiance = texture(sssIrradiance, uvs).rgb;
+ float sss_radius = texture(sssRadius, uvs).r;
float depth_view = get_view_z_from_depth(texture(depthBuffer, uvs).r);
float rand = texelfetch_noise_tex(gl_FragCoord.xy).r;
@@ -58,44 +63,36 @@ void main(void)
/* Compute kernel bounds in 2D. */
float homcoord = ProjectionMatrix[2][3] * depth_view + ProjectionMatrix[3][3];
- vec2 scale = vec2(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) * sss_data.aa / homcoord;
+ vec2 scale = vec2(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) * sss_radius / homcoord;
vec2 finalStep = scale * radii_max_radius.w;
finalStep *= 0.5; /* samples range -1..1 */
/* Center sample */
- vec3 accum = sss_data.rgb * kernel[0].rgb;
+ vec3 accum = sss_irradiance * kernel[0].rgb;
for (int i = 1; i < sss_samples && i < MAX_SSS_SAMPLES; i++) {
vec2 sample_uv = uvs + kernel[i].a * finalStep *
((abs(kernel[i].a) > sssJitterThreshold) ? dir : dir_rand);
- vec3 color = texture(sssData, sample_uv).rgb;
+ vec3 color = texture(sssIrradiance, sample_uv).rgb;
float sample_depth = texture(depthBuffer, sample_uv).r;
sample_depth = get_view_z_from_depth(sample_depth);
-
/* Depth correction factor. */
float depth_delta = depth_view - sample_depth;
- float s = clamp(1.0 - exp(-(depth_delta * depth_delta) / (2.0 * sss_data.a)), 0.0, 1.0);
-
+ float s = clamp(1.0 - exp(-(depth_delta * depth_delta) / (2.0 * sss_radius)), 0.0, 1.0);
/* Out of view samples. */
if (any(lessThan(sample_uv, vec2(0.0))) || any(greaterThan(sample_uv, vec2(1.0)))) {
s = 1.0;
}
-
- accum += kernel[i].rgb * mix(color, sss_data.rgb, s);
+ /* Mix with first sample in failure case and apply kernel color. */
+ accum += kernel[i].rgb * mix(color, sss_irradiance, s);
}
-#ifdef FIRST_PASS
- FragColor = vec4(accum, sss_data.a);
+#ifdef RESULT_ACCUM
+ sssDirect = vec4(accum, 1.0);
+ sssColor = vec4(texture(sssAlbedo, uvs).rgb, 1.0);
+#elif defined(FIRST_PASS)
+ sssRadiance = vec4(accum, 1.0);
#else /* SECOND_PASS */
-# ifdef USE_SEP_ALBEDO
-# ifdef RESULT_ACCUM
- FragColor = vec4(accum, 1.0);
- sssColor = texture(sssAlbedo, uvs);
-# else
- FragColor = vec4(accum * texture(sssAlbedo, uvs).rgb, 1.0);
-# endif
-# else
- FragColor = vec4(accum, 1.0);
-# endif
+ sssRadiance = vec4(accum * texture(sssAlbedo, uvs).rgb, 1.0);
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl
new file mode 100644
index 00000000000..7edb0053da7
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl
@@ -0,0 +1,165 @@
+
+in vec4 uvcoordsvar;
+
+out vec4 FragColor;
+
+uniform sampler1D sssTexProfile;
+uniform sampler2D sssRadius;
+
+uniform sampler2DArray sssShadowCubes;
+uniform sampler2DArray sssShadowCascades;
+
+#define MAX_SSS_SAMPLES 65
+#define SSS_LUT_SIZE 64.0
+#define SSS_LUT_SCALE ((SSS_LUT_SIZE - 1.0) / float(SSS_LUT_SIZE))
+#define SSS_LUT_BIAS (0.5 / float(SSS_LUT_SIZE))
+
+layout(std140) uniform sssProfile
+{
+ vec4 kernel[MAX_SSS_SAMPLES];
+ vec4 radii_max_radius;
+ int sss_samples;
+};
+
+vec3 sss_profile(float s)
+{
+ s /= radii_max_radius.w;
+ return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb;
+}
+
+#ifndef UTIL_TEX
+# define UTIL_TEX
+uniform sampler2DArray utilTex;
+# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
+#endif /* UTIL_TEX */
+
+float light_translucent_power_with_falloff(LightData ld, vec3 N, vec4 l_vector)
+{
+ float power, falloff;
+ /* XXX : Removing Area Power. */
+ /* TODO : put this out of the shader. */
+ if (ld.l_type >= AREA_RECT) {
+ power = (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0);
+ if (ld.l_type == AREA_ELLIPSE) {
+ power *= M_PI * 0.25;
+ }
+ power *= 0.3 * 20.0 *
+ max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */
+ power /= (l_vector.w * l_vector.w);
+ falloff = dot(N, l_vector.xyz / l_vector.w);
+ }
+ else if (ld.l_type == SUN) {
+ power = 1.0 / (1.0 + (ld.l_radius * ld.l_radius * 0.5));
+ power *= ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/
+ power *= M_2PI * 0.78; /* Matching cycles with point light. */
+ power *= 0.082; /* XXX ad hoc, empirical */
+ falloff = dot(N, -ld.l_forward);
+ }
+ else {
+ power = (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0);
+ power *= 1.5; /* XXX ad hoc, empirical */
+ power /= (l_vector.w * l_vector.w);
+ falloff = dot(N, l_vector.xyz / l_vector.w);
+ }
+ /* No transmittance at grazing angle (hide artifacts) */
+ return power * saturate(falloff * 2.0);
+}
+
+/* Some driver poorly optimize this code. Use direct reference to matrices. */
+#define sd(x) shadows_data[x]
+#define scube(x) shadows_cube_data[x]
+#define scascade(x) shadows_cascade_data[x]
+
+vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, vec2 rand, float sss_scale)
+{
+ int shadow_id = int(ld.l_shadowid);
+
+ vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0);
+
+ /* We use the full l_vector.xyz so that the spread is minimize
+ * if the shading point is further away from the light source */
+ /* TODO(fclem) do something better than this. */
+ // vec3 T, B;
+ // make_orthonormal_basis(L.xyz / L.w, T, B);
+ // rand.xy *= data.sh_blur;
+ // W = W + T * rand.x + B * rand.y;
+
+ float s, dist;
+ int data_id = int(sd(shadow_id).sh_data_index);
+ if (ld.l_type == SUN) {
+ vec4 view_z = vec4(dot(W - cameraPos, cameraForward));
+
+ vec4 weights = step(scascade(data_id).split_end_distances, view_z);
+ float id = abs(4.0 - dot(weights, weights));
+ if (id > 3.0) {
+ return vec3(0.0);
+ }
+
+ /* Same factor as in get_cascade_world_distance(). */
+ float range = abs(sd(shadow_id).sh_far - sd(shadow_id).sh_near);
+
+ vec4 shpos = scascade(data_id).shadowmat[int(id)] * vec4(W, 1.0);
+ dist = shpos.z * range;
+
+ if (shpos.z > 1.0 || shpos.z < 0.0) {
+ return vec3(0.0);
+ }
+
+ float tex_id = scascade(data_id).sh_tex_index;
+ s = sample_cascade(sssShadowCascades, shpos.xy, tex_id + id).r;
+ s *= range;
+ }
+ else {
+ vec3 cubevec = transform_point(scube(data_id).shadowmat, W);
+ dist = length(cubevec);
+ cubevec /= dist;
+ /* tex_id == data_id for cube shadowmap */
+ float tex_id = float(data_id);
+ s = sample_cube(sssShadowCubes, cubevec, tex_id).r;
+ s = length(cubevec / max_v3(abs(cubevec))) *
+ linear_depth(true, s, sd(shadow_id).sh_far, sd(shadow_id).sh_near);
+ }
+ float delta = dist - s;
+
+ float power = light_translucent_power_with_falloff(ld, N, l_vector);
+
+ return power * sss_profile(abs(delta) / sss_scale);
+}
+
+#undef sd
+#undef scube
+#undef scsmd
+
+void main(void)
+{
+ vec2 uvs = uvcoordsvar.xy;
+ float sss_scale = texture(sssRadius, uvs).r;
+ vec3 W = get_world_space_from_depth(uvs, texture(depthBuffer, uvs).r);
+ vec3 N = normalize(cross(dFdx(W), dFdy(W)));
+
+ vec3 rand = texelfetch_noise_tex(gl_FragCoord.xy).zwy;
+ rand.xy *= fast_sqrt(rand.z);
+
+ vec3 accum = vec3(0.0);
+ for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) {
+ LightData ld = lights_data[i];
+
+ /* Only shadowed light can produce translucency */
+ if (ld.l_shadowid < 0.0) {
+ continue;
+ }
+
+ vec4 l_vector; /* Non-Normalized Light Vector with length in last component. */
+ l_vector.xyz = ld.l_position - W;
+ l_vector.w = length(l_vector.xyz);
+
+ float att = light_attenuation(ld, l_vector);
+ if (att < 1e-8) {
+ continue;
+ }
+
+ accum += att * ld.l_color * light_translucent(ld, W, -N, l_vector, rand.xy, sss_scale);
+ }
+
+ FragColor = vec4(accum, 1.0);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
index c3643cccbfc..72017e971fc 100644
--- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
@@ -1,6 +1,6 @@
-uniform sampler2DArray shadowCubeTexture;
-uniform sampler2DArray shadowCascadeTexture;
+uniform sampler2DArrayShadow shadowCubeTexture;
+uniform sampler2DArrayShadow shadowCascadeTexture;
#define LAMPS_LIB
@@ -24,129 +24,115 @@ layout(std140) uniform light_block
/* Used to define the area light shape, doesn't directly correspond to a Blender light type. */
#define AREA_ELLIPSE 100.0
-#if defined(SHADOW_VSM)
-# define ShadowSample vec2
-# define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).rg
-# define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).rg
-#elif defined(SHADOW_ESM)
-# define ShadowSample float
-# define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r
-# define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r
-#else
-# define ShadowSample float
-# define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r
-# define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r
-#endif
-
-#if defined(SHADOW_VSM)
-# define get_depth_delta(dist, s) (dist - s.x)
-#else
-# define get_depth_delta(dist, s) (dist - s)
-#endif
-
- /* ----------------------------------------------------------- */
- /* ----------------------- Shadow tests ---------------------- */
- /* ----------------------------------------------------------- */
-
-#if defined(SHADOW_VSM)
-
-float shadow_test(ShadowSample moments, float dist, ShadowData sd)
+float cubeFaceIndexEEVEE(vec3 P)
{
- float p = 0.0;
-
- if (dist <= moments.x) {
- p = 1.0;
+ vec3 aP = abs(P);
+ if (all(greaterThan(aP.xx, aP.yz))) {
+ return (P.x > 0.0) ? 0.0 : 1.0;
+ }
+ else if (all(greaterThan(aP.yy, aP.xz))) {
+ return (P.y > 0.0) ? 2.0 : 3.0;
+ }
+ else {
+ return (P.z > 0.0) ? 4.0 : 5.0;
}
-
- float variance = moments.y - (moments.x * moments.x);
- variance = max(variance, sd.sh_bias / 10.0);
-
- float d = moments.x - dist;
- float p_max = variance / (variance + d * d);
-
- /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */
- p_max = clamp((p_max - sd.sh_bleed) / (1.0 - sd.sh_bleed), 0.0, 1.0);
-
- return max(p, p_max);
}
-#elif defined(SHADOW_ESM)
-
-float shadow_test(ShadowSample z, float dist, ShadowData sd)
+vec2 cubeFaceCoordEEVEE(vec3 P, float face, float scale)
{
- return saturate(exp(sd.sh_exp * (z - dist + sd.sh_bias)));
+ if (face < 2.0) {
+ return (P.zy / P.x) * scale * vec2(-0.5, -sign(P.x) * 0.5) + 0.5;
+ }
+ else if (face < 4.0) {
+ return (P.xz / P.y) * scale * vec2(sign(P.y) * 0.5, 0.5) + 0.5;
+ }
+ else {
+ return (P.xy / P.z) * scale * vec2(0.5, -sign(P.z) * 0.5) + 0.5;
+ }
}
-#else
-
-float shadow_test(ShadowSample z, float dist, ShadowData sd)
+vec2 cubeFaceCoordEEVEE(vec3 P, float face, sampler2DArray tex)
{
- return step(0, z - dist + sd.sh_bias);
+ /* Scaling to compensate the 1px border around the face. */
+ float cube_res = float(textureSize(tex, 0).x);
+ float scale = (cube_res) / (cube_res + 1.0);
+ return cubeFaceCoordEEVEE(P, face, scale);
}
-#endif
-
-/* ----------------------------------------------------------- */
-/* ----------------------- Shadow types ---------------------- */
-/* ----------------------------------------------------------- */
-
-float shadow_cubemap(ShadowData sd, ShadowCubeData scd, float texid, vec3 W)
+vec2 cubeFaceCoordEEVEE(vec3 P, float face, sampler2DArrayShadow tex)
{
- vec3 cubevec = W - scd.position.xyz;
- float dist = length(cubevec);
+ /* Scaling to compensate the 1px border around the face. */
+ float cube_res = float(textureSize(tex, 0).x);
+ float scale = (cube_res) / (cube_res + 1.0);
+ return cubeFaceCoordEEVEE(P, face, scale);
+}
- cubevec /= dist;
+vec4 sample_cube(sampler2DArray tex, vec3 cubevec, float cube)
+{
+ /* Manual Shadow Cube Layer indexing. */
+ /* TODO Shadow Cube Array. */
+ float face = cubeFaceIndexEEVEE(cubevec);
+ vec2 uv = cubeFaceCoordEEVEE(cubevec, face, tex);
- ShadowSample s = sample_cube(cubevec, texid);
- return shadow_test(s, dist, sd);
+ vec3 coord = vec3(uv, cube * 6.0 + face);
+ return texture(tex, coord);
}
-float evaluate_cascade(ShadowData sd, mat4 shadowmat, vec3 W, float range, float texid)
+vec4 sample_cascade(sampler2DArray tex, vec2 co, float cascade_id)
{
- vec4 shpos = shadowmat * vec4(W, 1.0);
- float dist = shpos.z * range;
+ return texture(tex, vec3(co, cascade_id));
+}
- ShadowSample s = sample_cascade(shpos.xy, texid);
- float vis = shadow_test(s, dist, sd);
+/* Some driver poorly optimize this code. Use direct reference to matrices. */
+#define sd(x) shadows_data[x]
+#define scube(x) shadows_cube_data[x]
+#define scascade(x) shadows_cascade_data[x]
- /* If fragment is out of shadowmap range, do not occlude */
- if (shpos.z < 1.0 && shpos.z > 0.0) {
- return vis;
- }
- else {
- return 1.0;
- }
+float sample_cube_shadow(int shadow_id, vec3 W)
+{
+ int data_id = int(sd(shadow_id).sh_data_index);
+ vec3 cubevec = transform_point(scube(data_id).shadowmat, W);
+ float dist = max_v3(abs(cubevec)) - sd(shadow_id).sh_bias;
+ dist = buffer_depth(true, dist, sd(shadow_id).sh_far, sd(shadow_id).sh_near);
+ /* Manual Shadow Cube Layer indexing. */
+ /* TODO Shadow Cube Array. */
+ float face = cubeFaceIndexEEVEE(cubevec);
+ vec2 coord = cubeFaceCoordEEVEE(cubevec, face, shadowCubeTexture);
+ /* tex_id == data_id for cube shadowmap */
+ float tex_id = float(data_id);
+ return texture(shadowCubeTexture, vec4(coord, tex_id * 6.0 + face, dist));
}
-float shadow_cascade(ShadowData sd, int scd_id, float texid, vec3 W)
+float sample_cascade_shadow(int shadow_id, vec3 W)
{
+ int data_id = int(sd(shadow_id).sh_data_index);
+ float tex_id = scascade(data_id).sh_tex_index;
vec4 view_z = vec4(dot(W - cameraPos, cameraForward));
- vec4 weights = smoothstep(shadows_cascade_data[scd_id].split_end_distances,
- shadows_cascade_data[scd_id].split_start_distances.yzwx,
- view_z);
-
- weights.yzw -= weights.xyz;
-
- vec4 vis = vec4(1.0);
- float range = abs(sd.sh_far - sd.sh_near); /* Same factor as in get_cascade_world_distance(). */
-
- /* Branching using (weights > 0.0) is reaally slooow on intel so avoid it for now. */
- /* TODO OPTI: Only do 2 samples and blend. */
- vis.x = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[0], W, range, texid + 0);
- vis.y = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[1], W, range, texid + 1);
- vis.z = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[2], W, range, texid + 2);
- vis.w = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[3], W, range, texid + 3);
-
- float weight_sum = dot(vec4(1.0), weights);
- if (weight_sum > 0.9999) {
- float vis_sum = dot(vec4(1.0), vis * weights);
- return vis_sum / weight_sum;
- }
- else {
- float vis_sum = dot(vec4(1.0), vis * step(0.001, weights));
- return mix(1.0, vis_sum, weight_sum);
- }
+ vec4 weights = 1.0 - smoothstep(scascade(data_id).split_end_distances,
+ scascade(data_id).split_start_distances.yzwx,
+ view_z);
+ float tot_weight = dot(weights.xyz, vec3(1.0));
+
+ int cascade = int(clamp(tot_weight, 0.0, 3.0));
+ float blend = fract(tot_weight);
+ float vis = weights.w;
+ vec4 coord, shpos;
+ /* Main cascade. */
+ shpos = scascade(data_id).shadowmat[cascade] * vec4(W, 1.0);
+ coord = vec4(shpos.xy, tex_id + float(cascade), shpos.z - sd(shadow_id).sh_bias);
+ vis += texture(shadowCascadeTexture, coord) * (1.0 - blend);
+
+ cascade = min(3, cascade + 1);
+ /* Second cascade. */
+ shpos = scascade(data_id).shadowmat[cascade] * vec4(W, 1.0);
+ coord = vec4(shpos.xy, tex_id + float(cascade), shpos.z - sd(shadow_id).sh_bias);
+ vis += texture(shadowCascadeTexture, coord) * blend;
+
+ return saturate(vis);
}
+#undef sd
+#undef scube
+#undef scsmd
/* ----------------------------------------------------------- */
/* --------------------- Light Functions --------------------- */
@@ -173,16 +159,9 @@ float spot_attenuation(LightData ld, vec3 l_vector)
return spotmask;
}
-float light_visibility(LightData ld,
- vec3 W,
-#ifndef VOLUMETRICS
- vec3 viewPosition,
- vec3 vN,
-#endif
- vec4 l_vector)
+float light_attenuation(LightData ld, vec4 l_vector)
{
float vis = 1.0;
-
if (ld.l_type == SPOT) {
vis *= spot_attenuation(ld, l_vector.xyz);
}
@@ -192,69 +171,66 @@ float light_visibility(LightData ld,
if (ld.l_type != SUN) {
vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence);
}
+ return vis;
+}
+
+float light_visibility(LightData ld,
+ vec3 W,
+#ifndef VOLUMETRICS
+ vec3 viewPosition,
+ float tracing_depth,
+ vec3 true_normal,
+ float rand_x,
+ const bool use_contact_shadows,
+#endif
+ vec4 l_vector)
+{
+ float vis = light_attenuation(ld, l_vector);
#if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW)
/* shadowing */
if (ld.l_shadowid >= 0.0 && vis > 0.001) {
- ShadowData data = shadows_data[int(ld.l_shadowid)];
if (ld.l_type == SUN) {
- vis *= shadow_cascade(data, int(data.sh_data_start), data.sh_tex_start, W);
+ vis *= sample_cascade_shadow(int(ld.l_shadowid), W);
}
else {
- vis *= shadow_cubemap(
- data, shadows_cube_data[int(data.sh_data_start)], data.sh_tex_start, W);
+ vis *= sample_cube_shadow(int(ld.l_shadowid), W);
}
# ifndef VOLUMETRICS
+ ShadowData sd = shadows_data[int(ld.l_shadowid)];
/* Only compute if not already in shadow. */
- if (data.sh_contact_dist > 0.0) {
- vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0);
- float trace_distance = (ld.l_type != SUN) ? min(data.sh_contact_dist, l_vector.w) :
- data.sh_contact_dist;
-
- vec3 T, B;
- make_orthonormal_basis(L.xyz / L.w, T, B);
-
- vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
- rand.zw *= fast_sqrt(rand.y) * data.sh_contact_spread;
-
- /* We use the full l_vector.xyz so that the spread is minimize
- * if the shading point is further away from the light source */
- vec3 ray_dir = L.xyz + T * rand.z + B * rand.w;
- ray_dir = transform_direction(ViewMatrix, ray_dir);
- ray_dir = normalize(ray_dir);
-
- vec3 ray_ori = viewPosition;
-
- /* Fix translucency shadowed by contact shadows. */
- vN = (gl_FrontFacing) ? vN : -vN;
-
- if (dot(vN, ray_dir) <= 0.0) {
- return vis;
+ if (use_contact_shadows && sd.sh_contact_dist > 0.0 && vis > 1e-8) {
+ /* Contact Shadows. */
+ vec3 ray_ori, ray_dir;
+ float trace_distance;
+
+ if (ld.l_type == SUN) {
+ trace_distance = sd.sh_contact_dist;
+ ray_dir = shadows_cascade_data[int(sd.sh_data_index)].sh_shadow_vec * trace_distance;
+ }
+ else {
+ ray_dir = shadows_cube_data[int(sd.sh_data_index)].position.xyz - W;
+ float len = length(ray_dir);
+ trace_distance = min(sd.sh_contact_dist, len);
+ ray_dir *= trace_distance / len;
}
- float bias = 0.5; /* Constant Bias */
- bias += 1.0 - abs(dot(vN, ray_dir)); /* Angle dependent bias */
- bias *= gl_FrontFacing ? data.sh_contact_offset : -data.sh_contact_offset;
-
- vec3 nor_bias = vN * bias;
- ray_ori += nor_bias;
-
- ray_dir *= trace_distance;
- ray_dir -= nor_bias;
+ ray_dir = transform_direction(ViewMatrix, ray_dir);
+ ray_ori = vec3(viewPosition.xy, tracing_depth) + true_normal * sd.sh_contact_offset;
vec3 hit_pos = raycast(
- -1, ray_ori, ray_dir, data.sh_contact_thickness, rand.x, 0.1, 0.001, false);
+ -1, ray_ori, ray_dir, sd.sh_contact_thickness, rand_x, 0.1, 0.001, false);
if (hit_pos.z > 0.0) {
hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z);
float hit_dist = distance(viewPosition, hit_pos);
float dist_ratio = hit_dist / trace_distance;
- return vis * saturate(dist_ratio * dist_ratio * dist_ratio);
+ return vis * saturate(dist_ratio * 3.0 - 2.0);
}
}
-# endif
+# endif /* VOLUMETRICS */
}
#endif
@@ -325,134 +301,3 @@ float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector)
}
}
#endif
-
-#define MAX_SSS_SAMPLES 65
-#define SSS_LUT_SIZE 64.0
-#define SSS_LUT_SCALE ((SSS_LUT_SIZE - 1.0) / float(SSS_LUT_SIZE))
-#define SSS_LUT_BIAS (0.5 / float(SSS_LUT_SIZE))
-
-#ifdef USE_TRANSLUCENCY
-layout(std140) uniform sssProfile
-{
- vec4 kernel[MAX_SSS_SAMPLES];
- vec4 radii_max_radius;
- int sss_samples;
-};
-
-uniform sampler1D sssTexProfile;
-
-vec3 sss_profile(float s)
-{
- s /= radii_max_radius.w;
- return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb;
-}
-#endif
-
-vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale)
-{
-#if !defined(USE_TRANSLUCENCY) || defined(VOLUMETRICS)
- return vec3(0.0);
-#else
- vec3 vis = vec3(1.0);
-
- if (ld.l_type == SPOT) {
- vis *= spot_attenuation(ld, l_vector.xyz);
- }
- if (ld.l_type >= SPOT) {
- vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
- }
- if (ld.l_type != SUN) {
- vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence);
- }
-
- /* Only shadowed light can produce translucency */
- if (ld.l_shadowid >= 0.0 && vis.x > 0.001) {
- ShadowData data = shadows_data[int(ld.l_shadowid)];
- float delta;
-
- vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0);
-
- vec3 T, B;
- make_orthonormal_basis(L.xyz / L.w, T, B);
-
- vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
- rand.zw *= fast_sqrt(rand.y) * data.sh_blur;
-
- /* We use the full l_vector.xyz so that the spread is minimize
- * if the shading point is further away from the light source */
- W = W + T * rand.z + B * rand.w;
-
- if (ld.l_type == SUN) {
- int scd_id = int(data.sh_data_start);
- vec4 view_z = vec4(dot(W - cameraPos, cameraForward));
-
- vec4 weights = step(shadows_cascade_data[scd_id].split_end_distances, view_z);
- float id = abs(4.0 - dot(weights, weights));
-
- if (id > 3.0) {
- return vec3(0.0);
- }
-
- /* Same factor as in get_cascade_world_distance(). */
- float range = abs(data.sh_far - data.sh_near);
-
- vec4 shpos = shadows_cascade_data[scd_id].shadowmat[int(id)] * vec4(W, 1.0);
- float dist = shpos.z * range;
-
- if (shpos.z > 1.0 || shpos.z < 0.0) {
- return vec3(0.0);
- }
-
- ShadowSample s = sample_cascade(shpos.xy, data.sh_tex_start + id);
- delta = get_depth_delta(dist, s);
- }
- else {
- vec3 cubevec = W - shadows_cube_data[int(data.sh_data_start)].position.xyz;
- float dist = length(cubevec);
- cubevec /= dist;
-
- ShadowSample s = sample_cube(cubevec, data.sh_tex_start);
- delta = get_depth_delta(dist, s);
- }
-
- /* XXX : Removing Area Power. */
- /* TODO : put this out of the shader. */
- float falloff;
- if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) {
- vis *= (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0);
- if (ld.l_type == AREA_ELLIPSE) {
- vis *= M_PI * 0.25;
- }
- vis *= 0.3 * 20.0 *
- max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */
- vis /= (l_vector.w * l_vector.w);
- falloff = dot(N, l_vector.xyz / l_vector.w);
- }
- else if (ld.l_type == SUN) {
- vis /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f);
- vis *= ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/
- vis *= M_2PI * 0.78; /* Matching cycles with point light. */
- vis *= 0.082; /* XXX ad hoc, empirical */
- falloff = dot(N, -ld.l_forward);
- }
- else {
- vis *= (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0);
- vis *= 1.5; /* XXX ad hoc, empirical */
- vis /= (l_vector.w * l_vector.w);
- falloff = dot(N, l_vector.xyz / l_vector.w);
- }
- // vis *= M_1_PI; /* Normalize */
-
- /* Applying profile */
- vis *= sss_profile(abs(delta) / scale);
-
- /* No transmittance at grazing angle (hide artifacts) */
- vis *= saturate(falloff * 2.0);
- }
- else {
- vis = vec3(0.0);
- }
-
- return vis;
-#endif
-}
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 53f1517505c..e9bdfec008f 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -144,14 +144,12 @@ void CLOSURE_NAME(vec3 N
,
float ior
#endif
+ ,
+ const bool use_contact_shadows
#ifdef CLOSURE_DIFFUSE
,
out vec3 out_diff
#endif
-#ifdef CLOSURE_SUBSURFACE
- ,
- out vec3 out_trans
-#endif
#ifdef CLOSURE_GLOSSY
,
out vec3 out_spec
@@ -170,10 +168,6 @@ void CLOSURE_NAME(vec3 N
out_diff = vec3(0.0);
#endif
-#ifdef CLOSURE_SUBSURFACE
- out_trans = vec3(0.0);
-#endif
-
#ifdef CLOSURE_GLOSSY
out_spec = vec3(0.0);
#endif
@@ -230,6 +224,16 @@ void CLOSURE_NAME(vec3 N
vec3 out_spec_clear = vec3(0.0);
# endif
+ float tracing_depth = gl_FragCoord.z;
+ /* Constant bias (due to depth buffer precision) */
+ /* Magic numbers for 24bits of precision.
+ * From http://terathon.com/gdc07_lengyel.pdf (slide 26) */
+ tracing_depth -= mix(2.4e-7, 4.8e-7, gl_FragCoord.z);
+ /* Convert to view Z. */
+ tracing_depth = get_view_z_from_depth(tracing_depth);
+
+ vec3 true_normal = normalize(cross(dFdx(viewPosition), dFdy(viewPosition)));
+
for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) {
LightData ld = lights_data[i];
@@ -237,7 +241,14 @@ void CLOSURE_NAME(vec3 N
l_vector.xyz = ld.l_position - worldPosition;
l_vector.w = length(l_vector.xyz);
- float l_vis = light_visibility(ld, worldPosition, viewPosition, viewNormal, l_vector);
+ float l_vis = light_visibility(ld,
+ worldPosition,
+ viewPosition,
+ tracing_depth,
+ true_normal,
+ rand.x,
+ use_contact_shadows,
+ l_vector);
if (l_vis < 1e-8) {
continue;
@@ -249,10 +260,6 @@ void CLOSURE_NAME(vec3 N
out_diff += l_color_vis * light_diffuse(ld, N, V, l_vector);
# endif
-# ifdef CLOSURE_SUBSURFACE
- out_trans += ld.l_color * light_translucent(ld, worldPosition, -N, l_vector, sss_scale);
-# endif
-
# ifdef CLOSURE_GLOSSY
out_spec += l_color_vis * light_specular(ld, ltc_mat, N, V, l_vector) * ld.l_spec;
# endif
@@ -441,10 +448,17 @@ void CLOSURE_NAME(vec3 N
/* Ambient Occlusion */
/* ---------------------------- */
# if defined(CLOSURE_GLOSSY) || defined(CLOSURE_DIFFUSE)
- /* HACK: Fix for translucent BSDF. (see T65631) */
- bool same_side = dot((gl_FrontFacing) ? worldNormal : -worldNormal, N) > 0.0;
+ if (!use_contact_shadows) {
+ /* HACK: Fix for translucent BSDF. (see T65631) */
+ N = -N;
+ }
vec3 bent_normal;
- float final_ao = occlusion_compute(same_side ? N : -N, viewPosition, ao, rand, bent_normal);
+ float final_ao = occlusion_compute(gl_FrontFacing ? N : -N, viewPosition, ao, rand, bent_normal);
+ if (!use_contact_shadows) {
+ N = -N;
+ /* Bypass bent normal. */
+ bent_normal = N;
+ }
# endif
/* ---------------------------- */
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index 14e0c947b47..f88cfdf3787 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -120,7 +120,8 @@ void prepare_raycast(vec3 ray_origin,
ss_ray = ss_start * m.xyyy + 0.5;
ss_step *= m.xyyy;
- ss_ray.xy += m * ssrPixelSize * 2.0; /* take the center of the texel. * 2 because halfres. */
+ /* take the center of the texel. */
+ // ss_ray.xy += sign(ss_ray.xy) * m * ssrPixelSize * (1.0 + hizMipOffset);
}
/* See times_and_deltas. */
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl
deleted file mode 100644
index 5646c257562..00000000000
--- a/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl
+++ /dev/null
@@ -1,199 +0,0 @@
-/* Copy the depth only shadowmap into another texture while converting
- * to linear depth (or other storage method) and doing a 3x3 box filter. */
-
-layout(std140) uniform shadow_render_block
-{
- /* Use vectors to avoid alignment padding. */
- ivec4 shadowSampleCount;
- vec4 shadowInvSampleCount;
- vec4 filterSize;
- int viewCount;
- int baseId;
- float cubeTexelSize;
- float storedTexelSize;
- float nearClip;
- float farClip;
- float exponent;
-};
-
-#ifdef CSM
-uniform sampler2DArray shadowTexture;
-#else
-uniform samplerCube shadowTexture;
-#endif
-
-flat in int layerID;
-
-#ifdef CSM
-# define cascadeID layerID
-#else
-# define cascadeID 0
-#endif
-
-out vec4 FragColor;
-
-#define linear_depth(z) \
- ((nearClip * farClip) / (clamp(z, 0.0, 0.999999) * (nearClip - farClip) + farClip))
-
-/* add bias so background filtering does not bleed into shadow map */
-#define BACKGROUND_BIAS 0.05
-
-#ifdef CSM
-vec4 get_world_distance(vec4 depths, vec3 cos[4])
-{
- depths += step(vec4(0.9999), depths) * BACKGROUND_BIAS;
- return clamp(
- depths * abs(farClip - nearClip), 0.0, 1e10); /* Same factor as in shadow_cascade(). */
-}
-
-float get_world_distance(float depth, vec3 cos)
-{
- depth += step(0.9999, depth) * BACKGROUND_BIAS;
- return clamp(
- depth * abs(farClip - nearClip), 0.0, 1e10); /* Same factor as in shadow_cascade(). */
-}
-
-#else /* CUBEMAP */
-vec4 get_world_distance(vec4 depths, vec3 cos[4])
-{
- depths = linear_depth(depths);
- cos[0] = normalize(abs(cos[0]));
- cos[1] = normalize(abs(cos[1]));
- cos[2] = normalize(abs(cos[2]));
- cos[3] = normalize(abs(cos[3]));
- vec4 cos_vec;
- cos_vec.x = max(cos[0].x, max(cos[0].y, cos[0].z));
- cos_vec.y = max(cos[1].x, max(cos[1].y, cos[1].z));
- cos_vec.z = max(cos[2].x, max(cos[2].y, cos[2].z));
- cos_vec.w = max(cos[3].x, max(cos[3].y, cos[3].z));
- return depths / cos_vec;
-}
-
-float get_world_distance(float depth, vec3 cos)
-{
- depth = linear_depth(depth);
- cos = normalize(abs(cos));
- float cos_vec = max(cos.x, max(cos.y, cos.z));
- return depth / cos_vec;
-}
-#endif
-
-/* Marco Salvi's GDC 2008 presentation about shadow maps pre-filtering techniques slide 24 */
-#define ln_space_prefilter_step(ref, sample) exp(sample - ref)
-#define ln_space_prefilter_finalize(ref, sum) (ref + log(SAMPLE_WEIGHT * sum))
-
-#define SAMPLE_WEIGHT 0.11111
-
-#ifdef ESM
-void prefilter(vec4 depths, float ref, inout float accum)
-{
- accum += dot(ln_space_prefilter_step(ref, depths), vec4(1.0));
-}
-#else /* VSM */
-void prefilter(vec4 depths, float ref, inout vec2 accum)
-{
- vec4 depths_sqr = depths * depths;
- accum += vec2(dot(vec4(1.0), depths), dot(vec4(1.0), depths_sqr)) * SAMPLE_WEIGHT;
-}
-#endif
-
-#ifdef CSM
-vec3 get_texco(vec2 uvs, vec2 ofs)
-{
- return vec3(uvs + ofs, float(cascadeID));
-}
-#else /* CUBEMAP */
-const vec3 minorAxisX[6] = vec3[6](vec3(0.0f, 0.0f, -1.0f),
- vec3(0.0f, 0.0f, 1.0f),
- vec3(1.0f, 0.0f, 0.0f),
- vec3(1.0f, 0.0f, 0.0f),
- vec3(1.0f, 0.0f, 0.0f),
- vec3(-1.0f, 0.0f, 0.0f));
-
-const vec3 minorAxisY[6] = vec3[6](vec3(0.0f, -1.0f, 0.0f),
- vec3(0.0f, -1.0f, 0.0f),
- vec3(0.0f, 0.0f, 1.0f),
- vec3(0.0f, 0.0f, -1.0f),
- vec3(0.0f, -1.0f, 0.0f),
- vec3(0.0f, -1.0f, 0.0f));
-
-const vec3 majorAxis[6] = vec3[6](vec3(1.0f, 0.0f, 0.0f),
- vec3(-1.0f, 0.0f, 0.0f),
- vec3(0.0f, 1.0f, 0.0f),
- vec3(0.0f, -1.0f, 0.0f),
- vec3(0.0f, 0.0f, 1.0f),
- vec3(0.0f, 0.0f, -1.0f));
-
-vec3 get_texco(vec2 uvs, vec2 ofs)
-{
- uvs += ofs;
- return majorAxis[layerID] + uvs.x * minorAxisX[layerID] + uvs.y * minorAxisY[layerID];
-}
-#endif
-
-void main()
-{
- /* Copy the depth only shadowmap into another texture while converting
- * to linear depth and do a 3x3 box blur. */
-
-#ifdef CSM
- vec2 uvs = gl_FragCoord.xy * storedTexelSize;
-#else /* CUBEMAP */
- vec2 uvs = gl_FragCoord.xy * cubeTexelSize * 2.0 - 1.0;
-#endif
-
- /* Center texel */
- vec3 co = get_texco(uvs, vec2(0.0));
- float depth = texture(shadowTexture, co).r;
- depth = get_world_distance(depth, co);
-
- if (filterSize[cascadeID] == 0.0) {
-#ifdef ESM
- FragColor = vec4(depth);
-#else /* VSM */
- FragColor = vec2(depth, depth * depth).xyxy;
-#endif
- return;
- }
-
-#ifdef ESM
- float ref = depth;
- float accum = 1.0;
-#else /* VSM */
- float ref = 0.0; /* UNUSED */
- vec2 accum = vec2(depth, depth * depth) * SAMPLE_WEIGHT;
-#endif
-
- vec3 ofs = vec3(1.0, 0.0, -1.0) * filterSize[cascadeID];
-
- vec3 cos[4];
- cos[0] = get_texco(uvs, ofs.zz);
- cos[1] = get_texco(uvs, ofs.yz);
- cos[2] = get_texco(uvs, ofs.xz);
- cos[3] = get_texco(uvs, ofs.zy);
-
- vec4 depths;
- depths.x = texture(shadowTexture, cos[0]).r;
- depths.y = texture(shadowTexture, cos[1]).r;
- depths.z = texture(shadowTexture, cos[2]).r;
- depths.w = texture(shadowTexture, cos[3]).r;
- depths = get_world_distance(depths, cos);
- prefilter(depths, ref, accum);
-
- cos[0] = get_texco(uvs, ofs.xy);
- cos[1] = get_texco(uvs, ofs.zx);
- cos[2] = get_texco(uvs, ofs.yx);
- cos[3] = get_texco(uvs, ofs.xx);
- depths.x = texture(shadowTexture, cos[0]).r;
- depths.y = texture(shadowTexture, cos[1]).r;
- depths.z = texture(shadowTexture, cos[2]).r;
- depths.w = texture(shadowTexture, cos[3]).r;
- depths = get_world_distance(depths, cos);
- prefilter(depths, ref, accum);
-
-#ifdef ESM
- accum = ln_space_prefilter_finalize(ref, accum);
-#endif
- /* Clamp infinite sum. */
- FragColor = vec2(clamp(accum, 0.0, 1e16)).xyxy;
-}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_process_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_process_geom.glsl
deleted file mode 100644
index 591666560c4..00000000000
--- a/source/blender/draw/engines/eevee/shaders/shadow_process_geom.glsl
+++ /dev/null
@@ -1,36 +0,0 @@
-
-layout(triangles) in;
-layout(triangle_strip, max_vertices = 3) out;
-
-layout(std140) uniform shadow_render_block
-{
- /* Use vectors to avoid alignment padding. */
- ivec4 shadowSampleCount;
- vec4 shadowInvSampleCount;
- vec4 filterSize;
- int viewCount;
- int baseId;
- float cubeTexelSize;
- float storedTexelSize;
- float nearClip;
- float farClip;
- float exponent;
-};
-
-in int layerID_g[];
-
-flat out int layerID;
-
-void main()
-{
- gl_Layer = layerID_g[0];
- layerID = gl_Layer - baseId;
-
- gl_Position = gl_in[0].gl_Position;
- EmitVertex();
- gl_Position = gl_in[1].gl_Position;
- EmitVertex();
- gl_Position = gl_in[2].gl_Position;
- EmitVertex();
- EndPrimitive();
-}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_process_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_process_vert.glsl
deleted file mode 100644
index 95e6a48b81f..00000000000
--- a/source/blender/draw/engines/eevee/shaders/shadow_process_vert.glsl
+++ /dev/null
@@ -1,32 +0,0 @@
-
-layout(std140) uniform shadow_render_block
-{
- /* Use vectors to avoid alignment padding. */
- ivec4 shadowSampleCount;
- vec4 shadowInvSampleCount;
- vec4 filterSize;
- int viewCount;
- int baseId;
- float cubeTexelSize;
- float storedTexelSize;
- float nearClip;
- float farClip;
- float exponent;
-};
-
-out int layerID_g;
-
-void main()
-{
- int v = gl_VertexID % 3;
- layerID_g = gl_VertexID / 3;
- float x = -1.0 + float((v & 1) << 2);
- float y = -1.0 + float((v & 2) << 1);
- gl_Position = vec4(x, y, 1.0, 1.0);
-
- /* HACK avoid changing drawcall parameters. */
- if (layerID_g >= viewCount) {
- gl_Position = vec4(0.0);
- }
- layerID_g += baseId;
-}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
deleted file mode 100644
index 5c19ccd5ce1..00000000000
--- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
+++ /dev/null
@@ -1,322 +0,0 @@
-
-layout(std140) uniform shadow_render_block
-{
- /* Use vectors to avoid alignment padding. */
- ivec4 shadowSampleCount;
- vec4 shadowInvSampleCount;
- vec4 filterSize;
- int viewCount;
- int baseId;
- float cubeTexelSize;
- float storedTexelSize;
- float nearClip;
- float farClip;
- float exponent;
-};
-
-#ifdef CSM
-uniform sampler2DArray shadowTexture;
-#else
-uniform samplerCube shadowTexture;
-#endif
-
-flat in int layerID;
-
-#ifdef CSM
-# define cascadeID layerID
-#else
-# define cascadeID 0
-#endif
-
-out vec4 FragColor;
-
-vec3 octahedral_to_cubemap_proj(vec2 co)
-{
- co = co * 2.0 - 1.0;
-
- vec2 abs_co = abs(co);
- vec3 v = vec3(co, 1.0 - (abs_co.x + abs_co.y));
-
- if (abs_co.x + abs_co.y > 1.0) {
- v.xy = (abs(co.yx) - 1.0) * -sign(co.xy);
- }
-
- return v;
-}
-
-/* Marco Salvi's GDC 2008 presentation about shadow maps pre-filtering techniques slide 24 */
-/* http://advances.realtimerendering.com/s2009/SIGGRAPH%202009%20-%20Lighting%20Research%20at%20Bungie.pdf
- * Slide 55. */
-#define ln_space_prefilter_step(ref, sample) exp(sample - ref)
-#define ln_space_prefilter_finalize(ref, sum) (ref + log(shadowInvSampleCount[cascadeID] * sum))
-
-#ifdef CSM
-vec3 get_texco(vec3 cos, const vec2 ofs)
-{
- cos.xy += ofs * filterSize[cascadeID];
- return cos;
-}
-#else /* CUBEMAP */
-/* global vars */
-vec3 T = vec3(0.0);
-vec3 B = vec3(0.0);
-
-void make_orthonormal_basis(vec3 N)
-{
- vec3 UpVector = (abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
- T = normalize(cross(UpVector, N));
- B = cross(N, T);
-}
-
-vec3 get_texco(vec3 cos, const vec2 ofs)
-{
- return cos + ofs.x * T + ofs.y * B;
-}
-
-#endif
-
-#ifdef ESM
-void grouped_samples_accum(vec3 cos,
- const vec2 co1,
- const vec2 co2,
- const vec2 co3,
- const vec2 co4,
- float ref,
- inout vec4 accum)
-{
- vec4 depths;
- depths.x = texture(shadowTexture, get_texco(cos, co1)).r;
- depths.y = texture(shadowTexture, get_texco(cos, co2)).r;
- depths.z = texture(shadowTexture, get_texco(cos, co3)).r;
- depths.w = texture(shadowTexture, get_texco(cos, co4)).r;
-
- accum += ln_space_prefilter_step(ref, depths);
-}
-#else /* VSM */
-void grouped_samples_accum(vec3 cos,
- const vec2 co1,
- const vec2 co2,
- const vec2 co3,
- const vec2 co4,
- float ref,
- inout vec2 accum)
-{
- vec4 depths1, depths2;
- depths1.xy = texture(shadowTexture, get_texco(cos, co1)).rg;
- depths1.zw = texture(shadowTexture, get_texco(cos, co2)).rg;
- depths2.xy = texture(shadowTexture, get_texco(cos, co3)).rg;
- depths2.zw = texture(shadowTexture, get_texco(cos, co4)).rg;
-
- accum += depths1.xy + depths1.zw + depths2.xy + depths2.zw;
-}
-#endif
-
-void main()
-{
- vec3 cos;
-
- cos.xy = gl_FragCoord.xy * storedTexelSize;
-
-#ifdef CSM
- cos.z = float(cascadeID);
-#else /* CUBEMAP */
- /* add a 2 pixel border to ensure filtering is correct */
- cos.xy *= 1.0 + storedTexelSize * 2.0;
- cos.xy -= storedTexelSize;
-
- float pattern = 1.0;
-
- /* edge mirroring : only mirror if directly adjacent
- * (not diagonally adjacent) */
- vec2 m = abs(cos.xy - 0.5) + 0.5;
- vec2 f = floor(m);
- if (f.x - f.y != 0.0) {
- cos.xy = 1.0 - cos.xy;
- }
-
- /* clamp to [0-1] */
- cos.xy = fract(cos.xy);
-
- /* get cubemap vector */
- cos = normalize(octahedral_to_cubemap_proj(cos.xy));
- make_orthonormal_basis(cos);
-
- T *= filterSize[cascadeID];
- B *= filterSize[cascadeID];
-#endif
-
-#ifdef ESM
- /* disc blur in log space. */
- vec4 depths;
- depths.x = texture(shadowTexture, get_texco(cos, concentric[0])).r;
- depths.y = texture(shadowTexture, get_texco(cos, concentric[1])).r;
- depths.z = texture(shadowTexture, get_texco(cos, concentric[2])).r;
- depths.w = texture(shadowTexture, get_texco(cos, concentric[3])).r;
- float ref = depths.x;
- vec4 accum = ln_space_prefilter_step(ref, depths);
-
-#else /* VSM */
- float ref = 0.0; /* UNUSED */
- vec2 accum = vec2(0.0);
- grouped_samples_accum(
- cos, concentric[0], concentric[1], concentric[2], concentric[3], ref, accum);
-#endif
-
- /**
- * Making the `grouped_samples_accum` be called within a loop would be
- * the most conventional solution, however in some older gpus, transverse the huge
- * `const vec2 concentric[]` array with variable indices is extremely slow.
- * The solution is to use constant indices to access the array.
- */
- if (shadowSampleCount[cascadeID] > 4) {
- grouped_samples_accum(
- cos, concentric[4], concentric[5], concentric[6], concentric[7], ref, accum);
- grouped_samples_accum(
- cos, concentric[8], concentric[9], concentric[10], concentric[11], ref, accum);
- grouped_samples_accum(
- cos, concentric[12], concentric[13], concentric[14], concentric[15], ref, accum);
- }
- if (shadowSampleCount[cascadeID] > 16) {
- grouped_samples_accum(
- cos, concentric[16], concentric[17], concentric[18], concentric[19], ref, accum);
- grouped_samples_accum(
- cos, concentric[20], concentric[21], concentric[22], concentric[23], ref, accum);
- grouped_samples_accum(
- cos, concentric[24], concentric[25], concentric[26], concentric[27], ref, accum);
- grouped_samples_accum(
- cos, concentric[28], concentric[29], concentric[30], concentric[31], ref, accum);
- grouped_samples_accum(
- cos, concentric[32], concentric[33], concentric[34], concentric[35], ref, accum);
- }
-#ifdef HIGH_BLUR
- if (shadowSampleCount[cascadeID] > 36) {
- grouped_samples_accum(
- cos, concentric[36], concentric[37], concentric[38], concentric[39], ref, accum);
- grouped_samples_accum(
- cos, concentric[40], concentric[41], concentric[42], concentric[43], ref, accum);
- grouped_samples_accum(
- cos, concentric[44], concentric[45], concentric[46], concentric[47], ref, accum);
- grouped_samples_accum(
- cos, concentric[48], concentric[49], concentric[50], concentric[51], ref, accum);
- grouped_samples_accum(
- cos, concentric[52], concentric[53], concentric[54], concentric[55], ref, accum);
- grouped_samples_accum(
- cos, concentric[56], concentric[57], concentric[58], concentric[59], ref, accum);
- grouped_samples_accum(
- cos, concentric[60], concentric[61], concentric[62], concentric[63], ref, accum);
- }
- if (shadowSampleCount[cascadeID] > 64) {
- grouped_samples_accum(
- cos, concentric[64], concentric[65], concentric[66], concentric[67], ref, accum);
- grouped_samples_accum(
- cos, concentric[68], concentric[69], concentric[70], concentric[71], ref, accum);
- grouped_samples_accum(
- cos, concentric[72], concentric[73], concentric[74], concentric[75], ref, accum);
- grouped_samples_accum(
- cos, concentric[76], concentric[77], concentric[78], concentric[79], ref, accum);
- grouped_samples_accum(
- cos, concentric[80], concentric[81], concentric[82], concentric[83], ref, accum);
- grouped_samples_accum(
- cos, concentric[84], concentric[85], concentric[86], concentric[87], ref, accum);
- grouped_samples_accum(
- cos, concentric[88], concentric[89], concentric[90], concentric[91], ref, accum);
- grouped_samples_accum(
- cos, concentric[92], concentric[93], concentric[94], concentric[95], ref, accum);
- grouped_samples_accum(
- cos, concentric[96], concentric[97], concentric[98], concentric[99], ref, accum);
- }
- if (shadowSampleCount[cascadeID] > 100) {
- grouped_samples_accum(
- cos, concentric[100], concentric[101], concentric[102], concentric[103], ref, accum);
- grouped_samples_accum(
- cos, concentric[104], concentric[105], concentric[106], concentric[107], ref, accum);
- grouped_samples_accum(
- cos, concentric[108], concentric[109], concentric[110], concentric[111], ref, accum);
- grouped_samples_accum(
- cos, concentric[112], concentric[113], concentric[114], concentric[115], ref, accum);
- grouped_samples_accum(
- cos, concentric[116], concentric[117], concentric[118], concentric[119], ref, accum);
- grouped_samples_accum(
- cos, concentric[120], concentric[121], concentric[122], concentric[123], ref, accum);
- grouped_samples_accum(
- cos, concentric[124], concentric[125], concentric[126], concentric[127], ref, accum);
- grouped_samples_accum(
- cos, concentric[128], concentric[129], concentric[130], concentric[131], ref, accum);
- grouped_samples_accum(
- cos, concentric[132], concentric[133], concentric[134], concentric[135], ref, accum);
- grouped_samples_accum(
- cos, concentric[136], concentric[137], concentric[138], concentric[139], ref, accum);
- grouped_samples_accum(
- cos, concentric[140], concentric[141], concentric[142], concentric[143], ref, accum);
- }
- if (shadowSampleCount[cascadeID] > 144) {
- grouped_samples_accum(
- cos, concentric[144], concentric[145], concentric[146], concentric[147], ref, accum);
- grouped_samples_accum(
- cos, concentric[148], concentric[149], concentric[150], concentric[151], ref, accum);
- grouped_samples_accum(
- cos, concentric[152], concentric[153], concentric[154], concentric[155], ref, accum);
- grouped_samples_accum(
- cos, concentric[156], concentric[157], concentric[158], concentric[159], ref, accum);
- grouped_samples_accum(
- cos, concentric[160], concentric[161], concentric[162], concentric[163], ref, accum);
- grouped_samples_accum(
- cos, concentric[164], concentric[165], concentric[166], concentric[167], ref, accum);
- grouped_samples_accum(
- cos, concentric[168], concentric[169], concentric[170], concentric[171], ref, accum);
- grouped_samples_accum(
- cos, concentric[172], concentric[173], concentric[174], concentric[175], ref, accum);
- grouped_samples_accum(
- cos, concentric[176], concentric[177], concentric[178], concentric[179], ref, accum);
- grouped_samples_accum(
- cos, concentric[180], concentric[181], concentric[182], concentric[183], ref, accum);
- grouped_samples_accum(
- cos, concentric[184], concentric[185], concentric[186], concentric[187], ref, accum);
- grouped_samples_accum(
- cos, concentric[188], concentric[189], concentric[190], concentric[191], ref, accum);
- grouped_samples_accum(
- cos, concentric[192], concentric[193], concentric[194], concentric[195], ref, accum);
- }
- if (shadowSampleCount[cascadeID] > 196) {
- grouped_samples_accum(
- cos, concentric[196], concentric[197], concentric[198], concentric[199], ref, accum);
- grouped_samples_accum(
- cos, concentric[200], concentric[201], concentric[202], concentric[203], ref, accum);
- grouped_samples_accum(
- cos, concentric[204], concentric[205], concentric[206], concentric[207], ref, accum);
- grouped_samples_accum(
- cos, concentric[208], concentric[209], concentric[210], concentric[211], ref, accum);
- grouped_samples_accum(
- cos, concentric[212], concentric[213], concentric[114], concentric[215], ref, accum);
- grouped_samples_accum(
- cos, concentric[216], concentric[217], concentric[218], concentric[219], ref, accum);
- grouped_samples_accum(
- cos, concentric[220], concentric[221], concentric[222], concentric[223], ref, accum);
- grouped_samples_accum(
- cos, concentric[224], concentric[225], concentric[226], concentric[227], ref, accum);
- grouped_samples_accum(
- cos, concentric[228], concentric[229], concentric[230], concentric[231], ref, accum);
- grouped_samples_accum(
- cos, concentric[232], concentric[233], concentric[234], concentric[235], ref, accum);
- grouped_samples_accum(
- cos, concentric[236], concentric[237], concentric[238], concentric[239], ref, accum);
- grouped_samples_accum(
- cos, concentric[240], concentric[241], concentric[242], concentric[243], ref, accum);
- grouped_samples_accum(
- cos, concentric[244], concentric[245], concentric[246], concentric[247], ref, accum);
- grouped_samples_accum(
- cos, concentric[248], concentric[249], concentric[250], concentric[251], ref, accum);
- grouped_samples_accum(
- cos, concentric[252], concentric[253], concentric[254], concentric[255], ref, accum);
- }
-#endif
-
-#ifdef ESM
- accum.x = dot(vec4(1.0), accum);
- accum.x = ln_space_prefilter_finalize(ref, accum.x);
- FragColor = accum.xxxx;
-
-#else /* VSM */
- FragColor = accum.xyxy * shadowInvSampleCount[cascadeID];
-#endif
-}