struct VertexInput { @location(0) position: vec2, @location(1) texcoord: vec2, @location(2) color: vec4, }; struct VertexOutput { @builtin(position) position: vec4, @location(0) texcoord: vec2, @location(1) color: vec4, }; @group(0) @binding(0) var coverage_texture: texture_2d; @group(0) @binding(1) var coverage_sampler: sampler; @vertex fn vs_main( in: VertexInput, ) -> VertexOutput { var out: VertexOutput; var adjusted: vec2 = in.position; adjusted *= vec2(2.0, -2.0); adjusted += vec2(-1.0, 1.0); out.position = vec4(adjusted, 0.0, 1.0); out.texcoord = in.texcoord; out.color = in.color; return out; } @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { let coverage = textureSample(coverage_texture, coverage_sampler, in.texcoord).r; let alpha = coverage * in.color.a; return vec4(in.color.rgb * alpha, alpha); }