Awesome
three-gpu-pathtracer
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 Primitive Geometry Example
Beauty Demos
Interior Scene w/ Equirect Rendering
Features
Test Scenes
Model Viewer Fidelity Scene Comparisons
Tools
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.
- To install dependencies, run
npm install
- To start the demos run
npm start
- Visit
http://localhost:1234/<demo-name.html>
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
```js
constructor( renderer : WebGLRenderer, material : Material )
```
Takes a WebGLRenderer to use and material to test again.
### .detect
```js
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
- 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.
Screenshots
<p align="center"> <i>Sample materials</i> </p> <p align="center"> <i>"SD Macross City Standoff Diorama" scene by <a href="https://sketchfab.com/3d-models/sd-macross-city-standoff-diorama-b154220f7e7441799d6be2f7ff9658c7">tipatat</a></i> </p> <p align="center"> <i>"Interior Scene" model by <a href="https://sketchfab.com/3d-models/interior-scene-45ddbbc4c2dc4f8ca9ed99da9a78326a">Allay Design</a></i> </p> <p align="center"> <i>Perseverance Rover, Ingenuity Helicopter models by <a href="https://mars.nasa.gov/resources/25042/mars-perseverance-rover-3d-model/">NASA / JPL-Caltech</a></i> </p> <p align="center"> <i>Gelatinous Cube model by <a href="https://sketchfab.com/3d-models/gelatinous-cube-e08385238f4d4b59b012233a9fbdca21">glenatron</a></i> </p> <p align="center"> <i>Lego models courtesy of the <a href="https://omr.ldraw.org/">LDraw Official Model Repository</a></i> </p> <p align="center"> <i>Octopus Tea model by <a href="https://sketchfab.com/3d-models/cartoon-octopus-takes-a-tea-bath-107260cf0fd24202a67eb037a6c760a5 ">AzTiZ</a></i> </p> <p align="center"> <i>Botanists Study model by <a href="https://sketchfab.com/3d-models/the-botanists-study-8b7b5743b1c848ed8ea58f5518c44e7e">riikkakilpelainen</a></i> </p> <p align="center"> <i>Japanese Bridge Garden model by <a href="https://sketchfab.com/3d-models/japanese-bridge-garden-d122e17593eb4012913cde927486d15a">kristenlee</a></i> </p>Resources
Raytracing in One Weekend Book