Getting Started ¶
Installation ¶
This library requires the peer dependency three. Check the release notes for supported versions.
npm install postprocessing
Usage ¶
The renderer, scene and camera are created as normal. Please refer to the three.js manual for more information on how to create a scene.
import { PerspectiveCamera, Scene, WebGLRenderer } from "three";
// Recommended settings for postprocessing:
const renderer = new WebGLRenderer({
powerPreference: "high-performance",
antialias: false,
stencil: false,
depth: false
});
document.body.append(renderer.domElement);
const scene = new Scene();
const camera = new PerspectiveCamera();
Postprocessing uses RenderPipelines to render Passes. Common setups will only require one pipeline that contains a ClearPass, a GeometryPass and one or more EffectPass instances. The latter is used to render fullscreen Effects.
import {
ClearPass,
EffectPass,
GeometryPass,
RenderPipeline,
ToneMappingEffect
} from "postprocessing";
const pipeline = new RenderPipeline(renderer);
pipeline.add(
new ClearPass(),
new GeometryPass(scene, camera),
new EffectPass(new ToneMappingEffect())
);
function onResize(): void {
const width = container.clientWidth;
const height = container.clientHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
// The resolution must be set through the pipeline.
pipeline.setSize(width, height);
}
window.addEventListener("resize", onResize);
onResize();
// Use pipeline.render() instead of renderer.render()
renderer.setAnimationLoop(timestamp => pipeline.render(timestamp));
TipIt’s recommended to apply anti-aliasing effects with an additional, separate
EffectPass. See the anti-aliasing demos for details.
Precompilation ¶
Render pipelines can be precompiled to avoid frame stuttering during the initial render call. The compile method takes care of compiling fullscreen shaders as well as all shaders used by 3D objects that are rendered by a GeometryPass. It’s also possible to recompile individual passes as needed if, for example, the scene of a GeometryPass is changed or the effects of an EffectPass are replaced.
pipeline.compile()
.then(() => renderer.setAnimationLoop((timestamp) => pipeline.render(timestamp)))
.catch((e) => console.error(e));
Color Space Considerations ¶
It’s recommended to follow a linear workflow for color management and postprocessing supports this automatically. In most cases, WebGLRenderer.outputColorSpace can be left at default and postprocessing will follow suit. Built-in passes automatically convert colors when they render to screen and internal render operations are always performed in the appropriate color space.
Postprocessing uses HalfFloatType frame buffers by default to store intermediate results with minimal information loss. Linear colors normally require at least 12 bits per color channel to prevent color degradation and banding. The default buffer type supports HDR-like workflows with correct tone mapping. When alpha is disabled, postprocessing will use the compact R11F_G11F_B10F framebuffer format to save space. For more details see Geometry Buffer.
If hardware support and resource efficiency is a concern, postprocessing can be configured to use UnsignedByteType sRGB frame buffers as shown below. With low precision sRGB buffers, colors will be clamped to [0.0, 1.0] and information loss will shift to the darker spectrum which still leads to noticable banding in dark scenes. Linear, high precision HalfFloatType buffers don’t have these issues and are generally the preferred option.
import { UnsignedByteType } from "three";
const geoPass = new GeometryPass(scene, camera, {
frameBufferType: UnsignedByteType // enables low precision buffers
});
See three’s color management manual for more information on the topic.