HDR, Bloom and SSR

This commit is contained in:
Halbear 2026-09-04 00:23:48 +01:00
parent 577836a03f
commit 04befce27d
44 changed files with 1377 additions and 269 deletions

View file

@ -0,0 +1,128 @@
#version 450
layout(location = 0) in vec2 fragTexCoord;
layout(location = 0) out vec4 outColor;
layout(set = 0, binding = 0) uniform sampler2D albedoSampler;
layout(set = 0, binding = 1) uniform sampler2D worldPosSampler;
layout(set = 0, binding = 2) uniform sampler2D normalSampler;
layout(set = 0, binding = 3) uniform sampler2D pbrSampler;
layout(set = 1, binding = 0) uniform CameraProperties {
mat4 projection;
mat4 invProjection;
mat4 view;
mat4 invView;
float ssrStepSize;
float ssrMaxDistance;
int maxSteps;
int padding;
vec4 cameraWorldPos;
} ubo;
const float THICKNESS = 0.35;
const float MIN_REFLECTION = 0.01;
float edgeFade(vec2 uv) {
vec2 fade = smoothstep(vec2(0.0), vec2(0.08), uv) *
smoothstep(vec2(0.0), vec2(0.08), vec2(1.0) - uv);
return fade.x * fade.y;
}
void main() {
vec4 sceneColor = texture(albedoSampler, fragTexCoord);
vec4 posSample = texture(worldPosSampler, fragTexCoord);
vec4 normalSample = texture(normalSampler, fragTexCoord);
vec4 pbrSample = texture(pbrSampler, fragTexCoord);
if (posSample.a == 0.0 || length(posSample.xyz) == 0.0 || length(normalSample.xyz) < 0.001) {
outColor = sceneColor;
return;
}
vec3 worldPos = posSample.xyz;
vec3 worldNormal = normalize(normalSample.xyz);
float roughness = clamp(pbrSample.g, 0.0, 1.0);
float metallic = clamp(pbrSample.b, 0.0, 1.0);
float reflectiveness = clamp(pbrSample.a, 0.0, 1.0);
float refractiveness = clamp(normalSample.a, 0.0, 2.0);
vec3 viewDirToCamera = normalize(ubo.cameraWorldPos.xyz - worldPos);
float NoV = clamp(dot(worldNormal, viewDirToCamera), 0.0, 1.0);
float fresnel = pow(1.0 - NoV, 5.0);
float materialReflection = reflectiveness + refractiveness - 1;
materialReflection *= mix(0.75, 1.0, metallic);
materialReflection *= smoothstep(0.7, 0.05, roughness);
materialReflection *= mix(0.45, 1.0, fresnel);
if (materialReflection <= MIN_REFLECTION) {
outColor = sceneColor;
return;
}
vec3 viewDir = normalize(worldPos - ubo.cameraWorldPos.xyz);
vec3 reflectDir = normalize(reflect(viewDir, worldNormal));
if (dot(reflectDir, worldNormal) <= 0.0) {
outColor = sceneColor;
return;
}
int steps = clamp(ubo.maxSteps, 1, 128);
float stepSize = max(ubo.ssrStepSize, 0.01);
float maxDistance = max(ubo.ssrMaxDistance, stepSize);
vec3 rayPos = worldPos;
vec2 hitUV = vec2(0.0);
bool hitFound = false;
for (int i = 0; i < steps; i++) {
rayPos += reflectDir * stepSize;
if (distance(rayPos, worldPos) > maxDistance) {
break;
}
vec4 clip = ubo.projection * ubo.view * vec4(rayPos, 1.0);
if (clip.w <= 0.0) {
break;
}
vec2 uv = clip.xy / clip.w;
uv = uv * 0.5 + 0.5;
uv.y = 1.0 - uv.y;
if (uv.x <= 0.0 || uv.x >= 1.0 || uv.y <= 0.0 || uv.y >= 1.0) {
break;
}
vec4 surfaceWorld = texture(worldPosSampler, uv);
if (surfaceWorld.a == 0.0 || length(surfaceWorld.xyz) == 0.0) {
continue;
}
float rayViewZ = abs((ubo.view * vec4(rayPos, 1.0)).z);
float surfaceViewZ = abs((ubo.view * vec4(surfaceWorld.xyz, 1.0)).z);
float depthDelta = rayViewZ - surfaceViewZ;
if (depthDelta >= 0.0 && depthDelta < THICKNESS) {
hitUV = uv;
hitFound = true;
break;
}
}
if (!hitFound) {
outColor = sceneColor;
return;
}
vec3 reflectedColor = texture(albedoSampler, hitUV).rgb;
float fade = edgeFade(hitUV);
float weight = clamp(materialReflection * fade, 0.0, 0.85);
outColor = vec4(mix(sceneColor.rgb, reflectedColor, weight), sceneColor.a);
}