summaryrefslogtreecommitdiff
path: root/alligator.wgsl
diff options
context:
space:
mode:
Diffstat (limited to 'alligator.wgsl')
-rw-r--r--alligator.wgsl90
1 files changed, 90 insertions, 0 deletions
diff --git a/alligator.wgsl b/alligator.wgsl
new file mode 100644
index 0000000..319db89
--- /dev/null
+++ b/alligator.wgsl
@@ -0,0 +1,90 @@
+const SQRT_2: f32 = 0.70710678118654757;
+
+struct VertexInput {
+ @location(0) position: vec2<f32>,
+ @location(1) curve_uv: vec2<f32>,
+ @location(2) color_uv: vec2<f32>,
+ @location(3) color1: vec4<f32>,
+ @location(4) color2: vec4<f32>,
+ @location(5) color3: vec4<f32>,
+ @location(6) color4: vec4<f32>,
+ @location(7) normal_uv: vec2<f32>,
+ @location(8) normal1: vec3<f32>,
+ @location(9) normal2: vec3<f32>,
+ @location(10) normal3: vec3<f32>,
+ @location(11) normal4: vec3<f32>,
+}
+
+struct VertexOutput {
+ @builtin(position) position: vec4<f32>,
+ @location(0) curve_uv: vec2<f32>,
+ @location(1) color_uv: vec2<f32>,
+ @location(2) color1: vec4<f32>,
+ @location(3) color2: vec4<f32>,
+ @location(4) color3: vec4<f32>,
+ @location(5) color4: vec4<f32>,
+ @location(6) normal_uv: vec2<f32>,
+ @location(7) normal1: vec3<f32>,
+ @location(8) normal2: vec3<f32>,
+ @location(9) normal3: vec3<f32>,
+ @location(10) normal4: vec3<f32>,
+}
+
+fn square(in: f32) -> f32 {
+ return in * in;
+}
+
+fn cube(in: f32) -> f32 {
+ return in * in * in;
+}
+
+fn lerp(a: vec3<f32>, b: vec3<f32>, t: f32) -> vec3<f32> {
+ return (b - a) * t + a;
+}
+
+fn oklab_to_linear_srgb(color: vec3<f32>) -> vec3<f32> {
+ let l = cube(color.r + 0.3963377774 * color.g + 0.2158037573 * color.b);
+ let m = cube(color.r - 0.1055613458 * color.g - 0.0638541728 * color.b);
+ let s = cube(color.r - 0.0894841775 * color.g - 1.2914855480 * color.b);
+
+ return vec3<f32>(
+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
+ -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
+ -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s,
+ );
+}
+
+@vertex
+fn vs_main(vertex: VertexInput) -> VertexOutput {
+ var out: VertexOutput;
+ out.position = vec4(vertex.position, 1.0, 1.0);
+ out.curve_uv = vertex.curve_uv;
+ out.color_uv = vertex.color_uv;
+ out.color1 = vertex.color1;
+ out.color2 = vertex.color2;
+ out.color3 = vertex.color3;
+ out.color4 = vertex.color4;
+ out.normal_uv = vertex.normal_uv;
+ out.normal1 = vertex.normal1;
+ out.normal2 = vertex.normal2;
+ out.normal3 = vertex.normal3;
+ out.normal4 = vertex.normal4;
+ return out;
+}
+
+@fragment
+fn fs_main(vertex: VertexOutput) -> @location(0) vec4<f32> {
+ let radius = length(vertex.curve_uv);
+ let afwidth = length(vec2(dpdxFine(radius), dpdyFine(radius))) * SQRT_2;
+ let in_circle = 1.0 - smoothstep(1.0 - afwidth, 1.0 + afwidth, radius);
+
+ let inside_color = oklab_to_linear_srgb(lerp(vertex.color1.rgb, vertex.color2.rgb, length(vertex.color_uv)));
+ let outside_color = oklab_to_linear_srgb(lerp(vertex.color3.rgb, vertex.color4.rgb, 1.0 - length(vertex.color_uv)));
+ let color = lerp(outside_color, inside_color, in_circle);
+
+ let inside_normal = lerp(vertex.normal1, vertex.normal2, length(vertex.normal_uv));
+ let outside_normal = lerp(vertex.normal3, vertex.normal4, 1.0 - length(vertex.normal_uv));
+ let normal = lerp(outside_normal, inside_normal, in_circle);
+
+ return vec4<f32>(color, in_circle);
+} \ No newline at end of file