-
Notifications
You must be signed in to change notification settings - Fork 68
User Guide
Ray Tracing Renderer is designed to serve as a drop-in replacement for WebGLRenderer. However, Ray Tracing Renderer differs in several ways, and this guide explains the differences and additions introduced by this renderer.
Ray Tracing Renderer is designed to be called in a loop using requestAnimationFrame
. This functionality differs from WebGLRenderer. With WebGLRenderer, a single call to render()
will render the entire scene, but this is not true with RayTracingRenderer. The renderer draws the scene progressively, meaning that the more time that is spent rendering, the higher quality the resulting image looks. Thus render()
should be called continuously using an animation loop.
Your loop should resemble the following form:
const renderer = new THREE.RayTracingRenderer();
// ... create scene and camera
function tick() {
renderer.render(scene, camera);
requestAnimationFrame(tick);
}
tick();
As of now, DirectionalLight is the only supported native light source, but we are in the process of adding support for other lights.
Ray Tracing Renderer's most useful light source is the newly added Environment Light. By providing the Environment Light with an HDR environment map, the scene can be illuminated and shadowed entirely by the provided image. This method is the most realistic way of lighting a scene.
The easiest way to use the Environment Light is to obtain an image in the .hdr
format, and loading the image with Three's RGBELoader.
In your HTML, load the RGBELoader script after Three.js:
<script src="three.js"></script>
<script src="RGBELoader.js"></script>
Then the loader can be used:
const scene = new THREE.Scene();
const envMap = new THREE.RGBELoader().load('envmap.hdr'); // load the hdr texture
const envLight = new THREE.EnvironmentLight(envMap); // create an Environment Light from the hdr texture
scene.add(envLight);
- For a free source of environment maps, check out HDRI Haven.
Soft Directional Light is a new light source extending the Directional Light. It functions the same with the addition of a softness
parameter which controls the softness of its shadows. A value of 1.0
will cast a hard shadow, while a value of 0.0
will cast a very soft shadow.
const scene = new THREE.Scene();
const dirLight = new THREE.SoftDirectionalLight(0xffffff, 0.5, 0.3); // color, intensity, softness
dirLight.softness = 0.6; // change softness to 0.6 for a softer shadow
scene.add(envLight);
Ray Tracing Renderer does not support asynchronous loading of textures. Thus you should only call render()
when the textures have fully loaded. This can easily be done using the LoadingManager's onLoad listener.
const renderer = new THREE.RayTracingRenderer();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera();
function tick() {
renderer.render(scene, camera);
requestAnimationFrame(tick);
}
const material = new THREE.MeshStandardMaterial();
material.map = new THREE.TextureLoader().load('diffuse.jpg');
const geometry = new THREE.BoxBufferGeometry();
const mesh = new Three.Mesh(geometry, material);
scene.add(mesh);
// start render loop only when all textures have been downloaded
THREE.DefaultLoadingManager.onLoad = tick;
Ray Tracing Renderer supports MeshStandardMaterial. In addition, the renderer adds a new RayTracingMaterial
class which inherets from MeshStandardMaterial
, while adding some new properties.
If the transparent
property of your material to true
, the resulting material will be transparent and will reflect light at grazing angles. When enabled, the metalness and roughness properties of your material are ignored.
const material = new THREE.MeshStandardMaterial();
material.transparent = true; // material will behave like glass
By default, the transparent material is modeled as a thin surface which means it does not refract light. In order to render thick glass, bodies of water, or other solid transparent objects, set the solid
property to true
on the RayTracingMaterial
. This enables refraction. Note that for this effect to work correctly, the geometry of your mesh should be closed and it should have an inside surface.
const material = new THREE.RayTracingMaterial();
material.transparent = true; // material will behave like glass;
material.solid = true; // material will refract light as it enters the transparent medium
The Ray Tracing Renderer is able to seamlessly blend your scene with the environment lighting. To do this, set the shadowCatcher
property to true
on the RayTracingMaterial
. A material with this property ignores the color
property, and instead takes its color from the environment light behind it. Any other mesh now casts shadows onto the shadow catcher, and it will appear as though the shadows are being cast onto the environment itself! For the effect to look the best, the geometry of this shadow catcher should match the geometry of the underlying environment.
const material = new THREE.RayTracingMaterial();
material.shadowCatcher = true; // material will catch shadows and blend with the environment map;
const geometry = new THREE.PlaneBufferGeometry(1000, 1000); // create ground plane
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(Math.PI / 2); // rotate plane so it rests on the ground, pointing upward
// Place box on top of ground plane
// The box will now appear to naturally sit on the environment light's floor
const boxGeometry = new THREE.BoxBufferGeometry(10, 10, 10);
const boxMaterial = new THREE.MeshStandardMaterial();
const boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);
mesh.position.set(0, 5, 0);
To improve realism, you may opt to use a camera model that simulates a camera lens. To do this, use the provided LensCamera
instead of PerspectiveCamera. This camera introduces depth of field which increases fidelity of the image.
const camera = new THREE.LensCamera();
camera.aperture = 0.01; // specifies the depth of field
camera.focus = 10; // specifies the distance to the focal point
Ray Tracing Renderer simulates realistic light propagation and records the resulting lighting of the scene in HDR. This light must be must be compressed, or tone mapped, to a smaller range in order to be displayed on your monitor. Both WebGLRenderer and RayTracingRenderer provide properties which allow you to configure how this tone mapping is done.
There are several operators which map HDR to your monitor. By default, the renderer uses THREE.LinearToneMapping
. This operator provides a reasonable default but can sometimes result in clipping of very bright or very dim lights. In these cases, another operator is better suited.
- For less lighting contrast, try
THREE.ReinhardToneMapping
orTHREE.Uncharted2ToneMapping
. - For more lighting contrast, try
THREE.CineonToneMapping
orTHREE.ACESFilmicToneMapping
Three.js provides a helpful example which previews how these tone mapping properties affect the renderer.
const renderer = new THREE.RayTracingRenderer();
renderer.toneMapping = THREE.Uncharted2ToneMapping; // a low contrast operator
renderer.toneMappingExposure = 2; // the higher the number, the brighter the scene
// Only affects THREE.Uncharted2ToneMapping.
// The higher the number, the less contrast in the scene
renderer.toneMappingWhitePoint = 8;