diff --git a/ALVARIZA-BILLAR_DESERT_KANY/checklistProjet.md b/ALVARIZA-BILLAR_DESERT_KANY/checklistProjet.md index 64caead21a080d9b38c64a46feb278894baae95c..079f3f40534bee49e93bcc360b122ea6c28b98e1 100644 --- a/ALVARIZA-BILLAR_DESERT_KANY/checklistProjet.md +++ b/ALVARIZA-BILLAR_DESERT_KANY/checklistProjet.md @@ -1,19 +1,19 @@ - [ ] Esthetisme -- [ ] Mise en page de la page web +- [x] Mise en page de la page web - [ ] Paragraphe(s) d'explications techniques -- [ ] Légèreté du dossier (<2Mo) +- [x] Légèreté du dossier (<2Mo) - [x] Géométrie - [x] Couleur - [ ] Transparence -- [ ] Eclairage +- [x] Eclairage - [ ] Ombres portées -- [ ] Position de la caméra -- [ ] Brouillard -- [ ] Effet miroir +- [x] Position de la caméra +- [x] Brouillard +- [x] Effet miroir - [x] Texture classique - [ ] Texture avec transparence -- [ ] Sprites -- [ ] Environment map +- [x] Sprites +- [x] Environment map - [x] Skybox - [x] Animations - [ ] normal maps diff --git a/ALVARIZA-BILLAR_DESERT_KANY/script.js b/ALVARIZA-BILLAR_DESERT_KANY/script.js index f5a6c9203c68d08a3ba5edfd17adb77999b6d4c9..b8b1e8be36cbee2513730e3d14a9fd09ec2e6a44 100644 --- a/ALVARIZA-BILLAR_DESERT_KANY/script.js +++ b/ALVARIZA-BILLAR_DESERT_KANY/script.js @@ -21,6 +21,9 @@ let cameraControls; const clock = new THREE.Clock(); let beton; let car; +let envMap; +let cubeCamera, renderTarget; + const stats = new Stats(); stats.showPanel(0); // 0: afficher le panneau des FPS @@ -39,11 +42,11 @@ function fillScene() { capsuleBeton(); dalleBeton(); poleAndFlag(); - house(); // TODO : à compléter + house(); pompe(); forest(); man(); - //scene.fog = new THREE.Fog(0x999999, 10000, 20000); // Couleur grise, densité du brouillard + scene.fog = new THREE.Fog(0x999999, 10000, 50000); // Couleur grise, densité du brouillard } @@ -51,13 +54,16 @@ function fillScene() { * Fonction qui gère les lumières */ function light() { - scene.add(new THREE.AmbientLight(0x222222)); - var light = new THREE.DirectionalLight(0xFFFFFF, 0.9); - light.position.set(200, 500, 500); - scene.add(light); - light = new THREE.DirectionalLight(0xFFFFFF, 10); - light.position.set(-200, -100, -400); - scene.add(light); + // Lumière forte pour accentuer les reflets métalliques + const metallicLight = new THREE.PointLight(0xffffff, 200, 5000); + metallicLight.position.set(-3000, 1000, 2000); + scene.add(metallicLight); + + // Une lumière directionnelle pour les reflets doux + const directionalLight = new THREE.DirectionalLight(0xffffff, 1); + directionalLight.position.set(500, 1000, -1000); + scene.add(directionalLight); + } /** @@ -72,7 +78,7 @@ function ground() { var solidGround = new THREE.Mesh( new THREE.PlaneGeometry(100000, 100000, 1000, 1000), - new THREE.MeshLambertMaterial({map: grassTexture}) + new THREE.MeshStandardMaterial({map: grassTexture}) ); solidGround.rotation.x = -Math.PI / 2; scene.add(solidGround); @@ -92,7 +98,7 @@ function road() { roadTexture.wrapT = THREE.RepeatWrapping; roadTexture.repeat.set(1, 10); - var roadMaterial = new THREE.MeshLambertMaterial({ // Matériau de la route pour éviter le clipping + var roadMaterial = new THREE.MeshStandardMaterial({ // Matériau de la route pour éviter le clipping map: roadTexture, polygonOffset: true, polygonOffsetFactor: -2, @@ -167,7 +173,7 @@ function capsuleBeton() { var capsuleGeometry = new THREE.ExtrudeGeometry(capsuleShape, extrudeSettings); // Géométrie de la capsule capsuleGeometry.center(); // Centrer la géométrie - var capsuleMaterial = new THREE.MeshLambertMaterial({map: betonTexture}); // Matériau de la capsule (béton) + var capsuleMaterial = new THREE.MeshStandardMaterial({map: betonTexture}); // Matériau de la capsule (béton) var capsuleMesh = new THREE.Mesh(capsuleGeometry, capsuleMaterial); // Création du mesh capsuleMesh.rotation.x = Math.PI / 2; capsuleMesh.rotation.z = 1.35; @@ -183,7 +189,7 @@ function dalleBeton() { // Récupérer la texture béton via la fonction dédiée var betonTexture = createBetonTexture(); - var betonMaterial = new THREE.MeshLambertMaterial({map: betonTexture}); + var betonMaterial = new THREE.MeshStandardMaterial({map: betonTexture}); beton = new THREE.Mesh( new THREE.BoxGeometry(5500, 350, 5500), @@ -246,7 +252,7 @@ function house() { const outerCubeDepth = 4000; const outerCubeMesh = new THREE.Mesh( new THREE.BoxGeometry(outerCubeWidth, outerCubeHeight, outerCubeDepth), - new THREE.MeshLambertMaterial({color: 0x888888}) + new THREE.MeshStandardMaterial({color: 0x888888}) ); outerCubeMesh.updateMatrix(); @@ -257,7 +263,7 @@ function house() { const houseRoof1Depth = outerCubeDepth + 250; const houseRoof1 = new THREE.Mesh( new THREE.BoxGeometry(houseRoof1Width, houseRoof1Height, houseRoof1Depth), - new THREE.MeshLambertMaterial({color: 0x888888}) + new THREE.MeshStandardMaterial({color: 0x888888}) ); @@ -267,7 +273,7 @@ function house() { const houseRoof2Depth = houseRoof1Depth + 250; const houseRoof2 = new THREE.Mesh( new THREE.BoxGeometry(houseRoof2Width, houseRoof2Height, houseRoof2Depth), - new THREE.MeshLambertMaterial({color: 0x888888}) + new THREE.MeshStandardMaterial({color: 0x888888}) ); @@ -277,7 +283,7 @@ function house() { const innerCubeDepth = outerCubeDepth - 500; const innerCubeMesh = new THREE.Mesh( new THREE.BoxGeometry(innerCubeWidth, innerCubeHeight, innerCubeDepth), - new THREE.MeshLambertMaterial({color: 0x888888}) + new THREE.MeshStandardMaterial({color: 0x888888}) ); innerCubeMesh.updateMatrix(); @@ -287,7 +293,7 @@ function house() { const doorDepth = outerCubeDepth / 5; const doorMesh = new THREE.Mesh( new THREE.BoxGeometry(doorWidth, doorHeight, doorDepth), - new THREE.MeshLambertMaterial({color: 0x888888}) + new THREE.MeshStandardMaterial({color: 0x888888}) ); doorMesh.position.set( (innerCubeWidth / 1.9) + 1, @@ -302,7 +308,7 @@ function house() { const windowLeftDepth = outerCubeDepth / 5; const windowLeftMesh = new THREE.Mesh( new THREE.BoxGeometry(windowLeftWidth, windowLeftHeight, windowLeftDepth), - new THREE.MeshLambertMaterial({color: 0x888888}) + new THREE.MeshStandardMaterial({color: 0x888888}) ); windowLeftMesh.position.set( (innerCubeWidth / 1.9) + 1, @@ -317,7 +323,7 @@ function house() { const windowRightDepth = windowLeftDepth; const windowRightMesh = new THREE.Mesh( new THREE.BoxGeometry(windowRightWidth, windowRightHeight, windowRightDepth), - new THREE.MeshLambertMaterial({color: 0x888888}) + new THREE.MeshStandardMaterial({color: 0x888888}) ); windowRightMesh.position.set( (innerCubeWidth / 1.9) + 1, @@ -332,7 +338,7 @@ function house() { const windowCentralDepth = outerCubeWidth + 2; const windowCentralMesh = new THREE.Mesh( new THREE.BoxGeometry(windowCentralWidth, windowCentralHeight, windowCentralDepth), - new THREE.MeshLambertMaterial({color: 0x888888}) + new THREE.MeshStandardMaterial({color: 0x888888}) ); windowCentralMesh.position.set(0, 0, 0); windowCentralMesh.updateMatrix(); @@ -342,11 +348,11 @@ function house() { const roofConeHeight = outerCubeHeight; const roofConeMesh = new THREE.Mesh( new THREE.ConeGeometry(roofConeWidth, roofConeHeight, 4), - new THREE.MeshLambertMaterial({color: 0xFF0000}) + new THREE.MeshStandardMaterial({color: 0xFF0000}) ); roofConeMesh.position.set( dallePosition.x, - dallePosition.y + (dalleHeight * 2) + outerCubeHeight + (houseRoof1Height * 2) + (houseRoof2Height * 2) - 100 , // Posé sur le 1er toit + dallePosition.y + (dalleHeight * 2) + outerCubeHeight + (houseRoof1Height * 2) + (houseRoof2Height * 2) - 100, // Posé sur le 1er toit dallePosition.z ); @@ -360,6 +366,18 @@ function house() { const roofHesh1 = CSG.subtract(houseRoof1, innerCubeMesh); const roofHesh2 = CSG.subtract(houseRoof2, innerCubeMesh); + roofConeMesh.castShadow = true; + roofConeMesh.receiveShadow = true; + + baseHesh.castShadow = true; + baseHesh.receiveShadow = true; + + roofHesh1.castShadow = true; + roofHesh1.receiveShadow = true; + + roofHesh2.castShadow = true; + roofHesh2.receiveShadow = true; + baseHesh.position.set( dallePosition.x, @@ -395,7 +413,29 @@ function house() { // Creation de la lumiere à 360° au centre du toit pyramidal - const pyramidLight = new THREE.PointLight(0xFFCC06, 1, 1000); + const pyramidLight = new THREE.PointLight(0xffcc66, 1000, 5000); + pyramidLight.position.set( + dallePosition.x, + dallePosition.y + dalleHeight / 2 + outerCubeHeight + houseRoof1Height * 1.655 + houseRoof2Height * 1.655 + roofConeHeight / 3, + dallePosition.z + ) + + + // Activer les ombres pour la lumière + // Activation des ombres + pyramidLight.castShadow = true; + pyramidLight.shadow.mapSize.width = 4096; // Résolution élevée pour des ombres nettes + pyramidLight.shadow.mapSize.height = 4096; + pyramidLight.shadow.camera.near = 1; + pyramidLight.shadow.camera.far = 5000; + + // Ajouter la lumière à la scène + scene.add(pyramidLight); + + + // Ajouter un helper pour voir la position de la lumière + const lightHelper = new THREE.PointLightHelper(pyramidLight, 1000); + scene.add(lightHelper); } @@ -410,14 +450,23 @@ function pompe() { ]; pompePositions.forEach(position => { - // Base de la pompe (rectangle rou ge) + // Base de la pompe (rectangle rouge) + // Matériau métallique avec reflets pour la base de la pompe + const baseMaterial = new THREE.MeshStandardMaterial({ + color: 0xff0000, // Rouge brillant + metalness: 1.0, // Métallique au maximum + roughness: 0.05, // Surface réfléchissante + envMap: envMap, // Appliquer l'environnement pour les reflets + }); + + // Base de la pompe (rectangle rouge métallique) const baseGeometry = new THREE.BoxGeometry(300, 1000, 300); - const baseMaterial = new THREE.MeshLambertMaterial({color: 0xff0000}); const base = new THREE.Mesh(baseGeometry, baseMaterial); base.position.set(position.x, 500, position.z); base.rotation.y = 0.2225; scene.add(base); + // Partie métallique supérieure (détail en acier) const metalGeometry = new THREE.BoxGeometry(320, 50, 320); const metalMaterial = new THREE.MeshStandardMaterial({color: 0xaaaaaa, metalness: 1, roughness: 0.3}); @@ -467,7 +516,7 @@ function forest() { .load('tree_bonus.obj', function (object) { object.traverse(function (child) { if (child.isMesh) { - child.material = new THREE.MeshLambertMaterial({color: 0x006600}); + child.material = new THREE.MeshStandardMaterial({color: 0x006600}); } }); @@ -509,6 +558,12 @@ function init() { renderer.setSize(canvasWidth, canvasHeight); renderer.setClearColor(0xAAAAAA, 1.0); + // Création d'une caméra de capture pour les reflets dynamiques + renderTarget = new THREE.WebGLCubeRenderTarget(1024, {format: THREE.RGBAFormat, generateMipmaps: true}); + cubeCamera = new THREE.CubeCamera(1, 10000, renderTarget); + scene.add(cubeCamera); + + var container = document.getElementById('webGL'); container.appendChild(renderer.domElement); @@ -526,6 +581,16 @@ function init() { gui.add(window, 'carSpeed', 10, 200).step(5).name('Vitesse f1'); gui.add(window, 'carMoving').name('F1 mouvement'); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; + + // Charger un environnement de réflexion pour le métal + const cubeTextureLoader = new THREE.CubeTextureLoader(); + envMap = cubeTextureLoader.setPath('textures/skybox/').load([ + 'px.jpg', 'nx.jpg', // Côtés + 'py.jpg', 'ny.jpg', // Dessus / Dessous + 'pz.jpg', 'nz.jpg' // Devant / Derrière + ]); }