diff options
Diffstat (limited to 'wgpu/src/shader')
-rw-r--r-- | wgpu/src/shader/blit.wgsl | 20 | ||||
-rw-r--r-- | wgpu/src/shader/image.wgsl | 37 | ||||
-rw-r--r-- | wgpu/src/shader/quad/solid.wgsl | 12 |
3 files changed, 42 insertions, 27 deletions
diff --git a/wgpu/src/shader/blit.wgsl b/wgpu/src/shader/blit.wgsl index c2ea223f..d7633808 100644 --- a/wgpu/src/shader/blit.wgsl +++ b/wgpu/src/shader/blit.wgsl @@ -1,22 +1,14 @@ -var<private> positions: array<vec2<f32>, 6> = array<vec2<f32>, 6>( - vec2<f32>(-1.0, 1.0), - vec2<f32>(-1.0, -1.0), - vec2<f32>(1.0, -1.0), - vec2<f32>(-1.0, 1.0), - vec2<f32>(1.0, 1.0), - vec2<f32>(1.0, -1.0) -); - var<private> uvs: array<vec2<f32>, 6> = array<vec2<f32>, 6>( vec2<f32>(0.0, 0.0), - vec2<f32>(0.0, 1.0), + vec2<f32>(1.0, 0.0), vec2<f32>(1.0, 1.0), vec2<f32>(0.0, 0.0), - vec2<f32>(1.0, 0.0), + vec2<f32>(0.0, 1.0), vec2<f32>(1.0, 1.0) ); @group(0) @binding(0) var u_sampler: sampler; +@group(0) @binding(1) var<uniform> u_ratio: vec2<f32>; @group(1) @binding(0) var u_texture: texture_2d<f32>; struct VertexInput { @@ -30,9 +22,11 @@ struct VertexOutput { @vertex fn vs_main(input: VertexInput) -> VertexOutput { + let uv = uvs[input.vertex_index]; + var out: VertexOutput; - out.uv = uvs[input.vertex_index]; - out.position = vec4<f32>(positions[input.vertex_index], 0.0, 1.0); + out.uv = uv * u_ratio; + out.position = vec4<f32>(uv * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0); return out; } diff --git a/wgpu/src/shader/image.wgsl b/wgpu/src/shader/image.wgsl index 7b2e5238..0eeb100f 100644 --- a/wgpu/src/shader/image.wgsl +++ b/wgpu/src/shader/image.wgsl @@ -9,40 +9,55 @@ struct Globals { struct VertexInput { @builtin(vertex_index) vertex_index: u32, @location(0) pos: vec2<f32>, - @location(1) scale: vec2<f32>, - @location(2) atlas_pos: vec2<f32>, - @location(3) atlas_scale: vec2<f32>, - @location(4) layer: i32, + @location(1) center: vec2<f32>, + @location(2) scale: vec2<f32>, + @location(3) rotation: f32, + @location(4) opacity: f32, + @location(5) atlas_pos: vec2<f32>, + @location(6) atlas_scale: vec2<f32>, + @location(7) layer: i32, } struct VertexOutput { @builtin(position) position: vec4<f32>, @location(0) uv: vec2<f32>, @location(1) layer: f32, // this should be an i32, but naga currently reads that as requiring interpolation. + @location(2) opacity: f32, } @vertex fn vs_main(input: VertexInput) -> VertexOutput { var out: VertexOutput; - let v_pos = vertex_position(input.vertex_index); + // Generate a vertex position in the range [0, 1] from the vertex index. + var v_pos = vertex_position(input.vertex_index); + // Map the vertex position to the atlas texture. out.uv = vec2<f32>(v_pos * input.atlas_scale + input.atlas_pos); out.layer = f32(input.layer); + out.opacity = input.opacity; - var transform: mat4x4<f32> = mat4x4<f32>( - vec4<f32>(input.scale.x, 0.0, 0.0, 0.0), - vec4<f32>(0.0, input.scale.y, 0.0, 0.0), + // Calculate the vertex position and move the center to the origin + v_pos = round(input.pos) + v_pos * input.scale - input.center; + + // Apply the rotation around the center of the image + let cos_rot = cos(input.rotation); + let sin_rot = sin(input.rotation); + let rotate = mat4x4<f32>( + vec4<f32>(cos_rot, sin_rot, 0.0, 0.0), + vec4<f32>(-sin_rot, cos_rot, 0.0, 0.0), vec4<f32>(0.0, 0.0, 1.0, 0.0), - vec4<f32>(input.pos, 0.0, 1.0) + vec4<f32>(0.0, 0.0, 0.0, 1.0) ); - out.position = globals.transform * transform * vec4<f32>(v_pos, 0.0, 1.0); + // Calculate the final position of the vertex + out.position = globals.transform * (vec4<f32>(input.center, 0.0, 0.0) + rotate * vec4<f32>(v_pos, 0.0, 1.0)); return out; } @fragment fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> { - return textureSample(u_texture, u_sampler, input.uv, i32(input.layer)); + // Sample the texture at the given UV coordinate and layer. + return textureSample(u_texture, u_sampler, input.uv, i32(input.layer)) * vec4<f32>(1.0, 1.0, 1.0, input.opacity); } diff --git a/wgpu/src/shader/quad/solid.wgsl b/wgpu/src/shader/quad/solid.wgsl index 1274f814..d908afbc 100644 --- a/wgpu/src/shader/quad/solid.wgsl +++ b/wgpu/src/shader/quad/solid.wgsl @@ -107,13 +107,19 @@ fn solid_fs_main( let quad_color = vec4<f32>(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha); if input.shadow_color.a > 0.0 { - let shadow_distance = rounded_box_sdf(input.position.xy - input.pos - input.shadow_offset - (input.scale / 2.0), input.scale / 2.0, border_radius); + let shadow_radius = select_border_radius( + input.border_radius, + input.position.xy - input.shadow_offset, + (input.pos + input.scale * 0.5).xy + ); + let shadow_distance = max(rounded_box_sdf(input.position.xy - input.pos - input.shadow_offset - (input.scale / 2.0), input.scale / 2.0, shadow_radius), 0.); + let shadow_alpha = 1.0 - smoothstep(-input.shadow_blur_radius, input.shadow_blur_radius, shadow_distance); let shadow_color = input.shadow_color; - let base_color = select( + let base_color = mix( vec4<f32>(shadow_color.x, shadow_color.y, shadow_color.z, 0.0), quad_color, - quad_color.a > 0.0 + quad_color.a ); return mix(base_color, shadow_color, (1.0 - radius_alpha) * shadow_alpha); |