@group(0) @binding(0) var mySampler : sampler; @group(0) @binding(1) var myTexture : texture_2d; @group(0) @binding(2) var resolution : vec2; struct VertexOutput { @builtin(position) position : vec4, @location(0) uv : vec2, }; @vertex fn vertexMain(@location(0) position : vec3, @location(1) uv : vec2) -> VertexOutput { var out : VertexOutput; out.position = vec4(position, 1.0); out.uv = uv; return out; } @fragment fn fragmentMain(@location(0) uv : vec2) -> @location(0) vec4 { let texelSize = 1.0 / resolution; // Sample surrounding pixels let colorCenter = textureSample(myTexture, mySampler, uv); let colorN = textureSample(myTexture, mySampler, uv + vec2(0.0, texelSize.y)); let colorS = textureSample(myTexture, mySampler, uv - vec2(0.0, texelSize.y)); let colorE = textureSample(myTexture, mySampler, uv + vec2(texelSize.x, 0.0)); let colorW = textureSample(myTexture, mySampler, uv - vec2(texelSize.x, 0.0)); let luma = dot(colorCenter.rgb, vec3(0.299, 0.587, 0.114)); let lumaN = dot(colorN.rgb, vec3(0.299, 0.587, 0.114)); let lumaS = dot(colorS.rgb, vec3(0.299, 0.587, 0.114)); let lumaE = dot(colorE.rgb, vec3(0.299, 0.587, 0.114)); let lumaW = dot(colorW.rgb, vec3(0.299, 0.587, 0.114)); let edgeH = abs(lumaW - lumaE); let edgeV = abs(lumaN - lumaS); let edge = max(edgeH, edgeV); let threshold = 0.1; if (edge < threshold) { return colorCenter; // No edge — return original } // Basic blur let blur = (colorN + colorS + colorE + colorW) * 0.25; return vec4(blur.rgb, 1.0); }