From 40f45d7b7e35dd4937abe6b5ce16b6256b4f1eeb Mon Sep 17 00:00:00 2001 From: shan Date: Thu, 29 Sep 2022 10:52:58 -0700 Subject: Adds linear gradient support to 2D meshes in the canvas widget. --- wgpu/src/shader/triangle_gradient.wgsl | 83 ++++++++++++++++++++++++++++++++++ wgpu/src/shader/triangle_solid.wgsl | 18 ++++++++ 2 files changed, 101 insertions(+) create mode 100644 wgpu/src/shader/triangle_gradient.wgsl create mode 100644 wgpu/src/shader/triangle_solid.wgsl (limited to 'wgpu/src/shader') diff --git a/wgpu/src/shader/triangle_gradient.wgsl b/wgpu/src/shader/triangle_gradient.wgsl new file mode 100644 index 00000000..cb35b61c --- /dev/null +++ b/wgpu/src/shader/triangle_gradient.wgsl @@ -0,0 +1,83 @@ +// uniforms +struct GradientUniforms { + transform: mat4x4, + @size(16) start: vec2, + @size(16) end: vec2, + @size(16) start_stop: i32, + @size(16) end_stop: i32, +} + +struct Stop { + color: vec4, + offset: f32, +}; + +@group(0) @binding(0) +var gradient_uniforms: GradientUniforms; + +@group(0) @binding(1) +var color_stops: array; + +struct VertexOutput { + @builtin(position) position: vec4, + @location(0) raw_position: vec2 +} + +@vertex +fn vs_main(@location(0) input: vec2) -> VertexOutput { + var output: VertexOutput; + output.position = gradient_uniforms.transform * vec4(input.xy, 0.0, 1.0); + output.raw_position = input; + + return output; +} + +@fragment +fn fs_gradient(input: VertexOutput) -> @location(0) vec4 { + let v1 = gradient_uniforms.end - gradient_uniforms.start; + let v2 = input.raw_position.xy - gradient_uniforms.start; + let unit = normalize(v1); + let offset = dot(unit, v2) / length(v1); + + let min_stop = color_stops[gradient_uniforms.start_stop]; + let max_stop = color_stops[gradient_uniforms.end_stop]; + + var color: vec4; + + if (offset <= min_stop.offset) { + color = min_stop.color; + } else if (offset >= max_stop.offset) { + color = max_stop.color; + } else { + var min = min_stop; + var max = max_stop; + var min_index = gradient_uniforms.start_stop; + var max_index = gradient_uniforms.end_stop; + + loop { + if (min_index >= max_index - 1) { + break; + } + + let index = min_index + (max_index - min_index) / 2; + + let stop = color_stops[index]; + + if (offset <= stop.offset) { + max = stop; + max_index = index; + } else { + min = stop; + min_index = index; + } + } + + color = mix(min.color, max.color, smoothstep( + min.offset, + max.offset, + offset + )); + } + + return color; +} \ No newline at end of file diff --git a/wgpu/src/shader/triangle_solid.wgsl b/wgpu/src/shader/triangle_solid.wgsl new file mode 100644 index 00000000..126eceaa --- /dev/null +++ b/wgpu/src/shader/triangle_solid.wgsl @@ -0,0 +1,18 @@ +// uniforms +struct SolidUniforms { + transform: mat4x4, + color: vec4 +} + +@group(0) @binding(0) +var solid_uniforms: SolidUniforms; + +@vertex +fn vs_main(@location(0) input: vec2) -> @builtin(position) vec4 { + return solid_uniforms.transform * vec4(input.xy, 0.0, 1.0); +} + +@fragment +fn fs_solid() -> @location(0) vec4 { + return solid_uniforms.color; +} \ No newline at end of file -- cgit From f7ce7244d017ec16545a3e52b6e7cf634bbffd4a Mon Sep 17 00:00:00 2001 From: shan Date: Wed, 5 Oct 2022 11:32:59 -0700 Subject: Adjusted gradient uniforms to be more tightly packed. --- wgpu/src/shader/triangle_gradient.wgsl | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'wgpu/src/shader') diff --git a/wgpu/src/shader/triangle_gradient.wgsl b/wgpu/src/shader/triangle_gradient.wgsl index cb35b61c..df7158af 100644 --- a/wgpu/src/shader/triangle_gradient.wgsl +++ b/wgpu/src/shader/triangle_gradient.wgsl @@ -1,10 +1,10 @@ // uniforms struct GradientUniforms { transform: mat4x4, - @size(16) start: vec2, - @size(16) end: vec2, - @size(16) start_stop: i32, - @size(16) end_stop: i32, + //xy = start, wz = end + position: vec4, + //x = start, y = end, zw = padding + stop_range: vec4, } struct Stop { @@ -13,7 +13,7 @@ struct Stop { }; @group(0) @binding(0) -var gradient_uniforms: GradientUniforms; +var uniforms: GradientUniforms; @group(0) @binding(1) var color_stops: array; @@ -26,7 +26,7 @@ struct VertexOutput { @vertex fn vs_main(@location(0) input: vec2) -> VertexOutput { var output: VertexOutput; - output.position = gradient_uniforms.transform * vec4(input.xy, 0.0, 1.0); + output.position = uniforms.transform * vec4(input.xy, 0.0, 1.0); output.raw_position = input; return output; @@ -34,13 +34,18 @@ fn vs_main(@location(0) input: vec2) -> VertexOutput { @fragment fn fs_gradient(input: VertexOutput) -> @location(0) vec4 { - let v1 = gradient_uniforms.end - gradient_uniforms.start; - let v2 = input.raw_position.xy - gradient_uniforms.start; + let start = uniforms.position.xy; + let end = uniforms.position.zw; + let start_stop = uniforms.stop_range.x; + let end_stop = uniforms.stop_range.y; + + let v1 = end - start; + let v2 = input.raw_position.xy - start; let unit = normalize(v1); let offset = dot(unit, v2) / length(v1); - let min_stop = color_stops[gradient_uniforms.start_stop]; - let max_stop = color_stops[gradient_uniforms.end_stop]; + let min_stop = color_stops[start_stop]; + let max_stop = color_stops[end_stop]; var color: vec4; @@ -51,8 +56,8 @@ fn fs_gradient(input: VertexOutput) -> @location(0) vec4 { } else { var min = min_stop; var max = max_stop; - var min_index = gradient_uniforms.start_stop; - var max_index = gradient_uniforms.end_stop; + var min_index = start_stop; + var max_index = end_stop; loop { if (min_index >= max_index - 1) { -- cgit From cb7c4676543cd508dfae8d4dcbd9cc8b61b1a94e Mon Sep 17 00:00:00 2001 From: shan Date: Thu, 6 Oct 2022 07:28:05 -0700 Subject: Fixed lint issues & cleaned up some documentation. --- wgpu/src/shader/triangle_gradient.wgsl | 2 +- wgpu/src/shader/triangle_solid.wgsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'wgpu/src/shader') diff --git a/wgpu/src/shader/triangle_gradient.wgsl b/wgpu/src/shader/triangle_gradient.wgsl index df7158af..4efda260 100644 --- a/wgpu/src/shader/triangle_gradient.wgsl +++ b/wgpu/src/shader/triangle_gradient.wgsl @@ -85,4 +85,4 @@ fn fs_gradient(input: VertexOutput) -> @location(0) vec4 { } return color; -} \ No newline at end of file +} diff --git a/wgpu/src/shader/triangle_solid.wgsl b/wgpu/src/shader/triangle_solid.wgsl index 126eceaa..be51ebb0 100644 --- a/wgpu/src/shader/triangle_solid.wgsl +++ b/wgpu/src/shader/triangle_solid.wgsl @@ -15,4 +15,4 @@ fn vs_main(@location(0) input: vec2) -> @builtin(position) vec4 { @fragment fn fs_solid() -> @location(0) vec4 { return solid_uniforms.color; -} \ No newline at end of file +} -- cgit From f9a6efcaa03728f43aaa105af8936c1ed4778388 Mon Sep 17 00:00:00 2001 From: shan Date: Thu, 6 Oct 2022 19:41:00 -0700 Subject: Fixed some more imports/documentation. --- wgpu/src/shader/triangle_gradient.wgsl | 4 ++-- wgpu/src/shader/triangle_solid.wgsl | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'wgpu/src/shader') diff --git a/wgpu/src/shader/triangle_gradient.wgsl b/wgpu/src/shader/triangle_gradient.wgsl index 4efda260..03ba9d88 100644 --- a/wgpu/src/shader/triangle_gradient.wgsl +++ b/wgpu/src/shader/triangle_gradient.wgsl @@ -1,9 +1,8 @@ -// uniforms struct GradientUniforms { transform: mat4x4, //xy = start, wz = end position: vec4, - //x = start, y = end, zw = padding + //x = start stop, y = end stop, zw = padding stop_range: vec4, } @@ -32,6 +31,7 @@ fn vs_main(@location(0) input: vec2) -> VertexOutput { return output; } +//TODO: rewrite without branching @fragment fn fs_gradient(input: VertexOutput) -> @location(0) vec4 { let start = uniforms.position.xy; diff --git a/wgpu/src/shader/triangle_solid.wgsl b/wgpu/src/shader/triangle_solid.wgsl index be51ebb0..9eb2df24 100644 --- a/wgpu/src/shader/triangle_solid.wgsl +++ b/wgpu/src/shader/triangle_solid.wgsl @@ -1,4 +1,3 @@ -// uniforms struct SolidUniforms { transform: mat4x4, color: vec4 -- cgit From c4565759e4294540f54a81e4d91ddea7a769d3d4 Mon Sep 17 00:00:00 2001 From: bungoboingo Date: Tue, 18 Oct 2022 15:18:37 -0700 Subject: Cleaned up namespaces re: PR comments. --- wgpu/src/shader/gradient.wgsl | 88 ++++++++++++++++++++++++++++++++++ wgpu/src/shader/solid.wgsl | 17 +++++++ wgpu/src/shader/triangle_gradient.wgsl | 88 ---------------------------------- wgpu/src/shader/triangle_solid.wgsl | 17 ------- 4 files changed, 105 insertions(+), 105 deletions(-) create mode 100644 wgpu/src/shader/gradient.wgsl create mode 100644 wgpu/src/shader/solid.wgsl delete mode 100644 wgpu/src/shader/triangle_gradient.wgsl delete mode 100644 wgpu/src/shader/triangle_solid.wgsl (limited to 'wgpu/src/shader') diff --git a/wgpu/src/shader/gradient.wgsl b/wgpu/src/shader/gradient.wgsl new file mode 100644 index 00000000..63825aec --- /dev/null +++ b/wgpu/src/shader/gradient.wgsl @@ -0,0 +1,88 @@ +struct Uniforms { + transform: mat4x4, + //xy = start, wz = end + position: vec4, + //x = start stop, y = end stop, zw = padding + stop_range: vec4, +} + +struct Stop { + color: vec4, + offset: f32, +}; + +@group(0) @binding(0) +var uniforms: Uniforms; + +@group(0) @binding(1) +var color_stops: array; + +struct VertexOutput { + @builtin(position) position: vec4, + @location(0) raw_position: vec2 +} + +@vertex +fn vs_main(@location(0) input: vec2) -> VertexOutput { + var output: VertexOutput; + output.position = uniforms.transform * vec4(input.xy, 0.0, 1.0); + output.raw_position = input; + + return output; +} + +//TODO: rewrite without branching +@fragment +fn fs_main(input: VertexOutput) -> @location(0) vec4 { + let start = uniforms.position.xy; + let end = uniforms.position.zw; + let start_stop = uniforms.stop_range.x; + let end_stop = uniforms.stop_range.y; + + let v1 = end - start; + let v2 = input.raw_position.xy - start; + let unit = normalize(v1); + let offset = dot(unit, v2) / length(v1); + + let min_stop = color_stops[start_stop]; + let max_stop = color_stops[end_stop]; + + var color: vec4; + + if (offset <= min_stop.offset) { + color = min_stop.color; + } else if (offset >= max_stop.offset) { + color = max_stop.color; + } else { + var min = min_stop; + var max = max_stop; + var min_index = start_stop; + var max_index = end_stop; + + loop { + if (min_index >= max_index - 1) { + break; + } + + let index = min_index + (max_index - min_index) / 2; + + let stop = color_stops[index]; + + if (offset <= stop.offset) { + max = stop; + max_index = index; + } else { + min = stop; + min_index = index; + } + } + + color = mix(min.color, max.color, smoothstep( + min.offset, + max.offset, + offset + )); + } + + return color; +} diff --git a/wgpu/src/shader/solid.wgsl b/wgpu/src/shader/solid.wgsl new file mode 100644 index 00000000..68a8fea3 --- /dev/null +++ b/wgpu/src/shader/solid.wgsl @@ -0,0 +1,17 @@ +struct Uniforms { + transform: mat4x4, + color: vec4 +} + +@group(0) @binding(0) +var uniforms: Uniforms; + +@vertex +fn vs_main(@location(0) input: vec2) -> @builtin(position) vec4 { + return uniforms.transform * vec4(input.xy, 0.0, 1.0); +} + +@fragment +fn fs_main() -> @location(0) vec4 { + return uniforms.color; +} diff --git a/wgpu/src/shader/triangle_gradient.wgsl b/wgpu/src/shader/triangle_gradient.wgsl deleted file mode 100644 index 03ba9d88..00000000 --- a/wgpu/src/shader/triangle_gradient.wgsl +++ /dev/null @@ -1,88 +0,0 @@ -struct GradientUniforms { - transform: mat4x4, - //xy = start, wz = end - position: vec4, - //x = start stop, y = end stop, zw = padding - stop_range: vec4, -} - -struct Stop { - color: vec4, - offset: f32, -}; - -@group(0) @binding(0) -var uniforms: GradientUniforms; - -@group(0) @binding(1) -var color_stops: array; - -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) raw_position: vec2 -} - -@vertex -fn vs_main(@location(0) input: vec2) -> VertexOutput { - var output: VertexOutput; - output.position = uniforms.transform * vec4(input.xy, 0.0, 1.0); - output.raw_position = input; - - return output; -} - -//TODO: rewrite without branching -@fragment -fn fs_gradient(input: VertexOutput) -> @location(0) vec4 { - let start = uniforms.position.xy; - let end = uniforms.position.zw; - let start_stop = uniforms.stop_range.x; - let end_stop = uniforms.stop_range.y; - - let v1 = end - start; - let v2 = input.raw_position.xy - start; - let unit = normalize(v1); - let offset = dot(unit, v2) / length(v1); - - let min_stop = color_stops[start_stop]; - let max_stop = color_stops[end_stop]; - - var color: vec4; - - if (offset <= min_stop.offset) { - color = min_stop.color; - } else if (offset >= max_stop.offset) { - color = max_stop.color; - } else { - var min = min_stop; - var max = max_stop; - var min_index = start_stop; - var max_index = end_stop; - - loop { - if (min_index >= max_index - 1) { - break; - } - - let index = min_index + (max_index - min_index) / 2; - - let stop = color_stops[index]; - - if (offset <= stop.offset) { - max = stop; - max_index = index; - } else { - min = stop; - min_index = index; - } - } - - color = mix(min.color, max.color, smoothstep( - min.offset, - max.offset, - offset - )); - } - - return color; -} diff --git a/wgpu/src/shader/triangle_solid.wgsl b/wgpu/src/shader/triangle_solid.wgsl deleted file mode 100644 index 9eb2df24..00000000 --- a/wgpu/src/shader/triangle_solid.wgsl +++ /dev/null @@ -1,17 +0,0 @@ -struct SolidUniforms { - transform: mat4x4, - color: vec4 -} - -@group(0) @binding(0) -var solid_uniforms: SolidUniforms; - -@vertex -fn vs_main(@location(0) input: vec2) -> @builtin(position) vec4 { - return solid_uniforms.transform * vec4(input.xy, 0.0, 1.0); -} - -@fragment -fn fs_solid() -> @location(0) vec4 { - return solid_uniforms.color; -} -- cgit From c0596179bd8582e4f4b5289cdeee8de4fa3de464 Mon Sep 17 00:00:00 2001 From: Robert Krahn Date: Thu, 3 Nov 2022 00:35:01 +0100 Subject: non uniform border radius for quads --- wgpu/src/shader/quad.wgsl | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) (limited to 'wgpu/src/shader') diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl index 73edd97c..cf4f7e4d 100644 --- a/wgpu/src/shader/quad.wgsl +++ b/wgpu/src/shader/quad.wgsl @@ -11,7 +11,7 @@ struct VertexInput { @location(2) scale: vec2, @location(3) color: vec4, @location(4) border_color: vec4, - @location(5) border_radius: f32, + @location(5) border_radius: vec4, @location(6) border_width: f32, } @@ -21,7 +21,7 @@ struct VertexOutput { @location(1) border_color: vec4, @location(2) pos: vec2, @location(3) scale: vec2, - @location(4) border_radius: f32, + @location(4) border_radius: vec4, @location(5) border_width: f32, } @@ -32,9 +32,12 @@ fn vs_main(input: VertexInput) -> VertexOutput { var pos: vec2 = input.pos * globals.scale; var scale: vec2 = input.scale * globals.scale; - var border_radius: f32 = min( - input.border_radius, - min(input.scale.x, input.scale.y) / 2.0 + var min_border_radius = min(input.scale.x, input.scale.y) * 0.5; + var border_radius: vec4 = vec4( + min(input.border_radius.x, min_border_radius), + min(input.border_radius.y, min_border_radius), + min(input.border_radius.z, min_border_radius), + min(input.border_radius.w, min_border_radius) ); var transform: mat4x4 = mat4x4( @@ -76,6 +79,18 @@ fn distance_alg( return sqrt(dist.x * dist.x + dist.y * dist.y); } +// Based on the fragement position and the center of the quad, select one of the 4 radi. +// Order matches CSS border radius attribute: +// radi.x = top-left, radi.y = top-right, radi.z = bottom-right, radi.w = bottom-left +fn select_border_radius(radi: vec4, position: vec2, center: vec2) -> f32 { + var rx = radi.x; + var ry = radi.y; + rx = select(radi.x, radi.y, position.x > center.x); + ry = select(radi.w, radi.z, position.x > center.x); + rx = select(rx, ry, position.y > center.y); + return rx; +} + @fragment fn fs_main( @@ -83,14 +98,17 @@ fn fs_main( ) -> @location(0) vec4 { var mixed_color: vec4 = input.color; + var border_radius = select_border_radius( + input.border_radius, + input.position.xy, + (input.pos + input.scale * 0.5).xy + ); + if (input.border_width > 0.0) { - var internal_border: f32 = max( - input.border_radius - input.border_width, - 0.0 - ); + var internal_border: f32 = max(border_radius - input.border_width, 0.0); var internal_distance: f32 = distance_alg( - vec2(input.position.x, input.position.y), + input.position.xy, input.pos + vec2(input.border_width, input.border_width), input.scale - vec2(input.border_width * 2.0, input.border_width * 2.0), internal_border @@ -109,13 +127,14 @@ fn fs_main( vec2(input.position.x, input.position.y), input.pos, input.scale, - input.border_radius + border_radius ); var radius_alpha: f32 = 1.0 - smoothstep( - max(input.border_radius - 0.5, 0.0), - input.border_radius + 0.5, - dist); + max(border_radius - 0.5, 0.0), + border_radius + 0.5, + dist + ); return vec4(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha); } -- cgit From 33c3c0c0aa774bb7462e3c42aa04c591a66376a7 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 14 Nov 2022 00:02:42 +0100 Subject: Group all solid triangles independently of color --- wgpu/src/shader/solid.wgsl | 29 +++++++++++++++++++++-------- wgpu/src/shader/triangle.wgsl | 30 ------------------------------ 2 files changed, 21 insertions(+), 38 deletions(-) delete mode 100644 wgpu/src/shader/triangle.wgsl (limited to 'wgpu/src/shader') diff --git a/wgpu/src/shader/solid.wgsl b/wgpu/src/shader/solid.wgsl index 68a8fea3..b24402f8 100644 --- a/wgpu/src/shader/solid.wgsl +++ b/wgpu/src/shader/solid.wgsl @@ -1,17 +1,30 @@ -struct Uniforms { +struct Globals { transform: mat4x4, - color: vec4 } -@group(0) @binding(0) -var uniforms: Uniforms; +@group(0) @binding(0) var globals: Globals; + +struct VertexInput { + @location(0) position: vec2, + @location(1) color: vec4, +} + +struct VertexOutput { + @builtin(position) position: vec4, + @location(0) color: vec4, +} @vertex -fn vs_main(@location(0) input: vec2) -> @builtin(position) vec4 { - return uniforms.transform * vec4(input.xy, 0.0, 1.0); +fn vs_main(input: VertexInput) -> VertexOutput { + var out: VertexOutput; + + out.color = input.color; + out.position = globals.transform * vec4(input.position, 0.0, 1.0); + + return out; } @fragment -fn fs_main() -> @location(0) vec4 { - return uniforms.color; +fn fs_main(input: VertexOutput) -> @location(0) vec4 { + return input.color; } diff --git a/wgpu/src/shader/triangle.wgsl b/wgpu/src/shader/triangle.wgsl deleted file mode 100644 index b24402f8..00000000 --- a/wgpu/src/shader/triangle.wgsl +++ /dev/null @@ -1,30 +0,0 @@ -struct Globals { - transform: mat4x4, -} - -@group(0) @binding(0) var globals: Globals; - -struct VertexInput { - @location(0) position: vec2, - @location(1) color: vec4, -} - -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) color: vec4, -} - -@vertex -fn vs_main(input: VertexInput) -> VertexOutput { - var out: VertexOutput; - - out.color = input.color; - out.position = globals.transform * vec4(input.position, 0.0, 1.0); - - return out; -} - -@fragment -fn fs_main(input: VertexOutput) -> @location(0) vec4 { - return input.color; -} -- cgit