From 534a49aa995c63719909fb057c6570a3985474b8 Mon Sep 17 00:00:00 2001
From: Sefer Algul <algul.sefer@univ-lorraine.fr>
Date: Sat, 15 Feb 2025 12:01:30 +0100
Subject: [PATCH] =?UTF-8?q?ajout=20ombre+intensit=C3=A9=20soleil?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ALGUL/index.js | 141 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 104 insertions(+), 37 deletions(-)

diff --git a/ALGUL/index.js b/ALGUL/index.js
index 90b33bd..8f1558a 100644
--- a/ALGUL/index.js
+++ b/ALGUL/index.js
@@ -2,17 +2,24 @@ import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.m
 import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three@0.150.1/examples/jsm/controls/OrbitControls.js';
 import { GLTFLoader } from 'https://cdn.jsdelivr.net/npm/three@0.150.1/examples/jsm/loaders/GLTFLoader.js';
 import { OBJLoader } from 'https://cdn.jsdelivr.net/npm/three@0.150.1/examples/jsm/loaders/OBJLoader.js';
+import * as dat from 'https://cdn.jsdelivr.net/npm/dat.gui@0.7.9/build/dat.gui.module.js';
 
+// SCENE
 const scene = new THREE.Scene();
-scene.background = new THREE.Color(0x87CEEB);  
-
+scene.background = new THREE.Color(0x87CEEB);
 
+// CAMERA
 const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 5000);
-const renderer = new THREE.WebGLRenderer({ antialias: true });
+camera.position.set(380, 200, 30);
 
+// RENDERER
+const renderer = new THREE.WebGLRenderer({ antialias: true });
+renderer.shadowMap.enabled = true;               // Active les ombres
+renderer.shadowMap.type = THREE.PCFSoftShadowMap;
 renderer.setSize(window.innerWidth, window.innerHeight);
 document.body.appendChild(renderer.domElement);
 
+// CONTROLS
 const controls = new OrbitControls(camera, renderer.domElement);
 controls.enableDamping = true;
 controls.dampingFactor = 0.05;
@@ -21,7 +28,7 @@ controls.maxDistance = 2000;
 controls.minDistance = 50;
 controls.target.set(0, 0, 0);
 
-// Lumières
+// LUMIÈRES
 const light = new THREE.DirectionalLight(0xffffff, 1);
 light.position.set(10, 50, 50);
 scene.add(light);
@@ -32,14 +39,43 @@ scene.add(ambientLight);
 const hemisphereLight = new THREE.HemisphereLight(0x87CEEB, 0x222222, 1);
 scene.add(hemisphereLight);
 
-camera.position.set(380, 200, 30);
+// SOLEIL
+const sunGeometry = new THREE.SphereGeometry(50, 32, 32);
+const sunMaterial = new THREE.MeshBasicMaterial({ color: 0xffcc00 });
+const sun = new THREE.Mesh(sunGeometry, sunMaterial);
+sun.position.set(-700, 800, -1000);
+scene.add(sun);
 
-// Chargement des ponts
+// DirectionalLight pour le soleil (avec ombres)
+const sunLight = new THREE.DirectionalLight(0xffddaa, 3);
+sunLight.position.set(500, 1000, -1000);
+sunLight.castShadow = true;                      // Indispensable pour projeter des ombres
+sunLight.shadow.mapSize.width = 2048;
+sunLight.shadow.mapSize.height = 2048;
+sunLight.shadow.camera.near = 1;
+sunLight.shadow.camera.far = 3000;
+sunLight.shadow.camera.left = -1000;
+sunLight.shadow.camera.right = 1000;
+sunLight.shadow.camera.top = 1000;
+sunLight.shadow.camera.bottom = -1000;
+scene.add(sunLight);
+
+// CHARGEMENT DES PONTS
 const loader = new GLTFLoader();
