Compare commits
No commits in common. "363e56ff1882adc96163c46bcd4795e90da026d2" and "37f0d30fee6862c5a2f829230e514d993d9e0386" have entirely different histories.
363e56ff18
...
37f0d30fee
@ -1,9 +1,42 @@
|
|||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import { state } from '../state.js';
|
import { state } from '../state.js';
|
||||||
import { onResizePostprocessing } from './postprocessing.js';
|
|
||||||
import { updateScreenEffect } from '../scene/magic-mirror.js'
|
import { updateScreenEffect } from '../scene/magic-mirror.js'
|
||||||
import sceneFeatureManager from '../scene/SceneFeatureManager.js';
|
import sceneFeatureManager from '../scene/SceneFeatureManager.js';
|
||||||
|
|
||||||
|
function updateCamera() {
|
||||||
|
const globalTime = Date.now() * 0.0001;
|
||||||
|
const lookAtTime = Date.now() * 0.0002;
|
||||||
|
|
||||||
|
// Base Camera Position in front of the TV
|
||||||
|
const baseX = 0;
|
||||||
|
const baseY = 3.6;
|
||||||
|
const baseZ = -5.0;
|
||||||
|
const camAmplitude = new THREE.Vector3(1.0, 1.0, 6.0);
|
||||||
|
|
||||||
|
// Base LookAt target (Center of the screen)
|
||||||
|
const baseTargetX = 0;
|
||||||
|
const baseTargetY = 1.6;
|
||||||
|
const baseTargetZ = -30.0;
|
||||||
|
const lookAmplitude = 8.0;
|
||||||
|
|
||||||
|
// Camera Position Offsets (Drift)
|
||||||
|
const camOffsetX = Math.sin(globalTime * 3.1) * camAmplitude.x;
|
||||||
|
const camOffsetY = Math.cos(globalTime * 2.5) * camAmplitude.y;
|
||||||
|
const camOffsetZ = Math.cos(globalTime * 3.2) * camAmplitude.z;
|
||||||
|
|
||||||
|
state.camera.position.x = baseX + camOffsetX;
|
||||||
|
state.camera.position.y = baseY + camOffsetY;
|
||||||
|
state.camera.position.z = baseZ + camOffsetZ;
|
||||||
|
|
||||||
|
// LookAt Target Offsets (Subtle Gaze Shift)
|
||||||
|
const lookOffsetX = Math.sin(lookAtTime * 1.5) * lookAmplitude;
|
||||||
|
const lookOffsetZ = Math.cos(lookAtTime * 2.5) * lookAmplitude;
|
||||||
|
const lookOffsetY = Math.cos(lookAtTime * 1.2) * lookAmplitude * 0.5;
|
||||||
|
|
||||||
|
// Apply lookAt to the subtly shifted target
|
||||||
|
state.camera.lookAt(baseTargetX + lookOffsetX, baseTargetY + lookOffsetY, baseTargetZ + lookOffsetZ);
|
||||||
|
}
|
||||||
|
|
||||||
function updateScreenLight() {
|
function updateScreenLight() {
|
||||||
if (state.isVideoLoaded && state.screenLight.intensity > 0) {
|
if (state.isVideoLoaded && state.screenLight.intensity > 0) {
|
||||||
const pulseTarget = state.originalScreenIntensity + (Math.random() - 0.5) * state.screenIntensityPulse;
|
const pulseTarget = state.originalScreenIntensity + (Math.random() - 0.5) * state.screenIntensityPulse;
|
||||||
@ -48,17 +81,14 @@ export function animate() {
|
|||||||
|
|
||||||
sceneFeatureManager.update(deltaTime);
|
sceneFeatureManager.update(deltaTime);
|
||||||
state.effectsManager.update();
|
state.effectsManager.update();
|
||||||
|
updateCamera();
|
||||||
updateScreenLight();
|
updateScreenLight();
|
||||||
updateVideo();
|
updateVideo();
|
||||||
updateShaderTime();
|
updateShaderTime();
|
||||||
updateScreenEffect();
|
updateScreenEffect();
|
||||||
|
|
||||||
// RENDER!
|
// RENDER!
|
||||||
if (state.composer) {
|
state.renderer.render(state.scene, state.camera);
|
||||||
state.composer.render();
|
|
||||||
} else {
|
|
||||||
state.renderer.render(state.scene, state.camera);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Window Resize Handler ---
|
// --- Window Resize Handler ---
|
||||||
@ -66,5 +96,4 @@ export function onWindowResize() {
|
|||||||
state.camera.aspect = window.innerWidth / window.innerHeight;
|
state.camera.aspect = window.innerWidth / window.innerHeight;
|
||||||
state.camera.updateProjectionMatrix();
|
state.camera.updateProjectionMatrix();
|
||||||
state.renderer.setSize(window.innerWidth, window.innerHeight);
|
state.renderer.setSize(window.innerWidth, window.innerHeight);
|
||||||
onResizePostprocessing();
|
|
||||||
}
|
}
|
||||||
@ -3,7 +3,7 @@ import { state, initState } from '../state.js';
|
|||||||
import { EffectsManager } from '../effects/EffectsManager.js';
|
import { EffectsManager } from '../effects/EffectsManager.js';
|
||||||
import { createSceneObjects } from '../scene/root.js';
|
import { createSceneObjects } from '../scene/root.js';
|
||||||
import { animate, onWindowResize } from './animate.js';
|
import { animate, onWindowResize } from './animate.js';
|
||||||
import { initPostprocessing } from './postprocessing.js';
|
import { loadVideoFile, playNextVideo } from './video-player.js';
|
||||||
|
|
||||||
// --- Initialization ---
|
// --- Initialization ---
|
||||||
export function init() {
|
export function init() {
|
||||||
@ -37,8 +37,6 @@ export function init() {
|
|||||||
// 9. Event Listeners
|
// 9. Event Listeners
|
||||||
window.addEventListener('resize', onWindowResize, false);
|
window.addEventListener('resize', onWindowResize, false);
|
||||||
|
|
||||||
initPostprocessing();
|
|
||||||
|
|
||||||
// Start the animation loop
|
// Start the animation loop
|
||||||
animate();
|
animate();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
import * as THREE from 'three';
|
|
||||||
import { state } from '../state.js';
|
|
||||||
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
||||||
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
|
|
||||||
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js';
|
|
||||||
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
|
|
||||||
|
|
||||||
export function initPostprocessing() {
|
|
||||||
const composer = new EffectComposer(state.renderer);
|
|
||||||
|
|
||||||
// 1. The first pass is always to render the scene itself.
|
|
||||||
const renderPass = new RenderPass(state.scene, state.camera);
|
|
||||||
composer.addPass(renderPass);
|
|
||||||
|
|
||||||
const resolution = new THREE.Vector2( window.innerWidth, window.innerHeight );
|
|
||||||
const bloomPass = new UnrealBloomPass( resolution, 0.9, 0.1, 0.6 );
|
|
||||||
composer.addPass( bloomPass );
|
|
||||||
|
|
||||||
// 3. Add an output pass to render the final result to the screen.
|
|
||||||
const outputPass = new OutputPass();
|
|
||||||
composer.addPass(outputPass);
|
|
||||||
|
|
||||||
// Store the composer and passes in the global state
|
|
||||||
state.composer = composer;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function onResizePostprocessing() {
|
|
||||||
if (state.composer) {
|
|
||||||
state.composer.setSize(window.innerWidth, window.innerHeight);
|
|
||||||
}
|
|
||||||
if (state.ssaoPass) {
|
|
||||||
state.ssaoPass.setSize(window.innerWidth, window.innerHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import { init } from './core/init.js';
|
import { init } from './core/init.js';
|
||||||
|
import { StainedGlass } from './scene/stained-glass-window.js';
|
||||||
|
|
||||||
// Start everything
|
// Start everything
|
||||||
init();
|
init();
|
||||||
@ -1,142 +0,0 @@
|
|||||||
import * as THREE from 'three';
|
|
||||||
import { state } from '../state.js';
|
|
||||||
import { SceneFeature } from './SceneFeature.js';
|
|
||||||
import sceneFeatureManager from './SceneFeatureManager.js';
|
|
||||||
|
|
||||||
const minSwitchInterval = 2;
|
|
||||||
const maxSwitchInterval = 10;
|
|
||||||
|
|
||||||
export class CameraManager extends SceneFeature {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.cameras = [];
|
|
||||||
this.activeCameraIndex = 0;
|
|
||||||
this.switchInterval = 10; // seconds
|
|
||||||
this.lastSwitchTime = 0;
|
|
||||||
sceneFeatureManager.register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
// The main camera from init.js is our first camera
|
|
||||||
const mainCamera = state.camera;
|
|
||||||
this.cameras.push({
|
|
||||||
camera: mainCamera,
|
|
||||||
type: 'dynamic',
|
|
||||||
name: 'MainDynamicCamera',
|
|
||||||
update: this.updateDynamicCamera, // Assign its update function
|
|
||||||
});
|
|
||||||
|
|
||||||
// --- Static Camera 1: Left Aisle View ---
|
|
||||||
const staticCam1 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
|
||||||
staticCam1.position.set(-5, 3, -13);
|
|
||||||
staticCam1.lookAt(0, 2, -18); // Look at the stage
|
|
||||||
this.cameras.push({
|
|
||||||
camera: staticCam1,
|
|
||||||
type: 'static',
|
|
||||||
name: 'LeftAisleCam'
|
|
||||||
});
|
|
||||||
|
|
||||||
// --- Static Camera 2: Right Aisle View ---
|
|
||||||
const staticCam2 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
|
||||||
staticCam2.position.set(5, 4, -12);
|
|
||||||
staticCam2.lookAt(0, 1.5, -18); // Look at the stage
|
|
||||||
this.cameras.push({
|
|
||||||
camera: staticCam2,
|
|
||||||
type: 'static',
|
|
||||||
name: 'RightAisleCam'
|
|
||||||
});
|
|
||||||
|
|
||||||
// --- Static Camera 3: Far-Back view ---
|
|
||||||
const staticCam3 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
|
||||||
staticCam3.position.set(0, 3, 12);
|
|
||||||
staticCam3.lookAt(0, 1.5, -20); // Look at the stage
|
|
||||||
this.cameras.push({
|
|
||||||
camera: staticCam3,
|
|
||||||
type: 'static',
|
|
||||||
name: 'BackCam'
|
|
||||||
});
|
|
||||||
|
|
||||||
// --- Static Camera 3: Back view ---
|
|
||||||
const staticCam4 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
|
||||||
staticCam4.position.set(0, 4, 0);
|
|
||||||
staticCam4.lookAt(0, 1.5, -20); // Look at the stage
|
|
||||||
this.cameras.push({
|
|
||||||
camera: staticCam4,
|
|
||||||
type: 'static',
|
|
||||||
name: 'BackCam'
|
|
||||||
});
|
|
||||||
|
|
||||||
// --- Add Debug Helpers ---
|
|
||||||
if (state.debugCamera) {
|
|
||||||
this.cameras.forEach(camData => {
|
|
||||||
const helper = new THREE.CameraHelper(camData.camera);
|
|
||||||
state.scene.add(helper);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lastSwitchTime = state.clock.getElapsedTime();
|
|
||||||
this.switchCamera(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the logic moved from animate.js
|
|
||||||
updateDynamicCamera() {
|
|
||||||
const globalTime = Date.now() * 0.0001;
|
|
||||||
const lookAtTime = Date.now() * 0.0002;
|
|
||||||
|
|
||||||
const baseX = 0, baseY = 3.6, baseZ = -5.0;
|
|
||||||
const camAmplitude = new THREE.Vector3(1.0, 1.0, 6.0);
|
|
||||||
|
|
||||||
const baseTargetX = 0, baseTargetY = 1.6, baseTargetZ = -30.0;
|
|
||||||
const lookAmplitude = 8.0;
|
|
||||||
|
|
||||||
const camOffsetX = Math.sin(globalTime * 3.1) * camAmplitude.x;
|
|
||||||
const camOffsetY = Math.cos(globalTime * 2.5) * camAmplitude.y;
|
|
||||||
const camOffsetZ = Math.cos(globalTime * 3.2) * camAmplitude.z;
|
|
||||||
|
|
||||||
state.camera.position.x = baseX + camOffsetX;
|
|
||||||
state.camera.position.y = baseY + camOffsetY;
|
|
||||||
state.camera.position.z = baseZ + camOffsetZ;
|
|
||||||
|
|
||||||
const lookOffsetX = Math.sin(lookAtTime * 1.5) * lookAmplitude;
|
|
||||||
const lookOffsetZ = Math.cos(lookAtTime * 2.5) * lookAmplitude;
|
|
||||||
const lookOffsetY = Math.cos(lookAtTime * 1.2) * lookAmplitude * 0.5;
|
|
||||||
|
|
||||||
state.camera.lookAt(baseTargetX + lookOffsetX, baseTargetY + lookOffsetY, baseTargetZ + lookOffsetZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
switchCamera(index) {
|
|
||||||
if (index >= this.cameras.length || index < 0) return;
|
|
||||||
|
|
||||||
this.activeCameraIndex = index;
|
|
||||||
const newCam = this.cameras[this.activeCameraIndex].camera;
|
|
||||||
|
|
||||||
// Copy properties from the new camera to the main state camera
|
|
||||||
state.camera.position.copy(newCam.position);
|
|
||||||
state.camera.rotation.copy(newCam.rotation);
|
|
||||||
state.camera.fov = newCam.fov;
|
|
||||||
state.camera.aspect = newCam.aspect;
|
|
||||||
state.camera.near = newCam.near;
|
|
||||||
state.camera.far = newCam.far;
|
|
||||||
state.camera.updateProjectionMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaTime) {
|
|
||||||
const time = state.clock.getElapsedTime();
|
|
||||||
|
|
||||||
// Handle camera switching
|
|
||||||
if (time > this.lastSwitchTime + this.switchInterval) {
|
|
||||||
const newIndex = Math.floor(Math.random() * this.cameras.length);
|
|
||||||
this.switchCamera(newIndex);
|
|
||||||
this.lastSwitchTime = time;
|
|
||||||
this.switchInterval = minSwitchInterval + Math.random() * (maxSwitchInterval - minSwitchInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the currently active camera if it has an update function
|
|
||||||
const activeCamData = this.cameras[this.activeCameraIndex];
|
|
||||||
if (activeCamData.update) {
|
|
||||||
activeCamData.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new CameraManager();
|
|
||||||
@ -2,7 +2,6 @@ import * as THREE from 'three';
|
|||||||
import { state } from '../state.js';
|
import { state } from '../state.js';
|
||||||
import { SceneFeature } from './SceneFeature.js';
|
import { SceneFeature } from './SceneFeature.js';
|
||||||
import sceneFeatureManager from './SceneFeatureManager.js';
|
import sceneFeatureManager from './SceneFeatureManager.js';
|
||||||
import { applyVibrancyToMaterial } from '../shaders/vibrant-billboard-shader.js';
|
|
||||||
const dancerTextureUrls = [
|
const dancerTextureUrls = [
|
||||||
'/textures/dancer1.png',
|
'/textures/dancer1.png',
|
||||||
];
|
];
|
||||||
@ -52,15 +51,13 @@ export class Dancers extends SceneFeature {
|
|||||||
// Configure texture for a 2x2 sprite sheet
|
// Configure texture for a 2x2 sprite sheet
|
||||||
processedTexture.repeat.set(0.5, 0.5);
|
processedTexture.repeat.set(0.5, 0.5);
|
||||||
|
|
||||||
const material = new THREE.MeshStandardMaterial({
|
return new THREE.MeshStandardMaterial({
|
||||||
map: processedTexture,
|
map: processedTexture,
|
||||||
side: THREE.DoubleSide,
|
side: THREE.DoubleSide,
|
||||||
alphaTest: 0.5,
|
alphaTest: 0.5,
|
||||||
roughness: 0.7,
|
roughness: 0.7,
|
||||||
metalness: 0.1,
|
metalness: 0.1,
|
||||||
});
|
});
|
||||||
applyVibrancyToMaterial(material, processedTexture);
|
|
||||||
return material;
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createDancers = () => {
|
const createDancers = () => {
|
||||||
@ -172,8 +169,7 @@ export class Dancers extends SceneFeature {
|
|||||||
mesh.position.y = dancerObj.baseY;
|
mesh.position.y = dancerObj.baseY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const musicTime = state.clock.getElapsedTime();
|
if (state.music && state.music.beatIntensity > 0.8 && Math.random() < 0.2) {
|
||||||
if (state.music && state.music.beatIntensity > 0.8 && Math.random() < 0.2 && musicTime > 10) {
|
|
||||||
dancerObj.isJumping = true;
|
dancerObj.isJumping = true;
|
||||||
dancerObj.jumpStartTime = time;
|
dancerObj.jumpStartTime = time;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,14 +17,14 @@ export class LightBall extends SceneFeature {
|
|||||||
|
|
||||||
init() {
|
init() {
|
||||||
// --- Ball Properties ---
|
// --- Ball Properties ---
|
||||||
const ballRadius = 0.2;
|
const ballRadius = 0.4;
|
||||||
const lightIntensity = 5.0;
|
const lightIntensity = 5.0;
|
||||||
const lightColors = [0xff2222, 0x11ff11, 0x2222ff, 0xffff11, 0x00ffff, 0xff00ff]; // Red, Green, Blue, Yellow
|
const lightColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0x00ffff, 0xff00ff]; // Red, Green, Blue, Yellow
|
||||||
|
|
||||||
lightColors.forEach(color => {
|
lightColors.forEach(color => {
|
||||||
// --- Create the Ball ---
|
// --- Create the Ball ---
|
||||||
const ballGeometry = new THREE.SphereGeometry(ballRadius, 32, 32);
|
const ballGeometry = new THREE.SphereGeometry(ballRadius, 32, 32);
|
||||||
const ballMaterial = new THREE.MeshBasicMaterial({ color: color, emissive: color, emissiveIntensity: 1.2 });
|
const ballMaterial = new THREE.MeshBasicMaterial({ color: color, emissive: color, emissiveIntensity: 1.0 });
|
||||||
const ball = new THREE.Mesh(ballGeometry, ballMaterial);
|
const ball = new THREE.Mesh(ballGeometry, ballMaterial);
|
||||||
ball.castShadow = false;
|
ball.castShadow = false;
|
||||||
ball.receiveShadow = false;
|
ball.receiveShadow = false;
|
||||||
@ -40,7 +40,7 @@ export class LightBall extends SceneFeature {
|
|||||||
);
|
);
|
||||||
light.position.copy(ball.position);
|
light.position.copy(ball.position);
|
||||||
|
|
||||||
//state.scene.add(ball);
|
state.scene.add(ball);
|
||||||
state.scene.add(light);
|
state.scene.add(light);
|
||||||
|
|
||||||
this.lightBalls.push({
|
this.lightBalls.push({
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import * as THREE from 'three';
|
|||||||
import { state } from '../state.js';
|
import { state } from '../state.js';
|
||||||
import { SceneFeature } from './SceneFeature.js';
|
import { SceneFeature } from './SceneFeature.js';
|
||||||
import sceneFeatureManager from './SceneFeatureManager.js';
|
import sceneFeatureManager from './SceneFeatureManager.js';
|
||||||
import { applyVibrancyToMaterial } from '../shaders/vibrant-billboard-shader.js';
|
|
||||||
const musicianTextureUrls = [
|
const musicianTextureUrls = [
|
||||||
'/textures/musician1.png',
|
'/textures/musician1.png',
|
||||||
'/textures/musician2.png',
|
'/textures/musician2.png',
|
||||||
@ -43,7 +42,7 @@ export class MedievalMusicians extends SceneFeature {
|
|||||||
// 3. Process the entire canvas to make background transparent
|
// 3. Process the entire canvas to make background transparent
|
||||||
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
const data = imageData.data;
|
const data = imageData.data;
|
||||||
const threshold = 25; // Adjust this for more/less color tolerance
|
const threshold = 20; // Adjust this for more/less color tolerance
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i += 4) {
|
for (let i = 0; i < data.length; i += 4) {
|
||||||
const r = data[i];
|
const r = data[i];
|
||||||
@ -65,16 +64,13 @@ export class MedievalMusicians extends SceneFeature {
|
|||||||
const materials = await Promise.all(musicianTextureUrls.map(async (url) => {
|
const materials = await Promise.all(musicianTextureUrls.map(async (url) => {
|
||||||
const texture = await state.loader.loadAsync(url);
|
const texture = await state.loader.loadAsync(url);
|
||||||
const processedTexture = processTexture(texture);
|
const processedTexture = processTexture(texture);
|
||||||
const material = new THREE.MeshStandardMaterial({
|
return new THREE.MeshStandardMaterial({
|
||||||
map: processedTexture,
|
map: processedTexture,
|
||||||
side: THREE.DoubleSide,
|
side: THREE.DoubleSide,
|
||||||
alphaTest: 0.5, // Treat pixels with alpha < 0.5 as fully transparent
|
alphaTest: 0.5, // Treat pixels with alpha < 0.5 as fully transparent
|
||||||
roughness: 0.7,
|
roughness: 0.7,
|
||||||
metalness: 0.1,
|
metalness: 0.1,
|
||||||
});
|
});
|
||||||
|
|
||||||
applyVibrancyToMaterial(material, processedTexture);
|
|
||||||
return material;
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createMusicians = () => {
|
const createMusicians = () => {
|
||||||
@ -243,8 +239,7 @@ export class MedievalMusicians extends SceneFeature {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let currentJumpChance = jumpChance * deltaTime; // Base chance over time
|
let currentJumpChance = jumpChance * deltaTime; // Base chance over time
|
||||||
const musicTime = state.clock.getElapsedTime();
|
if (state.music && state.music.beatIntensity > 0.8) {
|
||||||
if (state.music && state.music.beatIntensity > 0.8 && musicTime > 15) {
|
|
||||||
currentJumpChance = 0.1; // High, fixed chance on the beat
|
currentJumpChance = 0.1; // High, fixed chance on the beat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@ export class PartyGuests extends SceneFeature {
|
|||||||
const pos = new THREE.Vector3(
|
const pos = new THREE.Vector3(
|
||||||
(Math.random() - 0.5) * 10,
|
(Math.random() - 0.5) * 10,
|
||||||
guestHeight / 2,
|
guestHeight / 2,
|
||||||
(Math.random() * 20) - 2 // Position them in the main hall
|
(Math.random() * 20) - 6 // Position them in the main hall
|
||||||
);
|
);
|
||||||
guest.position.copy(pos);
|
guest.position.copy(pos);
|
||||||
state.scene.add(guest);
|
state.scene.add(guest);
|
||||||
@ -99,7 +99,7 @@ export class PartyGuests extends SceneFeature {
|
|||||||
|
|
||||||
const time = state.clock.getElapsedTime();
|
const time = state.clock.getElapsedTime();
|
||||||
const moveSpeed = 1.0; // Move slower
|
const moveSpeed = 1.0; // Move slower
|
||||||
const movementArea = { x: 10, z: 30, y: 0, centerZ: 2 };
|
const movementArea = { x: 10, z: 30, y: 0, centerZ: 5 };
|
||||||
const jumpChance = 0.05; // Jump way more
|
const jumpChance = 0.05; // Jump way more
|
||||||
const jumpDuration = 0.5;
|
const jumpDuration = 0.5;
|
||||||
const jumpHeight = 0.1;
|
const jumpHeight = 0.1;
|
||||||
|
|||||||
@ -59,18 +59,6 @@ export class Pews extends SceneFeature {
|
|||||||
rightSupport.position.set(pewLength / 2, supportHeight / 2, -supportDepth / 2 + 0.1);
|
rightSupport.position.set(pewLength / 2, supportHeight / 2, -supportDepth / 2 + 0.1);
|
||||||
pewGroup.add(leftSupport, rightSupport);
|
pewGroup.add(leftSupport, rightSupport);
|
||||||
|
|
||||||
// Add a simple "baked" shadow plane underneath
|
|
||||||
const shadowGeo = new THREE.PlaneGeometry(pewLength, supportDepth);
|
|
||||||
const shadowMaterial = new THREE.MeshBasicMaterial({
|
|
||||||
color: 0x000000,
|
|
||||||
transparent: true,
|
|
||||||
opacity: 0.3
|
|
||||||
});
|
|
||||||
const shadowMesh = new THREE.Mesh(shadowGeo, shadowMaterial);
|
|
||||||
shadowMesh.rotation.x = -Math.PI / 2;
|
|
||||||
shadowMesh.position.y = 0.01; // Place it just above the floor to prevent z-fighting
|
|
||||||
pewGroup.add(shadowMesh);
|
|
||||||
|
|
||||||
pewGroup.traverse(child => {
|
pewGroup.traverse(child => {
|
||||||
if (child.isMesh) {
|
if (child.isMesh) {
|
||||||
child.castShadow = true;
|
child.castShadow = true;
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { state } from '../state.js';
|
|||||||
import floorTextureUrl from '/textures/stone_floor.png';
|
import floorTextureUrl from '/textures/stone_floor.png';
|
||||||
import sceneFeatureManager from './SceneFeatureManager.js';
|
import sceneFeatureManager from './SceneFeatureManager.js';
|
||||||
// Scene Features registered here:
|
// Scene Features registered here:
|
||||||
import { CameraManager } from './camera-manager.js';
|
|
||||||
import { RoomWalls } from './room-walls.js';
|
import { RoomWalls } from './room-walls.js';
|
||||||
import { LightBall } from './light-ball.js';
|
import { LightBall } from './light-ball.js';
|
||||||
import { Pews } from './pews.js';
|
import { Pews } from './pews.js';
|
||||||
@ -15,7 +14,7 @@ import { Dancers } from './dancers.js';
|
|||||||
import { MusicVisualizer } from './music-visualizer.js';
|
import { MusicVisualizer } from './music-visualizer.js';
|
||||||
import { RoseWindowLight } from './rose-window-light.js';
|
import { RoseWindowLight } from './rose-window-light.js';
|
||||||
import { RoseWindowLightshafts } from './rose-window-lightshafts.js';
|
import { RoseWindowLightshafts } from './rose-window-lightshafts.js';
|
||||||
import { StainedGlass } from './stained-glass-window.js';
|
|
||||||
// Scene Features ^^^
|
// Scene Features ^^^
|
||||||
|
|
||||||
// --- Scene Modeling Function ---
|
// --- Scene Modeling Function ---
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
import * as THREE from 'three';
|
|
||||||
|
|
||||||
export function applyVibrancyToMaterial(material, texture) {
|
|
||||||
// Inject custom shader code to boost vibrancy
|
|
||||||
material.onBeforeCompile = (shader) => {
|
|
||||||
// Pass the texture map to the fragment shader
|
|
||||||
shader.uniforms.vibrancyMap = { value: texture };
|
|
||||||
|
|
||||||
shader.fragmentShader = 'uniform sampler2D vibrancyMap;\n' + shader.fragmentShader;
|
|
||||||
shader.fragmentShader = shader.fragmentShader.replace(
|
|
||||||
'#include <dithering_fragment>',
|
|
||||||
`
|
|
||||||
#include <dithering_fragment>
|
|
||||||
// Get the pure texture color
|
|
||||||
vec4 texColor = texture2D(vibrancyMap, vMapUv);
|
|
||||||
// Mix the final lit color with the pure texture color to keep it vibrant
|
|
||||||
float vibrancy = 0.3; // 0.0 = full lighting, 1.0 = full texture color
|
|
||||||
gl_FragColor.rgb = mix(gl_FragColor.rgb, texColor.rgb, vibrancy) + texColor.rgb * 0.2;
|
|
||||||
`
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -9,8 +9,6 @@ export function initState() {
|
|||||||
camera: null,
|
camera: null,
|
||||||
renderer: null,
|
renderer: null,
|
||||||
clock: new THREE.Clock(),
|
clock: new THREE.Clock(),
|
||||||
composer: null,
|
|
||||||
ssaoPass: null,
|
|
||||||
tvScreen: null,
|
tvScreen: null,
|
||||||
tvScreenPowered: false,
|
tvScreenPowered: false,
|
||||||
videoTexture: null,
|
videoTexture: null,
|
||||||
@ -38,8 +36,7 @@ export function initState() {
|
|||||||
screenIntensityPulse: 0.2,
|
screenIntensityPulse: 0.2,
|
||||||
roomSize: 5,
|
roomSize: 5,
|
||||||
roomHeight: 3,
|
roomHeight: 3,
|
||||||
debugLight: false, // Turn on light helpers
|
debugLight: false,
|
||||||
debugCamera: false, // Turn on camera helpers
|
|
||||||
|
|
||||||
// DOM Elements
|
// DOM Elements
|
||||||
container: document.body,
|
container: document.body,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user