shader: collapse palm chip background pass and refine dot rendering
This commit is contained in:
@@ -582,48 +582,9 @@ fn vs_hand_palm_chip(vertex: DotVertexInput, instance: DotInstanceInput) -> Hand
|
|||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_hand_palm_chip(in: HandPalmChipVertexOutput) -> @location(0) vec4f {
|
fn fs_hand_palm_chip(in: HandPalmChipVertexOutput) -> @location(0) vec4f {
|
||||||
// Inactive palm matrix: only independent dots, with no filled patch underneath.
|
// The live palm-dot pass draws every chip cell, including the idle dots.
|
||||||
let panel = rounded_rect_alpha(in.local, 0.16, 0.050);
|
// Keeping this background pass transparent prevents a second offset dot grid.
|
||||||
let inner = rounded_rect_alpha(in.local * vec2f(1.03, 1.03), 0.13, 0.062);
|
return output_color(vec3f(0.0, 0.0, 0.0), 0.0);
|
||||||
|
|
||||||
let uv = clamp(in.local * 0.5 + vec2f(0.5, 0.5), vec2f(0.0, 0.0), vec2f(1.0, 1.0));
|
|
||||||
let patch_mask = smoothstep(0.0, 0.36, inner) * panel;
|
|
||||||
|
|
||||||
let grid = max(in.grid * 1.42, vec2f(1.0, 1.0));
|
|
||||||
let cell_uv = fract(uv * grid) - vec2f(0.5, 0.5);
|
|
||||||
let dot_dist = length(cell_uv);
|
|
||||||
let dot_aa = max(fwidth(dot_dist) * 1.5, 0.008);
|
|
||||||
let dots = 1.0 - smoothstep(0.135 - dot_aa, 0.135 + dot_aa, dot_dist);
|
|
||||||
let dot_glow = 1.0 - smoothstep(0.14, 0.28, dot_dist);
|
|
||||||
let visible_dots = dots * patch_mask;
|
|
||||||
let visible_glow = dot_glow * patch_mask;
|
|
||||||
|
|
||||||
// Synthetic low-level pressure only changes nearby dots; it does not fill the patch.
|
|
||||||
let horizontal = step(in.grid.y, in.grid.x);
|
|
||||||
let pressure_center = mix(vec2f(0.0, 0.0), vec2f(-0.10, 0.0), horizontal);
|
|
||||||
let pressure_scale = mix(vec2f(1.00, 0.82), vec2f(0.82, 1.00), horizontal);
|
|
||||||
let pressure_dist = length((in.local - pressure_center) * pressure_scale);
|
|
||||||
let pressure = (1.0 - smoothstep(0.06, 0.32, pressure_dist)) * patch_mask;
|
|
||||||
let pressure_hot = (1.0 - smoothstep(0.02, 0.14, pressure_dist)) * patch_mask;
|
|
||||||
|
|
||||||
let idle_dot_color = vec3f(0.18, 0.32, 0.38);
|
|
||||||
let active_dot_color = idle_dot_color;
|
|
||||||
let hot_dot_color = idle_dot_color;
|
|
||||||
|
|
||||||
let dot_color = mix(idle_dot_color, active_dot_color, pressure);
|
|
||||||
|
|
||||||
let color = dot_color * visible_dots * 1.25
|
|
||||||
+ hot_dot_color * visible_dots * pressure_hot * 0.85
|
|
||||||
+ active_dot_color * visible_glow * pressure * 0.14;
|
|
||||||
|
|
||||||
let alpha = clamp(
|
|
||||||
visible_dots * (0.46 + pressure * 0.38)
|
|
||||||
+ visible_dots * pressure_hot * 0.22
|
|
||||||
+ visible_glow * pressure * 0.045,
|
|
||||||
0.0,
|
|
||||||
0.96,
|
|
||||||
);
|
|
||||||
return output_color(color, alpha);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
@@ -631,9 +592,8 @@ fn vs_hand_palm_dot(vertex: DotVertexInput, instance: DotInstanceInput) -> DotVe
|
|||||||
let intensity = saturate(instance.style.x);
|
let intensity = saturate(instance.style.x);
|
||||||
let shaped = smoothstep(0.0, 1.0, intensity);
|
let shaped = smoothstep(0.0, 1.0, intensity);
|
||||||
|
|
||||||
// Palm chip pixels are deliberately smaller than fingertip beads so they read as a chip matrix.
|
|
||||||
let center = hand_image_uv_to_clip(instance.world_position.xy);
|
let center = hand_image_uv_to_clip(instance.world_position.xy);
|
||||||
let pixel_size = u.glyph.x * mix(0.16, 0.30, shaped);
|
let pixel_size = u.glyph.x * mix(0.22, 0.34, shaped);
|
||||||
let ndc_offset = vertex.local * vec2f(pixel_size / u.viewport.x, pixel_size / u.viewport.y) * 2.0;
|
let ndc_offset = vertex.local * vec2f(pixel_size / u.viewport.x, pixel_size / u.viewport.y) * 2.0;
|
||||||
|
|
||||||
var out: DotVertexOutput;
|
var out: DotVertexOutput;
|
||||||
@@ -646,17 +606,16 @@ fn vs_hand_palm_dot(vertex: DotVertexInput, instance: DotInstanceInput) -> DotVe
|
|||||||
@fragment
|
@fragment
|
||||||
fn fs_hand_palm_dot(in: DotVertexOutput) -> @location(0) vec4f {
|
fn fs_hand_palm_dot(in: DotVertexOutput) -> @location(0) vec4f {
|
||||||
let intensity = saturate(in.intensity);
|
let intensity = saturate(in.intensity);
|
||||||
let pixel = chip_pixel_alpha(in.local, 0.52, 0.070);
|
|
||||||
let glow = circle_alpha(in.local, 0.95, 0.22) * intensity * 0.36;
|
|
||||||
|
|
||||||
let cold = vec3f(0.070, 0.340, 0.360);
|
let core = circle_alpha(in.local, 0.48, 0.07);
|
||||||
|
let halo = circle_alpha(in.local, 0.74, 0.14) * (0.10 + intensity * 0.26);
|
||||||
|
|
||||||
|
let idle = vec3f(0.060, 0.250, 0.320);
|
||||||
let gradient = sample_range_color(intensity);
|
let gradient = sample_range_color(intensity);
|
||||||
let color = mix(cold, gradient, smoothstep(0.0, 0.20, intensity))
|
let color = mix(idle, gradient, smoothstep(0.0, 0.18, intensity))
|
||||||
* (0.58 + intensity * 1.04)
|
* mix(0.78, 1.18, intensity);
|
||||||
+ gradient * glow * 0.72;
|
|
||||||
|
|
||||||
let alpha = max(pixel * (0.20 + intensity * 0.76), glow);
|
return output_color(color, max(core, halo));
|
||||||
return output_color(color, alpha);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
|
|||||||
Reference in New Issue
Block a user