diff options
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl')
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl new file mode 100644 index 00000000000..0727e73f507 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl @@ -0,0 +1,88 @@ + +uniform samplerCube probeDepth; +uniform int outputSize; +uniform float lodFactor; +uniform float storedTexelSize; +uniform float lodMax; +uniform float nearClip; +uniform float farClip; +uniform float visibilityRange; +uniform float visibilityBlur; + +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; +} + +float linear_depth(float z) +{ + return (nearClip * farClip) / (z * (nearClip - farClip) + farClip); +} + +float get_world_distance(float depth, vec3 cos) +{ + float is_background = step(1.0, depth); + depth = linear_depth(depth); + depth += 1e1 * is_background; + cos = normalize(abs(cos)); + float cos_vec = max(cos.x, max(cos.y, cos.z)); + return depth / cos_vec; +} + +void main() +{ + ivec2 texel = ivec2(gl_FragCoord.xy) % ivec2(outputSize); + + vec3 cos; + + cos.xy = (vec2(texel) + 0.5) * storedTexelSize; + + /* 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)); + + vec3 T, B; + make_orthonormal_basis(cos, T, B); /* Generate tangent space */ + + vec2 accum = vec2(0.0); + + for (float i = 0; i < sampleCount; i++) { + vec3 sample = sample_cone(i, M_PI_2 * visibilityBlur, cos, T, B); + float depth = texture(probeDepth, sample).r; + depth = get_world_distance(depth, sample); + accum += vec2(depth, depth * depth); + } + + accum *= invSampleCount; + accum = abs(accum); + + /* Encode to normalized RGBA 8 */ + FragColor = visibility_encode(accum, visibilityRange); +}
\ No newline at end of file |