diff --git a/packages/wolf_3d_renderer/shaders/wolf_world.frag b/packages/wolf_3d_renderer/shaders/wolf_world.frag index f40c556..00af15d 100644 --- a/packages/wolf_3d_renderer/shaders/wolf_world.frag +++ b/packages/wolf_3d_renderer/shaders/wolf_world.frag @@ -35,6 +35,18 @@ void main() { vec2 edgeDelta = uv - clampedUv; float overflow = max(abs(edgeDelta.x), abs(edgeDelta.y)); + // Sample near-edge scene colors and spread them onto the bezel. + vec2 inwardDir = normalize(-edgeDelta + vec2(1e-6)); + vec2 bleedStep = vec2(uTexel.x * 1.6, uTexel.y * 1.6); + vec2 bleedUv1 = clamp(clampedUv + inwardDir * bleedStep, 0.0, 1.0); + vec2 bleedUv2 = clamp(clampedUv + inwardDir * bleedStep * 2.6, 0.0, 1.0); + vec2 bleedUv3 = clamp(clampedUv + inwardDir * bleedStep * 4.2, 0.0, 1.0); + vec3 edgeBleedColor = + texture(uTexture, clampedUv).rgb * 0.52 + + texture(uTexture, bleedUv1).rgb * 0.28 + + texture(uTexture, bleedUv2).rgb * 0.14 + + texture(uTexture, bleedUv3).rgb * 0.06; + // 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); @@ -50,14 +62,15 @@ void main() { 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. + // Deeper arcade-style profile: tighter, scene-tinted bleed rolloff. float bezelGlow = exp(-bezelDistance * 82.0) * mix(1.0, 0.56, cornerFactor); - float innerLip = exp(-bezelDistance * 170.0) * 0.14; + float innerLip = exp(-bezelDistance * 170.0) * 0.10; + float bleedStrength = smoothstep(0.12, 0.0, overflow) * (0.78 - cornerFactor * 0.26); vec3 bezelColor = vec3(0.225, 0.225, 0.215) * verticalShade * depthShade + - vec3(0.062, 0.072, 0.062) * bezelGlow + - vec3(innerLip) + + edgeBleedColor * bezelGlow * bleedStrength * 1.12 + + edgeBleedColor * innerLip * 0.36 + vec3(moldedHighlight) + vec3(grain); fragColor = vec4(bezelColor, 1.0);