diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-06-22 03:28:49 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-06-22 04:51:06 +0300 |
commit | 2c7f6db8d1b2d2a0d59d5212899632ec838e86cc (patch) | |
tree | 488b310b063571f4fd1cc37f68cbb41918f3d955 /source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl | |
parent | ed59d03bfcac7e0b21c82febe6b6f2f786b62034 (diff) |
Eevee: Minmax Depth Pyramid.
This commit introduce the computation of a depth pyramid containing min and max depth values of the original depth buffer.
This is useful for Clustered Light Culling but also for raytracing on the depth buffer (SSR).
It's also usefull to have to fetch higher mips in order to improve texture cache usage.
As of now, 1st mip (highest res) is half the resolution of the depth buffer, but everything is already done to be able to make a fullres copy of the depth buffer in the 1st mip instead of downsampling.
Also, the texture used is RG_32F which is a too much but enough to cover the 24bits of the depth buffer. Reducing the texture size would make things quite faster.
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl')
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl new file mode 100644 index 00000000000..9f81206070b --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl @@ -0,0 +1,66 @@ +/** + * Shader that downsample depth buffer, + * saving min and max value of each texel in the above mipmaps. + * Adapted from http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/ + **/ + +uniform sampler2D depthBuffer; + +out vec4 FragMinMax; + +vec2 sampleLowerMip(ivec2 texel) +{ +#ifdef INPUT_DEPTH + return texelFetch(depthBuffer, texel, 0).rr; +#else + return texelFetch(depthBuffer, texel, 0).rg; +#endif +} + +void minmax(inout vec2 val[2]) +{ + val[0].x = min(val[0].x, val[1].x); + val[0].y = max(val[0].y, val[1].y); +} + +void main() +{ + vec2 val[2]; + ivec2 texelPos = ivec2(gl_FragCoord.xy); + ivec2 mipsize = textureSize(depthBuffer, 0); +#ifndef COPY_DEPTH + texelPos *= 2; +#endif + + val[0] = sampleLowerMip(texelPos); +#ifndef COPY_DEPTH + val[1] = sampleLowerMip(texelPos + ivec2(1, 0)); + minmax(val); + val[1] = sampleLowerMip(texelPos + ivec2(1, 1)); + minmax(val); + val[1] = sampleLowerMip(texelPos + ivec2(0, 1)); + minmax(val); + + /* if we are reducing an odd-width texture then fetch the edge texels */ + if (((mipsize.x & 1) != 0) && (int(gl_FragCoord.x) == mipsize.x-3)) { + /* if both edges are odd, fetch the top-left corner texel */ + if (((mipsize.y & 1) != 0) && (int(gl_FragCoord.y) == mipsize.y-3)) { + val[1] = sampleLowerMip(texelPos + ivec2(-1, -1)); + minmax(val); + } + val[1] = sampleLowerMip(texelPos + ivec2(0, -1)); + minmax(val); + val[1] = sampleLowerMip(texelPos + ivec2(1, -1)); + minmax(val); + } + /* if we are reducing an odd-height texture then fetch the edge texels */ + else if (((mipsize.y & 1) != 0) && (int(gl_FragCoord.y) == mipsize.y-3)) { + val[1] = sampleLowerMip(texelPos + ivec2(0, -1)); + minmax(val); + val[1] = sampleLowerMip(texelPos + ivec2(1, -1)); + minmax(val); + } +#endif + + FragMinMax = vec4(val[0], 0.0, 1.0); +}
\ No newline at end of file |