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!
Setup
Basic Primitive Geometry Example
Beauty Demos
Interior Scene w/ Equirect Rendering
Features
Test Scenes
Model Viewer Fidelity Scene Comparisons
Tools
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.
- To install dependencies, run
npm install
- To start the demos run
npm start
- Visit
http://localhost:1234/<demo-name.html>
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!
constructor( renderer : WebGLRenderer )
bounces = 10 : Number
Max number of lights bounces to trace.
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 = ( 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 = 100 : Number
Number of milliseconds to delay rendering samples after the path tracer has been reset.
fadeDuration = 500 : Number
How long to take to fade the fully path traced scene in in milliseconds wen rendering to the canvas.
minSamples = 5 : Number
How many samples to render before displaying to the canvas.
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 = 0.1 : Number
The scale to render the low resolution pass at.
synchronizeRenderSize = true : Boolean
Whether to automatically update the sie of the path traced buffer when the canvas size changes.
renderScale = 1 : Number
The scale to render the path traced image at. Only relevant if synchronizeRenderSize
is true.
renderToCanvas = true : Boolean
Whether to automatically render the path traced buffer to the canvas when renderSample
is called.
rasterizeScene = true : Boolean
Whether to automatically rasterize the scene with the three.js renderer while the path traced buffer is rendering.
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.
readonly samples : Number
The number of samples that have been rendered.
readonly target : WebGLRenderTarget
The path traced render target. This potentially changes every call to renderSample
.
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(
scene : Scene,
camera : Camera,
options = {
onProgress = null : value => void,
} : Object
) : void
Asynchronous version of setScene
. Requires calling setBVHWorker
first.
updateCamera() : void
Updates the camera parameters. Must be called if any of the parameters on the previously set camera change.
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() : 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() : void
Updates lights used in path tracing. Must be called if any lights are added or removed or properties change.
renderSample() : void
Render a single sample to the path tracer target. If renderToCanvas
is true then the image is rendered to the canvas.
reset() : void
Restart the rendering.
dispose() : void
Dispose the path tracer assets. Any materials or textures used must be disposed separately.
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 = 25 : Number
The distance from the camera in meters that everything is is perfect focus.
fStop = 1.4 : Number
The fstop value of the camera. If this is changed then the bokehSize
field is implicitly updated.
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 = 0 : Number
The number of sides / blades on the aperture.
apertureRotation = 0 : Number
The rotation of the aperture shape in radians.
anamorphicRatio = 1 : Number
The anamorphic ratio of the lens. A higher value will stretch the bokeh effect horizontally.
extends THREE.Camera
A class indicating that the path tracer should render an equirectangular view. Does not work with three.js raster rendering.
extends THREE.SpotLight
radius = 0 : Number
The radius of the spotlight surface. Increase this value to add softness to shadows.
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.
extends THREE.RectAreaLight
isCircular = false : Boolean
Whether the area light should be rendered as a circle or a rectangle.
extends Loader
Loader for loading and parsing IES profile data. Load and parse functions return a DataTexture
with the profile contents.
Utility for generating a PMREM blurred environment map that can be used with the path tracer.
constructor( renderer : WebGLRenderer )
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() : void
Disposes of the temporary files and textures for generation.
exponent = 2 : Number
topColor = 0xffffff : Color
bottomColor = 0x000000 : Color
constructor( resolution = 512 : Number )
update() : void
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( 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
.
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.
The particulate density of the volume.
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,
}
- The project requires use of WebGL2.
- All textures must use the same wrap and interpolation flags.
- SpotLights, DirectionalLights, and PointLights are only supported with MIS.
- Only MeshStandardMaterial and MeshPhysicalMaterial are supported.
- Instanced geometry and interleaved buffers are not supported.
- Emissive materials are supported but do not take advantage of MIS.
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
Raytracing in One Weekend Book