denoiser — WebGPU denoising for the web

Path-traced frames are denoised with Intel Open Image Denoise (OIDN) networks, matching native OIDN output, on interchangeable runtimes (hand-written WGSL, WebNN, ONNX Runtime; AutoRuntime picks one). Raster and hybrid pipelines get real-time temporal denoisers (AMD FidelityFX shadows and reflections, ported to WGSL). Everything shares one GPUDevice with your renderer, including three.js WebGPURenderer / TSL nodes. No native code, no server round-trip. These demos need a WebGPU browser (Chrome/Edge 113+, Safari 26+) and have been validated on Apple GPUs only so far.

Start here

The API in a few lines, then what good input looks like.

Path tracing + OIDN

Whole-frame denoising of path-traced renders with the OIDN networks, in three.js, raw WebGPU and Babylon.js.

Real-time denoising

One ray per pixel, every frame: the FidelityFX shadow and reflection denoisers, and how they compare.

Ray-traced shadows & reflections in a raster app

A three.js raster scene that traces two effects at 1 ray per pixel, denoised every frame by ffxShadows() / ffxReflections(), vs shadow maps and env maps.

  • real-time FFX
  • three.js
  • upscaler

Reflections, explained: probe, SSR, ray tracing

A guided tour of how engines find reflections (probes, SSR, ray tracing, the hybrid): split-screen comparisons of where each one breaks, a view of where every pixel's reflection comes from, and what each costs.

  • real-time FFX
  • three.js

Reflections in two rooms: probes, SSR and rays

A probe per room and one in the doorway give every surface the right reflection for almost nothing; SSR and one traced ray per pixel + ffxReflections() add the moving mirror ball, contact and what the probes never saw. Lights that change colour, probes re-baked or frozen.

  • real-time FFX
  • three.js

Reflection probes on r186 (preview of three.js #35046)

Ben Houston's box-projected, blended reflection probes, running on three r186 until his PR lands: two rooms, a doorway probe, same API, swap in his when it ships.

  • three.js

Baked + dynamic shadows: when to split

Bake what never moves (a lightmap, denoised once with OIDN, or a world-space cache), trace only the moving objects every frame with FFX: what the split buys, what it costs, and when to use it.

  • real-time FFX
  • OIDN
  • three.js

three.js SSR: FidelityFX vs recurrentDenoise

three's SSR denoise example with the ffxReflections() TSL node swapped in, split-screen against three's own denoiser.

  • real-time FFX
  • three.js

FidelityFX shadows & reflections

AMD's FidelityFX denoisers ported to WGSL: 1-sample ray-traced signals denoised every frame vs a converged reference.

  • real-time FFX
  • raw WebGPU

Realtime vs OIDN

Noisy SSR denoised two ways: three's temporal recurrentDenoise every frame vs OIDN single-image denoising on a cadence.

  • OIDN
  • three.js

Pipelines & performance

Denoise and upscale on one GPUDevice, and the numbers behind it.

Tools & tests

Internal harnesses, smoke tests and probes. They run locally with yarn examples and are not deployed.

Run the examples locally

git clone https://github.com/pmndrs/denoiser
cd denoiser
yarn install
yarn build:lib
yarn examples          # http://localhost:5160/

One dev server for everything: this page at / and every example at /<name>/, the same paths as this site. The tools & tests above only run there. yarn examples --list prints them; yarn examples <name> starts one example on its own.

Enable WebNN in Chrome

The WebNN runtime (and AutoRuntime's fp16 WebNN path) needs WebNN, which Chrome still ships behind a flag. Without it the examples fall back to WGSL and the WebNN button is greyed out.

Turn on chrome://flags/#web-machine-learning-neural-network ("WebNN API") and relaunch, or start Chrome with:

--enable-features=WebMachineLearningNeuralNetwork