Feature: anti-aliasing of projection screen

This commit is contained in:
Dejvino 2026-01-03 20:21:53 +00:00
parent e2ac3e90a1
commit 1586df7e51

View File

@ -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;