How do you deal with clipping when rendering to a limited colorspace? In my naïve raytracer experiment I work internally with RGB values, and after all the tracing has been done, I end up with raw RGB triplets that I need to write down to some image format with a limited gamut, typically sRGB.

Since bright spots in my image can have values far beyond (1,1,1), I need to clip them. Right now I just limit each channel individually, but that will obviously introduce a shift in hue when one channel clips before another. Here is a typical (enlarged) example from my code where the yellow-green object turns into yellow around the highlight:



I'm now looking for a way to solve this problem, but all the solutions I come up with seems to have the same drawback: eventually you have to discard information. For example, I've thought about working with another colorspace like Lab internally, but even then I would first have to transform it to sRGB for rendering the final image file.

Before I dig myself into this any further, I would like to see if there is either:


An objectively "best" way to solve this problem, or..
An industry standard way that is used in practice
Effectively, before you start to think about clipping/clamping, you'll need a general approach to map the much wider color range you are working in onto the [0,1] triplets you want to output. There are various way to do this, look up HDR tone mapping to get a good first impression of what is possible. Simply clipping things to [0,1] will leave you with a very cramped color space to work in, throwing away much of the advantages of raytracying in "high dynamic range" (floats).

On to the actual problem at hand, to prevent clamped colours from shifting hue, a naive but functional approach is:


Take the max component m from (R, G, B)
If m > 1, scale all three components by 1 / m.


This does not take the relative luminance of the color components into account, but if you eventually end up doing something like tone-mapping anyway that would be a better time to tackle that problem.