From 94ae337e96ebe69ae6821d590a06f16ddbcdc6e5 Mon Sep 17 00:00:00 2001 From: Dejvino Date: Tue, 30 Dec 2025 21:52:17 +0000 Subject: [PATCH] Feature: waving projection screen --- party-stage/src/scene/projection-screen.js | 27 +++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/party-stage/src/scene/projection-screen.js b/party-stage/src/scene/projection-screen.js index 099a9f1..c4603cf 100644 --- a/party-stage/src/scene/projection-screen.js +++ b/party-stage/src/scene/projection-screen.js @@ -95,6 +95,7 @@ export class ProjectionScreen extends SceneFeature { super(); projectionScreenInstance = this; this.isVisualizerActive = false; + this.originalPositions = null; sceneFeatureManager.register(this); } @@ -125,9 +126,11 @@ export class ProjectionScreen extends SceneFeature { // 16:9 Aspect Ratio, large size const width = 10; const height = width * (9 / 16); - const geometry = new THREE.PlaneGeometry(width, height); + const geometry = new THREE.PlaneGeometry(width, height, 32, 32); // Initial black material + this.originalPositions = geometry.attributes.position.clone(); + const material = new THREE.MeshBasicMaterial({ color: 0x000000 }); this.mesh = new THREE.Mesh(geometry, material); @@ -151,6 +154,28 @@ export class ProjectionScreen extends SceneFeature { update(deltaTime) { updateScreenEffect(); + // Wobble Logic + if (this.mesh && this.originalPositions) { + const time = state.clock.getElapsedTime(); + const waveSpeed = 0.5; + const waveFrequency = 1.2; + const waveAmplitude = 0.3; + // same as stage-curtain ^^^ + + const positions = this.mesh.geometry.attributes.position; + + for (let i = 0; i < positions.count; i++) { + const originalX = this.originalPositions.getX(i); + const originalZ = this.originalPositions.getZ(i); + + const zOffset = Math.sin(originalX * waveFrequency + time * waveSpeed) * waveAmplitude; + + positions.setZ(i, originalZ + zOffset); + } + positions.needsUpdate = true; + this.mesh.geometry.computeVertexNormals(); + } + if (this.isVisualizerActive && state.tvScreen.material.uniforms) { state.tvScreen.material.uniforms.u_time.value = state.clock.getElapsedTime(); const beat = (state.music && state.music.beatIntensity) ? state.music.beatIntensity : 0.0;