#type vertex #version 430 layout(location = 0) in vec3 a_Position; layout(location = 1) in vec2 a_TexCoord; out vec2 v_TexCoord; void main() { vec4 position = vec4(a_Position.xy, 0.0, 1.0); v_TexCoord = a_TexCoord; gl_Position = position; } #type fragment #version 430 layout(location = 0) out vec4 o_Color; in vec2 v_TexCoord; uniform sampler2D u_SSRTexture; uniform sampler2D u_DepthTexture; uniform sampler2D u_MaterialInfoTexture; uniform vec2 u_ScreenSize; uniform float u_BlurRadius = 4.0; void main() { vec2 texelSize = 1.0 / u_ScreenSize; vec4 center = texture(u_SSRTexture, v_TexCoord); if (center.a <= 0.001) { o_Color = vec4(0.0); return; } float roughness = texture(u_MaterialInfoTexture, v_TexCoord).g; float effectiveBlurRadius = max(u_BlurRadius * roughness * roughness, 1.0); float centerDepth = texture(u_DepthTexture, v_TexCoord).r; vec3 result = vec3(0.0); float totalWeight = 0.0; const int kRadius = 6; float sigma = effectiveBlurRadius * 0.5; for (int x = -kRadius; x <= kRadius; x++) { for (int y = -kRadius; y <= kRadius; y++) { vec2 offset = vec2(float(x), float(y)) * texelSize * effectiveBlurRadius / float(kRadius); vec2 sampleUV = v_TexCoord + offset; if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || sampleUV.y < 0.0 || sampleUV.y > 1.0) continue; float sampleDepth = texture(u_DepthTexture, sampleUV).r; float depthDiff = abs(centerDepth - sampleDepth); float depthWeight = exp(-depthDiff * 200.0); float spatialWeight = exp(-(float(x * x + y * y)) / (2.0 * sigma * sigma)); vec4 sampleColor = texture(u_SSRTexture, sampleUV); float alphaWeight = sampleColor.a > 0.01 ? 1.0 : 0.0; float weight = spatialWeight * depthWeight * alphaWeight; result += sampleColor.rgb * weight; totalWeight += weight; } } if (totalWeight > 0.0) result /= totalWeight; else result = center.rgb; o_Color = vec4(result, center.a); }