struct VertexOutput { @builtin(position) clip_position: vec4, @location(0) tex_coords: vec2, } struct Uniforms { texture_scale: vec4, } @group(0) @binding(1) var uniforms: Uniforms; @vertex fn vs_main( @builtin(vertex_index) in_vertex_index: u32, ) -> VertexOutput { var out: VertexOutput; let i = in_vertex_index / 3u + in_vertex_index % 3u; let x = -1.0 + f32(i % 2u) * 322.0; let y = -1.0 + f32(i / 2u) * 242.0; out.clip_position = vec4((vec2(x, y) - vec2(160.0, 120.0)) / uniforms.texture_scale.xy, 0.0, 1.0); out.tex_coords = vec2(x, y); return out; } @group(0) @binding(0) var screen_texture: texture_2d; fn sample_pixel(coords: vec2, offset: vec4) -> vec3 { let is_outside = any(vec2(coords) >= vec2(320u, 240u)); if(is_outside) { return vec3(0.0); } else { let f = max(vec4(0.008) / offset - vec4(0.0024), vec4(0.0)); return textureLoad(screen_texture, coords, 0).rgb * (f.x + f.y + f.z + f.w); } } @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { let pixel = floor(in.tex_coords); let o = vec2(0.5) - (in.tex_coords - pixel); let pixel = vec2(pixel); let offset_x = o.xxxx + vec4(-0.125, 0.375, 0.125, -0.375) * uniforms.texture_scale.z; let offset_y = o.yyyy + vec4(-0.375, -0.125, 0.375, 0.125) * uniforms.texture_scale.z; let offset_x0 = max(abs(offset_x + vec4(-1.0)) - vec4(0.5), vec4(0.0)); let offset_x1 = max(abs(offset_x) - vec4(0.5), vec4(0.0)); let offset_x2 = max(abs(offset_x + vec4(1.0)) - vec4(0.5), vec4(0.0)); let offset_x0 = offset_x0 * offset_x0; let offset_x1 = offset_x1 * offset_x1; let offset_x2 = offset_x2 * offset_x2; let offset_yr = offset_y + vec4(-1.0); let offset_yr = vec4(0.02) + offset_yr * offset_yr; var acc = sample_pixel(pixel + vec2(-1, -1), offset_x0 + offset_yr); acc = acc + sample_pixel(pixel + vec2(0, -1), offset_x1 + offset_yr); acc = acc + sample_pixel(pixel + vec2(1, -1), offset_x2 + offset_yr); let offset_yr = vec4(0.02) + offset_y * offset_y; acc = acc + sample_pixel(pixel + vec2(-1, 0), offset_x0 + offset_yr); acc = acc + sample_pixel(pixel, offset_x1 + offset_yr); acc = acc + sample_pixel(pixel + vec2(1, 0), offset_x2 + offset_yr); let offset_yr = offset_y + vec4(1.0); let offset_yr = vec4(0.02) + offset_yr * offset_yr; acc = acc + sample_pixel(pixel + vec2(-1, 1), offset_x0 + offset_yr); acc = acc + sample_pixel(pixel + vec2(0, 1), offset_x1 + offset_yr); acc = acc + sample_pixel(pixel + vec2(1, 1), offset_x2 + offset_yr); return vec4(acc, 1.0); }