diff --git a/party-cathedral/src/core/animate.js b/party-cathedral/src/core/animate.js index 1e05ba1..d07ad2a 100644 --- a/party-cathedral/src/core/animate.js +++ b/party-cathedral/src/core/animate.js @@ -1,5 +1,6 @@ import * as THREE from 'three'; import { state } from '../state.js'; +import { onResizePostprocessing } from './postprocessing.js'; import { updateScreenEffect } from '../scene/magic-mirror.js' import sceneFeatureManager from '../scene/SceneFeatureManager.js'; @@ -53,7 +54,11 @@ export function animate() { updateScreenEffect(); // RENDER! - state.renderer.render(state.scene, state.camera); + if (state.composer) { + state.composer.render(); + } else { + state.renderer.render(state.scene, state.camera); + } } // --- Window Resize Handler --- @@ -61,4 +66,5 @@ export function onWindowResize() { state.camera.aspect = window.innerWidth / window.innerHeight; state.camera.updateProjectionMatrix(); state.renderer.setSize(window.innerWidth, window.innerHeight); + onResizePostprocessing(); } \ No newline at end of file diff --git a/party-cathedral/src/core/init.js b/party-cathedral/src/core/init.js index 805ece1..8d7d595 100644 --- a/party-cathedral/src/core/init.js +++ b/party-cathedral/src/core/init.js @@ -3,7 +3,7 @@ import { state, initState } from '../state.js'; import { EffectsManager } from '../effects/EffectsManager.js'; import { createSceneObjects } from '../scene/root.js'; import { animate, onWindowResize } from './animate.js'; -import { loadVideoFile, playNextVideo } from './video-player.js'; +import { initPostprocessing } from './postprocessing.js'; // --- Initialization --- export function init() { @@ -36,7 +36,9 @@ export function init() { // 9. Event Listeners window.addEventListener('resize', onWindowResize, false); - + + initPostprocessing(); + // Start the animation loop animate(); } diff --git a/party-cathedral/src/core/postprocessing.js b/party-cathedral/src/core/postprocessing.js new file mode 100644 index 0000000..7d1419c --- /dev/null +++ b/party-cathedral/src/core/postprocessing.js @@ -0,0 +1,34 @@ +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); + } +} \ No newline at end of file diff --git a/party-cathedral/src/main.js b/party-cathedral/src/main.js index eae66cb..a19d709 100644 --- a/party-cathedral/src/main.js +++ b/party-cathedral/src/main.js @@ -1,6 +1,5 @@ import * as THREE from 'three'; import { init } from './core/init.js'; -import { StainedGlass } from './scene/stained-glass-window.js'; // Start everything init(); \ No newline at end of file diff --git a/party-cathedral/src/scene/light-ball.js b/party-cathedral/src/scene/light-ball.js index fddc031..f4753f5 100644 --- a/party-cathedral/src/scene/light-ball.js +++ b/party-cathedral/src/scene/light-ball.js @@ -17,14 +17,14 @@ export class LightBall extends SceneFeature { init() { // --- Ball Properties --- - const ballRadius = 0.4; + const ballRadius = 0.2; const lightIntensity = 5.0; - const lightColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0x00ffff, 0xff00ff]; // Red, Green, Blue, Yellow + const lightColors = [0xff2222, 0x11ff11, 0x2222ff, 0xffff11, 0x00ffff, 0xff00ff]; // Red, Green, Blue, Yellow lightColors.forEach(color => { // --- Create the Ball --- const ballGeometry = new THREE.SphereGeometry(ballRadius, 32, 32); - const ballMaterial = new THREE.MeshBasicMaterial({ color: color, emissive: color, emissiveIntensity: 1.0 }); + const ballMaterial = new THREE.MeshBasicMaterial({ color: color, emissive: color, emissiveIntensity: 1.2 }); const ball = new THREE.Mesh(ballGeometry, ballMaterial); ball.castShadow = false; ball.receiveShadow = false; @@ -40,7 +40,7 @@ export class LightBall extends SceneFeature { ); light.position.copy(ball.position); - state.scene.add(ball); + //state.scene.add(ball); state.scene.add(light); this.lightBalls.push({ diff --git a/party-cathedral/src/scene/medieval-musicians.js b/party-cathedral/src/scene/medieval-musicians.js index 048475c..472973c 100644 --- a/party-cathedral/src/scene/medieval-musicians.js +++ b/party-cathedral/src/scene/medieval-musicians.js @@ -42,7 +42,7 @@ export class MedievalMusicians extends SceneFeature { // 3. Process the entire canvas to make background transparent const imageData = context.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; - const threshold = 20; // Adjust this for more/less color tolerance + const threshold = 25; // Adjust this for more/less color tolerance for (let i = 0; i < data.length; i += 4) { const r = data[i]; @@ -85,8 +85,8 @@ export class MedievalMusicians extends SceneFeature { // 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.6; // 0.0 = full lighting, 1.0 = full texture color - gl_FragColor.rgb = mix(gl_FragColor.rgb, texColor.rgb, vibrancy); + 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; ` ); }; diff --git a/party-cathedral/src/scene/root.js b/party-cathedral/src/scene/root.js index 426ebf9..3a429c8 100644 --- a/party-cathedral/src/scene/root.js +++ b/party-cathedral/src/scene/root.js @@ -15,6 +15,7 @@ import { Dancers } from './dancers.js'; import { MusicVisualizer } from './music-visualizer.js'; import { RoseWindowLight } from './rose-window-light.js'; import { RoseWindowLightshafts } from './rose-window-lightshafts.js'; +import { StainedGlass } from './stained-glass-window.js'; // Scene Features ^^^ // --- Scene Modeling Function --- diff --git a/party-cathedral/src/state.js b/party-cathedral/src/state.js index 4910de4..4846e6c 100644 --- a/party-cathedral/src/state.js +++ b/party-cathedral/src/state.js @@ -9,6 +9,8 @@ export function initState() { camera: null, renderer: null, clock: new THREE.Clock(), + composer: null, + ssaoPass: null, tvScreen: null, tvScreenPowered: false, videoTexture: null,