three-gpu-pathtracer

npm version build github twitter sponsors

Path tracing project using three-mesh-bvh and WebGL 2 to accelerate high quality, physically based rendering on the GPU. Features include support for GGX surface model, material information, textures, normal maps, emission, environment maps, tiled rendering, and more!

More features and capabilities in progress!

Examples

Setup

Basic glTF Setup Example

Basic Primitive Geometry Example

Beauty Demos

Physically Based Materials

Lego Models

Interior Scene

Depth of Field

HDR Image

Features

Skinned Geometry Support

Morph Target Support

Area Light Support

Spot Light Support

Volumetric Fog Support

Test Scenes

Material Test Orb

Transmission Preset Orb

Model Viewer Fidelity Scene Comparisons

Physical Material Database

Tools

Animation Rendering

Ambient Occlusion Material

Running examples locally

To run and modify the examples locally, make sure you have Node and NPM installed. Check the supported versions in the test configuration.

In order to install dependencies, you will need make and a C++ compiler available.

On Debian or Ubuntu, run sudo apt install build-essential. It should just work on MacOS.

Use

Basic Renderer

import * as THREE from 'three';
import { WebGLPathTracer } from 'three-gpu-pathtracer';

// init scene, camera, controls, etc

renderer = new THREE.WebGLRenderer();
renderer.toneMapping = THREE.ACESFilmicToneMapping;

pathTracer = new WebGLPathTracer( renderer );
pathTracer.setScene( scene, camera );

animate();

function animate() {

	requestAnimationFrame( animate );
	pathTracer.renderSample();

}

Blurred Environment Map

Using a pre blurred envioronment map can help improve frame convergence time at the cost of sharp environment reflections. If performance is concern then multiple importance sampling can be disabled and blurred environment map used.

import { BlurredEnvMapGenerator } from 'three-gpu-pathtracer';

// ...

const envMap = await new RGBELoader().setDataType( THREE.FloatType ).loadAsync( envMapUrl );
const generator = new BlurredEnvMapGenerator( renderer );
const blurredEnvMap = generator.generate( envMap, 0.35 );

// render!

Exports

WebGLPathTracer

constructor

constructor( renderer : WebGLRenderer )

.bounces

bounces = 10 : Number

Max number of lights bounces to trace.

.filteredGlossyFactor

filteredGlossyFactor = 0 : Number

Factor for alleviating bright pixels from rays that hit diffuse surfaces then specular surfaces. Setting this higher alleviates fireflies but will remove some specular caustics.

.tiles

tiles = ( 3, 3 ) : Vector2

Number of tiles on x and y to render to. Can be used to improve the responsiveness of a page while still rendering a high resolution target.

.renderDelay

renderDelay = 100 : Number

Number of milliseconds to delay rendering samples after the path tracer has been reset.

.fadeDuration

fadeDuration = 500 : Number

How long to take to fade the fully path traced scene in in milliseconds wen rendering to the canvas.

.minSamples

minSamples = 5 : Number

How many samples to render before displaying to the canvas.

.dynamicLowRes

dynamicLowRes = false : Boolean

Whether to render an extra low resolution of the scene while the full resolution renders. The scale is defined by lowResScale.

.lowResScale

lowResScale = 0.1 : Number

The scale to render the low resolution pass at.

.synchronizeRenderSize

synchronizeRenderSize = true : Boolean

Whether to automatically update the sie of the path traced buffer when the canvas size changes.

.renderScale

renderScale = 1 : Number

The scale to render the path traced image at. Only relevant if synchronizeRenderSize is true.

.renderToCanvas

renderToCanvas = true : Boolean

Whether to automatically render the path traced buffer to the canvas when renderSample is called.

.rasterizeScene

rasterizeScene = true : Boolean

Whether to automatically rasterize the scene with the three.js renderer while the path traced buffer is rendering.

.textureSize

textureSize = ( 1024, 1024 ) : Vector2

The dimensions to expand or shrink all textures to so all scene textures can be packed into a single texture array.

.samples

readonly samples : Number

The number of samples that have been rendered.

.target

readonly target : WebGLRenderTarget

The path traced render target. This potentially changes every call to renderSample.

.setScene

setScene( scene : Scene, camera : Camera ) : void

Sets the scene and camera to render. Must be called again when the camera object changes, the geometry in the scene changes, or new materials are assigned.

While only changed data is updated it is still a relatively expensive function. Prefer to use the other “update” functions where possible.

.setSceneAsync

setSceneAsync(
	scene : Scene,
	camera : Camera,
	options = {
		onProgress = null : value => void,
	} : Object
) : void

Asynchronous version of setScene. Requires calling setBVHWorker first.

.updateCamera

updateCamera() : void

Updates the camera parameters. Must be called if any of the parameters on the previously set camera change.

.updateMaterials

updateMaterials() : void

Updates the material properties. Must be called when properties change for any materials already being used.

Note that materials used with WebGLPathTracer support the following additional properties:

// Whether to render the object as completely transparent against the rest
// of the environment so other objects can be composited later
matte = false : Boolean;

// Whether the object should cast a shadow
castShadow = true : Boolean;

.updateEnvironment

updateEnvironment() : void

