The Renderer

The painter that brings your scene to life

Understanding the WebGLRenderer

The renderer is what actually draws your 3D scene onto a 2D canvas. It takes your scene and camera, does all the complex math, and outputs pixels. Honestly, it's like frickin' magic. Three.js provides several renderers, but WebGLRenderer is by far the most common - it uses your GPU for hardware-accelerated graphics.

Basic Setup

At minimum, you need to create a renderer, set its size, and call render() in a loop:

typescript
// Create the renderer
const canvas = document.querySelector('#webgl');
const renderer = new THREE.WebGLRenderer({ canvas });

// Set the size to match the container
renderer.setSize(width, height);

// Match device pixel density (for sharp rendering on retina displays)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

// Render loop
function tick() {
  renderer.render(scene, camera);
  requestAnimationFrame(tick);
}
tick();

Antialiasing

Antialiasing smooths out jagged edges on your geometry. Compare these two cubes. The left has no antialiasing but the right has it enabled.

typescript
// Enable antialiasing (slight performance cost)
const renderer = new THREE.WebGLRenderer({
  canvas,
  antialias: true
});

While smooth edges are usually the goal in 3D rendering, enabling antialiasing in Three.js isn't always a "set it and forget it" win. There are several technical and creative reasons why you might intentionally leave it turned off.

You might skip antialiasing to save performance on mobile devices or complex VR scenes where every millisecond of GPU time counts. It is also standard to disable it when using the EffectComposer, as post-processing stacks usually require specialized passes like FXAA or SMAA rather than the renderer's default setting. Finally, you might leave it off for stylistic reasons to achieve a sharp, "crunchy" retro or pixel-art aesthetic. Some of us out there still like that look and feel :)

Transparent Background

By default, the renderer fills the canvas with a color. Setting alpha: true allows the canvas background to show through, which is useful for overlaying 3D on top of HTML content.

typescript
// Enable transparent background
const renderer = new THREE.WebGLRenderer({
  canvas,
  alpha: true
});

// Optional: set clear color with alpha
renderer.setClearColor(0x000000, 0); // fully transparent

Pixel Ratio

Modern devices have high pixel density displays (retina). Without setting the pixel ratio, your scene will look blurry:

typescript
// Set pixel ratio for sharp rendering
// Cap at 2 to avoid performance issues on very high DPI screens
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

Tone Mapping

Tone mapping controls how HDR (high dynamic range) colors are converted to what your screen can display. This is especially important when working with realistic lighting.

typescript
// Different tone mapping options
renderer.toneMapping = THREE.NoToneMapping;      // Default, no conversion
renderer.toneMapping = THREE.LinearToneMapping;  // Simple linear
renderer.toneMapping = THREE.ReinhardToneMapping; // Film-like
renderer.toneMapping = THREE.CineonToneMapping;  // Cinematic
renderer.toneMapping = THREE.ACESFilmicToneMapping; // Industry standard

// Exposure control (works with tone mapping)
renderer.toneMappingExposure = 1.0;

You might disable tone mapping when your scene relies on specific hex colors or unlit materials that must appear exactly as defined without being shifted by exposure calculations. It is also common to leave it off if you are using a custom post-processing pipeline for color grading, where you prefer to manipulate the raw HDR data yourself.

In projects that don't use high dynamic range (HDR) lighting, tone mapping can sometimes make the visuals appear dull or muddy rather than improving the contrast. Last but not least, disabling it is useful for UI elements and 2D overlays to ensure your interface doesn't change color as the camera moves through differently lit areas of the scene. That can be distracting and take the user out of the experience you are trying so hard to build.

Enabling Shadows

Shadow rendering is disabled by default for performance. You need to explicitly enable it:

typescript
// Enable shadow maps
renderer.shadowMap.enabled = true;

// Shadow quality options
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Soft shadows (default: PCFShadowMap)

// Then configure your lights and objects
directionalLight.castShadow = true;
mesh.castShadow = true;
floor.receiveShadow = true;

We'll talk more about Shadows in a later article.

Output Color Space

For accurate color reproduction, especially with textures, set the output color space:

typescript
// Use sRGB for correct color display
renderer.outputColorSpace = THREE.SRGBColorSpace;

You use outputColorSpace to ensure the renderer correctly translates internal linear colors for standard displays, typically by setting it to SRGBColorSpace. It is essential for maintaining a "linear workflow," which prevents your scene from appearing washed out or overly dark when using standard lights and textures. You should enable it for nearly every modern project to ensure visual consistency with industry-standard assets like GLTF models. It is generally only bypassed if you are handling the final color encoding manually within a custom post-processing shader.

Basically, this ensures colors match what you see in image editors and the web. Turn it on.

←   CamerasThe Scene Graph   →