#version 450 layout(location = 0) in vec2 inTextCoord; layout(location = 0) out vec4 outFragColor; layout(set = 0, binding = 0) uniform sampler2DMS inputTexture; layout(set = 0, binding = 1) uniform sampler2D bloomImage; layout(push_constant) uniform PassConfig { int horizontal; float GAMMA_CONST; float Exposure; float blur_radius; vec2 bloomSize; } config; vec4 msaa(int sampleCount, sampler2DMS textureIn, vec2 TextCoord) { ivec2 size = textureSize(textureIn); ivec2 pixelCoords = clamp(ivec2(TextCoord * vec2(size)), ivec2(0), size - 1); vec4 colorSum = vec4(0.0); for (int i = 0; i < sampleCount; i++) colorSum += texelFetch(textureIn, pixelCoords, i); return colorSum / float(sampleCount); } vec3 bloomAt(ivec2 pixel, ivec2 size) { return texelFetch(bloomImage, clamp(pixel, ivec2(0), size - 1), 0).rgb; } vec3 upsampleBloom(vec2 uv) { ivec2 size = textureSize(bloomImage, 0); vec2 pixel = uv * vec2(size) - 0.5; ivec2 base = ivec2(floor(pixel)); vec2 blend = fract(pixel); return mix(mix(bloomAt(base, size), bloomAt(base + ivec2(1, 0), size), blend.x), mix(bloomAt(base + ivec2(0, 1), size), bloomAt(base + ivec2(1, 1), size), blend.x), blend.y); } void main() { vec4 sceneColor = msaa(textureSamples(inputTexture), inputTexture, inTextCoord); vec3 hdrColour = max(sceneColor.rgb + upsampleBloom(inTextCoord), vec3(0.0)); vec3 result = vec3(1.0) - exp(-hdrColour * config.Exposure); outFragColor = vec4(pow(result, vec3(1.0 / config.GAMMA_CONST)), sceneColor.a); }