As a Roblox developer, it is currently too hard to do advanced color correction.
If Roblox is able to address this issue, it would improve my development experience because it would allow very fine grained control over how a game looks and feels, and it would allow for a wide variety of fancy effects.
A color LUT and a LUT for colors valued 1-2 instead of 0-1 would be ideal.
All the information below is intended to describe what LUTs are, how they can be used, how they impact Roblox, etc, but ultimately nothing below is significantly important to the feature request.
Use cases (Also the tl;dr)
LUTs can efficiently account for quite a few post processing shaders without requiring developers to be able to write their own shader code for Roblox, which has a whole host of problems associated with it.
Uses color LUTS would add:
- Any basic color correction effect is supported, Roblox doesn’t have to do anything
- Sepia effect
- Curves effect
- Spooky or cartoony LUTs
- Making some colors glow more than others, or tuning the glow of colors in a game
- Assuming LUT effects could be phased or interpolated, making colors smoothly blink, flash, flicker, etc. (E.g. making the border around a door flash smoothly)
What is a LUT?
A color LUT (color lookup table) is an image which maps all possible colors to a set of new colors. Many games use LUTs for color correction because LUTs allow you to apply any color transformations that affect single pixel colors without requiring information about other pixels, such as brightness, contrast, saturation, hue shifts, and more.
LUTs allow for all the things that a Roblox ColorCorrectionEffect
does, but LUTs allow for conditional control of how colors are tuned, since you can map any color to any other color.
Caveats and constraints
The entire RGB space can be represented using a single 4096x4096 LUT texture (4 1024x1024 Roblox textures, since 1024x1024 is the max texture resolution), which uncompressed is only 67.1 MB of VRAM. Since a PNG can store full RGBA, the alpha channel is additionally free to control something, such as the strength of bloom (emissivity).
LUTs with emissivity (HDR LUTs in Roblox)
Unfortunately, a LUT that controls emissivity uniquely for every single possible color would not be realistic, as the entire RGBA space is much, much bigger, and therefore much more costly to represent in RAM. A full LUT would be a 65536x65536 RGBA texture (17.17 GB uncompressed, good luck fitting that in VRAM )
However, since a single LUT texture maps 256x256x256 colors with values from 0-1, simply duplicating this LUT allows for mapping colors which have higher values than 1 (value as in HSV) e.g. mapping colors in the value range 1-2, allowing you to still effectively LUT colors that glow even if you can’t map finely by input color value. (In simpler terms, if you have glowy red and slightly glowier red, you can’t make the glowy red blue while you make the slightly glowier red green, since you can’t map by the glowiness, they’d both have to be the same final glowiness)
Interpolation can be used past values of 2 to attempt to approximate LUT values beyond 2. For example, clamping the input value of the color from 0-2 when deciding the LUT to use, and then scaling the output LUT by the additional LUT (e.g. if the value of the input color is 3, and the output LUT is 0.5, the final value would be 0.5 * (1 + (3 - 2))
, multiplying the value by 1
plus the extra color value above 2
.