GLTFLoader .metallicF0Factor affects rendered color of the albedo texture


PBR materials created by GLTFLoader when importing glTF asset have other than standard value of the .metallicF0Factor property, which leads to subtle color tint in the rendering (blue color get violetish tone). In accordance with glTF spec, the default .metallicF0Factor should be 0.04 for non-metals.
Setting .metallicF0Factor property to its default value of 0.004 resolves this issue.

Is it a bug? Or there is something else I should consider?

Summoning @sebavan

Yup it defaults to 0.04 for us. A repro would be nice to check your issue deeper but it feels right that the tint shifts a bit.


This is the repo:
Just a simple glTF loader.

You can inspect the metallic properties of the 'Wolf Classic Full Line.CABINET_DOOR_FINISH.-1213503305’ non-conductive material. It’s F0 Factor = 1.

It’s not hard to make a workaround in my code such as
pbr.metallicF0Factor = 0.04;

But I think, it should be done (if it should) by GLTFLoader, where default PBRMaterial is used. Just to follow the glTF spec.


In fact, the small difference in color makes noticable difference in the rendered image. The image at the centre is the original texture, the image on right side is with factor 0.04.

This is all expected from a gltf standpoint the factor is a multiplier to the default value which is 0.04 so placing 0.04 in the factor is equivalent to a value of 0.0016 which is really low.

F0 is inferred from the ior value to default to 0.04 with default being 1.5.

The color shift comes from the ibl lighting in your case.

Maybe @PatrickRyan would have some other feedback ?

@val, I would definitely take a look at your lighting setup, if you are trying to match your base color, especially on flat surfaces like cabinet doors, it is mostly about the lighting setup. Here is a sample PG that I have been using to demonstrate this:

You can see in both of these images that you have a chip in the upper left of each colored sphere/cube which is an emissive texture of the base color applied to the mesh. This has no lighting information on it so it is a faithful representation of the base color texture. The reason it matches the color in the mesh, which is lit, has to do with the angle and quality of the light in the environment. We are using large area lights and the rotation gives us the most faithful representation of the base color.

However, if you go into the environment texture and rotate the environment, you will see we deviate from the color quite a bit:

It also stands to reason that if you have an environment that is too dark like this one you will also have a shift:

This is the same for one that is too bright as well. You also need to consider tone mapping which can also make a difference. This version is enabling ACES tone mapping, but also an exposure adjustment to compensate for the fact that the ACES curve was developed to be seen on a bright screen in a dark room:

All of these elements play a role in matching the final render of your scene to the input color. Lighting will certainly always play a role in the final color output, otherwise we would just set all materials to unlit and skip lighting calculations all together, but this would not feel realistic as no surface is so evenly lit that it only shows the material pigment color with no specular reflections or shadow contributions.

The trick here is to balance the light in your scene to make your materials feel as they should which includes placement, size and intensity, even if you are talking about an IBL. This IBL was authored in Maya and rendered out to give a specific look with the positions, size, and intensity of each light contributing to the final look:

I would look at your light placement (if you are using punctual lights) as well as the rotation of your environment. It may also be beneficial to author an HDRI that gives your products the best overall look if you are rendering out a lot of similar types of products. Placement of lights in this case should be higher so that we get more of a downlight render with some bounce which will look more natural as this is what we are used to seeing in real life.

1 Like


Thank you for your answer. But I assume that the IBL may provide color shift for metals only. Non-conductive materials should not change their albedo color (I mean hue) in PBR.

Most PBR guides states F0~0.04 for non-metals. Why loaded glTF non-conductive material has high metallic F0? Is it correct?


Hi Patrick,

Thank you for your detailed explanation. And thanks for this great calibrating PG.

I understand that the PBR works much better on spheres rather than on flat surfaces. And definitely I don’t aim to achieve ‘pbr.unlit=true’ flat rendering. Also, it’s true that the “correct” picture highly depends on the lighting setup setup and direction on the key light - mostly only one direction angle from 360 gives most suitable (say photorealistic) result.

In addition to IBL I use 6 x light cluster of 3 angled downlights+3 softer angled uplights (something like 3-point lighting in your Studio texture) plus at least one key light (PointLight) to produce shadows. The number of additional lights is indeterminated.
But the PG with only IBL is sufficient to illustrate what I think looks a bit incorrect.

I think that the door material, which is non-metal receives to many specular highlights due to high F0 value of the glTF imported material (you can inspect metallic properties of said material to see the actual F0 valu). Setting F0 factor to the value of 0.04, which most PBR cookbooks recommend makes wood looks more realistic (see attached image) even with only IBL lighting.

But, I assume that is my only opinion and it may be not correct at all. Definitely just looking at the picture I can’t decide the correct level of highlights for the material with particular roughness settings. I’ll try to use your calibrating environment to play with wooden textures - to see how they look with different roughness level compared to flat colors.

Thanks again

They do not have high F0 only 0.04 which maps to polyurethane. This is rhe default value from the spec as well. Think about a sharp glossy ballon this is not metallic for instance but heavily reflective. Also even fully diffuse would be impacted by the env (by its diffuse contribution)

From your other answer, you change a factor, and not F0.

F0 is 0.04 but you add an extra factor making it 0.04 * 0.04 = 0.0016 which is smaller than the default in cookbooks.


It is my bad. Just confused with the property name. So the effective f0 = f0 value * f0 factor. Got it.

Thank you for your time

1 Like

Thank you for trying to help me. But I don’t want to take your time working with the model, which is just 3d visualization of the particular floorplan design using procedural models of cabinetry with indeteminated number of punctual lights (recessed lights, etc).

Hdri. Yes, I really want to switch to ibl almost at full (with custom HDRI textures), but so far I have to use punctual lighting to get the realistic reflections of scene geometry at the cabinet doors. While hdri reflections I put on the metallic parts, because hdri provides much better visuals on small metallic parts than reflection probes do.

Babylonjs 4.2 introduced very interesting ‘ray-tracer’ alike reflections I want to switch to when version 5.0 will be released. I hope I can get rid off reflection probes and redesign my lighting setup.