diff --git a/neothesia-core/src/render/glow/shader.wgsl b/neothesia-core/src/render/glow/shader.wgsl index e06380b7..c644f330 100644 --- a/neothesia-core/src/render/glow/shader.wgsl +++ b/neothesia-core/src/render/glow/shader.wgsl @@ -1,7 +1,6 @@ struct ViewUniform { transform: mat4x4, size: vec2, - scale: f32, } @group(0) @binding(0) @@ -25,14 +24,11 @@ struct VertexOutput { @vertex fn vs_main(vertex: Vertex, quad: QuadInstance) -> VertexOutput { - var quad_position = quad.q_position * view_uniform.scale; - var quad_size = quad.size * view_uniform.scale; - 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(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) + vec4(quad.q_position, 0.0, 1.0) ); var out: VertexOutput; diff --git a/neothesia-core/src/render/quad/shader.wgsl b/neothesia-core/src/render/quad/shader.wgsl index 1627237b..c9d99539 100644 --- a/neothesia-core/src/render/quad/shader.wgsl +++ b/neothesia-core/src/render/quad/shader.wgsl @@ -1,7 +1,6 @@ struct ViewUniform { transform: mat4x4, size: vec2, - scale: f32, } @group(0) @binding(0) @@ -20,93 +19,75 @@ struct QuadInstance { struct VertexOutput { @builtin(position) position: vec4, + @location(0) src_position: vec2, - @location(0) quad_size: vec2, - @location(1) quad_color: vec4, - @location(2) quad_border_radius: vec4, - @location(3) quad_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 quad_position = quad.q_position * view_uniform.scale; - var quad_size = quad.size * view_uniform.scale; - 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(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) + vec4(quad.q_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_position = quad_position; - out.quad_size = quad_size; - - var max_border_radius = min(quad.size.x, quad.size.y) * 0.5; - out.quad_border_radius = vec4( - min(quad.border_radius.x, max_border_radius), - min(quad.border_radius.y, max_border_radius), - min(quad.border_radius.z, max_border_radius), - min(quad.border_radius.w, max_border_radius) - ) * view_uniform.scale; + out.quad_size = quad.size; + out.quad_border_radius = quad.border_radius; return out; } -// SFD code is licenced under: MIT by Héctor Ramón & Iced contributors -fn distance_alg( - frag_coord: vec2, +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: f32 + radius: vec4, ) -> f32 { - var inner_half_size: vec2 = (size - vec2(radius, radius) * 2.0) / 2.0; - var top_left: vec2 = position + vec2(radius, radius); - return rounded_box_sdf(frag_coord - top_left - inner_half_size, inner_half_size, 0.0); + 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; + } } -// Given a vector from a point to the center of a rounded rectangle of the given `size` and -// border `radius`, determines the point's distance from the nearest edge of the rounded rectangle -fn rounded_box_sdf(to_center: vec2, size: vec2, radius: f32) -> f32 { - return length(max(abs(to_center) - size + vec2(radius, radius), vec2(0.0, 0.0))) - radius; -} - -// Based on the fragment position and the center of the quad, select one of the 4 radii. -// Order matches CSS border radius attribute: -// radii.x = top-left, radii.y = top-right, radii.z = bottom-right, radii.w = bottom-left -fn select_border_radius(radii: vec4, position: vec2, center: vec2) -> f32 { - var rx = radii.x; - var ry = radii.y; - rx = select(radii.x, radii.y, position.x > center.x); - ry = select(radii.w, radii.z, position.x > center.x); - rx = select(rx, ry, position.y > center.y); - return rx; -} @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { - var border_radius = select_border_radius( - in.quad_border_radius, - in.position.xy, - (in.quad_position + (in.quad_size * 0.5)).xy - ); - - var dist: f32 = distance_alg( - vec2(in.position.x, in.position.y), - in.quad_position, + let alpha: f32 = fragment_alpha( + in.src_position.xy, in.quad_size, - border_radius - ); - - var alpha: f32 = 1.0 - smoothstep( - max(border_radius - 0.5, 0.0), - border_radius + 0.5, - dist + in.quad_border_radius ); - return vec4(in.quad_color.xyz, in.quad_color.w * alpha); + return vec4(in.quad_color.xyz, in.quad_color.w * alpha); } diff --git a/neothesia-core/src/render/waterfall/pipeline/shader.wgsl b/neothesia-core/src/render/waterfall/pipeline/shader.wgsl index 7a60efb1..0800f787 100644 --- a/neothesia-core/src/render/waterfall/pipeline/shader.wgsl +++ b/neothesia-core/src/render/waterfall/pipeline/shader.wgsl @@ -38,15 +38,15 @@ struct VertexOutput { @vertex fn vs_main(vertex: Vertex, note: NoteInstance) -> VertexOutput { - let speed = time_uniform.speed; + let speed = time_uniform.speed / view_uniform.scale; - let size = vec2(note.size.x, note.size.y * abs(speed)) * view_uniform.scale; + let size = vec2(note.size.x, note.size.y * abs(speed)); // In an ideal world this should not be hard-coded let keyboard_h = view_uniform.size.y / 5.0; let keyboard_y = view_uniform.size.y - keyboard_h; - var pos = vec2(note.n_position.x * view_uniform.scale, keyboard_y); + var pos = vec2(note.n_position.x, keyboard_y); if speed > 0.0 { // If notes are falling from top to down, we need to adjust the position, @@ -71,7 +71,7 @@ fn vs_main(vertex: Vertex, note: NoteInstance) -> VertexOutput { out.src_position = vertex.position; out.size = size; out.color = note.color; - out.radius = note.radius * view_uniform.scale; + out.radius = note.radius; return out; } @@ -100,7 +100,7 @@ fn dist( @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { let dist: f32 = dist( - in.position.xy, + in.position.xy / view_uniform.scale, in.note_pos, in.size, in.radius, diff --git a/neothesia/src/context.rs b/neothesia/src/context.rs index fb770195..f9c30741 100644 --- a/neothesia/src/context.rs +++ b/neothesia/src/context.rs @@ -79,8 +79,8 @@ impl Context { pub fn resize(&mut self) { self.transform.data.update( - self.window_state.physical_size.width as f32, - self.window_state.physical_size.height as f32, + self.window_state.logical_size.width, + self.window_state.logical_size.height, self.window_state.scale_factor as f32, ); self.transform.update(&self.gpu.queue); diff --git a/neothesia/src/scene/playing_scene/top_bar/mod.rs b/neothesia/src/scene/playing_scene/top_bar/mod.rs index 7ac7a59d..782788e6 100644 --- a/neothesia/src/scene/playing_scene/top_bar/mod.rs +++ b/neothesia/src/scene/playing_scene/top_bar/mod.rs @@ -135,7 +135,7 @@ impl TopBar { .color([67, 67, 67]) .hover_color([87, 87, 87]) .preseed_color([97, 97, 97]) - .border_radius([10.0, 0.0, 0.0, 10.0]) + .border_radius([10.0, 0.0, 10.0, 0.0]) .icon(icons::minus_icon()) .text_justify(nuon::TextJustify::Left) .build(ui) @@ -159,7 +159,7 @@ impl TopBar { .color([67, 67, 67]) .hover_color([87, 87, 87]) .preseed_color([97, 97, 97]) - .border_radius([0.0, 10.0, 10.0, 0.0]) + .border_radius([0.0, 10.0, 0.0, 10.0]) .icon(icons::plus_icon()) .text_justify(nuon::TextJustify::Right) .build(ui)