From 1586df7e51af3fe1953df78886e4d53dcd7bd498 Mon Sep 17 00:00:00 2001 From: Dejvino Date: Sat, 3 Jan 2026 20:21:53 +0000 Subject: [PATCH] Feature: anti-aliasing of projection screen --- party-stage/src/scene/projection-screen.js | 31 +++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/party-stage/src/scene/projection-screen.js b/party-stage/src/scene/projection-screen.js index 07cd687..2839e6e 100644 --- a/party-stage/src/scene/projection-screen.js +++ b/party-stage/src/scene/projection-screen.js @@ -33,10 +33,17 @@ void main() { float ledCountY = ${ledCountY}.0; vec2 gridUV = vec2(vUv.x * ledCountX, vUv.y * ledCountY); + + // Anti-aliasing: Calculate grid density + vec2 gridDeriv = fwidth(gridUV); + float gridDensity = max(gridDeriv.x, gridDeriv.y); + float blurFactor = smoothstep(0.3, 0.8, gridDensity); + vec2 cell = fract(gridUV); vec2 pixelatedUV = (floor(gridUV) + 0.5) / vec2(ledCountX, ledCountY); + vec2 sampleUV = mix(pixelatedUV, vUv, blurFactor); - vec4 color = texture2D(videoTexture, pixelatedUV); + vec4 color = texture2D(videoTexture, sampleUV); // Effect 1: Static/Noise (Power On/Off) if (u_effect_type > 0.0) { @@ -46,7 +53,10 @@ void main() { } float dist = distance(cell, vec2(0.5)); - float mask = 1.0 - smoothstep(0.35, 0.45, dist); + float edgeSoftness = clamp(gridDensity * 1.5, 0.0, 0.5); + float mask = 1.0 - smoothstep(0.35 - edgeSoftness, 0.45 + edgeSoftness, dist); + mask = mix(mask, 1.0, blurFactor); + float brightness = max(color.r, max(color.g, color.b)); float contentAlpha = smoothstep(0.05, 0.15, brightness); @@ -71,11 +81,18 @@ void main() { float ledCountY = 72.0; vec2 gridUV = vec2(vUv.x * ledCountX, vUv.y * ledCountY); + + vec2 gridDeriv = fwidth(gridUV); + float gridDensity = max(gridDeriv.x, gridDeriv.y); + float blurFactor = smoothstep(0.3, 0.8, gridDensity); + vec2 cell = fract(gridUV); - vec2 uv = (floor(gridUV) + 0.5) / vec2(ledCountX, ledCountY); + vec2 uv = mix((floor(gridUV) + 0.5) / vec2(ledCountX, ledCountY), vUv, blurFactor); float dist = distance(cell, vec2(0.5)); - float mask = 1.0 - smoothstep(0.35, 0.45, dist); + float edgeSoftness = clamp(gridDensity * 1.5, 0.0, 0.5); + float mask = 1.0 - smoothstep(0.35 - edgeSoftness, 0.45 + edgeSoftness, dist); + mask = mix(mask, 1.0, blurFactor); float d = length(uv - 0.5); float angle = atan(uv.y - 0.5, uv.x - 0.5); @@ -221,7 +238,8 @@ export class ProjectionScreen extends SceneFeature { vertexShader: screenVertexShader, fragmentShader: visualizerFragmentShader, side: THREE.DoubleSide, - transparent: true + transparent: true, + derivatives: true }); state.screenLight.intensity = state.originalScreenIntensity; } @@ -311,7 +329,8 @@ export function turnTvScreenOn() { vertexShader: screenVertexShader, fragmentShader: screenFragmentShader, side: THREE.DoubleSide, - transparent: true + transparent: true, + derivatives: true }); state.tvScreen.material.needsUpdate = true;