PBR Material: How to get it to work?

This is driving me crazy :sob:

In Blender I have this:

And in BabylonJS I get that:

Where are the reflections? how do we activate them?

The PBRMaterial relies heaviely on a good environment texture.
You won’t get screen space reflections as far as I know but when you put an environment in your scene then it will reflect in the materials.

// found the link!
You can see the difference it makes and how to use it in this playground
https://www.babylonjs-playground.com/#8MGKWK

I do not think this is really a Blender question, per say. The source of reflections in PBR come from the environment texture onto materials with a metallic or specular elements. While Blender may cast reflections, I do not think it is automatic in BJS, & not been exported.

It would have to be done post load. Not sure myself. You might get more responses removing Blender from the title. People who might know might filter out those topics.

2 Likes

This is a good point!
Blender does use built-in environments in LookDev mode. These do not get exported to the gltf file.
That is the reason why you need to load a separate environment file in Babylon.

For testing you can download or use a texture from the playground but I think for production you should use your own.
Here is a list of provided textures.
https://doc.babylonjs.com/resources/playground_textures#hdr-as-dds

1 Like

Hello :smiley:
Thank you for your answers, that’s very nice to feel supported.

So, although “real scene reflection” would be nice, what worries me right now is that I do not even get the IBL environment reflection… while I exported the scene with the Urban environment with the Blender exporter.

When I check the textures in the PBR material, everything seems fine; except that there is a metallic texture added; which I suppose is due to some peculiarity of BabylonJS?

Here is my scene:
https://www.babylonjs-playground.com/#53Z9W5

EDIT:
After reading the thread here: Issues with PBR Material on BabylonJS version 4
I thought maybe this is the HDR image I use that is faulty, so I tried the setting used by @PatrickRyan in the PG he provided.

Here is the results:
https://www.babylonjs-playground.com/#53Z9W5#1

Still no reflection…

EDIT 2:
To be honest, I start to think that BabylonJS does not use my roughness texture, because if I change the roughness value to 0, I do get IBL reflections; so the IBL does work, just the texture that is not working.
I checked the textures with the inspector, for some reason, BabylonJS added a metallic texture (that I did not have in Blender):
image
While the roughness texture (that I do have in Blender) has been replaced by a pure white:
opera_2019-11-16_10-52-25

If that can help here is my node setting in Blender:

@JCPalmer would it be possible that the exporter is replacing the roughness texture with a white texture?

Oh no! I deleted my post accidentially… again… this was not the first time it happened to me :sob:. When you accidentally click the three dots below twice on your own post it gets deleted without prompt :frowning:

Here is the playground link again

https://www.babylonjs-playground.com/#53Z9W5#3

Will try to edit the rest in here again

–

I changed the loading mechanism. Somehow on the other playground the env texture did not get set correctly.

For the roughness: The information how it is calculated on a material is baked in to the .dds file. When generating it there are a few options to change (numper of mipmaps, etc). I did not get a perfect mapping from Blender to Babylon myself yet so any help would be appreciated.

To make it more like in the Blender scene I made a loading callback which alters the roughness of all Materials (at least all of the PBRMaterials that are attached to a mesh).

Hopefully this helps you to find the solution for the rest :slight_smile:

What you do is similar to what I tried when checking that the IBL was working: you are changing the roughness value directly. However, it seems that the problem is that the roughness texture is not being used (see my EDIT 2)…

Hm… you are correct. I seem to have overlooked this.

I somehow really don’t get it though.
When looking at the decor_material in the inspector the roughness texture is plugged in correctly. Although there is microSurfaceTexture, too… which is not set.
When looking in the object with a console.log the metallicTexture is set bug not the reclectivityTexture or microSurface… this is strange as the inspector says something different.
Setting the material to use metallic green for roughness does not work either.

It seems the metallic texture does not to work, too… BUT… when you change the w-angle in the inspecor you can see things changing…
I don’t want to give up on inspecting this but this is above my understanding. I have no time left to dig deeper this weekend. :slightly_frowning_face: Hopefully someone canfigure this out. I’m quite interested in the resolution.

okay… wait… one last edit

It DOES work when setting the microSurfaceTexture to the metallicTexture!
https://www.babylonjs-playground.com/#53Z9W5#5

1 Like

So that happens to more than me. @Deltakosh might you suggest to the supplier that they put in something more about this? There is an undelete, but I got an error with that. I click something else first. Don’t remember what.

@Nodragem, if you are using the .babylon exporter, please switch to 6.2.3 put out this week. A change was made for roughness textures. Also, roughness must be on the green channel.

1 Like

Thank you :slight_smile: I will try with the new version of the exporter. What do you mean by “roughness must be on the green channel”? how do I do that in Blender?

@Nodragem, I make a quick run through this thread and I see a few things going on in your scene. In most of them, the metallic channel is pointing at your roughness map. This is incorrect as the metallic map should be largely areas of 0.0 (black) and 1.0 (white) as this map primarily determines the color of the specular reflection from your material. If the material is metallic, the specular reflection draws from the basecolor map and reflects that color. If the material is dielectric, the specular reflections will be the color of the light. Note the difference below:


The top row is metallic (roughness 0.4 and 0.5) and the bottom row is dielectric (roughness 0.4 and 0.5). This does not have an environment map to better illustrate what I am talking but you can see that the directional light on top has a green tint and the specular on the bottom is white. Both rows are the same color in basecolor.

The only time you see grey values in a metallic map is in the transitions between metallic and dielectric. Think of a aluminium wheel rim that has mud spattered on it. The material transitions from the metallic of the rim to dielectric of the mud. The grays in the metallic map simulate a blending between the types.

