Une interprétation 3D de la peinture classique de nature morte vanitas, mettant en scène un crâne, une bougie et des objets symboliques représentant la fugacité de la vie.
Cette scène est inspirée des peintures vanitas du XVIIe siècle, qui contiennent des objets symboliques rappelant aux spectateurs le passage du temps, la fragilité de la vie et la vanité des ambitions terrestres.
Cette scène 3D exploite plusieurs techniques avancées du Three.js :
Architecture de rendu : Implémentation WebGL via THREE.WebGLRenderer avec paramètres optimisés (antialias: true, physicallyCorrectLights: true). Utilisation du pipeline ACESFilmicToneMapping avec toneMappingExposure à 1.2 pour une reproduction fidèle des contrastes. Système d'ombres PCFSoftShadowMap avec résolution 2048×2048 et shadow.bias à -0.0005 pour éliminer les artefacts d'auto-ombrage. Viewport configuré à 846×494 pixels pour un ratio adapté aux natures mortes.
Modélisation : Chargement asynchrone des modèles OBJ via THREE.OBJLoader avec gestion des événements (onLoad, onProgress, onError). Le crâne subit une transformation (scale: 6,6,6) et rotation (-π/2, 0, -π/5). Architecture componentielle avec THREE.Group pour le chandelier (11 sous-maillages) et la table (6 sous-maillages). Manipulation vertex-level de la flamme avec déformation procédurale à travers positionAttribute.setX/Z pour simuler l'irrégularité.
Éclairage multi-sources : Lumière directionnelle principale (0xFFAA55, intensité 0.5) positionnée à (-200,200,100) avec shadow.camera configurée dans un frustum (-500,500,-500,500). Système de triple éclairage pour la bougie: flameLight (0xff9933, intensité 2.2, distance 400, power 120), innerLight (0xffffcc, intensité 1.2, distance 150, power 70) et ambientFlameLight (0xff5500, intensité 0.6, distance 600, power 40). Lumière ambiante globale (0x222222) pour éviter les zones totalement noires.
Matériaux PBR avancés : Crâne utilisant MeshPhongMaterial avec cartes multiples (map: crackMap, normalMap: crackNormalMap, normalScale: 1,1, displacementMap: crackNormalMap, displacementScale: 0.5) et propriétés optiques (shininess: 40, emissive: 0x664422, emissiveIntensity: 0.1). Chandelier avec MeshStandardMaterial différencié (base: roughness 0.2, metalness 0.5; détails: roughness 0.25, metalness 0.8). Flamme avec THREE.MeshBasicMaterial utilisant THREE.AdditiveBlending pour l'effet lumineux. Table avec texture de bois chargée dynamiquement et propriétés roughness: 0.6, metalness: 0.2.
Animation et dynamisme procédural : Animation de la flamme basée sur deltaTime avec modulation sinusoïdale (flickerSpeed: 2.0, flickerIntensity: 0.12, swaySpeed: 1.0, swayAmount: 0.5). Système de 15 particules avec cycles de vie (userData.life), vélocité et opacité variables. Background dynamique généré par Canvas 2D avec gradients radiaux dont les valeurs RGB sont modulées par le vacillement de la flamme (centerIntensity, midIntensity, outerIntensity calculés avec pulseFactor). OrbitControls configuré avec target à (0,50,0) pour un pivot de caméra naturel.
Texture et effets visuels : Génération procédurale de textures via Canvas 2D (512×512) pour les gradients et effets lumineux. createGradientTexture pour la fleur (#ff007f à #ff99cc). Texture d'arrière-plan recalculée à chaque frame avec createRadialGradient pour simuler les variations de la lumière. Halo lumineux (flameHalo) avec matériau transparent (opacity: 0.15) et échelle animée. Effet de cire fondue simulé par une demi-sphère déformée (meltedWaxGeometry) avec material.transparent et opacity: 0.9.
Optimisation de performance : Utilisation stratégique de groupes (THREE.Group) pour réduire les matrices de transformation. Gestion efficace des ressources avec .dispose() pour les textures. Culling automatique des objets hors frustum. Configuration sélective du castShadow uniquement sur les objets pertinents. Géométries simplifiées avec paramètres de segmentation adaptés (ex: CylinderGeometry avec segments réduits pour les éléments secondaires). Réutilisation des matériaux entre maillages du même type. Implémentation robuste avec gestion d'erreurs via try/catch et logging.