Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • e47747u/webgl25
  • vincen251u/webgl25
  • villard5/webgl25
3 results
Show changes
Commits on Source (2)
......@@ -34,14 +34,14 @@ https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_obj_mtl.htm
## CHECK LIST
*(ajouter X pour cocher)*
- [X] 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] Géométrie
- [X] Couleur
- [X] Transparence
- [X] Eclairage
- [ ] Ombres portées
- [X] Ombres portées
- [X] Position de la caméra
- [X] Brouillard
- [X] Effet miroir
......@@ -52,4 +52,4 @@ https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_obj_mtl.htm
- [ ] Skybox
- [ ] specular maps
- [X] normal maps
- [ ] Interaction par GUI
- [X] Interaction par GUI
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; // Remplacer GLTFLoader par OBJLoader
import { Coordinates } from '../lib/Coordinates.js';
// import { Coordinates } from '../lib/Coordinates.js';
import { GUI } from 'https://cdn.jsdelivr.net/npm/lil-gui@0.17/+esm';
var camera, renderer;
window.scene = new THREE.Scene();
// var camera, renderer;
// window.scene = new THREE.Scene();
var camera, renderer, scene;
scene = new THREE.Scene();
var cameraControls;
var clock = new THREE.Clock();
var transparentCube;
var light1, light2;
var params = {
ambientLightIntensity: 0.2,
light1Intensity: 4,
light2Intensity: 3,
fogDensity: 0.001,
enableShadows: true,
enableFog: true,
cameraX: -400,
cameraY: 150,
cameraZ: -20,
light1X: 200,
light1Y: 400,
light1Z: 400,
shadowBias: -0.0005,
shadowRadius: 2,
showHelpers: false
};
const objLoader = new OBJLoader(); // Utilisation de OBJLoader au lieu de GLTFLoader
function fillScene() {
scene.fog = new THREE.FogExp2(0xB0BEC5, 0.001);
scene.fog = new THREE.FogExp2(0xB0BEC5, params.fogDensity);
// LIGHTS avec configuration précise des ombres
const ambientLight = new THREE.AmbientLight(0x444444, params.ambientLightIntensity);
scene.add(ambientLight);
// LIGHTS
scene.add(new THREE.AmbientLight(0x222222));
// Lumière directionnelle principale pour les ombres
light1 = new THREE.DirectionalLight(0xFFFFFF, params.light1Intensity);
light1.position.set(params.light1X, params.light1Y, params.light1Z);
light1.castShadow = params.enableShadows;
scene.add(light1);
var light = new THREE.DirectionalLight(0xFFFFFF, 4);
light.position.set(200, 400, 400);
light.castShadow = true; // Cette lumière génère des ombres
scene.add(light);
// Configuration des paramètres d'ombre
light1.shadow.mapSize.width = 2048; // Haute résolution pour des ombres nettes
light1.shadow.mapSize.height = 2048;
light1.shadow.camera.near = 10;
light1.shadow.camera.far = 1000;
light1.shadow.bias = params.shadowBias; // Contrôlable via GUI
light1.shadow.radius = params.shadowRadius; // Contrôlable via GUI
light = new THREE.DirectionalLight(0xFFFFFF, 3);
light.position.set(-200, -100, -400);
light.castShadow = true; // Cette lumière génère des ombres
scene.add(light);
// Configuration critique: définir la boîte de la caméra d'ombre
light1.shadow.camera.left = -500;
light1.shadow.camera.right = 500;
light1.shadow.camera.top = 500;
light1.shadow.camera.bottom = -500;
// Optionally adjust the shadow for the light
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
light.shadow.camera.near = 1;
light.shadow.camera.far = 1000;
light.shadow.bias = -0.005;
// Helper pour visualiser la zone d'ombre
const helper1 = new THREE.CameraHelper(light1.shadow.camera);
helper1.visible = params.showHelpers;
scene.add(helper1);
Coordinates.drawGround({ size: 800 });
// Coordinates.drawGround({ size: 800 });
// Cube Transparent au Centre
var transparentMaterial = new THREE.MeshBasicMaterial({
......@@ -43,9 +75,8 @@ function fillScene() {
});
var cubeGeometry = new THREE.BoxGeometry(100, 100, 100);
transparentCube = new THREE.Mesh(cubeGeometry, transparentMaterial);
transparentCube.position.set(0, 50, 0);
transparentCube.castShadow = true; // Activer la projection d'ombre
transparentCube.receiveShadow = true; // Activer la réception d'ombre
transparentCube.position.set(0, -100, 0);
scene.add(transparentCube);
// Sol
......@@ -53,7 +84,7 @@ function fillScene() {
var floorMaterial = new THREE.MeshStandardMaterial({ map: floorTexture });
var floor = new THREE.Mesh(new THREE.PlaneGeometry(400, 400), floorMaterial);
floor.rotation.x = -Math.PI / 2;
floor.position.y = 0;
floor.position.y = -100;
floor.receiveShadow = true; // Le sol reçoit des ombres
scene.add(floor);
......@@ -62,82 +93,252 @@ function fillScene() {
var wallMaterial = new THREE.MeshStandardMaterial({ map: wallTexture });
var backWall = new THREE.Mesh(new THREE.PlaneGeometry(400, 300), wallMaterial);
backWall.position.set(0, 150, -200);
backWall.position.set(0, 50, -200);
scene.add(backWall);
var leftWall = new THREE.Mesh(new THREE.PlaneGeometry(400, 300), wallMaterial);
leftWall.rotation.y = Math.PI / 2;
leftWall.position.set(-200, 150, 0);
leftWall.position.set(-200, 50, 0);
scene.add(leftWall);
var rightWall = new THREE.Mesh(new THREE.PlaneGeometry(400, 300), wallMaterial);
rightWall.rotation.y = -Math.PI / 2;
rightWall.position.set(200, 150, 0);
rightWall.position.set(200, 50, 0);
scene.add(rightWall);
var frontWall = new THREE.Mesh(new THREE.PlaneGeometry(400, 300), wallMaterial);
frontWall.rotation.y = Math.PI;
frontWall.position.set(0, 150, 200);
frontWall.position.set(0, 50, 200);
scene.add(frontWall);
// Lit
objLoader.load('elements/wooden_bed.obj', function (object) {
let bed = object;
bed.position.set(130 - 50, 0, 127);
bed.scale.set(100, 100, 100);
bed.rotation.y = 11;
bed.castShadow = true; // Activer la projection d'ombre
bed.receiveShadow = true; // Activer la réception d'ombre
scene.add(bed);
// Lit avec texture et matériaux différents
objLoader.load('elements/wooden_bed.obj', function (object) {
let bed = object;
// Textures
var woodTexture = new THREE.TextureLoader().load('elements/sol_boiserie.jpg');
// Matériaux
const woodMaterial = new THREE.MeshStandardMaterial({
map: woodTexture,
color: 0x8B4513,
roughness: 0.8,
metalness: 0.2
});
const redMaterial = new THREE.MeshStandardMaterial({
color: 0xAA0000, // Rouge foncé
roughness: 0.7,
metalness: 0.1
});
const whiteMaterial = new THREE.MeshStandardMaterial({
color: 0xFFFFFF, // Blanc
roughness: 0.5,
metalness: 0.0
});
// Compter les meshes pour identifier différentes parties
let meshCount = 0;
// Appliquer les matériaux en fonction de l'index des meshes
bed.traverse(function (child) {
if (child instanceof THREE.Mesh) {
if (meshCount % 3 === 0) {
child.material = whiteMaterial; // Cadre
} else if (meshCount % 3 === 1) {
child.material = woodMaterial; // Couverture
} else {
child.material = redMaterial; // Oreillers
}
meshCount++;
}
});
enableShadows(bed);
bed.position.set(130 - 50, -100, 127);
bed.scale.set(100, 100, 100);
bed.rotation.y = 11;
bed.castShadow = true;
bed.receiveShadow = true;
scene.add(bed);
});
// Chaise
objLoader.load('elements/wooden_chair.obj', function (object) {
let chair1 = object.clone();
let chair2 = object.clone();
// Appliquer le même matériau bois que la table aux chaises
const woodTexture = new THREE.TextureLoader().load('elements/sol_boiserie.jpg');
const chairMaterial = new THREE.MeshStandardMaterial({
map: woodTexture, // Utiliser la texture pour le bois
color: 0x8B4513, // Teinte supplémentaire (peut être ajustée)
roughness: 0.8,
metalness: 0.2
});
// Appliquer le matériau à chaque chaise
chair1.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = chairMaterial;
}
});
chair2.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = chairMaterial;
}
});
enableShadows(chair1);
enableShadows(chair2);
chair1.position.set(100, 0, 0); // Première chaise à côté du lit
chair1.position.set(100, -100, 0); // Première chaise à côté du lit
chair1.rotation.y = 12;
chair2.position.set(-100, 0, -150); // Deuxième chaise à côté de la première
chair2.position.set(-100, -100, -150); // Deuxième chaise à côté de la première
chair2.rotation.y = 12;
chair1.scale.set(100, 100, 100);
chair2.scale.set(100, 100, 100);
chair1.castShadow = true; // Activer la projection d'ombre
chair1.receiveShadow = true; // Activer la réception d'ombre
chair2.castShadow = true; // Activer la projection d'ombre
chair2.receiveShadow = true; // Activer la réception d'ombre
scene.add(chair1);
scene.add(chair2);
});
// Table
objLoader.load('elements/wooden_table.obj', function (object) {
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: 0x8B4513, // Couleur bois
roughness: 0.8,
metalness: 0.2
// Charger la table au format OBJ
const objLoader = new OBJLoader();
objLoader.load('elements/wooden_table.obj', function (object) {
// Appliquer un matériau à tous les enfants de l'objet
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: 0x8B4513, // Couleur bois
roughness: 0.8,
metalness: 0.2
});
}
});
// Ajuster la position, la taille et la rotation de la table
object.position.set(100, -100, -110); // Position entre les chaises
object.scale.set(100, 100, 100); // Échelle à ajuster selon le modèle
object.rotation.y = Math.PI / 4;
enableShadows(object);
// Ajouter la table à la scène
scene.add(object);
// Charger la théière et la placer sur la table
objLoader.load('elements/tea.obj', function (teapot) {
// Appliquer un matériau à la théière
teapot.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: 0x0000FF, // Couleur bleu
roughness: 0.2,
metalness: 0.8
});
}
});
}
// Positionner la théière sur la table
teapot.position.set(100, 5, -110); // Même position X/Z que la table mais plus haut en Y
teapot.scale.set(10, 10, 10); // Échelle appropriée pour la théière
teapot.rotation.y = Math.PI / 4; // Même rotation que la table
// Ajouter la théière à la scène
scene.add(teapot);
// Charger le vase et le placer à côté de la théière
objLoader.load('elements/vase.obj', function (vase) {
// Appliquer un matériau au vase
vase.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: 0x0000FF, // Couleur orange-rouge
roughness: 0.1,
metalness: 0.2
});
}
});
// Positionner le vase à côté de la théière sur la table
vase.position.set(80, -16, -130); // Position décalée par rapport à la théière
vase.scale.set(1, 1, 1); // Ajuster l'échelle selon la taille du modèle
vase.rotation.x = -(Math.PI / 2); // 90 degrés
// Ajouter le vase à la scène
scene.add(vase);
// Créer un verre simple avec une géométrie de cylindre
const glassGeometry = new THREE.CylinderGeometry(3, 2.5, 8, 16);
const glassMaterial = new THREE.MeshPhysicalMaterial({
color: 0x0066FF, // Couleur bleue
transparent: true, // Transparent pour l'effet verre
opacity: 0.6, // Semi-transparent
roughness: 0.1, // Lisse
metalness: 0.0, // Non métallique
clearcoat: 1.0, // Effet de vernis
clearcoatRoughness: 0.1 // Vernis lisse
});
const glass = new THREE.Mesh(glassGeometry, glassMaterial);
// Positionner le verre à côté du vase sur la table
glass.position.set(65, -13, -130); // Ajusté pour être à côté du vase
glass.scale.set(1, 1, 1);
// Ajouter le verre à la scène
scene.add(glass);
// Ajouter deux bougies sur la table
objLoader.load('elements/candle.obj', function (candle) {
// Appliquer un matériau à la bougie
candle.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: 0xF5DEB3, // Couleur crème
roughness: 0.7,
metalness: 0.1
});
}
});
// Créer un clone pour la deuxième bougie
const candle1 = candle;
const candle2 = candle.clone();
// Positionner les bougies sur la table
candle1.position.set(110, -16, -90); // Premier emplacement
candle1.scale.set(3, 3, 3); // Ajuster la taille selon le modèle
candle1.rotation.y = Math.PI / 6; // Légère rotation
candle2.position.set(110, -16, -100); // Deuxième emplacement
candle2.scale.set(3, 3, 3);
candle2.rotation.y = -Math.PI / 8; // Rotation différente
// Ajouter les bougies à la scène
scene.add(candle1);
scene.add(candle2);
});
});
});
});
object.position.set(100, 0, -110);
object.scale.set(100, 100, 100);
object.rotation.y = Math.PI / 4;
object.castShadow = true; // Activer la projection d'ombre
object.receiveShadow = true; // Activer la réception d'ombre
scene.add(object);
});
// Fenêtre
var windowTexture = new THREE.TextureLoader().load('elements/window.jpg');
var windowMaterial = new THREE.MeshStandardMaterial({ map: windowTexture });
var window = new THREE.Mesh(new THREE.PlaneGeometry(75, 125), windowMaterial);
window.position.set(199, 160, -80);
window.position.set(199, 60, -80);
window.rotation.y = 11;
scene.add(window);
......@@ -146,19 +347,199 @@ function fillScene() {
var doorMaterial = new THREE.MeshStandardMaterial({ map: doorTexture });
var door1 = new THREE.Mesh(new THREE.PlaneGeometry(150, 250), doorMaterial);
door1.position.set(-60, 125, 199);
door1.position.set(-60, 25, 199);
door1.rotation.y = 22;
door1.castShadow = true; // Activer la projection d'ombre
door1.receiveShadow = true; // Activer la réception d'ombre
scene.add(door1);
var door2 = new THREE.Mesh(new THREE.PlaneGeometry(150, 250), doorMaterial);
door2.position.set(0, 125, -199);
door2.position.set(0, 25, -199);
door2.castShadow = true; // Activer la projection d'ombre
door2.receiveShadow = true; // Activer la réception d'ombre
scene.add(door2);
// Premier tableau (celui d'origine)
const painting1 = createWallPainting(35, 25, 60, 80, 198, -Math.PI);
scene.add(painting1);
// Deuxième tableau (duplicata à côté)
const painting2 = createWallPainting(35, 25, 120, 80, 198, -Math.PI);
scene.add(painting2);
// Troisième tableau (plus large en haut)
const painting3 = createWallPainting(70, 40, 198, 100, 100, -Math.PI/2);
scene.add(painting3);
// Quatrième tableau (sur le mur de gauche)
const painting4 = createWallPainting(20, 70, 198, 80, -160, -Math.PI/2);
scene.add(painting4);
}
// Ajouter un tableau suspendu au mur
function createWallPainting(width, height, posX, posY, posZ, rotY) {
// Groupe contenant le tableau et la corde
const paintingGroup = new THREE.Group();
// Créer le cadre du tableau
const frameGeometry = new THREE.BoxGeometry(width + 5, height + 5, 2);
const frameTexture = new THREE.TextureLoader().load('elements/sol_boiserie.jpg');
const frameMaterial = new THREE.MeshStandardMaterial({
map: frameTexture,
color: 0x8B4513
});
const frame = new THREE.Mesh(frameGeometry, frameMaterial);
// Créer la toile du tableau (légèrement devant le cadre)
const canvasGeometry = new THREE.PlaneGeometry(width, height);
const canvasTexture = new THREE.TextureLoader().load('elements/sol_boiserie.jpg');
const canvasMaterial = new THREE.MeshStandardMaterial({ map: canvasTexture });
const canvas = new THREE.Mesh(canvasGeometry, canvasMaterial);
canvas.position.z = 1.1; // Légèrement devant le cadre
// Ajouter le cadre et la toile au groupe
paintingGroup.add(frame);
paintingGroup.add(canvas);
// Créer la corde pour suspendre le tableau (en forme de toit/triangle)
const ropeGeometry = new THREE.BufferGeometry();
const ropePoints = [
new THREE.Vector3(-width/2 + 5, height/2, 0), // Point gauche du tableau
new THREE.Vector3(0, height/2 + 10, 0), // Point haut de la corde (sommet du toit)
new THREE.Vector3(width/2 - 5, height/2, 0) // Point droit du tableau
];
ropeGeometry.setFromPoints(ropePoints);
const ropeMaterial = new THREE.LineBasicMaterial({ color: 0x5A3A22, linewidth: 2 });
const rope = new THREE.Line(ropeGeometry, ropeMaterial);
// Ajouter la corde au groupe
paintingGroup.add(rope);
// Positionner le tableau sur le mur
paintingGroup.position.set(posX, posY, posZ);
paintingGroup.rotation.y = rotY || 0; // Rotation optionnelle
return paintingGroup;
}
// Fonction utilitaire pour activer les ombres sur un objet et tous ses enfants
function enableShadows(object) {
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
return object; // Retourner l'objet pour permettre le chaînage
}
// Ajouter une fonction pour créer l'interface GUI
function createGUI() {
const gui = new GUI({ title: 'Contrôles' });
// Ajouter un dossier pour les positions des lumières
const light1PosFolder = gui.addFolder('Position Lumière 1');
light1PosFolder.add(params, 'light1X', -600, 600)
.name('X')
.onChange(value => {
light1.position.x = value;
// Mettre à jour les helpers
scene.children.forEach(child => {
if (child instanceof THREE.CameraHelper && child.camera === light1.shadow.camera) {
child.update();
}
});
});
light1PosFolder.add(params, 'light1Y', 0, 600)
.name('Y')
.onChange(value => {
light1.position.y = value;
scene.children.forEach(child => {
if (child instanceof THREE.CameraHelper && child.camera === light1.shadow.camera) {
child.update();
}
});
});
light1PosFolder.add(params, 'light1Z', -600, 600)
.name('Z')
.onChange(value => {
light1.position.z = value;
scene.children.forEach(child => {
if (child instanceof THREE.CameraHelper && child.camera === light1.shadow.camera) {
child.update();
}
});
});
// Dossier pour les lumières
const lightsFolder = gui.addFolder('Lumières');
lightsFolder.add(params, 'light1Intensity', 0, 10)
.name('Intensité lumière 1')
.onChange(value => {
light1.intensity = value;
});
lightsFolder.add(params, 'light2Intensity', 0, 10)
.name('Intensité lumière 2')
.onChange(value => {
light2.intensity = value;
});
// Dossier pour les effets
const effectsFolder = gui.addFolder('Effets');
effectsFolder.add(params, 'enableShadows')
.name('Ombres')
.onChange(value => {
renderer.shadowMap.enabled = value;
light1.castShadow = value;
light2.castShadow = value;
});
effectsFolder.add(params, 'enableFog')
.name('Brouillard')
.onChange(value => {
if (value) {
scene.fog = new THREE.FogExp2(0xB0BEC5, params.fogDensity);
} else {
scene.fog = null;
}
});
effectsFolder.add(params, 'fogDensity', 0, 0.01)
.name('Densité brouillard')
.onChange(value => {
if (scene.fog) {
scene.fog.density = value;
}
});
// Dossier pour la caméra
const cameraFolder = gui.addFolder('Caméra');
cameraFolder.add(params, 'cameraX', -600, 600)
.name('Position X')
.onChange(value => {
camera.position.x = value;
});
cameraFolder.add(params, 'cameraY', 0, 300)
.name('Position Y')
.onChange(value => {
camera.position.y = value;
});
cameraFolder.add(params, 'cameraZ', -600, 600)
.name('Position Z')
.onChange(value => {
camera.position.z = value;
});
return gui;
}
function init() {
var canvasWidth = 900;
var canvasHeight = 500;
......@@ -177,7 +558,7 @@ function init() {
// CAMERA
camera = new THREE.PerspectiveCamera(45, canvasRatio, 1, 4000);
camera.position.set(-400, 400, 20);
camera.position.set(-400, 150, -20);
camera.lookAt(new THREE.Vector3(0, 0, 0));
// CONTROLS
......@@ -185,6 +566,9 @@ function init() {
cameraControls.enableDamping = true;
cameraControls.dampingFactor = 0.05;
cameraControls.rotateSpeed = 1.0;
createGUI();
}
function addToDOM() {
......@@ -201,10 +585,17 @@ function animate() {
render();
}
// function render() {
// var delta = clock.getDelta();
// cameraControls.update();
// renderer.render(window.scene, camera);
// }
function render() {
var delta = clock.getDelta();
cameraControls.update();
renderer.render(window.scene, camera);
renderer.render(scene, camera); // CORRECTION CRITIQUE
}
try {
......
Image diff could not be displayed: it is too large. Options to address this: view the blob.
DUFOUR/elements/sol_boiserie.jpg

6.16 MiB | W: 0px | H: 0px

DUFOUR/elements/sol_boiserie.jpg

1.34 MiB | W: 0px | H: 0px

DUFOUR/elements/sol_boiserie.jpg
DUFOUR/elements/sol_boiserie.jpg
DUFOUR/elements/sol_boiserie.jpg
DUFOUR/elements/sol_boiserie.jpg
  • 2-up
  • Swipe
  • Onion skin
Image diff could not be displayed: it is too large. Options to address this: view the blob.
......@@ -14,7 +14,7 @@
justify-content: center;
width: 100%;
gap: 20px;
}
}
h2 {
font-style: italic;
font-weight: lighter;
......@@ -60,7 +60,7 @@
1889<br>
Huile sur toile</p>
<img src="img.jpg" alt="La Chambre de Van Gogh - Peinture originale">
<p>DE RYCKE Leanne <br>DUFOUR Louise <br><br>Reproduction 3D WEBGL <br>BUT1 INFO 2025</p>
<p>DE RYCKE Leanne <br>DUFOUR Louise <br><br>Reproduction 3D WEBGL <br>BUT2 INFO 2025</p>
</div>
<!-- Scène WebGL à droite -->
......