Feature: pixelated projection screen
This commit is contained in:
parent
c98d4890eb
commit
eb8e74273d
@ -17,6 +17,7 @@ uniform sampler2D videoTexture;
|
||||
uniform float u_effect_type;
|
||||
uniform float u_effect_strength;
|
||||
uniform float u_time;
|
||||
uniform float u_opacity;
|
||||
varying vec2 vUv;
|
||||
|
||||
float random(vec2 st) {
|
||||
@ -24,23 +25,36 @@ float random(vec2 st) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUv;
|
||||
vec4 color = texture2D(videoTexture, uv);
|
||||
// LED Grid Setup
|
||||
float ledCountX = 128.0;
|
||||
float ledCountY = 72.0; // 16:9 Aspect Ratio
|
||||
|
||||
vec2 gridUV = vec2(vUv.x * ledCountX, vUv.y * ledCountY);
|
||||
vec2 cell = fract(gridUV);
|
||||
vec2 pixelatedUV = (floor(gridUV) + 0.5) / vec2(ledCountX, ledCountY);
|
||||
|
||||
vec4 color = texture2D(videoTexture, pixelatedUV);
|
||||
|
||||
// Effect 1: Static/Noise (Power On/Off)
|
||||
if (u_effect_type > 0.0) {
|
||||
float noise = random(uv + u_time);
|
||||
float noise = random(pixelatedUV + u_time);
|
||||
vec3 noiseColor = vec3(noise);
|
||||
color.rgb = mix(color.rgb, noiseColor, u_effect_strength);
|
||||
}
|
||||
|
||||
gl_FragColor = color;
|
||||
float dist = distance(cell, vec2(0.5));
|
||||
float mask = 1.0 - smoothstep(0.35, 0.45, dist);
|
||||
float brightness = max(color.r, max(color.g, color.b));
|
||||
float contentAlpha = smoothstep(0.05, 0.15, brightness);
|
||||
|
||||
gl_FragColor = vec4(color.rgb, contentAlpha * mask * u_opacity);
|
||||
}
|
||||
`;
|
||||
|
||||
const visualizerFragmentShader = `
|
||||
uniform float u_time;
|
||||
uniform float u_beat;
|
||||
uniform float u_opacity;
|
||||
varying vec2 vUv;
|
||||
|
||||
vec3 hsv2rgb(vec3 c) {
|
||||
@ -50,17 +64,27 @@ vec3 hsv2rgb(vec3 c) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUv;
|
||||
float dist = length(uv - 0.5);
|
||||
float ledCountX = 128.0;
|
||||
float ledCountY = 72.0;
|
||||
|
||||
vec2 gridUV = vec2(vUv.x * ledCountX, vUv.y * ledCountY);
|
||||
vec2 cell = fract(gridUV);
|
||||
vec2 uv = (floor(gridUV) + 0.5) / vec2(ledCountX, ledCountY);
|
||||
|
||||
float dist = distance(cell, vec2(0.5));
|
||||
float mask = 1.0 - smoothstep(0.35, 0.45, dist);
|
||||
|
||||
float d = length(uv - 0.5);
|
||||
float angle = atan(uv.y - 0.5, uv.x - 0.5);
|
||||
|
||||
float wave = sin(dist * 20.0 - u_time * 2.0);
|
||||
float wave = sin(d * 20.0 - u_time * 2.0);
|
||||
float beatWave = sin(angle * 5.0 + u_time) * u_beat;
|
||||
|
||||
float hue = fract(u_time * 0.1 + dist * 0.2);
|
||||
float hue = fract(u_time * 0.1 + d * 0.2);
|
||||
float val = 0.5 + 0.5 * sin(wave + beatWave);
|
||||
float contentAlpha = smoothstep(0.1, 0.3, val);
|
||||
|
||||
gl_FragColor = vec4(hsv2rgb(vec3(hue, 0.8, val)), 1.0);
|
||||
gl_FragColor = vec4(hsv2rgb(vec3(hue, 0.8, val)), contentAlpha * mask * u_opacity);
|
||||
}
|
||||
`;
|
||||
|
||||
@ -86,6 +110,7 @@ export class ProjectionScreen extends SceneFeature {
|
||||
onComplete: null
|
||||
};
|
||||
state.originalScreenIntensity = 2.0;
|
||||
state.screenOpacity = 1.0;
|
||||
|
||||
// Ensure video element exists
|
||||
if (!state.videoElement) {
|
||||
@ -161,11 +186,13 @@ export class ProjectionScreen extends SceneFeature {
|
||||
state.tvScreen.material = new THREE.ShaderMaterial({
|
||||
uniforms: {
|
||||
u_time: { value: 0.0 },
|
||||
u_beat: { value: 0.0 }
|
||||
u_beat: { value: 0.0 },
|
||||
u_opacity: { value: state.screenOpacity }
|
||||
},
|
||||
vertexShader: screenVertexShader,
|
||||
fragmentShader: visualizerFragmentShader,
|
||||
side: THREE.DoubleSide
|
||||
side: THREE.DoubleSide,
|
||||
transparent: true
|
||||
});
|
||||
state.screenLight.intensity = state.originalScreenIntensity;
|
||||
}
|
||||
@ -194,10 +221,12 @@ export function turnTvScreenOn() {
|
||||
u_effect_type: { value: 0.0 },
|
||||
u_effect_strength: { value: 0.0 },
|
||||
u_time: { value: 0.0 },
|
||||
u_opacity: { value: state.screenOpacity !== undefined ? state.screenOpacity : 0.7 }
|
||||
},
|
||||
vertexShader: screenVertexShader,
|
||||
fragmentShader: screenFragmentShader,
|
||||
side: THREE.DoubleSide
|
||||
side: THREE.DoubleSide,
|
||||
transparent: true
|
||||
});
|
||||
|
||||
state.tvScreen.material.needsUpdate = true;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user