diff --git a/packages/wolf_3d_renderer/shaders/wolf_world.frag b/packages/wolf_3d_renderer/shaders/wolf_world.frag index 8f64370..f40c556 100644 --- a/packages/wolf_3d_renderer/shaders/wolf_world.frag +++ b/packages/wolf_3d_renderer/shaders/wolf_world.frag @@ -32,16 +32,32 @@ void main() { // Fill outside warped bounds with a darker consumer-TV charcoal bezel. if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { vec2 clampedUv = clamp(uv, 0.0, 1.0); - vec2 edgeDelta = abs(uv - clampedUv); - float overflow = max(edgeDelta.x, edgeDelta.y); + vec2 edgeDelta = uv - clampedUv; + float overflow = max(abs(edgeDelta.x), abs(edgeDelta.y)); - float verticalShade = 0.90 + 0.08 * (1.0 - (FlutterFragCoord().y / uResolution.y)); - float depthShade = 1.0 - smoothstep(0.0, 0.06, overflow) * 0.24; - float grain = sin(FlutterFragCoord().x * 0.21 + FlutterFragCoord().y * 0.11) * 0.007; - float moldedHighlight = smoothstep(0.08, 0.0, overflow) * 0.045; + // Approximate concave bezel depth by measuring how far this fragment is + // from the emissive screen boundary in aspect-corrected UV space. + vec2 aspectScale = vec2(uResolution.x / max(uResolution.y, 1.0), 1.0); + float bezelDistance = length(edgeDelta * aspectScale); + + // Corners receive less direct bleed because the nearest lit area is + // diagonally offset, so attenuate glow toward corner regions. + vec2 clampedCentered = clampedUv * 2.0 - 1.0; + float cornerFactor = smoothstep(0.60, 1.15, length(clampedCentered)); + + float verticalShade = 0.88 + 0.07 * (1.0 - (FlutterFragCoord().y / uResolution.y)); + float depthShade = 1.0 - smoothstep(0.0, 0.058, overflow) * 0.34; + float grain = sin(FlutterFragCoord().x * 0.21 + FlutterFragCoord().y * 0.11) * 0.006; + float moldedHighlight = smoothstep(0.072, 0.0, overflow) * 0.028; + + // Deeper arcade-style profile: tighter glow and steeper rolloff to shadow. + float bezelGlow = exp(-bezelDistance * 82.0) * mix(1.0, 0.56, cornerFactor); + float innerLip = exp(-bezelDistance * 170.0) * 0.14; vec3 bezelColor = - vec3(0.26, 0.26, 0.25) * verticalShade * depthShade + + vec3(0.225, 0.225, 0.215) * verticalShade * depthShade + + vec3(0.062, 0.072, 0.062) * bezelGlow + + vec3(innerLip) + vec3(moldedHighlight) + vec3(grain); fragColor = vec4(bezelColor, 1.0);