Weird fresnel rendering and weird fix , please help

Hi All

So I have this hoodie model. If I import it in the sandbax with default index of refraction and FO factor , I get these horrible bright edges on the geometry falloff. :

I then tested bumping index of refraction to maximum and then reducing the FO factor to 0.1 and it removes the issue :

what is going on here??? please help , this does not seem correct , why the weird settings makes it look better than the default?

Here are the two versions of settings exported from sandbox to test :

babylon assets to drag into sandbox and test.zip (4.0 MB)

(look at the hoodie area close to the shirt back)

also as a side not … the exported babylone scenes of the above model is inverting the decal materla UV of its x axis.

The attached test babylon scenes exported from the above glb model have the decal material inverted on the x axis … so that is a bug

Didnt want to report two different issues here , the first issue is what I want to understand , I just happened to then notice the bug of the babylone scenes i provided. here is the original glb model :

hoddie_v_1_1.zip (1.6 MB)

I don’t know what it is but it comes from the model itself and not Babylon.js. There are the same highlights in the official glTF viewer: glTF Sample Viewer


I think the issue is that the PBR metallic roughness model still will have Fresnel because F0 for fully dielectric materials is 0.04 and not 0 since there is no such thing as a perfectly non-specular PBR material. In the real world, the reason why that part of the cloth will be dark is because of occlusion. As in, there is no light that can reach this part of the model. Since there is no occlusion here, it will still reflect the light at grazing angles. IRL, you can test this by looking at a piece of cloth at grazing angles against a light.

Adding @PatrickRyan for advice here, but I think adding some ambient occlusion to this model will help a lot with the parts that should be dark due to occlusion.

@shaderbytes, I agree with @bghgary in that your F0 should be between 0.02 and 0.05 which is where most dieletric materials fall for their F0 value. Conductors are usually higher, but this is a safe range for dielectrics.

The other thing affecting the overall light in your original image is the IoR value of 3.0. If an IoR value of 1.0 is how fast light travels in a vacuum your value of 3.0 means light is traveling through your material at a speed three times slower than in a vacuum. Diamond affects light by bouncing it around inside the material before reflecting it from the surface which slows down the light, but the IoR of diamond is only 2.417 so you have set the cotton fabric of your material to slow light even more than a diamond meaning it is bending the light as it travels through the material. While some wavelengths of light are indeed absorbed by the material, we aren’t really dealing with bending light through a cotton or poly blend fabric. Almost all liquids and solids have an IoR over 1.3 with most plastics having an IoR between 1.3 and 1.7 so unless I have a specific material that I can get a precise IoR for, I tend to leave my IoR around 1.5.

This is what the render looks like with an IoR of 1.5 and an F0 of 0.04:

To help understand what light is doing on the surface, I disabled the skybox and changed the clear color to black. Your base color is very dark, and it may be a little low for PBR (26, 26, 26), not out of the ballpark but dark enough that you won’t see a lot of detail. The other thing that is likely contributing to the issue is that your normal map is pretty crunchy meaning there is a lot of change in the perturbed surface normal in a very short distance which you can see by the drastic change in color in the normal map:

Reducing the normal strength of your texture by approximately half will help control some of the surface noise as light tries to hit the ridges of the material and horizon occlusion tries to cull light that is on surfaces rolling away from the view angle. This should give a less mottled look to the fabric as crunchy normals will make the surface feel dotted with bright and dark pixels.

Lastly, I reduced the roughness of the material to about 0.7. There is nothing in the real world with a roughness of 1.0 and most fabrics will have some sort of reflective nature in the fibers from dyes, to thread composition, to plastics or coatings in the thread. This also gives you more headroom in case you needed to show a dirty fabric that may be coated in dried mud, which would almost certainly be rougher than a cotton or poly blend fabric but would also not be a roughness of 1.0.

Lastly, @bghgary is right that baking out an ambient occlusion map will help with culling light where it is not supposed to be like under the arms. Obviously this changes if the model is animated as you need to be careful how you bake an AO map for a mesh that will move. In that case, baking it in A or T pose will likely give you the best compromise for an AO that helps but does not break the lighting on the model when the pose changes.

I can repro the issue you reported about the texture being inverted when saving out to Babylon so we will look into that.

I hope this helps but feel free to ping with more questions.

4 Likes

This model has a roughness texture (with varying roughness ~170 / 255), so the roughness isn’t 1.0.

2 Likes

Thanks Gents ,

@PatrickRyan , I didnt expect the weird settings to be justfied , sorry about that confusion, I just did those to make the effect go away quickly , thumb sucked tweaks that make no sense. It was late night and I was not giving thought to things properly :wink: the question was more about why default settings look bad.

@bghgary

I guess a more refined question would be , why it F0 default setting in the sandbox is 1 ?

This is a model exported from blender using the standard Principled BSDF , which has a “Specular” setting that defaults to 0.5 .

This “specular” setting in a standard blender shader is in fact the F0 setting. The 0.5 value i presume is handled in exactly the same way other engines handle it. I had a discussion with a sketchfab engine dev on their forums a few years ago about this and he actually provided the math to explain the value here it is : quote :

Real time engines usually don’t use IOR as input (reason : 8bit texture map bad precision distribution + artistic control).

You can derive the F0 value from the ior with:

F0 = ((1-ior)/(1+ior))²

The default ior is 1.5, which gives you 0.04 (4% of light reflected at 0° angle for dielectric materials).
F0 values lie in the range 0-0.08, so that’s why the default F0 slider is set on 0.5.

SO the slider is a scalar of that range. I’ not saying you need to copy this BUT it must be the case with the blender slider then as well , since they also default to 0.5 slider value. ( and the both label it as specular , not F0. I think I read it is based on the disney PBR paper )

Between the exporter and the import is this conversion factored in correctly? As mentioned my blender materials “specular” value is 0.5 , so how did that become a value of 1 in the sandbox ?

Either it should have remained 0.5 ( if you are using it as a scalar as described above )
or it should be converted to the expected value , understanding that the imported value is a scalar that requires conversion.

( thinking about it , it must be a issue on the exporter? because you saw the same issues on the actual gltf viewer … )

thoughts…?

This PR will fix the problem with the inverted texture:

3 Likes

The F0 Factor slider you see in the inspector corresponds to this:
https://doc.babylonjs.com/typedoc/classes/babylon.pbrmaterial#metallicf0factor

In other words, it’s a multiplier on top of the other factors of F0.

We don’t have an adjustment for the F0 directly as it is inferred from other values (like metallic, ior, etc.)

@sebavan can correct me if I’m wrong here.

glTF stores metallic, ior via an extension, or specular via another extension. I’m not sure how Blender is converting the specular value when exporting to glTF, but I am fairly certain Babylon’s glTF importer is doing this correctly.

2 Likes

Hi @shaderbytes just checking in, was your question solved? :smile: