Three.js Setup — Creative Web

Three.js Setup Three.js adalah library JavaScript yang membuat pembuatan grafik 3D di web menjadi jauh lebih mudah. Three.js membungkus WebGL dengan API yang…

three.js adalah library JavaScript yang membuat WebGL bisa dipakai tanpa menulis shader dan buffer sendiri: kamu cukup bilang "ada kotak di sini, kamera di sana", dan three.js yang menyiapkan semuanya untuk GPU. Bayangin foto produk di studio Raka. Ada meja tempat produk ditata, ada kamera dengan lensa dan jaraknya, dan ada fotografer yang menekan tombol sehingga jadilah foto. Di three.js, mejanya adalah Scene, kameranya Camera, dan fotografernya Renderer, yang "memotret" scene lewat kamera ke sebuah <canvas>. Kurang satu saja, gak ada gambar.

Di lesson ini kita memasang panggung 3D pertama di toko Raka: kotak kemasan Kaos Sablon Kopi yang berputar.

🧪 Tebakan cepat: wadah 3D di toko Raka menyempit dari 320 jadi 160 px (tingginya tetap 240). Kode resize mengubah camera.aspect dan renderer.setSize, tapi lupa memanggil camera.updateProjectionMatrix(). Kotaknya tampil normal, melar, atau gepeng? Tebak dulu, jawabannya ada di bagian "Resize".

Pasang three.js

Versi terbaru di npm per Oktober 2026 adalah 0.186.1 (r186). Dengan bundler seperti Vite:

npm install three
import * as THREE from 'three';

Tanpa bundler, dokumentasi three.js memakai import map di <head>, supaya browser tahu dari mana 'three' diambil:

<script type="importmap">
{
  "imports": {
    "three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
    "three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"
  }
}
</script>
<script type="module" src="main.js"></script>

Scene, kamera, renderer

<div id="toko-3d" style="width: 320px; height: 240px"></div>
import * as THREE from 'three';

const wadah = document.getElementById('toko-3d');

// 1. Scene: panggung tempat semua benda diletakkan
const scene = new THREE.Scene();
scene.background = new THREE.Color('#1c1917');

// 2. Kamera: fov 75°, aspect lebar / tinggi, near 0.1, far 4
const camera = new THREE.PerspectiveCamera(75, wadah.clientWidth / wadah.clientHeight, 0.1, 4);
camera.position.z = 2;

// 3. Renderer: menggambar ke <canvas> miliknya sendiri
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(wadah.clientWidth, wadah.clientHeight);
wadah.appendChild(renderer.domElement);

// Kotak kemasan Kaos Sablon Kopi: 1,6 × 1 × 0,4
const kotak = new THREE.Mesh(
  new THREE.BoxGeometry(1.6, 1, 0.4),
  new THREE.MeshNormalMaterial()
);
kotak.rotation.x = 0.4;
scene.add(kotak);

Seberapa besar yang terlihat

Tinggi dunia yang terlihat di jarak d adalah 2 × d × tan(fov / 2). Kotak setinggi 1 di jarak 2, di canvas setinggi 240 px:

fov Tinggi terlihat Kotak mengisi Kira-kira
30° 1,07 93% 224 px, seperti lensa tele
75° 3,07 33% 78 px
110° 5,71 18% 42 px, seperti lensa lebar

fov adalah parameter yang paling mengubah tampilan: makin besar, makin banyak yang masuk, makin kecil tiap benda. far di sini sengaja 4, cukup untuk kotak di jarak 2: dorong kamera ke z = 4, dan separuh belakang kotak lewat dari far, jadi terpotong.

Render loop

Satu renderer.render(scene, camera) menghasilkan satu foto. Supaya bergerak, render tiap frame:

renderer.setAnimationLoop((time) => {
  kotak.rotation.y = time / 1000; // 1 radian per detik
  renderer.render(scene, camera);
});

Resize

new ResizeObserver(() => {
  camera.aspect = wadah.clientWidth / wadah.clientHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(wadah.clientWidth, wadah.clientHeight);
  renderer.render(scene, camera); // gambar ulang, juga saat loop berhenti
}).observe(wadah);

Kamera menyimpan hitungan proyeksinya dalam sebuah matriks, dan matriks itu baru dihitung ulang saat updateProjectionMatrix() dipanggil. Tanpa itu, wadah 160 × 240 (aspect 0,67) masih digambar dengan aspect lama 1,33: semua benda gepeng jadi setengah lebarnya. Itu jawaban tebakannya. Hal yang sama berlaku setelah mengubah camera.fov. Kalau canvas-nya selebar jendela, pakai window.addEventListener('resize', ...) dengan window.innerWidth dan window.innerHeight.

⚠️ Jebakan yang sering ketemu

TL;DR: Pasang three (0.186.1) lewat npm atau import map, lalu import * as THREE from 'three'. Tiga komponen wajib: Scene (wadah, scene.add mengisi scene.children), Camera (PerspectiveCamera(fov, aspect, near, far): fov derajat vertikal, aspect lebar / tinggi, near dan far batas jarak; mundurkan dengan position.z), dan Renderer (WebGLRenderer, setPixelRatio(Math.min(devicePixelRatio, 2)), setSize, appendChild(renderer.domElement)). Mesh = geometry + material. Gerakkan dengan renderer.setAnimationLoop((time) => { ...; renderer.render(scene, camera) }), sudut dari waktu. Saat ukuran berubah: camera.aspect, camera.updateProjectionMatrix(), renderer.setSize.

Yang akan kamu pelajari