+
+// 1er pont
 loader.load('modeles/old_bridge.glb', function (gltf) {
     const bridge = gltf.scene;
-    scene.add(bridge);
 
+    // Activer les ombres
+    bridge.traverse((node) => {
+        if (node.isMesh) {
+            node.castShadow = true;
+            node.receiveShadow = true;
+        }
+    });
+
+    scene.add(bridge);
     bridge.position.set(0, 100, 0);
     bridge.scale.set(0.5, 0.5, 0.5);
     bridge.rotation.y = Math.PI / 2;
@@ -50,10 +86,17 @@ loader.load('modeles/old_bridge.glb', function (gltf) {
     console.error("Erreur de chargement du pont :", error);
 });
 
+// 2e pont
 loader.load('modeles/old_bridge.glb', function (gltf) {
     const bridge2 = gltf.scene;
-    scene.add(bridge2);
+    bridge2.traverse((node) => {
+        if (node.isMesh) {
+            node.castShadow = true;
+            node.receiveShadow = true;
+        }
+    });
 
+    scene.add(bridge2);
     bridge2.position.set(-950, 100, 0);
     bridge2.scale.set(0.5, 0.5, 0.5);
     bridge2.rotation.y = Math.PI / 2;
@@ -63,40 +106,66 @@ loader.load('modeles/old_bridge.glb', function (gltf) {
 }, undefined, function (error) {
     console.error("Erreur de chargement du pont :", error);
 });
+
+// 3e pont
 loader.load('modeles/old_bridge.glb', function (gltf) {
     const bridge3 = gltf.scene;
-    scene.add(bridge3);
+    bridge3.traverse((node) => {
+        if (node.isMesh) {
+            node.castShadow = true;
+            node.receiveShadow = true;
+        }
+    });
 
+    scene.add(bridge3);
     bridge3.position.set(100, 100, 126);
     bridge3.scale.set(0.5, 0.5, 0.5);
     bridge3.rotation.y = Math.PI / -2;
 
-
     controls.target.copy(bridge3.position);
     controls.update();
 }, undefined, function (error) {
     console.error("Erreur de chargement du pont :", error);
 });
 
+// 4e pont
 loader.load('modeles/old_bridge.glb', function (gltf) {
     const bridge4 = gltf.scene;
-    scene.add(bridge4);
+    bridge4.traverse((node) => {
+        if (node.isMesh) {
+            node.castShadow = true;
+            node.receiveShadow = true;
+        }
+    });
 
+    scene.add(bridge4);
     bridge4.position.set(-850, 100, 126);
     bridge4.scale.set(0.5, 0.5, 0.5);
     bridge4.rotation.y = Math.PI / -2;
 
-
     controls.target.copy(bridge4.position);
     controls.update();
 }, undefined, function (error) {
     console.error("Erreur de chargement du pont :", error);
 });
 
-// Chargement des bateaux
+// CHARGEMENT DES BATEAUX
 loader.load('modeles/bateau.glb', function (gltf) {
     const boat1 = gltf.scene.clone();
+    boat1.traverse((node) => {
+        if (node.isMesh) {
+            node.castShadow = true;
+            node.receiveShadow = true;
+        }
+    });
+
     const boat2 = gltf.scene.clone();
+    boat2.traverse((node) => {
+        if (node.isMesh) {
+            node.castShadow = true;
+            node.receiveShadow = true;
+        }
+    });
 
     boat1.position.set(-300, 1, -500);
     boat1.scale.set(0.3, 0.3, 0.3);
@@ -111,18 +180,7 @@ loader.load('modeles/bateau.glb', function (gltf) {
     console.error("Erreur de chargement des bateaux :", error);
 });
 
-// Soleil
-const sunGeometry = new THREE.SphereGeometry(50, 32, 32);
-const sunMaterial = new THREE.MeshBasicMaterial({ color: 0xffcc00 });
-const sun = new THREE.Mesh(sunGeometry, sunMaterial);
-sun.position.set(-700, 800, -1000);
-scene.add(sun);
-
-const sunLight = new THREE.DirectionalLight(0xffddaa, 3);
-sunLight.position.set(500, 1000, -1000);
-scene.add(sunLight);
-
-// Sol (eau)
+// SOL (eau)
 const textureLoader = new THREE.TextureLoader();
 const groundTexture = textureLoader.load('textures/water2.jpg');
 groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
@@ -136,9 +194,11 @@ const solidGround = new THREE.Mesh(
 );
 solidGround.rotation.x = -Math.PI / 2;
 solidGround.position.y = -2;
+// Reçoit les ombres
+solidGround.receiveShadow = true;
 scene.add(solidGround);
 
-// Modèle Scream
+// MODÈLE SCREAM
 const objLoader = new OBJLoader();
 objLoader.load('modeles/scream/Scream 3D-bl.obj', function (obj) {
     const screamTexture = textureLoader.load('modeles/scream/Scream Texture.png');
@@ -146,6 +206,8 @@ objLoader.load('modeles/scream/Scream 3D-bl.obj', function (obj) {
     obj.traverse((child) => {
         if (child.isMesh) {
             child.material = new THREE.MeshBasicMaterial({ map: screamTexture });
+            child.castShadow = true;
+            child.receiveShadow = true;
         }
     });
 
@@ -159,25 +221,25 @@ objLoader.load('modeles/scream/Scream 3D-bl.obj', function (obj) {
     console.error("Erreur de chargement du modèle Scream :", error);
 });
 
-// SphereBox (Ciel panoramique)
+// SPHEREBOX (Ciel panoramique)
 const skyTexture = textureLoader.load('textures/skybox2.png');
 const skyMaterial = new THREE.MeshBasicMaterial({
     map: skyTexture,
-    side: THREE.BackSide 
+    side: THREE.BackSide
 });
-
-const skySphere = new THREE.Mesh(new THREE.SphereGeometry(3000, 32, 32), skyMaterial);
+const skySphere = new THREE.Mesh(
+    new THREE.SphereGeometry(3000, 32, 32),
+    skyMaterial
+);
 skySphere.rotation.x = Math.PI / 2;
 skySphere.rotation.z = Math.PI / -1;
-
-
 scene.add(skySphere);
 
+// SPRITES
 const spriteTexture = textureLoader.load('textures/sprite.png');
 const spriteMaterial = new THREE.SpriteMaterial({ map: spriteTexture });
 const sprite = new THREE.Sprite(spriteMaterial);
 sprite.position.set(40, 160, -30);
-
 sprite.scale.set(50, 100, 50);
 scene.add(sprite);
 
@@ -188,19 +250,24 @@ sprite2.position.set(20, 160, 0);
 sprite2.scale.set(50, 100, 50);
 scene.add(sprite2);
 
+// GUI
+const gui = new dat.GUI();
+gui.add(camera, 'fov', 10, 100).name('Zoom').onChange(() => {
+    camera.updateProjectionMatrix();
+});
+gui.add(sunLight, 'intensity', 0, 10).name('Soleil Intensité');
 
-// Animation
+// ANIMATION
 function animate() {
     requestAnimationFrame(animate);
     controls.update();
     renderer.render(scene, camera);
 }
-
 animate();
 
-// Redimensionnement
+// REDIMENSIONNEMENT
 window.addEventListener('resize', () => {
     renderer.setSize(window.innerWidth, window.innerHeight);
     camera.aspect = window.innerWidth / window.innerHeight;
     camera.updateProjectionMatrix();
-});
\ No newline at end of file
+});
-- 
GitLab