---
title: @vgpu/wgsl-std/color
description: Pure WGSL color utilities for shaders resolved by `@vgpu/wgsl`. Import these functions from WGSL modules when you need sRGB transfer, luminance, exposure, tone mapping, or bloom threshold helpers without declaring any resources.
---

# @vgpu/wgsl-std/color



## Import

```wgsl
import { applyExposure, luminance, luminanceThreshold, tonemapAces, tonemapReinhard } from "@vgpu/wgsl-std/color";
```

## Signature

```wgsl
export fn luminance(value: vec3f) -> f32;
export fn applyExposure(value: vec3f, exposure: f32) -> vec3f;
export fn srgbToLinear(value: f32) -> f32;
export fn srgbToLinear3(value: vec3f) -> vec3f;
export fn srgbToLinear4(value: vec4f) -> vec4f;
export fn linearToSrgb(value: f32) -> f32;
export fn linearToSrgb3(value: vec3f) -> vec3f;
export fn linearToSrgb4(value: vec4f) -> vec4f;
export fn tonemapAces(value: vec3f) -> vec3f;
export fn tonemapReinhard(value: vec3f) -> vec3f;
export fn luminanceThreshold(value: vec3f, threshold: f32, softKnee: f32) -> vec3f;
```

## Parameters

| Param     | Type    | Required | Default | Notes                                                                                                                                                              |
| --------- | ------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| value     | `f32`   | ✔        | —       | Scalar color channel for `srgbToLinear` or `linearToSrgb`. Expected range is usually `[0.0, 1.0]`; helpers do not clamp scalar transfer inputs.                    |
| value     | `vec3f` | ✔        | —       | RGB/linear-HDR color for `luminance`, `applyExposure`, `tonemap*`, `luminanceThreshold`, `srgbToLinear3`, and `linearToSrgb3`.                                     |
| value     | `vec4f` | ✔        | —       | RGBA color for `srgbToLinear4` and `linearToSrgb4`; RGB is converted and alpha is preserved unchanged.                                                             |
| exposure  | `f32`   | ✔        | —       | Exposure in stops/EV for `applyExposure`; `1.0` doubles, `0.0` leaves unchanged, `-2.0` multiplies by `0.25`.                                                      |
| threshold | `f32`   | ✔        | —       | Linear luminance threshold for `luminanceThreshold`.                                                                                                               |
| softKnee  | `f32`   | ✔        | —       | Width of bright-pass transition. Internally clamped with `max(softKnee, 0.000001)`, so `0.0` behaves as an extremely hard edge without invalid `smoothstep` edges. |

**Returns:** WGSL functions return `f32`, `vec3f`, or `vec4f` as declared. Transfer helpers return converted color, `luminance` returns Rec.709/sRGB relative luminance, exposure/tonemap/threshold helpers return linear color values.

**Throws:** These WGSL declarations do not throw. `resolveShader()` can still throw `VGPU-WGSL-SYM-NOEXPORT` for misspelled imports, `VGPU-WGSL-PKG-NOTFOUND` if the package import cannot be resolved, or validation errors such as `VGPU-WGSL-NAGA-UNKNOWN` if caller WGSL is invalid.

## Examples

```ts
const shaderWgsl = `
import { applyExposure, linearToSrgb3, srgbToLinear3, tonemapAces } from "@vgpu/wgsl-std/color";

fn grade(baseColorSrgb: vec3f, exposureStops: f32) -> vec3f {
  let linear = srgbToLinear3(baseColorSrgb);
  let exposed = applyExposure(linear, exposureStops);
  return linearToSrgb3(tonemapAces(exposed));
}
`;

console.log(shaderWgsl.includes("tonemapAces"));
```

```ts
const bloomWgsl = `
import { luminanceThreshold } from "@vgpu/wgsl-std/color";

fn bloomExtract(hdrColor: vec3f) -> vec3f {
  return luminanceThreshold(hdrColor, 1.0, 0.25);
}
`;

console.log(bloomWgsl.length > 0);
```

## Notes

* This module is pure WGSL: it declares no `@group`, no `@binding`, no overrides, no hidden state, and no entry points. It is safe to import into resolver graphs.
* `luminance` uses `dot(value, vec3f(0.2126, 0.7152, 0.0722))`; pass linear-light colors, not encoded sRGB.
* `tonemapAces` implements the Narkowicz ACES fit and clamps to `[0.0, 1.0]`; `tonemapReinhard` uses `value / (1.0 + luminance(value))` and does not explicitly clamp.
* sRGB transfer helpers implement the standard piecewise formulas and do not clamp. Clamp explicitly if your target requires saturated display-range values.
* This module intentionally does not include PBR, BRDF, Fresnel, IBL, Hable/Filament tone mappers, or a default display pipeline.
* **See also:** `@vgpu/wgsl-std/hash`, `@vgpu/wgsl-std/noise`, `resolveShader`.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)