v0.0.28
three-gpu-pathtracer
GPU-accelerated path tracing renderer for physically based rendering on the web. Supports PBR materials, area lights, depth of field, and volumetric fog for high-quality rendering visuals.
renderingvisualizationphysically-based
import { ACESFilmicToneMapping, Color, RectAreaLight } from 'three/webgpu';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { GenerateMeshBVHWorker } from 'three-mesh-bvh/worker';
import { GradientEquirectTexture } from 'three-gpu-pathtracer';
import { WebGPUPathTracer } from 'three-gpu-pathtracer/webgpu';
import { createFloor } from './floor.js';
// scene, camera and renderer are initialized here
const URL = 'https://raw.githubusercontent.com/gkjohnson/3d-demo-data/main/models/nasa-m2020/MER_static.glb';
const { scene: model } = await new GLTFLoader()
.setDRACOLoader( new DRACOLoader() )
.loadAsync( URL );
scene.background = new Color( 0xeeeeee );
renderer.toneMapping = ACESFilmicToneMapping;
scene.add( model, createFloor() );
camera.position.set( 1.65, 1.95, 2.9 );
controls.target.set( 0, 0.6, 0 );
controls.update();
// area lights: a warm key, a cool fill and a back light
const key = new RectAreaLight( 0xfff0dd, 9, 3.2, 3.2 );
key.position.set( 3.2, 3.4, 2.8 );
key.lookAt( 0, 1.35, 0 );
const fill = new RectAreaLight( 0xdfeaff, 2.25, 4, 4 );
fill.position.set( - 3.9, 2.1, 2.5 );
fill.lookAt( 0, 1.35, 0 );
const back = new RectAreaLight( 0xffffff, 13.5, 2.6, 2.6 );
back.position.set( - 1.9, 3.7, - 3.6 );
back.lookAt( 0, 1.35, 0 );
scene.add( key, fill, back );
// a dim gradient environment for soft fill light
const environment = new GradientEquirectTexture();
environment.topColor.set( 0x333333 );
environment.bottomColor.set( 0x111111 );
environment.update();
scene.environment = environment;
// BVHs build in workers and shaders compile in the background, so the page never stalls
const pathTracer = new WebGPUPathTracer( renderer );
pathTracer.setBVHWorker( GenerateMeshBVHWorker );
pathTracer.asyncCompile = true;
// mobile GPUs are slower: fewer paths per frame keep frames fast, and fewer pixels converge sooner
if ( matchMedia( '(pointer: coarse)' ).matches ) {
pathTracer.frameBudget = 50000;
renderer.setPixelRatio( window.devicePixelRatio / 2 );
}
// samples accumulate while the camera is still, up to 32, and restart when it moves
pathTracer.maxSamples = 32;
await pathTracer.setSceneAsync( scene, camera );
controls.addEventListener( 'change', () => pathTracer.updateCamera() );
window.addEventListener( 'resize', () => pathTracer.updateCamera() );
renderer.setAnimationLoop( () => pathTracer.renderSample() );Install
npm install three-gpu-pathtracerChangelog
0.0.28
Added
- WebGPUPathTracer: "setBVHWorker" and "setSceneAsync" to build the mesh BVHs in workers without blocking the page.
- WebGPUPathTracer: A "complete" event and flag once every pixel has reached "maxSamples" and the denoiser, if any, has run.
- WebGPUPathTracer: A "progress" event with the stage the render is in, "building", "compiling", "rendering" or "denoising", and how far along it is.
- WebGPUPathTracer: "renderToCanvas" flag to skip drawing the result to the render target.
- OIDNDenoiser: An "error" event when a pass started by "update" fails, such as the weights failing to download, and a "progress" event as each tile finishes.
- WebGPUPathTracer: The scene data is available to kernels and camera ray functions through the TSL context as "bvhData".
- WebGPUPathTracer: "renderAuxBuffer" draws the albedo or normal auxiliary buffer given to the denoiser.
- WebGPUPathTracer: "adaptiveFrameBudget" and "targetFrameTime" to tune "frameBudget" toward a GPU frame time, measured as "frameTime". Enabled by default, and requires a renderer created with "trackTimestamp". A reset restores the budget from before the last pixels of a capped render finished.
- WebGPUPathTracer: "adaptiveDynamicRes" adjusts "lowResScale" to the pixels a frame of "frameBudget" can render.
- WebGPUPathTracer: Subsurface scattering through volumes, with "scatterStrength", "multiscatterColor" and "scatterAnisotropy" material properties following the "KHR_materials_scatter" proposal, and "maxSubsurfaceBounces".
Changed
- WebGPUPathTracer: Requires three.js r187, which binds every storage buffer as an array.
- WebGPUPathTracer: Sobol is the default random strategy instead of Blue Dither.
- WebGPUPathTracer: "renderDelay" defaults to 16 and "fadeDuration" to 250, and the fade starts once the average pixel reaches "minSamples", so the full render shows sooner after the camera stops.
- OIDNDenoiser: Uses "oidn-webgpu" 0.6.0, the renamed "oidn-web" package, and paces denoising tiles to display frames.
- OIDNDenoiser: The albedo and normal auxiliary buffers are accumulated by the path tracer from the first scatter of every sample instead of rasterized, so they match the image under depth of field and transparency. "setScene" is gone and "update" takes the auxiliary buffer.
- AtlasTexture: Pages grow to the device texture size limit instead of 4096, so larger textures are no longer downsampled.
- WebGPUPathTracer: Pixels a camera declines count as finished once "maxSamples" is set.
- WebGPUPathTracer: Kernels are compiled asynchronously before the first render, so the page no longer freezes while they compile.
- WebGPUPathTracer: "updateEnvironment" no longer rebuilds an unchanged environment map on every call.
- WebGPUPathTracer: Shadow rays pass through partially transparent surfaces, attenuated by their opacity, and stop at the first opaque hit.
Fixed
- WebGPUPathTracer: Rough transmission at the critical angle producing a NaN direction, which could stall the GPU for minutes inside subsurface scattering volumes.
- WebGPUPathTracer: Diffuse surfaces losing energy when "specularIntensity" or "specularColor" is lowered.
- WebGPUPathTracer: Light through partially transparent objects hidden with "visibleToShadowRays" no longer being counted twice.
- WebGPUPathTracer: Environment map importance sampling accuracy.
- WebGPUPathTracer: Nearest filtered environment and background textures no longer fail to compile.
- WebGPUPathTracer: "setSceneAsync" no longer leaves geometry unusable when its attributes share a buffer, as in glTF files.
- WebGPUPathTracer: Path buffers being reallocated on every reset for the low resolution preview.
- WebGPUPathTracer: NaN pixels next to thin area lights.
- WebGPUPathTracer: Diffuse surfaces losing indirect light when viewed almost head-on.
- WebGPUPathTracer: Area and environment light being lost at the last bounce.
- WebGPUPathTracer: Transmissive volumes being tinted by the square of their color, now matching Blender.
- PathTracingSceneGenerator: ReferenceError when regenerating a scene whose geometry hasn't changed.
0.0.27
Added
- WebGPUPathTracer: Support for three.js' SunLight.
- WebGPUPathTracer: Support for a "visibleToCameraRays" flag on area lights to make them visible to the camera.
- WebGPUPathTracer: Support for render target textures.
Changed
- WebGPUPathTracer: Lights are chosen for sampling by their estimated contribution rather than uniformly, reducing noise in scenes with many lights.
- WebGPUPathTracer: One sided surfaces block light from both sides. Objects can opt out of casting shadows with a "visibleToShadowRays" flag.
Fixed
- WebGPUPathTracer rendering black after changing "maxBounces" or "maxTransparentBounces" once the render had settled.
- Memory leak on every reset, scene change, and dispose from compute kernels never being released.
- FSRUpscaler leaking GPU resources each time it was attached to the path tracer.
- WebGPUPathTracer.dispose not disposing the materials of its full screen quads.
- WebGPUPathTracer crashing on multi-material meshes with null material slots. The groups are now skipped.
0.0.26
Fixed
- Import missing a file extension that broke loading the WebGPU path tracer from a CDN.