@vshaders/color
v0.2.0
Published
OKLab/OKLCH conversions, perceptual color mixing, and procedural palettes as pure WGSL modules for vgpu shaders
Downloads
157
Maintainers
Readme
@vshaders/color
OKLab/OKLCH conversions, perceptual color mixing, and procedural palettes as pure WGSL modules for vgpu shaders:
import { mixOklab } from "@vshaders/color/oklab";
import { linearToSrgb3 } from "@vgpu/wgsl-std/color";
@fragment fn main(@builtin(position) position: vec4f) -> @location(0) vec4f {
let t = position.x / 512.0;
let gradient = mixOklab(vec3f(0.05, 0.03, 0.35), vec3f(0.9, 0.18, 0.12), t);
return vec4f(linearToSrgb3(gradient), 1.0);
}Why OKLab: naive RGB interpolation dips through gray in the middle of a gradient; interpolating in OKLab keeps perceived lightness and vividness even. It is the same reasoning behind CSS oklch(), in your shader.
All conversions operate on linear-light sRGB. Cross into and out of encoded sRGB with srgbToLinear3 / linearToSrgb3 from @vgpu/wgsl-std/color — this package composes with the standard library rather than duplicating it.
@vshaders/color/oklab
linearSrgbToOklab(color: vec3f) -> vec3foklabToLinearSrgb(lab: vec3f) -> vec3f— out-of-gamut results are not clamped; clamp or gamut-map explicitly.oklabToOklch(lab: vec3f) -> vec3f— returns(lightness, chroma, hueRadians). The hue of an achromatic color (chroma == 0) is indeterminate, asatan2(0, 0)is unspecified in WGSL.oklchToOklab(lch: vec3f) -> vec3fmixOklab(colorA: vec3f, colorB: vec3f, t: f32) -> vec3f— perceptually even blend between two linear-light sRGB colors; unclamped int.
@vshaders/color/palette
cosinePalette(t: f32, bias: vec3f, amplitude: vec3f, frequency: vec3f, phase: vec3f) -> vec3f— the cosine gradientbias + amplitude * cos(tau * (frequency * t + phase)).tis unbounded; withfrequency = vec3f(1.0)the palette repeats with period 1. Output is in whatever light spacebias/amplitudeare given in.
Provenance
The OKLab conversion matrices are Björn Ottosson's published reference implementation (bottosson.github.io/posts/oklab, public domain), transcribed to WGSL with a sign-safe cube root so slightly out-of-gamut inputs don't produce NaN. The cosine palette is a direct expression of the formula popularized by Inigo Quilez (iquilezles.org/articles/palettes).
License
MIT
