#version 450 #define brightboost 1 #define shape 2.0 #define hardBloomPix -1.5 layout(std140, set = 0, binding = 0) uniform UBO { mat4 MVP; vec4 OutputSize; vec4 OriginalSize; vec4 REFERENCESize; } global; #pragma stage vertex layout(location = 0) in vec4 Position; layout(location = 1) in vec2 TexCoord; layout(location = 0) out vec2 vTexCoord; void main() { gl_Position = global.MVP * Position; vTexCoord = TexCoord; // vTexCoord = floor(global.REFERENCESize.xy * TexCoord); // vTexCoord = (vTexCoord + 0.5) * global.REFERENCESize.zw; } #pragma stage fragment layout(location = 0) in vec2 vTexCoord; layout(location = 0) out vec4 FragColor; layout(set = 0, binding = 2) uniform sampler2D REFERENCE; // Nearest emulated sample given floating point position and texel offset. // Also zero's off screen. vec3 Fetch(vec2 pos, vec2 off) { pos = vTexCoord;//(floor(pos*global.REFERENCESize.xy+off)+vec2(0.5,0.5)) * global.REFERENCESize.zw; return brightboost * texture(REFERENCE, pos.xy).rgb; } // Distance in emulated pixels to nearest texel. vec2 Dist(vec2 pos) { pos = pos*global.REFERENCESize.xy; return -((pos - floor(pos)) - vec2(0.5)); } // 1D Gaussian. float Gaus(float pos, float scale) { return exp2(scale*pow(abs(pos), shape)); } // 7-tap Gaussian filter along horz line. vec3 Horz7(vec2 pos, float off) { vec3 a = Fetch(pos, vec2(-3.0, off)); vec3 b = Fetch(pos, vec2(-2.0, off)); vec3 c = Fetch(pos, vec2(-1.0, off)); vec3 d = Fetch(pos, vec2( 0.0, off)); vec3 e = Fetch(pos, vec2( 1.0, off)); vec3 f = Fetch(pos, vec2( 2.0, off)); vec3 g = Fetch(pos, vec2( 3.0, off)); float dst = Dist(pos).x; // Convert distance to weight. float scale = hardBloomPix; float wa = Gaus(dst - 3.0, scale); float wb = Gaus(dst - 2.0, scale); float wc = Gaus(dst - 1.0, scale); float wd = Gaus(dst + 0.0, scale); float we = Gaus(dst + 1.0, scale); float wf = Gaus(dst + 2.0, scale); float wg = Gaus(dst + 3.0, scale); // Return filtered sample. return (a*wa+b*wb+c*wc+d*wd+e*we+f*wf+g*wg)/(wa+wb+wc+wd+we+wf+wg); } void main() { FragColor = vec4(Horz7(vTexCoord, 1.0).rgb, 1.0); }