summaryrefslogtreecommitdiffstats
path: root/wgpu/src/shader/gradient.wgsl
diff options
context:
space:
mode:
authorLibravatar bungoboingo <shankern@protonmail.com>2022-10-18 15:18:37 -0700
committerLibravatar bungoboingo <shankern@protonmail.com>2022-10-18 15:18:37 -0700
commitc4565759e4294540f54a81e4d91ddea7a769d3d4 (patch)
treed326dca32fb327b81ef67fae565b88f386431792 /wgpu/src/shader/gradient.wgsl
parentbb8d46a3fdf925b4b2fa9e7db76e48caf020b212 (diff)
downloadiced-c4565759e4294540f54a81e4d91ddea7a769d3d4.tar.gz
iced-c4565759e4294540f54a81e4d91ddea7a769d3d4.tar.bz2
iced-c4565759e4294540f54a81e4d91ddea7a769d3d4.zip
Cleaned up namespaces re: PR comments.
Diffstat (limited to 'wgpu/src/shader/gradient.wgsl')
-rw-r--r--wgpu/src/shader/gradient.wgsl88
1 files changed, 88 insertions, 0 deletions
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<f32>,
+ //xy = start, wz = end
+ position: vec4<f32>,
+ //x = start stop, y = end stop, zw = padding
+ stop_range: vec4<i32>,
+}
+
+struct Stop {
+ color: vec4<f32>,
+ offset: f32,
+};
+
+@group(0) @binding(0)
+var<uniform> uniforms: Uniforms;
+
+@group(0) @binding(1)
+var<storage, read> color_stops: array<Stop>;
+
+struct VertexOutput {
+ @builtin(position) position: vec4<f32>,
+ @location(0) raw_position: vec2<f32>
+}
+
+@vertex
+fn vs_main(@location(0) input: vec2<f32>) -> VertexOutput {
+ var output: VertexOutput;
+ output.position = uniforms.transform * vec4<f32>(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<f32> {
+ 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<f32>;
+
+ 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;
+}