diff options
author | 2022-10-18 15:18:37 -0700 | |
---|---|---|
committer | 2022-10-18 15:18:37 -0700 | |
commit | c4565759e4294540f54a81e4d91ddea7a769d3d4 (patch) | |
tree | d326dca32fb327b81ef67fae565b88f386431792 /wgpu/src/shader/gradient.wgsl | |
parent | bb8d46a3fdf925b4b2fa9e7db76e48caf020b212 (diff) | |
download | iced-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.wgsl | 88 |
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; +} |