name: threejs-core
description: Sets up Three.js renderer, scene, WebGL context, animation loop, and resize handling. Use when the user asks to create a 3D scene, set up Three.js from scratch, initialize WebGL, create a render loop, or configure a renderer. Trigger keywords: three.js, threejs, WebGL, 3D scene, renderer, requestAnimationFrame.
Three.js Core Setup
Canonical Scene Setup
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
renderer.outputColorSpace = THREE.SRGBColorSpace;
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000,
);
camera.position.set(0, 2, 5);
scene.add(camera);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();
Renderer Options
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
canvas: myCanvas,
powerPreference: "high-performance",
logarithmicDepthBuffer: true,
});
Tone Mapping Options
renderer.toneMapping = THREE.NoToneMapping;
renderer.toneMapping = THREE.LinearToneMapping;
renderer.toneMapping = THREE.ReinhardToneMapping;
renderer.toneMapping = THREE.CineonToneMapping;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMapping = THREE.AgXToneMapping;
renderer.toneMapping = THREE.NeutralToneMapping;
Shadow Map Types
renderer.shadowMap.type = THREE.BasicShadowMap;
renderer.shadowMap.type = THREE.PCFShadowMap;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.shadowMap.type = THREE.VSMShadowMap;
Fixed Canvas (not full-screen)
const W = 800,
H = 600;
renderer.setSize(W, H);
camera.aspect = W / H;
camera.updateProjectionMatrix();
Clock (delta time)
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
const elapsed = clock.getElapsedTime();
mesh.rotation.y += delta * 0.5;
renderer.render(scene, camera);
}
Common Gotchas
BoxBufferGeometry → removed in r160, use BoxGeometry
sRGBEncoding → removed in r152, use outputColorSpace = THREE.SRGBColorSpace
renderer.gammaOutput → removed in r136, replaced by outputColorSpace
- Always
scene.add(camera) if you want audio listeners or child objects on camera
- Never call
renderer.render() outside the loop (causes double frames)
- Always clamp
devicePixelRatio to avoid rendering 3x or 4x pixels on high-DPI screens
Imports (r160+)
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
All addons live under three/addons/ in r160+.