# OIDNDenoiser

class in `three-gpu-pathtracer/webgpu`

```js
import { OIDNDenoiser } from 'three-gpu-pathtracer/webgpu';
```

Runs Open Image Denoise over a path traced image. Pass one to
"WebGPUPathTracer.setDenoiser", or drive it directly with "denoise".

"initUNetFromURL" and the weights are passed in rather than imported so neither the library
nor the network files become a dependency.

```js
import { initUNetFromURL } from 'oidn-web';
pathTracer.setDenoiser( new OIDNDenoiser( { initUNetFromURL, auxWeightsUrl } ) );
```

Weights come from the oidn-weights repository, where the "_small" and "_large" variants trade
quality against download size and per tile cost.

Example: Denoising a path traced image after a few samples

```js
import { ACESFilmicToneMapping, Color, EquirectangularReflectionMapping } from 'three/webgpu';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { HDRLoader } from 'three/addons/loaders/HDRLoader.js';
import { createFloor } from './floor.js';
import { initUNetFromURL } from 'oidn-web';
import { WebGPUPathTracer, OIDNDenoiser, RANDOM_SOBOL } from 'three-gpu-pathtracer/webgpu';

// scene, camera and renderer are initialized here

const URL = 'https://raw.githubusercontent.com/gkjohnson/3d-demo-data/main/models/nasa-m2020/Perseverance.glb';
const ENV_URL = 'https://raw.githubusercontent.com/gkjohnson/3d-demo-data/main/hdri/chinese_garden_1k.hdr';
const WEIGHTS_URL = 'https://raw.githubusercontent.com/gkjohnson/three-gpu-pathtracer/v0.0.25/example/src/denoise/rt_hdr_alb_nrm.tza';

const { scene: model } = await new GLTFLoader()
	.setDRACOLoader( new DRACOLoader() )
	.loadAsync( URL );
const environment = await new HDRLoader().loadAsync( ENV_URL );

environment.mapping = EquirectangularReflectionMapping;
scene.environment = environment;
scene.background = new Color( 0xeeeeee );
renderer.toneMapping = ACESFilmicToneMapping;

model.position.z = - 0.32;
scene.add( model, createFloor() );

camera.position.set( - 3.2, 2.2, 4.6 );
controls.target.set( 0, 0.9, 0 );
controls.update();

const pathTracer = new WebGPUPathTracer( renderer );

// 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 );

}
pathTracer.maxSamples = 6;
pathTracer.setRandom( RANDOM_SOBOL );
pathTracer.setDenoiser( new OIDNDenoiser( { initUNetFromURL, auxWeightsUrl: WEIGHTS_URL } ) );
pathTracer.setScene( scene, camera );
controls.addEventListener( 'change', () => pathTracer.updateCamera() );
window.addEventListener( 'resize', () => pathTracer.updateCamera() );
renderer.setAnimationLoop( () => pathTracer.renderSample() );
```

## Constructor

```js
new OIDNDenoiser( options: Object )
```

Every field below can also be assigned after construction.

- `options`, `Object`
  - `initUNetFromURL`, `function`
  - `auxWeightsUrl`, `string`: Weights for the guided model.
  - `colorWeightsUrl`, `string`, optional: Weights for the color only model, needed only
when `useAuxiliaryBuffers` is `false`.
  - `useAuxiliaryBuffers`, `boolean`, optional
  - `maxTileSize`, `number | null`, optional
  - `dynamicTile`, `DynamicTileSetting | null`, optional: `false` pins every tile to
`maxTileSize`. An object tunes the adaptive sizing.

## Properties

### .texture: ExternalTexture | null

The denoised result, or null until the first tile has been produced.

### .complete: boolean

Whether a pass has finished. Stays true until reset.

### .running: boolean

Whether a pass is running. The work is spread over several frames.

## Methods

### .init

```js
.init( renderer: WebGPURenderer )
```

- `renderer`, `WebGPURenderer`

### .setScene

```js
.setScene( scene: Scene, camera: Camera )
```

- `scene`, `Scene`
- `camera`, `Camera`

### .update

```js
.update( target: Texture ): Texture | null
```

Renders the auxiliary buffers and starts a pass. Safe to call every frame.

- `target`, `Texture`: The path traced result, in linear HDR.

### .denoise

```js
async .denoise( color: Texture, albedo: Texture | null, normal: Texture | null )
```

Runs a pass unless one is already running or finished. The optional albedo and normal
buffers guide the filter and select the guided model. Both hold [0,1] values, with normals
mapped so a flat normal is (0.5, 0.5, 1).

- `color`, `Texture`: The path traced result, in linear HDR.
- `albedo`, `Texture | null`, default `null`
- `normal`, `Texture | null`, default `null`

### .reset

```js
.reset(  )
```

Drops any running pass and the last result. Call it whenever the image changes, such as when
the camera moves.
