In deze Three.js intro bouw je vanaf nul je eerste driedimensionale scène die in de browser draait. Als mensen over 3D op het web praten, is de onderliggende technologie WebGL; maar werken met ruw WebGL betekent worstelen met honderden regels shader- en matrixcode. Precies hier komt Three.js in beeld en brengt het diezelfde taak terug tot een paar leesbare regels.
Wat is WebGL?
WebGL (Web Graphics Library) is een grafische API die vanuit JavaScript wordt aangeroepen en de browser directe toegang geeft tot je grafische kaart (GPU). Het is gebaseerd op de OpenGL ES-standaard en tekent hardware-versnelde graphics op een <canvas>-element zonder enige plug-in. Dat betekent dat 3D-modellen, deeltjessystemen en realtime belichting niet langer voorbehouden zijn aan desktopapplicaties; ze zijn ook mogelijk op een webpagina.
Het addertje is dat WebGL erg laag niveau is. Alleen al om één driehoek te tekenen moet je vertex- en fragmentshaders schrijven, buffers aanmaken en projectiematrices met de hand berekenen. Een abstractielaag is essentieel voor de productiviteit, en Three.js levert precies die laag.
Wat maakt Three.js makkelijker?
Three.js is een opensource JavaScript-bibliotheek die bovenop WebGL zit. Ze werkt met een scene graph-model: in plaats van elk object zelf in shaders om te zetten, denk je in termen van een logische hiërarchie. Standaard krijg je:
- Geometrieën: kant-en-klare vormen zoals kubus, bol, vlak en cilinder.
- Materialen: oppervlaktedefinities die wel of niet op licht reageren.
- Lichten en camera's: perspectiefcamera, gericht licht, omgevingslicht.
- Loaders: kant-en-klare tools voor 3D-modelformaten zoals
.glb/.gltf.
Drie kernbegrippen: scène, camera, renderer
In het hart van elke Three.js-applicatie leven drie objecten. De scène (Scene) is de container waarin alle objecten worden geplaatst. De camera (Camera) bepaalt vanuit welke hoek je naar de scène kijkt. De renderer neemt de scène vanuit het standpunt van de camera en tekent die op het canvas. Zodra je dit drietal hebt opgezet, is het skelet klaar:
import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75, // gezichtsveld (graden)
window.innerWidth / window.innerHeight, // beeldverhouding
0.1, // nabije clippingvlak
1000 // verre clippingvlak
);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
De PerspectiveCamera bootst het menselijk oog na en laat objecten in de verte kleiner lijken. Als we de camera niet langs de z-as naar achteren verplaatsen, blijft hij binnen in het object en zien we niets.
De eerste kubus maken
Laten we nu een object aan de scène toevoegen. In Three.js is een zichtbaar object meestal een Mesh; een Mesh is de combinatie van een geometrie (vorm) en een materiaal (oppervlak).
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00aaff });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
MeshBasicMaterial wordt niet door licht beïnvloed; het toont altijd een vlakke kleur, wat het ideaal maakt voor de eerste experimenten. Zodra je naar belichting overstapt, moet je MeshStandardMaterial gebruiken en een DirectionalLight aan de scène toevoegen, anders verschijnt het object pikzwart.
De animatielus
Eén frame tekenen is niet genoeg; voor een vloeiende animatie moeten we de scène bij elke schermverversing opnieuw renderen. De juiste manier is requestAnimationFrame, want dat blijft synchroon met de ververssnelheid van het scherm (meestal 60 FPS) en vertraagt automatisch wanneer het tabblad op de achtergrond staat.
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
Wanneer deze lus draait, zie je de blauwe kubus langzaam om twee assen draaien. Gefeliciteerd, je hebt zojuist je eerste realtime 3D-scène in de browser opgezet.
Omgaan met vensterformaat en volgende stappen
In een echt project moet je de camera en renderer bijwerken wanneer het venster van grootte verandert, zodat het beeld niet vervormt:
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
Vanaf hier zijn onderwerpen die het verkennen waard zijn: de scène met de muis draaien via OrbitControls, kant-en-klare 3D-modellen laden met GLTFLoader, plus schaduwen, texturen en post-processing-effecten. Het basisskelet blijft altijd hetzelfde; alleen de objecten die je aan de scène toevoegt, worden rijker.
Veelgestelde vragen
Heb ik geavanceerde wiskunde nodig om Three.js te leren?
Om te beginnen niet. De logica van scène, camera en mesh begrijpen is genoeg. Later, wanneer je eigen shaders of complexe camerabewegingen wilt maken, helpt basiskennis van vectoren en trigonometrie, maar voor je eerste projecten is dat niet nodig.
Kan ik Three.js aan een React-project toevoegen?
Ja. Met de bibliotheek react-three-fiber kun je Three.js als React-componenten schrijven en wordt de scene graph via de componentenboom beheerd. Omdat de onderliggende logica nog steeds pure Three.js is, is het een groot voordeel om eerst de kale bibliotheek te begrijpen.
Waarom ziet mijn kubus er zwart uit?
Je gebruikt waarschijnlijk een materiaal dat op licht reageert (zoals MeshStandardMaterial) terwijl er geen licht in de scène is. Voeg een licht aan de scène toe, of schakel voor een snelle test over naar MeshBasicMaterial.
Droom je van een 3D-webervaring? Of het nu gaat om interactieve productvisualisaties, geanimeerde introscènes of op WebGL gebaseerde portfolio's: we kunnen er samen aan werken. Neem contact op en laten we je idee tot leven brengen.