The 3D Handbook
Key term

Colour space: sRGB and linear

Why colour textures are stored in sRGB but lit in linear space, how the sRGB curve turns stored values into light, which maps must skip the conversion, and what goes wrong when the flag is set wrongly.

materialstexturingcolourengines

A colour space tells the engine how to read the numbers in a texture. Colour textures are stored in sRGB, a curved encoding, while lighting maths runs in linear space, where twice the number means twice the light. GPU Gems states the rule: "Renderers, shaders, and compositors like to operate with linear data" (Gritz & d'Eon 2007).

For a texture artist this comes down to one checkbox per texture. With the correct setting, materials look the same in every engine. With the wrong one, a roughness map turns glossy or a base colour washes out, although the file itself looks normal.

#Why there are two spaces

Screens do not turn pixel values into light in a straight line. Gritz and d'Eon explain that "A typical gamma of 2.2 means that a pixel at 50 percent intensity emits less than a quarter of the light" (Gritz & d'Eon 2007). sRGB is the standard encoding built around this behaviour. HP and Microsoft proposed it in 1996 and it became the IEC standard 61966-2-1 in 1999 (Wikipedia: sRGB). Its curve combines "a linear function at low brightness values and a displaced power law for the rest of the range", and simplified implementations approximate it as plain gamma 2.2 (Wikipedia: sRGB).

Lighting, on the other hand, adds and multiplies amounts of light. If you light the stored sRGB numbers directly, GPU Gems warns, "the scene will appear dimmer than an accurate simulation" (Gritz & d'Eon 2007). So engines decode sRGB textures to linear values when they sample them, light the scene in linear, and encode the result for the screen at the end. Unity describes this process: it uses "your GPU's sRGB sampler by default to crossover from gamma to linear color space" (Unity Manual: Introduction to linear color space in Unity), and says linear rendering "gives more accurate rendering than working in gamma color space" (Unity Manual: Introduction to linear color space in Unity).

A graph with stored 8-bit sRGB values from 0 to 255 on the horizontal axis and linear values from 0 to 1 on the vertical axis. A dashed grey diagonal shows what a linear mapping would look like. An orange curve sags well below it. Marked points show 128 becoming 0.216 and 188 becoming 0.50.
The sRGB decoding curve. A mid-grey of 128 in your image editor is only about 22% light; it takes 188 to reach half. Values computed with the standard sRGB formula.Diagram by the handbook author

#Decoded values

The standard decoding, as written in the W3C's reference code, divides small values by 12.92 and raises the rest with ((value + 0.055) / 1.055)^2.4 (w3c/csswg-drafts: Sample code for color conversions). Worked through for 8-bit values:

Stored sRGB (0–255) Linear value What it means
50 0.032 A dark base colour
128 0.216 "Mid-grey" in Photoshop, but only about a fifth of the light
188 0.503 The halfway point in light
240 0.871 A very bright base colour

#Which maps are colour and which are data

The rule: if a human judged the texture by eye as a colour, it is sRGB. If it stores a number the shader uses for maths, it is linear.

A channel-packed ORM texture holds three data maps, so it is always linear.

#Filtering and blending in linear space

The conversion matters for more than lighting. glTF asks that the transfer function be decoded "prior to linear interpolation" when a texture is filtered (Khronos Group: glTF 2.0 Specification), and notes that graphics APIs have "dedicated sRGB texture format enums" for this (Khronos Group: glTF 2.0 Specification). GPU Gems uses a two-pixel edge, "two pixels at 1.0 and two at 0.0", to show that averaging stored gamma values gives the wrong result (Gritz & d'Eon 2007). Worked through: averaging stored 0 and 255 gives 127.5, which decodes to about 0.21 of the light, not the 0.5 a real mix of black and white would give. This is why mipmaps of colour textures must be built from linear values.

#In different tools

#Further reading and watching

Related: texture maps explained, texture formats, compression and mipmaps, physically based rendering, bit depth and banding, tonemapping.

References

  1. Larry Gritz and Eugene d'Eon · Chapter 24. The Importance of Being Linear · GPU Gems 3 (NVIDIA), 2007 · book · accessed 2026-10-21
  2. Wikipedia contributors · sRGB · Wikipedia · web · accessed 2026-10-21
  3. Unity Technologies · Introduction to linear color space in Unity · Unity Manual (6000.2) · docs · accessed 2026-10-21
  4. W3C CSS Working Group · Sample code for color conversions (CSS Color Module Level 4) · w3c/csswg-drafts (GitHub) · docs · accessed 2026-10-21
  5. Khronos Group · glTF 2.0 Specification · Khronos Group (GitHub) · docs · accessed 2026-10-21
  6. Epic Games · Texture Compression Settings (Unreal Engine 4.27) · Unreal Engine documentation, 2021 · docs · accessed 2026-10-21
  7. Unity Technologies · Default texture import settings reference · Unity Manual (6000.2) · docs · accessed 2026-10-21
  8. Godot Engine contributors · Importing images (documentation source) · Godot documentation (GitHub) · docs · accessed 2026-10-21

Last updated 2026-10-22