Skip to content

Instantly share code, notes, and snippets.

@jprivet-dev
Created July 30, 2025 18:23
Show Gist options
  • Save jprivet-dev/1b2ba260436c162b03ef79199290fc64 to your computer and use it in GitHub Desktop.
Save jprivet-dev/1b2ba260436c162b03ef79199290fc64 to your computer and use it in GitHub Desktop.
Three.js - Tree low poly 01
<canvas id="treeCanvas"></canvas>
import * as THREE from "https://esm.sh/three";
import { OrbitControls } from "https://esm.sh/three/examples/jsm/controls/OrbitControls";
// Import pour le post-traitement si tu veux ajouter SSAO plus tard
// import { EffectComposer } from 'https://esm.sh/three/examples/jsm/postprocessing/EffectComposer';
// import { RenderPass } from 'https://esm.sh/three/examples/jsm/postprocessing/RenderPass';
// import { SSAOPass } from 'https://esm.sh/three/examples/jsm/postprocessing/SSAOPass';
// 1. Initialisation
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xeeeeee); // Gris très clair
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer({
antialias: true,
canvas: document.getElementById("treeCanvas")
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.shadowMap.enabled = true; // Activer les ombres
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Ombres douces
// 2. Lumières
// Lumière hémisphérique pour une illumination globale douce (simule le ciel et le sol)
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 1.0); // Couleur ciel (blanc), couleur sol (gris foncé), intensité
scene.add(hemiLight);
// Lumière directionnelle pour projeter des ombres
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); // Intensité ajustée
directionalLight.position.set(5, 10, 7.5); // Position de la lumière
directionalLight.castShadow = true; // Cette lumière projette des ombres
directionalLight.shadow.mapSize.width = 1024; // Qualité de la shadow map
directionalLight.shadow.mapSize.height = 1024;
directionalLight.shadow.camera.near = 0.5; // Limites de la caméra de la lumière
directionalLight.shadow.camera.far = 50;
directionalLight.shadow.camera.left = -10;
directionalLight.shadow.camera.right = 10;
directionalLight.shadow.camera.top = 10;
directionalLight.shadow.camera.bottom = -10;
directionalLight.shadow.radius = 2; // Douceur des ombres
scene.add(directionalLight);
// 3. Sol (pour recevoir les ombres)
const groundGeometry = new THREE.PlaneGeometry(20, 20);
const groundMaterial = new THREE.MeshStandardMaterial({
color: 0xcccccc, // Un gris légèrement plus foncé que le fond
roughness: 0.9,
metalness: 0.0
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2; // Rotation pour le mettre à plat
ground.receiveShadow = true; // Le sol reçoit les ombres
scene.add(ground);
// 4. Fonction pour créer un arbre low poly
function createLowPolyTree() {
const tree = new THREE.Group();
// Tronc (Cylindre low poly)
const trunkGeometry = new THREE.CylinderGeometry(0.5, 0.7, 3, 6);
const trunkMaterial = new THREE.MeshStandardMaterial({
color: 0x8b4513, // Marron
roughness: 0.9,
metalness: 0.0
});
const trunk = new THREE.Mesh(trunkGeometry, trunkMaterial);
trunk.position.y = 1.5;
trunk.castShadow = true; // Le tronc projette des ombres
trunk.receiveShadow = true; // Le tronc reçoit aussi des ombres sur lui-même
tree.add(trunk);
// Feuillage (Cônes low poly)
const leavesMaterial = new THREE.MeshStandardMaterial({
color: 0x228b22, // Vert foncé
roughness: 0.9,
metalness: 0.0
});
const cone1 = new THREE.Mesh(new THREE.ConeGeometry(2, 3, 8), leavesMaterial);
cone1.position.y = 4;
cone1.castShadow = true;
cone1.receiveShadow = true;
tree.add(cone1);
const cone2 = new THREE.Mesh(
new THREE.ConeGeometry(1.5, 2.5, 8),
leavesMaterial
);
cone2.position.y = 5.5;
cone2.castShadow = true;
cone2.receiveShadow = true;
tree.add(cone2);
return tree;
}
const myTree = createLowPolyTree();
scene.add(myTree);
camera.position.z = 10;
camera.position.y = 3;
// 5. Contrôles de la caméra
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
// 6. Animation
function animate() {
requestAnimationFrame(animate);
controls.update(); // Met à jour les contrôles
renderer.render(scene, camera);
}
animate();
// 7. Gestion du redimensionnement de la fenêtre
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.178.0/three.tsl.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.178.0/three.module.js"></script>
body {
margin: 0;
overflow: hidden;
}
canvas {
display: block;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment