diff --git a/RIFI/script.js b/RIFI/script.js index b0c796a5ff1a7a7e79d84164eb38e7a7b46e89c7..38c6e99ec07cd72f6fe36994d9654564fa024ae2 100644 --- a/RIFI/script.js +++ b/RIFI/script.js @@ -14,9 +14,7 @@ var candle, candleHolder, flame; var backgroundMesh; var environmentMap; var compass; -// var waxGroup; -// var cubeCamera, cubeRenderTarget; - +var cubeCamera, cubeRenderTarget; var params = { flickerSpeed: 2.0, @@ -25,7 +23,7 @@ var params = { candleLightIntensity: 2.2, candleLightDistance: 400, ambientLightIntensity: 0.22, - fogEnabled: true, + fogEnabled: false, fogColor: 0x000000, fogNear: 100, fogFar: 1000, @@ -36,10 +34,43 @@ var params = { showFlower: true }; -import {Coordinates} from './lib/Coordinates.js'; -function fillScene() { + +function init() { + renderer = new THREE.WebGLRenderer({ antialias: true }); + renderer.setSize(846, 494); + renderer.setClearColor(0x000000, 1.0); + renderer.physicallyCorrectLights = true; + renderer.toneMapping = THREE.ACESFilmicToneMapping; + renderer.toneMappingExposure = 1.2; + + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; + + var container = document.getElementById('webGL'); + container.appendChild(renderer.domElement); + + camera = new THREE.PerspectiveCamera(35, 846 / 494, 1, 8000); + camera.position.set(0, 200, 600); + scene = new THREE.Scene(); + + cameraControls = new OrbitControls(camera, renderer.domElement); + cameraControls.target.set(0, 50, 0); + + + cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256, { + format: THREE.RGBFormat, + generateMipmaps: true, + minFilter: THREE.LinearMipmapLinearFilter + }); + cubeCamera = new THREE.CubeCamera(1, 1000, cubeRenderTarget); + scene.add(cubeCamera); +} + + +function fillScene() { + createGradientBackground(); var mainLight = new THREE.DirectionalLight(0xFFAA55, 0.5); @@ -56,34 +87,33 @@ function fillScene() { mainLight.shadow.bias = -0.0005; scene.add(mainLight); - - const cubeTextureLoader = new THREE.CubeTextureLoader(); var ambientLight = new THREE.AmbientLight(0x222222, params.ambientLightIntensity); scene.add(ambientLight); - const environmentMap = cubeTextureLoader.load([ - 'textures/envmap/px.png', - 'textures/envmap/nx.png', - 'textures/envmap/py.png', - 'textures/envmap/ny.png', - 'textures/envmap/pz.png', - 'textures/envmap/nz.png' - -]); -scene.environment = environmentMap; - - -createTable(); -loadSkull(); -createEnhancedCandle(); -loadFlower(); -loadCompass(); -loadInk(); -loadWalnut(); -addMeltedWaxOnTable(); -loadKey(); + const cubeTextureLoader = new THREE.CubeTextureLoader(); + environmentMap = cubeTextureLoader.load([ + 'textures/envmap/px.png', + 'textures/envmap/nx.png', + 'textures/envmap/py.png', + 'textures/envmap/ny.png', + 'textures/envmap/pz.png', + 'textures/envmap/nz.png' + ]); + scene.environment = environmentMap; + + + createTable(); + loadSkull(); + createEnhancedCandle(); + loadFlower(); + loadInk(); + loadWalnut(); + loadKey(); + setupFog(); + loadCompass() } + function createGradientBackground() { const bgGeometry = new THREE.PlaneGeometry(2000, 1000); @@ -111,9 +141,7 @@ function createGradientBackground() { function setupFog() { if (params.fogEnabled) { - scene.fog = new THREE.Fog(params.fogColor, params.fogNear, params.fogFar); - } else { scene.fog = null; } @@ -265,39 +293,53 @@ function loadCompass() { const textureLoader = new THREE.TextureLoader(); textureLoader.load('textures/compass.jpg', function(texture) { + + texture.encoding = THREE.sRGBEncoding; + texture.flipY = false; + texture.generateMipmaps = true; + texture.needsUpdate = true; + loader.load( - 'boussole1.obj', + 'boussole1.obj', function (compass) { compass.scale.set(30, 30, 30); - compass.position.set(70, -10, 85); + compass.position.set(90, -10, 85); compass.rotation.set(0, -Math.PI / 1.5, 0); - const compassMaterial = new THREE.MeshStandardMaterial({ - map: texture, // Appliquer la texture - roughness: 0.3, // Ajuster la rugosité pour un effet réaliste - metalness: 0.8, // Ajuster la métallité pour un effet réaliste - envMap: cubeRenderTarget.texture, // Appliquer la carte d'environnement dynamique - envMapIntensity: 1.0, // Intensité de l'environnement pour un effet réaliste - transparent: false, // Désactiver la transparence - opacity: 1.0 // Opacité complète - + + const compassMaterial = new THREE.MeshPhysicalMaterial({ + map: texture, + + emissiveIntensity: 0.3, + metalness: 1.0, + roughness: 0.2, + reflectivity: 1.0, + clearcoat: 0.8, + clearcoatRoughness: 0.2, + envMapIntensity: 1.5, + side: THREE.DoubleSide }); compass.traverse(function(child) { if (child.isMesh) { child.material = compassMaterial; - child.castShadow = true; // Permettre à l'objet de projeter des ombres - child.receiveShadow = true; // Permettre à l'objet de recevoir des ombres + child.castShadow = true; + child.receiveShadow = true; } }); scene.add(compass); console.log("Objet chargé :", compass); - // Ajouter une lumière spécifique pour éclairer la boussole - const compassLight = new THREE.PointLight(0xffffff, 1, 100); - compassLight.position.set(70, 20, 85); // Positionner la lumière au-dessus de la boussole + const compassLight = new THREE.PointLight(0xffffcc, 2.0, 150); + compassLight.position.set(70, 20, 85); + compassLight.castShadow = true; scene.add(compassLight); + + const compassGlow = new THREE.PointLight(0xffffaa, 1.0, 80); + compassGlow.position.set(70, -5, 85); + scene.add(compassGlow); + }, function (xhr) { console.log((xhr.loaded / xhr.total * 100) + '% chargé'); @@ -319,7 +361,7 @@ function loadWalnut() { function (walnut) { walnut.scale.set(1, 1, 1); - walnut.position.set(120, 6, 120); + walnut.position.set(160, 6, 120); walnut.rotation.set(0, 0, 0); const walnutMaterial = new THREE.MeshPhongMaterial({ @@ -350,9 +392,6 @@ function loadWalnut() { ); } - - - function loadInk() { const loader = new OBJLoader(); @@ -394,7 +433,6 @@ function loadInk() { } - function loadKey() { const loader = new OBJLoader(); @@ -435,6 +473,9 @@ function loadKey() { } + + + function loadFlower() { var loader = new OBJLoader(); loader.load( @@ -756,7 +797,7 @@ function createEnhancedCandle() { candleGroup.position.set(-150, 10, 20); candleGroup.scale.set(2, 2, 2); - // Permettre au groupe entier de projeter et recevoir des ombres + candleGroup.traverse(function(object) { if (object.isMesh) { object.castShadow = true; @@ -793,15 +834,13 @@ function animateFlame() { const innerLight = flame.userData.innerLight; const ambientLight = flame.userData.ambientLight; const particles = flame.userData.particles; - - // Mouvement de balancement simplifié + const swayX = Math.sin(time * swaySpeed) * swayAmount; const swayZ = Math.cos(time * swaySpeed * 0.8) * swayAmount; - // Variation de hauteur simplifiée const heightVariation = 0.98 + flickerIntensity * Math.sin(time * flickerSpeed); - // Appliquer les transformations à la flamme principale + flame.scale.set(1, heightVariation, 1); flame.rotation.x = swayX * 0.1; flame.rotation.z = swayZ * 0.1; @@ -958,108 +997,30 @@ function updateBackgroundWithCandleLight(time, flickerFactor, swayX, swayZ) { } -// function addMeltedWaxOnTable() { -// waxGroup = new THREE.Group(); -// const waxMaterial = new THREE.MeshPhysicalMaterial({ -// color: 0xf3e5ab, // Couleur de la cire -// roughness: 0.8, -// metalness: 0.05, -// transparent: true, -// opacity: 0.95, -// thickness: 1.5, -// transmission: 0.5 -// }); - -// const waxCount = 8; // Nombre de gouttes de cire - -// for (let i = 0; i < waxCount; i++) { -// let waxDroplets = new THREE.Group(); - -// // Position de base près de la bougie -// let baseX = -150 + (Math.random() - 0.5) * 20; // Près de la position X de la bougie -// let baseZ = 1 + (Math.random() - 0.5) * 20; // Près de la position Z de la bougie - -// let dropCount = Math.floor(Math.random() * 5) + 3; // Nombre de gouttes par groupe - -// for (let j = 0; j < dropCount; j++) { -// let waxRadius = Math.random() * 2 + 1; // Rayon aléatoire pour les gouttes -// let waxGeometry = new THREE.SphereGeometry(waxRadius, 16, 16); -// let wax = new THREE.Mesh(waxGeometry, waxMaterial); - -// // Position initiale près de la bougie -// wax.position.set( -// baseX + Math.random() * 5 - 2.5, -// 50 - j * 5, // Position Y pour simuler la chute -// baseZ + Math.random() * 5 - 2.5 -// ); - -// // Étirer les gouttes pour un effet de dégoulinement -// wax.scale.y = Math.random() * 2 + 1; - -// // Activer les ombres -// wax.castShadow = true; -// wax.receiveShadow = true; - -// waxDroplets.add(wax); -// } - -// waxGroup.add(waxDroplets); -// } - -// scene.add(waxGroup); -// animateWax(waxGroup); // Animer les gouttes de cire -// } - -// function animateWax(waxGroup) { -// waxGroup.children.forEach((waxDroplets) => { -// // Position finale sur la table -// const targetY = -40; - -// // Durée aléatoire pour chaque goutte -// const duration = Math.random() * 2 + 1; - -// // Animation GSAP pour faire tomber les gouttes -// gsap.to(waxDroplets.position, { -// y: targetY, -// duration: duration, -// ease: "power2.out", -// onComplete: () => { -// // Effet de rebond lorsque la goutte touche la table -// gsap.to(waxDroplets.position, { -// y: targetY + 5, // Petit rebond -// duration: 0.2, -// yoyo: true, -// repeat: 1, -// ease: "power2.out" -// }); -// } -// }); -// }); -// } - function animate() { requestAnimationFrame(animate); var delta = clock.getDelta(); cameraControls.update(delta); + + if (compass) { + cubeCamera.position.copy(compass.position); + cubeCamera.update(renderer, scene); + } - animateFlame(); - // animateWax(waxGroup); - + renderer.render(scene, camera); } function initGUI() { var gui = new dat.GUI(); - // Dossier pour les paramètres de la flamme var flameFolder = gui.addFolder('Flamme'); flameFolder.add(params, 'flickerSpeed', 0.5, 5.0).name('Vitesse vacillement'); flameFolder.add(params, 'flickerIntensity', 0.01, 0.3).name('Intensité vacillement'); flameFolder.open(); - // Dossier pour les paramètres d'éclairage var lightFolder = gui.addFolder('Éclairage'); lightFolder.add(params, 'candleLightIntensity', 0.5, 5.0).name('Intensité bougie').onChange(function(value) { scene.traverse(function(object) { @@ -1084,7 +1045,7 @@ function initGUI() { }); lightFolder.open(); - // Dossier pour les éléments de la scène + var sceneFolder = gui.addFolder('Éléments de scène'); sceneFolder.add(params, 'showSkull').name('Afficher crâne').onChange(function(value) { if (skull) skull.visible = value; @@ -1101,12 +1062,11 @@ function initGUI() { var fogFolder = gui.addFolder('Brouillard'); fogFolder.add(params, 'fogEnabled').name('Activer brouillard').onChange(setupFog); - // Si vous utilisez THREE.Fog (linéaire) + fogFolder.add(params, 'fogNear', 1, 500).name('Distance proche').onChange(setupFog); fogFolder.add(params, 'fogFar', 500, 2000).name('Distance lointaine').onChange(setupFog); - // Si vous utilisez THREE.FogExp2 (exponentiel) - // fogFolder.add(params, 'fogDensity', 0.001, 0.05).name('Densité').onChange(setupFog); + fogFolder.addColor(params, 'fogColor').name('Couleur').onChange(function(value) { if (scene.fog) { @@ -1118,28 +1078,6 @@ function initGUI() { fogFolder.open(); } - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setSize(846, 494); - renderer.setClearColor(0x000000, 1.0); - renderer.physicallyCorrectLights = true; - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1.2; - - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - - var container = document.getElementById('webGL'); - container.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(35, 846 / 494, 1, 8000); - camera.position.set(0, 200, 600); - - cameraControls = new OrbitControls(camera, renderer.domElement); - cameraControls.target.set(0, 50, 0); -} - try { init(); fillScene();