diff options
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders')
14 files changed, 279 insertions, 135 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 68299fe7546..77c873c1503 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -8,12 +8,7 @@ #define LUT_SIZE 64 -uniform mat4 ProjectionMatrix; -uniform mat4 ViewProjectionMatrix; -uniform mat4 ViewMatrixInverse; -#ifndef SHADOW_SHADER -uniform mat4 ViewMatrix; -#else +#ifdef SHADOW_SHADER layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; mat4 FaceViewMatrix[6]; @@ -27,7 +22,21 @@ layout(std140) uniform shadow_render_block { }; flat in int shFace; /* Shadow layer we are rendering to. */ -#define ViewMatrix FaceViewMatrix[shFace] + +/* Replacing viewBlock */ +#define ViewMatrix FaceViewMatrix[shFace] +#define ViewProjectionMatrix ShadowMatrix[shFace] +/* TODO optimize */ +#define ProjectionMatrix \ +mat4(vec4(1.0, 0.0, 0.0, 0.0), \ + vec4(0.0, 1.0, 0.0, 0.0), \ + vec4(0.0, 0.0, -(farClip + nearClip) / (farClip - nearClip), -1.0), \ + vec4(0.0, 0.0, (-2.0 * farClip * nearClip) / (farClip - nearClip), 0.0)) + +#define ViewMatrixInverse inverse(ViewMatrix) +#define ViewProjectionMatrixInverse inverse(ViewProjectionMatrix) +#define ProjectionMatrixInverse inverse(ProjectionMatrix) +#define CameraTexCoFactors vec4(1.0f, 1.0f, 0.0f, 0.0f) #endif /* Buffers */ @@ -325,7 +334,7 @@ vec2 get_uvs_from_view(vec3 view) vec3 get_view_space_from_depth(vec2 uvcoords, float depth) { if (ProjectionMatrix[3][3] == 0.0) { - return (viewVecs[0].xyz + vec3(uvcoords, 0.0) * viewVecs[1].xyz) * get_view_z_from_depth(depth); + return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth); } else { return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz; @@ -418,19 +427,19 @@ float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float * Using Method #4: Spheremap Transform */ vec2 normal_encode(vec3 n, vec3 view) { - float p = sqrt(n.z * 8.0 + 8.0); - return n.xy / p + 0.5; + float p = sqrt(n.z * 8.0 + 8.0); + return n.xy / p + 0.5; } vec3 normal_decode(vec2 enc, vec3 view) { - vec2 fenc = enc * 4.0 - 2.0; - float f = dot(fenc, fenc); - float g = sqrt(1.0 - f / 4.0); - vec3 n; - n.xy = fenc*g; - n.z = 1 - f / 2; - return n; + vec2 fenc = enc * 4.0 - 2.0; + float f = dot(fenc, fenc); + float g = sqrt(1.0 - f / 4.0); + vec3 n; + n.xy = fenc*g; + n.z = 1 - f / 2; + return n; } /* ---- RGBM (shared multiplier) encoding ---- */ @@ -654,12 +663,12 @@ Closure closure_add(Closure cl1, Closure cl2) struct Closure { vec3 radiance; float opacity; -#ifdef USE_SSS +# ifdef USE_SSS vec4 sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO vec3 sss_albedo; -#endif -#endif +# endif +# endif vec4 ssr_data; vec2 ssr_normal; int ssr_id; @@ -669,15 +678,15 @@ struct Closure { #define TRANSPARENT_CLOSURE_FLAG -2 #define REFRACT_CLOSURE_FLAG -3 -#ifdef USE_SSS -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS +# ifdef USE_SSS_ALBEDO #define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1) -#else +# else #define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1) -#endif -#else +# endif +# else #define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1) -#endif +# endif uniform int outputSsrId; @@ -685,45 +694,51 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac) { Closure cl; - if (cl1.ssr_id == outputSsrId) { - cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); /* do not blend roughness */ - cl.ssr_normal = cl1.ssr_normal; - cl.ssr_id = cl1.ssr_id; - } - else { - cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */ - cl.ssr_normal = cl2.ssr_normal; - cl.ssr_id = cl2.ssr_id; - } if (cl1.ssr_id == TRANSPARENT_CLOSURE_FLAG) { cl1.radiance = cl2.radiance; -#ifdef USE_SSS + cl1.ssr_normal = cl2.ssr_normal; + cl1.ssr_data = cl2.ssr_data; + cl1.ssr_id = cl2.ssr_id; +# ifdef USE_SSS cl1.sss_data = cl2.sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO cl1.sss_albedo = cl2.sss_albedo; -#endif -#endif +# endif +# endif } if (cl2.ssr_id == TRANSPARENT_CLOSURE_FLAG) { cl2.radiance = cl1.radiance; -#ifdef USE_SSS + cl2.ssr_normal = cl1.ssr_normal; + cl2.ssr_data = cl1.ssr_data; + cl2.ssr_id = cl1.ssr_id; +# ifdef USE_SSS cl2.sss_data = cl1.sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO cl2.sss_albedo = cl1.sss_albedo; -#endif -#endif +# endif +# endif + } + if (cl1.ssr_id == outputSsrId) { + cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); /* do not blend roughness */ + cl.ssr_normal = cl1.ssr_normal; + cl.ssr_id = cl1.ssr_id; + } + else { + cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */ + cl.ssr_normal = cl2.ssr_normal; + cl.ssr_id = cl2.ssr_id; } cl.radiance = mix(cl1.radiance, cl2.radiance, fac); cl.opacity = mix(cl1.opacity, cl2.opacity, fac); -#ifdef USE_SSS +# ifdef USE_SSS cl.sss_data.rgb = mix(cl1.sss_data.rgb, cl2.sss_data.rgb, fac); cl.sss_data.a = (cl1.sss_data.a > 0.0) ? cl1.sss_data.a : cl2.sss_data.a; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO /* TODO Find a solution to this. Dither? */ cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo; -#endif -#endif +# endif +# endif return cl; } @@ -731,80 +746,73 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac) Closure closure_add(Closure cl1, Closure cl2) { Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2; -#ifdef USE_SSS +# ifdef USE_SSS cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO /* TODO Find a solution to this. Dither? */ cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo; -#endif -#endif +# endif +# endif cl.radiance = cl1.radiance + cl2.radiance; cl.opacity = saturate(cl1.opacity + cl2.opacity); return cl; } -#if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY) +# if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY) layout(location = 0) out vec4 fragColor; -#ifdef USE_SSS -#ifdef USE_SSS_ALBEDO -layout(location = 1) out vec4 sssData; -layout(location = 2) out vec4 sssAlbedo; -layout(location = 3) out vec4 ssrNormals; -layout(location = 4) out vec4 ssrData; -#else -layout(location = 1) out vec4 sssData; -layout(location = 2) out vec4 ssrNormals; -layout(location = 3) out vec4 ssrData; -#endif /* USE_SSS_ALBEDO */ -#else layout(location = 1) out vec4 ssrNormals; layout(location = 2) out vec4 ssrData; -#endif /* USE_SSS */ +# ifdef USE_SSS +layout(location = 3) out vec4 sssData; +# ifdef USE_SSS_ALBEDO +layout(location = 4) out vec4 sssAlbedo; +# endif /* USE_SSS_ALBEDO */ +# endif /* USE_SSS */ Closure nodetree_exec(void); /* Prototype */ -#if defined(USE_ALPHA_BLEND_VOLUMETRICS) +# if defined(USE_ALPHA_BLEND_VOLUMETRICS) /* Prototype because this file is included before volumetric_lib.glsl */ vec4 volumetric_resolve(vec4 scene_color, vec2 frag_uvs, float frag_depth); -#endif +# endif #define NODETREE_EXEC void main() { Closure cl = nodetree_exec(); -#ifndef USE_ALPHA_BLEND +# ifndef USE_ALPHA_BLEND /* Prevent alpha hash material writing into alpha channel. */ cl.opacity = 1.0; -#endif +# endif -#if defined(USE_ALPHA_BLEND_VOLUMETRICS) +# if defined(USE_ALPHA_BLEND_VOLUMETRICS) /* XXX fragile, better use real viewport resolution */ vec2 uvs = gl_FragCoord.xy / vec2(2 * textureSize(maxzBuffer, 0).xy); fragColor = volumetric_resolve(vec4(cl.radiance, cl.opacity), uvs, gl_FragCoord.z); -#else +# else fragColor = vec4(cl.radiance, cl.opacity); -#endif +# endif ssrNormals = cl.ssr_normal.xyyy; ssrData = cl.ssr_data; -#ifdef USE_SSS +# ifdef USE_SSS sssData = cl.sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO sssAlbedo = cl.sss_albedo.rgbb; -#endif -#endif +# endif +# endif /* For Probe capture */ -#ifdef USE_SSS -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS +# ifdef USE_SSS_ALBEDO fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * float(!sssToggle); -#else +# else fragColor.rgb += cl.sss_data.rgb * float(!sssToggle); -#endif -#endif +# endif +# endif } -#endif /* MESH_SHADER && !SHADOW_SHADER */ +# endif /* MESH_SHADER && !SHADOW_SHADER */ #endif /* VOLUMETRICS */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl index 32edf709d88..b7bcf5c8a8b 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl @@ -28,7 +28,8 @@ void main() gtao_deferred(normal, viewPosition, noise, depth, visibility, bent_normal); - FragColor = vec4(visibility); + /* Handle Background case. Prevent artifact due to uncleared Horizon Render Target. */ + FragColor = vec4((depth == 1.0) ? 0.0 : visibility); } #else diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl index 65d3970a82a..05fef73b159 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl @@ -23,7 +23,9 @@ uniform sampler2D depthBuffer; #define minmax(a, b) max(a, b) #endif -#ifdef GPU_INTEL +/* On some AMD card / driver conbination, it is needed otherwise, + * the shader does not write anything. */ +#if defined(GPU_INTEL) || defined(GPU_ATI) out vec4 fragColor; #endif @@ -65,10 +67,9 @@ void main() } #endif -#ifdef GPU_INTEL +#if defined(GPU_INTEL) || defined(GPU_ATI) /* Use color format instead of 24bit depth texture */ fragColor = vec4(val); -#else - gl_FragDepth = val; #endif + gl_FragDepth = val; }
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl new file mode 100644 index 00000000000..fe38b2e9aac --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl @@ -0,0 +1,31 @@ +/* Convert depth to Mist factor */ +uniform vec3 mistSettings; + +#define mistStart mistSettings.x +#define mistInvDistance mistSettings.y +#define mistFalloff mistSettings.z + +out vec4 fragColor; + +void main() +{ + vec2 texel_size = 1.0 / vec2(textureSize(depthBuffer, 0)).xy; + vec2 uvs = gl_FragCoord.xy * texel_size; + + float depth = textureLod(depthBuffer, uvs, 0.0).r; + vec3 co = get_view_space_from_depth(uvs, depth); + + float zcor = (ProjectionMatrix[3][3] == 0.0) ? length(co) : -co.z; + + /* bring depth into 0..1 range */ + float mist = saturate((zcor - mistStart) * mistInvDistance); + + /* falloff */ + mist = pow(mist, mistFalloff); + + fragColor = vec4(mist); + + // if (mist > 0.999) fragColor = vec4(1.0); + // else if (mist > 0.0001) fragColor = vec4(0.5); + // else fragColor = vec4(0.0); +} 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 184eac54c26..5ecf6323255 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl @@ -18,9 +18,10 @@ uniform sampler2DArray utilTex; #define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) #endif /* UTIL_TEX */ -out vec4 FragColor; - -uniform mat4 ProjectionMatrix; +layout(location = 0) out vec4 FragColor; +#ifdef RESULT_ACCUM +layout(location = 1) out vec4 sssColor; +#endif float get_view_z_from_depth(float depth) { @@ -84,10 +85,15 @@ void main(void) #ifdef FIRST_PASS FragColor = vec4(accum, sss_data.a); #else /* SECOND_PASS */ - #ifdef USE_SEP_ALBEDO +# 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); - #else +# endif +# else FragColor = vec4(accum, 1.0); - #endif +# endif #endif } diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl index 202b27be0ef..57da4d0d1ec 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl @@ -6,8 +6,6 @@ in int probe_id; in vec3 probe_location; in float sphere_size; -uniform mat4 ViewProjectionMatrix; - flat out int pid; out vec3 worldNormal; out vec3 worldPosition; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl index fd200ec5984..37f73714a8e 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl @@ -1,8 +1,6 @@ in vec3 pos; -uniform mat4 ViewProjectionMatrix; - uniform float sphere_size; uniform int offset; uniform ivec3 grid_resolution; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl index 655cc626bba..3808b59761f 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl @@ -1,5 +1,4 @@ -uniform mat4 ViewProjectionMatrix; uniform sampler2DArray probePlanars; in vec3 worldPosition; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl index a9716332eb5..3ecd85fd72e 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl @@ -4,8 +4,6 @@ in vec3 pos; in int probe_id; in mat4 probe_mat; -uniform mat4 ViewProjectionMatrix; - out vec3 worldPosition; flat out int probeIdx; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl index 40b04c986f3..23c16f0fa30 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl @@ -11,13 +11,13 @@ void main() { gl_Layer = instance[0]; layer = float(instance[0]); - gl_Position = vec4(vPos[0], 0.0, 0.0); + gl_Position = vec4(vPos[0], 0.0, 1.0); EmitVertex(); - gl_Position = vec4(vPos[1], 0.0, 0.0); + gl_Position = vec4(vPos[1], 0.0, 1.0); EmitVertex(); - gl_Position = vec4(vPos[2], 0.0, 0.0); + gl_Position = vec4(vPos[2], 0.0, 1.0); EmitVertex(); EndPrimitive(); diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl index fd7f3870d27..d53852193d5 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl @@ -19,7 +19,10 @@ out vec3 worldPosition; out vec3 viewPosition; /* Used for planar reflections */ -uniform vec4 ClipPlanes[1]; +/* keep in sync with EEVEE_ClipPlanesUniformBuffer */ +layout(std140) uniform clip_block { + vec4 ClipPlanes[1]; +}; #ifdef USE_FLAT_NORMAL flat out vec3 worldNormal; diff --git a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl index 1b53e503003..974c5724842 100644 --- a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl @@ -2,9 +2,11 @@ uniform mat4 ModelViewProjectionMatrix; uniform mat4 ModelMatrix; uniform mat4 ModelViewMatrix; -#ifdef CLIP_PLANES -uniform vec4 ClipPlanes[1]; -#endif + +/* keep in sync with DRWManager.view_data */ +layout(std140) uniform clip_block { + vec4 ClipPlanes[1]; +}; #ifndef HAIR_SHADER_FIBERS in vec3 pos; @@ -28,7 +30,7 @@ void main() #ifdef CLIP_PLANES vec4 worldPosition = (ModelMatrix * vec4(pos, 1.0)); - gl_ClipDistance[0] = dot(worldPosition, ClipPlanes[0]); + gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), ClipPlanes[0]); #endif /* TODO motion vectors */ } diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl index fcc304ca289..0fc7e4c9396 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl @@ -47,7 +47,7 @@ vec4 ln_space_prefilter(float w0, vec4 x, float w1, vec4 y) } #ifdef CSM -vec3 get_texco(vec3 cos, vec2 ofs) +vec3 get_texco(vec3 cos, const vec2 ofs) { cos.xy += ofs * shadowFilterSize; return cos; @@ -64,13 +64,43 @@ void make_orthonormal_basis(vec3 N) B = cross(N, T); } -vec3 get_texco(vec3 cos, vec2 ofs) +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, + 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(1.0, accum, shadowInvSampleCount, depths); +} +#else /* VSM */ +void grouped_samples_accum( + vec3 cos, + const vec2 co1, const vec2 co2, const vec2 co3, const vec2 co4, + 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; @@ -105,9 +135,8 @@ void main() { #endif #ifdef ESM - vec4 accum = vec4(0.0); - /* disc blur in log space. */ + vec4 accum = vec4(0.0); vec4 depths; depths.x = texture(shadowTexture, get_texco(cos, concentric[0])).r; depths.y = texture(shadowTexture, get_texco(cos, concentric[1])).r; @@ -115,32 +144,102 @@ void main() { depths.w = texture(shadowTexture, get_texco(cos, concentric[3])).r; accum = ln_space_prefilter(0.0, accum, shadowInvSampleCount, depths); - for (int i = 4; i < shadowSampleCount && i < CONCENTRIC_SAMPLE_NUM; i += 4) { - depths.x = texture(shadowTexture, get_texco(cos, concentric[i+0])).r; - depths.y = texture(shadowTexture, get_texco(cos, concentric[i+1])).r; - depths.z = texture(shadowTexture, get_texco(cos, concentric[i+2])).r; - depths.w = texture(shadowTexture, get_texco(cos, concentric[i+3])).r; - accum = ln_space_prefilter(1.0, accum, shadowInvSampleCount, depths); +#else /* VSM */ + vec2 accum = vec2(0.0); + grouped_samples_accum(cos, concentric[0], concentric[1], concentric[2], concentric[3], 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 > 4) { + grouped_samples_accum(cos, concentric[4], concentric[5], concentric[6], concentric[7], accum); + grouped_samples_accum(cos, concentric[8], concentric[9], concentric[10], concentric[11], accum); + grouped_samples_accum(cos, concentric[12], concentric[13], concentric[14], concentric[15], accum); + } + if (shadowSampleCount > 16) { + grouped_samples_accum(cos, concentric[16], concentric[17], concentric[18], concentric[19], accum); + grouped_samples_accum(cos, concentric[20], concentric[21], concentric[22], concentric[23], accum); + grouped_samples_accum(cos, concentric[24], concentric[25], concentric[26], concentric[27], accum); + grouped_samples_accum(cos, concentric[28], concentric[29], concentric[30], concentric[31], accum); + grouped_samples_accum(cos, concentric[32], concentric[33], concentric[34], concentric[35], accum); + } + if (shadowSampleCount > 36) { + grouped_samples_accum(cos, concentric[36], concentric[37], concentric[38], concentric[39], accum); + grouped_samples_accum(cos, concentric[40], concentric[41], concentric[42], concentric[43], accum); + grouped_samples_accum(cos, concentric[44], concentric[45], concentric[46], concentric[47], accum); + grouped_samples_accum(cos, concentric[48], concentric[49], concentric[50], concentric[51], accum); + grouped_samples_accum(cos, concentric[52], concentric[53], concentric[54], concentric[55], accum); + grouped_samples_accum(cos, concentric[56], concentric[57], concentric[58], concentric[59], accum); + grouped_samples_accum(cos, concentric[60], concentric[61], concentric[62], concentric[63], accum); + } + if (shadowSampleCount > 64) { + grouped_samples_accum(cos, concentric[64], concentric[65], concentric[66], concentric[67], accum); + grouped_samples_accum(cos, concentric[68], concentric[69], concentric[70], concentric[71], accum); + grouped_samples_accum(cos, concentric[72], concentric[73], concentric[74], concentric[75], accum); + grouped_samples_accum(cos, concentric[76], concentric[77], concentric[78], concentric[79], accum); + grouped_samples_accum(cos, concentric[80], concentric[81], concentric[82], concentric[83], accum); + grouped_samples_accum(cos, concentric[84], concentric[85], concentric[86], concentric[87], accum); + grouped_samples_accum(cos, concentric[88], concentric[89], concentric[90], concentric[91], accum); + grouped_samples_accum(cos, concentric[92], concentric[93], concentric[94], concentric[95], accum); + grouped_samples_accum(cos, concentric[96], concentric[97], concentric[98], concentric[99], accum); + } + if (shadowSampleCount > 100) { + grouped_samples_accum(cos, concentric[100], concentric[101], concentric[102], concentric[103], accum); + grouped_samples_accum(cos, concentric[104], concentric[105], concentric[106], concentric[107], accum); + grouped_samples_accum(cos, concentric[108], concentric[109], concentric[110], concentric[111], accum); + grouped_samples_accum(cos, concentric[112], concentric[113], concentric[114], concentric[115], accum); + grouped_samples_accum(cos, concentric[116], concentric[117], concentric[118], concentric[119], accum); + grouped_samples_accum(cos, concentric[120], concentric[121], concentric[122], concentric[123], accum); + grouped_samples_accum(cos, concentric[124], concentric[125], concentric[126], concentric[127], accum); + grouped_samples_accum(cos, concentric[128], concentric[129], concentric[130], concentric[131], accum); + grouped_samples_accum(cos, concentric[132], concentric[133], concentric[134], concentric[135], accum); + grouped_samples_accum(cos, concentric[136], concentric[137], concentric[138], concentric[139], accum); + grouped_samples_accum(cos, concentric[140], concentric[141], concentric[142], concentric[143], accum); + } + if (shadowSampleCount > 144) { + grouped_samples_accum(cos, concentric[144], concentric[145], concentric[146], concentric[147], accum); + grouped_samples_accum(cos, concentric[148], concentric[149], concentric[150], concentric[151], accum); + grouped_samples_accum(cos, concentric[152], concentric[153], concentric[154], concentric[155], accum); + grouped_samples_accum(cos, concentric[156], concentric[157], concentric[158], concentric[159], accum); + grouped_samples_accum(cos, concentric[160], concentric[161], concentric[162], concentric[163], accum); + grouped_samples_accum(cos, concentric[164], concentric[165], concentric[166], concentric[167], accum); + grouped_samples_accum(cos, concentric[168], concentric[169], concentric[170], concentric[171], accum); + grouped_samples_accum(cos, concentric[172], concentric[173], concentric[174], concentric[175], accum); + grouped_samples_accum(cos, concentric[176], concentric[177], concentric[178], concentric[179], accum); + grouped_samples_accum(cos, concentric[180], concentric[181], concentric[182], concentric[183], accum); + grouped_samples_accum(cos, concentric[184], concentric[185], concentric[186], concentric[187], accum); + grouped_samples_accum(cos, concentric[188], concentric[189], concentric[190], concentric[191], accum); + grouped_samples_accum(cos, concentric[192], concentric[193], concentric[194], concentric[195], accum); + } + if (shadowSampleCount > 196) { + grouped_samples_accum(cos, concentric[196], concentric[197], concentric[198], concentric[199], accum); + grouped_samples_accum(cos, concentric[200], concentric[201], concentric[202], concentric[203], accum); + grouped_samples_accum(cos, concentric[204], concentric[205], concentric[206], concentric[207], accum); + grouped_samples_accum(cos, concentric[208], concentric[209], concentric[210], concentric[211], accum); + grouped_samples_accum(cos, concentric[212], concentric[213], concentric[114], concentric[215], accum); + grouped_samples_accum(cos, concentric[216], concentric[217], concentric[218], concentric[219], accum); + grouped_samples_accum(cos, concentric[220], concentric[221], concentric[222], concentric[223], accum); + grouped_samples_accum(cos, concentric[224], concentric[225], concentric[226], concentric[227], accum); + grouped_samples_accum(cos, concentric[228], concentric[229], concentric[230], concentric[231], accum); + grouped_samples_accum(cos, concentric[232], concentric[233], concentric[234], concentric[235], accum); + grouped_samples_accum(cos, concentric[236], concentric[237], concentric[238], concentric[239], accum); + grouped_samples_accum(cos, concentric[240], concentric[241], concentric[242], concentric[243], accum); + grouped_samples_accum(cos, concentric[244], concentric[245], concentric[246], concentric[247], accum); + grouped_samples_accum(cos, concentric[248], concentric[249], concentric[250], concentric[251], accum); + grouped_samples_accum(cos, concentric[252], concentric[253], concentric[254], concentric[255], accum); } +#ifdef ESM accum.x = ln_space_prefilter(1.0, accum.x, 1.0, accum.y); accum.x = ln_space_prefilter(1.0, accum.x, 1.0, accum.z); accum.x = ln_space_prefilter(1.0, accum.x, 1.0, accum.w); FragColor = accum.xxxx; #else /* VSM */ - vec2 accum = vec2(0.0); - - /* disc blur. */ - vec4 depths1, depths2; - for (int i = 0; i < shadowSampleCount && i < CONCENTRIC_SAMPLE_NUM; i += 4) { - depths1.xy = texture(shadowTexture, get_texco(cos, concentric[i+0])).rg; - depths1.zw = texture(shadowTexture, get_texco(cos, concentric[i+1])).rg; - depths2.xy = texture(shadowTexture, get_texco(cos, concentric[i+2])).rg; - depths2.zw = texture(shadowTexture, get_texco(cos, concentric[i+3])).rg; - accum += depths1.xy + depths1.zw + depths2.xy + depths2.zw; - } - FragColor = accum.xyxy * shadowInvSampleCount; #endif -}
\ No newline at end of file +} diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl index 777902ccba8..29cbcfdd6e4 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl @@ -1,5 +1,5 @@ -uniform mat4 ShadowModelMatrix; +uniform mat4 ModelMatrix; #ifdef MESH_SHADER uniform mat3 WorldNormalMatrix; #endif @@ -17,7 +17,7 @@ out vec3 vNor; flat out int face; void main() { - vPos = ShadowModelMatrix * vec4(pos, 1.0); + vPos = ModelMatrix * vec4(pos, 1.0); face = gl_InstanceID; #ifdef MESH_SHADER |