Color are by default linear or gamma space? & What does the PBR Node expect as Input for baseColor and ambientColor

Hi Folks,

i have some questions regarding the PBR Node inputs and Color Values in General.

  1. When I generate a Color with a Color Node is this color in gamma space or linear space?
    (The node offers to convert in both spaces, but I dont know was is the default, if I select nothing)
    BTW: When I calculate my own lighting (e.g. a Rim Light) in the NME I use for the light color the option convert to linear space but i am unsure if this is right.

2.When i use the PBR Node inputs Albedo and Ambient Color, do they expect the colors to be in linear space or gamma space?

Great questions!

  1. Color defaults to linear space IIRC, so you’re right to be aware and cautious of the need to convert to gamma space.

PBR rendered output is almost always going to be gamma space natch, but your color operations don’t need to be ofc (it can cause incorrect results). Do your calcs in linear and convert to gamma at the very end when you connect to the output node

  1. I believe it is linear space for those inputs.

Important thing of course being that any color or texture used has sufficient bit-depth to represent the linear, pre-gamma values

HTH!

Just as 52.1 has no unit and can be meters or millimeters depending on your needs or calculations so far, the color of a color block in NME has no color space inherently attached to it. The “convert to linear space” / “convert to gamma space” switch will simply apply a linear / gamma space conversion calculation to the current value. It’s up to you to choose the right conversion (if any), depending on the color space the color is supposed to be at that time and the color space you want this color to be converted to.

PBRMetallicRoughness expects all its color inputs to be in a linear space, unlike Light which expects the colors to be in a gamma space.

1 Like

Yesterday i had a strange test case. I put the color 127,127,127 into the basecolor and pure white into the ambiencolor of the PBR Node. Output was Ambient with gammacorrection activated in the fragment output. This didnt deliver 127,127,127 as output color in my program.

The soultion was to use the POW node with a power of 2.2 on the color before connecting it to the basecolor. With this adjustment i had more or less the expected Color output.

Can you tell me why i had to use the power function to get the correct output?

The “lighting” output of the PBRMetallicRoughness node is in gamma space but the individual output components are in linear space. See Node Material and PBR | Babylon.js Documentation for more context.

1 Like

Hi with all your answers i still dont understand a simple testcase i build today.

Here i select 127,127,127 as the basecolor and the linear ambient output of the PBR Node as the output .
The see the same color the preview window as in the color selector , i have to either mark convert to linear in the color node and convert to gamma in the fragment output or have no conversion in the color node and the fragment output at all.

Shouldnt be the correct setup?: color 127,127,127 as input and only the correct to gamma in the fragment output.

I am not an expert of node materials, but since you feed your PBR metallic with linear, the fragment output should remain linear from the initial. Setting linear a second time to the fragment output will change it again (double it if I can say so). Same with gamma space. I see nothing peculiar in your NME. I can get consistent colors from gamma or linear. I believe if you want to work in a gamma space or linear space, you should choose to do so when you create the color. Altering the output should account what has been previously defined (the way I understand it). But then again, not an NME specialist, so I could be wrong. But then I believe the key point is:

If I apply this rule, it seems to work as expected. Doesn’t it?

The ambientClr output does not correspond to the ambientColor input: there are some calculations that involves the baseColor + ambientColor + metallicF0 values to get the ambientClr output.

If you want to get the same ambientClr than what you put in ambientColor, you must:

  • set the baseColor to full white
  • set the indexOfRefraction to 1

Sorry if i ask one more time: If we break the problem down completely. Does the fragment output expect a linear or a gammacorrected input by default.

The FragmentOutput block does not expect anything by default :slight_smile:

It simply outputs the color connected to its input to the screen. If you select the “Convert to gamma space” or “Convert to linear space” switch in the FragmentOutput block, the corresponding conversion will be performed on the input before generating the final color.

Regardless of what the block expects, we normally expect the final color to be generated in gamma space (sRGB) because of the way most of our display monitors work. To do this, you can either enter a linear color in the FragmentOutput block and select “Convert to gamma space”, or you can enter a gamma space color directly.

1 Like

FYI Patrick recently posted a great article about color space on Medium: How to Take Control of Color Space in Babylon.js | by Babylon.js | Feb, 2023 | Medium

2 Likes

Awesome job. Certainly looks like an article from Patrick :heart_eyes:. I could have detected without a signature. A must have for anyone who wants to master colors, colorspaces and profiling in BJS (and altogether). What would we do without you? :grin: