# Tone Mapping & Exposure

Lighting calculations happen in high dynamic range: the intensity of a pixel can far exceed what a standard display can show. Tone mapping is the final transform that compresses this HDR range into displayable colors, and it has a major impact on the look of your scene. In PlayCanvas, tone mapping is set per camera.

## Tone Mapping

The available tone mapping curves are:

* [`TONEMAP_LINEAR`](https://api.playcanvas.com/engine/variables/TONEMAP_LINEAR.html) — no compression; bright values simply clip at white. The default.
* [`TONEMAP_FILMIC`](https://api.playcanvas.com/engine/variables/TONEMAP_FILMIC.html) — a classic filmic curve with gentle roll-off in the highlights.
* [`TONEMAP_HEJL`](https://api.playcanvas.com/engine/variables/TONEMAP_HEJL.html) — a punchy, contrasty filmic approximation.
* [`TONEMAP_ACES`](https://api.playcanvas.com/engine/variables/TONEMAP_ACES.html) — the Academy Color Encoding System curve, widely used for cinematic, photorealistic rendering.
* [`TONEMAP_ACES2`](https://api.playcanvas.com/engine/variables/TONEMAP_ACES2.html) — a variant of ACES with a different balance of contrast and saturation.
* [`TONEMAP_NEUTRAL`](https://api.playcanvas.com/engine/variables/TONEMAP_NEUTRAL.html) — compresses highlights while keeping hue and saturation shifts minimal; a good choice when accurate colors matter (e.g. product configurators).

For physically based scenes with HDR lighting, `TONEMAP_ACES` or `TONEMAP_NEUTRAL` are usually the best starting points.

**Engine**

```javascript
camera.camera.toneMapping = pc.TONEMAP_ACES;
```

**Editor**

Select the camera in the Hierarchy and set **Tonemapping** in the [Camera Component](https://developer.playcanvas.com/user-manual/editor/scenes/components/camera.md).

**React**

```jsx
import { TONEMAP_ACES } from 'playcanvas';

<Entity name="camera">
  <Camera toneMapping={TONEMAP_ACES} />
</Entity>
```

**Web Components**

```html
<!-- tonemap: none | linear | filmic | hejl | aces | aces2 | neutral -->
<pc-entity name="camera">
  <pc-camera tonemap="aces"></pc-camera>
</pc-entity>
```

:::note

When post-processing is active via [CameraFrame](https://developer.playcanvas.com/user-manual/graphics/posteffects/cameraframe.md), tone mapping is applied by the post-processing pipeline instead — set it on the `CameraFrame`'s rendering options rather than the camera.

:::

## Gamma Correction

After tone mapping, the camera's output is gamma-encoded for display on standard sRGB screens. This is controlled by `gammaCorrection`:

* [`GAMMA_SRGB`](https://api.playcanvas.com/engine/variables/GAMMA_SRGB.html) — output is encoded for sRGB displays. The default and recommended setting for all normal rendering.
* [`GAMMA_NONE`](https://api.playcanvas.com/engine/variables/GAMMA_NONE.html) — output remains in linear space. This is only intended for advanced HDR pipelines where the output is rendered to an intermediate HDR texture that is tone mapped and gamma-corrected in a subsequent pass. On a standard display, it makes the scene appear too dark.

To understand why rendering is performed in linear space and gamma-encoded at the end, see [Linear Workflow](https://developer.playcanvas.com/user-manual/graphics/linear-workflow.md).

## Physical Exposure

By default, scene brightness is controlled by a simple `scene.exposure` multiplier. Alternatively, the camera can model the exposure of a physical camera using three properties familiar to photographers:

```javascript
app.scene.physicalUnits = true; // light intensities are now in physical units (lux)

camera.camera.aperture = 16;        // f-stops — higher means less exposure (default: 16)
camera.camera.shutter = 1 / 1000;   // seconds — longer means more exposure (default: 1/1000)
camera.camera.sensitivity = 1000;   // ISO — higher means more exposure (default: 1000)
```

:::note

`aperture`, `shutter` and `sensitivity` only take effect when `scene.physicalUnits` is `true`. When it is `false` (the default), `scene.exposure` is used instead.

:::

See it in action in the engine's physical units example:

[Live example: Physical Light Units](https://playcanvas.com/examples/#/graphics/light-physical-units) ([source](https://github.com/playcanvas/engine/blob/main/examples/src/examples/graphics/light-physical-units.example.mjs))
