Files
Prism/Editor/assets/shaders/SSRBlur.glsl

86 lines
2.1 KiB
GLSL

#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);
}