diff --git a/static/wgsl/shader.wgsl b/static/wgsl/shader.wgsl index c3e7745..7fe6ba8 100644 --- a/static/wgsl/shader.wgsl +++ b/static/wgsl/shader.wgsl @@ -582,48 +582,9 @@ fn vs_hand_palm_chip(vertex: DotVertexInput, instance: DotInstanceInput) -> Hand @fragment fn fs_hand_palm_chip(in: HandPalmChipVertexOutput) -> @location(0) vec4f { - // Inactive palm matrix: only independent dots, with no filled patch underneath. - let panel = rounded_rect_alpha(in.local, 0.16, 0.050); - let inner = rounded_rect_alpha(in.local * vec2f(1.03, 1.03), 0.13, 0.062); - - 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); + // The live palm-dot pass draws every chip cell, including the idle dots. + // Keeping this background pass transparent prevents a second offset dot grid. + return output_color(vec3f(0.0, 0.0, 0.0), 0.0); } @vertex @@ -631,9 +592,8 @@ fn vs_hand_palm_dot(vertex: DotVertexInput, instance: DotInstanceInput) -> DotVe let intensity = saturate(instance.style.x); 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 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; var out: DotVertexOutput; @@ -646,17 +606,16 @@ fn vs_hand_palm_dot(vertex: DotVertexInput, instance: DotInstanceInput) -> DotVe @fragment fn fs_hand_palm_dot(in: DotVertexOutput) -> @location(0) vec4f { 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 color = mix(cold, gradient, smoothstep(0.0, 0.20, intensity)) - * (0.58 + intensity * 1.04) - + gradient * glow * 0.72; + let color = mix(idle, gradient, smoothstep(0.0, 0.18, intensity)) + * mix(0.78, 1.18, intensity); - let alpha = max(pixel * (0.20 + intensity * 0.76), glow); - return output_color(color, alpha); + return output_color(color, max(core, halo)); } @vertex