From 10d0b257f929296b1991a440f62c87487c0076dc Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 7 Sep 2023 07:24:32 +0200 Subject: Use Oklab color interpolation only with `color::GAMMA_CORRECTION` --- wgpu/src/shader/quad/solid.wgsl | 99 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 wgpu/src/shader/quad/solid.wgsl (limited to 'wgpu/src/shader/quad/solid.wgsl') diff --git a/wgpu/src/shader/quad/solid.wgsl b/wgpu/src/shader/quad/solid.wgsl new file mode 100644 index 00000000..ebd6d877 --- /dev/null +++ b/wgpu/src/shader/quad/solid.wgsl @@ -0,0 +1,99 @@ +struct SolidVertexInput { + @location(0) v_pos: vec2, + @location(1) color: vec4, + @location(2) pos: vec2, + @location(3) scale: vec2, + @location(4) border_color: vec4, + @location(5) border_radius: vec4, + @location(6) border_width: f32, +} + +struct SolidVertexOutput { + @builtin(position) position: vec4, + @location(0) color: vec4, + @location(1) border_color: vec4, + @location(2) pos: vec2, + @location(3) scale: vec2, + @location(4) border_radius: vec4, + @location(5) border_width: f32, +} + +@vertex +fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput { + var out: SolidVertexOutput; + + var pos: vec2 = input.pos * globals.scale; + var scale: vec2 = input.scale * globals.scale; + + 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( + vec4(scale.x + 1.0, 0.0, 0.0, 0.0), + vec4(0.0, scale.y + 1.0, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(pos - vec2(0.5, 0.5), 0.0, 1.0) + ); + + out.position = globals.transform * transform * vec4(input.v_pos, 0.0, 1.0); + out.color = input.color; + out.border_color = input.border_color; + out.pos = pos; + out.scale = scale; + out.border_radius = border_radius * globals.scale; + out.border_width = input.border_width * globals.scale; + + return out; +} + +@fragment +fn solid_fs_main( + input: SolidVertexOutput +) -> @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(border_radius - input.border_width, 0.0); + + var internal_distance: f32 = distance_alg( + 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 + ); + + var border_mix: f32 = smoothstep( + max(internal_border - 0.5, 0.0), + internal_border + 0.5, + internal_distance + ); + + mixed_color = mix(input.color, input.border_color, vec4(border_mix, border_mix, border_mix, border_mix)); + } + + var dist: f32 = distance_alg( + vec2(input.position.x, input.position.y), + input.pos, + input.scale, + border_radius + ); + + var radius_alpha: f32 = 1.0 - smoothstep( + 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