If it is device specific I would like it to be documented as such. Most devices use sRGB, but it is possible that a device does not. In the future if Roblox supports HDR that would make this documentation even more important.
Additionally this documentation is important because of other color spaces. If I want to use the Oklab color space to blend between colors I’ll need to convert Color3’s into Oklab, however the conversion is different depending on if Roblox uses sRGB or linear RGB, or some other color space.
I believe Color3 is simply data that contains R, G, and B values.
Imo, when Color3 is applied to UI elements, parts, or decals, it appears that the renderer interprets it as sRGB. In other words, it may square each component of the color by 2.2.
also before the 3D renderer displays colors on the monitor, it maps them within the [0, 1] range using HDR tone mapping.
I may be wrong, but I think it might be more accurate to say that the renderer converts Color3 into sRGB, rather than recognizing Color3 as sRGB.
Different properties consuming the Color3 may interpret it in different ways. For example, colors you use in a GUI get directly copied to the screen but ones used for 3d content may be mapped in a more complex way even ignoring the impact of lighting. You can see this if you put a (flat-shaded) HandleAdornment and (gui) Frame with the same color next to each other:
There may be room to talk about color space in the documentation for particular properties but not on the type.
I think it makes sense to mention it on the type as well because that is where I (and potentially others) immediately went to for documentation. Having this information documented somewhere is definitely useful though.
As far as I can tell, UI is absolutely not linear RGB - if you mix red and green, you get a very dark yellow, which indicates no gamma correction is applied.
Another video that’s much more in-depth for people who want to learn more about colour science:
I don’t know the right precise terminology, but in simple terms, the GUI just sticks the color on the screen as is vs the 3d view does something more complex, I believe even ignoring the impact of lightning.
You can see this if you put a Frame and a HandleAdornment with the same color next to eachother:
All Color3s use the same RGB colour model represented as 0-1 values for red, green and blue, but the actual reproducible colours and processing of colours depends on where in the engine you’re inputting the colour from. General rule of thumb is that anything before the tonemapper is linear RGB and anything after is (probably) gamma.
Something potentially interesting to add to this: it depends on the lighting technology mode. If the mode is Compatibility, colors will be the same (also assuming no extra layered lighting effects).
Left: BoxHandleAdornment, Center: Gui Frame, Right: Part
Also, for some reason they do appear the same color in all lighting modes in the studio viewport. But when I take an image of it and view it as that, they are clearly different. Not sure why that is the case because my monitor is correctly calibrated.
I said they appear the same color, but that is only for my eyes. Using a color picker in the studio viewport does result in varying colors for each (when lighting tech mode is not compatibility). The difference is just more visually different in images.
Compatibility uses a tweaked tonemapper that tries to explicitly match the colours as a compatibility measure, hence the name.
It’s a holdover from very old games pre-Future is Bright. You’ll notice it has a bunch of other knock-on effects, like grossly clipping the brightness of lights, because that’s some of the other outdated behaviour it tries to recreate to keep old games working.
Thanks for the insight! I am just a bit confused still on what the actual conclusion of this post is though. In the context of rendering GUIs vs. world. Are Color3s inherently linear as an input?
For example, in world rendering is it true to say the tonemapper encodes/transforms Color3 which then eventually gets rendered correctly as sRGB but with extra layered lighting effects?
Then for GUI rendering, the example image you provided shows the blended color being quite dark. And shouldn’t that be an indicator that for GUIs, Color3 is not being encoded automatically? Or is it the opposite?
EDIT: When I say “inherently linear” I mean it in a way where Color3s exist in a linear space. The way I understand this topic is, to display sRGB on a display the pipeline is as follows:
linearRGB → software encodes as sRGB → monitor decodes for proper rendering
I may be saying things incorrectly, but to clarify by linear I mean what the data is considered before any potential encoding/transforms for a particular system. So for example, in GUI rendering, if we can blend Color3 and it displays properly as sRGB when drawn then would it not be accurate to say Color3 for this specific usecase exists in a linear space before rendering?
However, from your tests was the blended color the true sRGB color or no? If no that would mean Color3 is not getting automatically encoded, by Roblox, as sRGB which wouldn’t be good right?
Linear has a very specific meaning in colour science. A linear colour space means that colours are generated by linearly moving between the three primaries of the colour space (in this case, red, green and blue).
Monitors almost universally output colours in the sRGB colour space. sRGB is not linear because an exponent is applied to the colour channels. Therefore, to display a linear RGB colour on a monitor, you must apply ‘processing’ in the form of that exponent.
So UI objects are not linear RGB, they are sRGB. However, because they’re sRGB and the display is sRGB, no processing is required.
I understand the idea behind linear color spaces. I keep saying linear RGB because I am talking about what the data can be interpreted as before any transformations in a specific system. Another way to think about it is the colors are already technically sRGB because they will be encoded, but I think of it in terms of they haven’t been encoded yet and they exist in a linear space (linear RGB) in this particular case.
In other words
The result of rendering the data can be viewed as sRGB, but I am talking about what the data is initially considered. Hardware doesn’t automatically encode as sRGB; whatever software is in charge of that. Whether they actually do it or not is what I am trying to figure out in the case of Roblox. I agree that data can be interpreted in different ways depending on the scenario, but I am focusing on a specific scenario.
I ran a test, generating a gradient of shades of gray. I think it is safe to say that Roblox is automatically encoding as sRGB for GUIs. Below shows the classification for what I will label my results after.
My Results
Top: sRGB (perceptually linear brightness) Bottom: physically linear brightness
To achieve the bottom result, I did an extra, manual gamma encode. If the engine was not encoding automatically as sRGB then the bottom would appear as the top, but since it is being shown as such this actually proves the engine does encode as sRGB automatically for GUIs which is good.