As far as @JCPalmer commenting about roughness going in the green channel, he was referring to ORM packed materials. This is mainly used in glTF files to save on file size as you pack your Occlusion, Roughness, and Metallic maps into the R, G, and B channels of one texture which saves you two textures. There is an admittedly old article I wrote (I keep saying I need to update it and never find the time) about the early pipeline into glTF that does talk quite a bit about ORM textures. You might consider testing in glTF as an export format as it’s pretty easy to peel apart and make manual changes in the json or textures for testing purposes. Unfortunately the Babylon format is a black box so can only be debugged in the inspector.

The other thing I noticed is that in the later parts of the thread, the same roughness texture is hooked up in the microsurface channel. This is also incorrect as microsurface is a PBR-SG (spec-gloss variant of physically based rendering) channel for the gloss texture. If you connect to this input channel, you need to not connect anything in metallic and roughness. You are basically using two different incompatible rendering algorithms together which will produce wildly inconsistent results.

If you are trying to get accurate scene reflections from your environment, you either need to set up a reflection texture that is static or use reflection probes. The drawback here is that these reflection textures require the Standard Material, which is a blinn-phong material, not PBR.

The other thing you can do if you want to stick with PBR materials is to render out anequirectangular HDR file from Blender with lights and base surfaces for your environment. You will want to include any mesh that does not change, but if you have elements in your scene that need to move around or change based on user input, you need to leave these out of your bake. You can see in this section on how to create your environment DDS, that I rendered a simple studio setup with lights into an EXR which was then sent through Lys to create the DDS for environment lighting. This will mean that your reflections on smooth (low roughness) surfaces will look like your environment and not some other place which is always a challenge with IBL.

I hope some of this helps, but if you have questions and can share your source file, even privately, I can dig in and help you with setting it up.

5 Likes

Also, see this thread. Your direct link of your texture into the the roughness input does work for the .babylon exporter, even though it does not match this picture. The splitter node is only needed when using the other channels in the same texture.

The bug that was fixed was that the alpha channel can also be mapped to roughness & was hard coded to be the default.

I tried with the .glb exporter and with the new blender exporter. They both kind of work; except that I need to manually tweak the roughness / metallic value in the inspector down to 0.3-0.2 so that I get an effect that looks like what the texture is meant to do.
image
Here the results for the babylon file.
image
Same kind of tweak needed for the glb file, I needed to tweat the roughness value to get coherent results.

I don’t understand why I need to tweak the roughness / metallic values when I provide a texture for that purpose though…

@JCPalmer: Note that with the .babylon file, I needed to rotate the environment texture by about 90 degrees in the inspector so that I get similar reflection as with the .glb file. Not sure why…

Yeah, the environment texture works differently between .babylon & .glb in the Sandbox. The .babylon exporter does have a small handful of .env format files that you can specify for export from the world properties. Try with one of those being exported. Also, I have never had this.

You will probably need to do this at some point anyway, as I assume you not be deploying to the sandbox. As part of an html fill, you will both need a texture file, & either its load code specified in the .babylon file, or hand written.

Are there any workaround about that? Because if I take our old appartment demo, we have to use a unique HDR env for the whole scene, and fake rooms reflections using custom cubemaps (on PBR materials), to avoid having a kitchen reflected on bathroom mirrors for example:

image

1 Like

Note: This is a deleted post. I do not really know what happened. My dog jumped his front legs across mine. I knew there was an un-delete somewhere, but did not see it, I immediately selected everything & copied to the clipboard. That is how I got it back. I actually clicked the trash can again think that was it. Then hovered them all. The un-delete is circle arrow. I clicked it, but got Url not found.


BJS does actually support reflections which you code yourself at least for std materials. I managed to put it off once here: https://palmer-jc.github.io/scenes/get_baked/index.html
The code for this is here: Palmer-JC.github.io/index_JSON.html at master ¡ Palmer-JC/Palmer-JC.github.io ¡ GitHub

You make a reflectionTexture:

mirrorMaterial.reflectionTexture = new BABYLON.MirrorTexture("mirrorTex", 4096, scene, true);

You also need to assign a mirrorPlane to the texture. This is where I just kind of guessed:

mirrorMaterial.reflectionTexture.mirrorPlane = new BABYLON.Plane(0,0,-1,-6);

Then you add the an array of meshes as the source to be reflected.

mirrorMaterial.reflectionTexture.renderList = renderList;

Then add the reflection texture onto the exported material.

1 Like

@Vinc3r, without going to the standard material and using reflection probes, there’s no way in the current state of the engine to be able to break up environments into material groups or by submesh (so that you can have an environment per room). We have been thinking about how we would be able to do this in the future, but it’s a ways off from being put into the engine. We would need to recalculate as things in the scene change much like a reflection probe so there is a trade off for performance and re-rendering if things change.

For your apartment scene, you could get away with only recalculating your environments when the user makes a change so the system would be more forgiving for a scene like yours than it would be for a game that has more dynamic environments. This is why we have not been able to find a path yet.

What I would do with the mirrors in your scene is to take advantage of node material and a render texture. Setting a camera in front of your mirror will render what it will see, and then you can set up a node material to scrub UVs on your render texture based on the angle between your view and the normal of the mirror. This way you can get an accurate reflection with high resolution while also making it feel like a mirror. Mirrors don’t really benefit from PBR, so you can trade off the blinn/phong of node material for the power of being able to do whatever you want in the shader.

For the reflective surfaces in your scene like the vases, you will be tied more to your environment. But you can use a generic environment and control your roughness to minimize the disconnect between the surrounding mesh and your IBL reflections.

Honestly, this is where ray tracers dominate real time rendering, you just have to deal with one frame every few minutes so there’s always a trade off.