struct ViewUniform { transform: mat4x4, size: vec2, }; @group(0) @binding(0) var view_uniform: ViewUniform; struct Vertex { @location(0) position: vec2, }; struct QuadInstance{ @location(1) position: vec2, @location(2) size: vec2, @location(3) color: vec4, @location(4) border_radius: vec4, }; struct VertexOutput { @builtin(position) position: vec4, @location(0) src_position: vec2, @location(1) quad_size: vec2, @location(2) quad_color: vec4, @location(3) quad_border_radius: vec4, }; @vertex fn vs_main(vertex: Vertex, quad: QuadInstance) -> VertexOutput { var i_transform: mat4x4 = mat4x4( vec4(quad.size.x, 0.0, 0.0, 0.0), vec4(0.0, quad.size.y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(quad.position, 0.0, 1.0) ); var out: VertexOutput; out.position = view_uniform.transform * i_transform * vec4(vertex.position, 0.0, 1.0); out.src_position = vertex.position; out.quad_color = quad.color; out.quad_size = quad.size; out.quad_border_radius = quad.border_radius; return out; } fn corrner_alpha(radius: f32, pos: vec2, cords: vec2) -> f32{ let lower = radius - 0.7; let upper = radius + 0.7; return 1.0 - smoothstep(lower, upper, length(pos - cords)); } fn fragment_alpha( position: vec2, size: vec2, radius: vec4, ) -> f32 { let pos = position * size; // Top Left let tl = vec2(radius.x, radius.x); // Top Right let tr = vec2(size.x - radius.y, radius.y); // Bottom Left let bl = vec2(radius.z, size.y - radius.z); // Bottom Right let br = vec2(size.x - radius.w, size.y - radius.w); if (pos.x < tl.x && pos.y < tl.y) { return corrner_alpha(radius.x, pos, tl); } else if (pos.x > tr.x && pos.y < tr.y){ return corrner_alpha(radius.y, pos, tr); } else if (pos.x < bl.x && pos.y > bl.y){ return corrner_alpha(radius.z, pos, bl); } else if (pos.x > br.x && pos.y > br.y){ return corrner_alpha(radius.w, pos, br); } else { return 1.0; } } @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { let alpha: f32 = fragment_alpha( in.src_position.xy, in.quad_size, in.quad_border_radius ); return vec4(in.quad_color.xyz, in.quad_color.w * alpha); }