Updates lighting from the scene environment and background properties. Must be called if any associated scene settings change on the set scene object.

.updateLights

updateLights() : void

Updates lights used in path tracing. Must be called if any lights are added or removed or properties change.

.renderSample

renderSample() : void

Render a single sample to the path tracer target. If renderToCanvas is true then the image is rendered to the canvas.

.reset

reset() : void

Restart the rendering.

.dispose

dispose() : void

Dispose the path tracer assets. Any materials or textures used must be disposed separately.

PhysicalCamera

extends THREE.PerspectiveCamera

An extension of the three.js PerspectiveCamera with some other parameters associated with depth of field. These parameters otherwise do not affect the camera behavior are are for convenience of use with the PhysicalCameraUniform and pathtracer.

.focusDistance

focusDistance = 25 : Number

The distance from the camera in meters that everything is is perfect focus.

.fStop

fStop = 1.4 : Number

The fstop value of the camera. If this is changed then the bokehSize field is implicitly updated.

.bokehSize

bokehSize : Number

The bokeh size as derived from the fStop and focal length in millimeters. If this is set then the fStop is implicitly updated.

.apertureBlades

apertureBlades = 0 : Number

The number of sides / blades on the aperture.

.apertureRotation

apertureRotation = 0 : Number

The rotation of the aperture shape in radians.

.anamorphicRatio

anamorphicRatio = 1 : Number

The anamorphic ratio of the lens. A higher value will stretch the bokeh effect horizontally.

EquirectCamera

extends THREE.Camera

A class indicating that the path tracer should render an equirectangular view. Does not work with three.js raster rendering.

PhysicalSpotLight

extends THREE.SpotLight

.radius

radius = 0 : Number

The radius of the spotlight surface. Increase this value to add softness to shadows.

.iesMap

iesMap = null : Texture

The loaded IES texture describing directional light intensity. These can be loaded with the IESLoader.

Premade IES profiles can be downloaded from [ieslibrary.com]. And custom profiles can be generated using CNDL.

ShapedAreaLight

extends THREE.RectAreaLight

.isCircular

isCircular = false : Boolean

Whether the area light should be rendered as a circle or a rectangle.

IESLoader

extends Loader

Loader for loading and parsing IES profile data. Load and parse functions return a DataTexture with the profile contents.

BlurredEnvMapGenerator

Utility for generating a PMREM blurred environment map that can be used with the path tracer.

constructor

constructor( renderer : WebGLRenderer )

.generate

generate( texture : Texture, blur : Number ) : DataTexture

Takes a texture to blur and the amount to blur it. Returns a new DataTexture that has been PMREM blurred environment map that can have distribution data generated for importance sampling.

.dispose

dispose() : void

Disposes of the temporary files and textures for generation.

GradientEquirectTexture

.exponent

exponent = 2 : Number

.topColor

topColor = 0xffffff : Color

.bottomColor

bottomColor = 0x000000 : Color

constructor

constructor( resolution = 512 : Number )

.update

update() : void

MaterialBase

extends THREE.ShaderMaterial

Convenience base class that adds additional functions and implicitly adds object definitions for all uniforms of the shader to the object.

.setDefine

setDefine( name : string, value = undefined : any ) : void

Sets the define of the given name to the provided value. If the value is set to null or undefined then it is deleted from the defines of the material. If the define changed from the previous value then Material.needsUpdate is set to true.

FogVolumeMaterial

extends MeshStandardMaterial

A material used for rendering fog-like volumes within the scene. The color, emissive, and emissiveIntensity fields are all used in the render.

NOTE Since fog models many particles throughout the scene and cause many extra bounces fog materials can dramatically impact render time.

.density

The particulate density of the volume.

DenoiseMaterial

extends MaterialBase

Denoise material based on BrutPitt/glslSmartDeNoise intended to be the final pass to the screen. Includes tonemapping and color space conversions.

Uniforms

{

	// sigma - sigma Standard Deviation
	// kSigma - sigma coefficient
	// kSigma * sigma = radius of the circular kernel
	sigma = 5.0 : Number,
	kSigma = 1.0 : Number,

	// edge sharpening threshold
	threshold = 0.03 : Number,

}

CompatibilityDetector

Detects whether the path tracer can run on the current device by checking whether struct precision is reliable and the material shader will compile.

constructor

constructor( renderer : WebGLRenderer, material : Material )

Takes a WebGLRenderer to use and material to test again.

.detect

detect() : {
	pass: Boolean,
	message: String
}

Returns pass === true if the path tracer can run. If it cannot run then a message is returned indicating why.

Gotchas

Screenshots

Sample materials

"SD Macross City Standoff Diorama" scene by tipatat

"Interior Scene" model by Allay Design

Perseverance Rover, Ingenuity Helicopter models by NASA / JPL-Caltech

Gelatinous Cube model by glenatron

Lego models courtesy of the LDraw Official Model Repository

Octopus Tea model by AzTiZ

Botanists Study model by riikkakilpelainen

Japanese Bridge Garden model by kristenlee

Resources

Raytracing in One Weekend Book

PBR Book

knightcrawler25/GLSL-PathTracer

DassaultSystemes-Technology/dspbr-pt