How to create a PBR from multiple images

Vinc3r,
Are the assumptions, including example code statements in my response correct, then? And do those texture images explain my situation better?
Thank you very much again for your time and help!

My best,
Preston

Here an example using your textures:
https://www.babylonjs-playground.com/#K4S3GU#49, you will quickly see how to use them.

You haven’t mentionning your 3D modeler, are you using one? If yes, texture assignation can be done in it, and you can export your scene using gltf for example.

FIX! I just figured out that when assigning ORM texture through code we need to also tell that we don’t use roughness from alpha. useRoughnessFromMetallicTextureAlpha = false

A lot better now :smiley:

(this useRoughnessFromMetallicTextureAlpha thing seems to be automatically set when importing from a gltf file)

1 Like

Vinc3r,
YES!!! Holy beautifully textured reflections Bat-Man, that is exactly what I’m looking for! Thank you so much! It is just amazing how much difference one line of code can make!

I am so stoked, and can’t wait to share this with the team! It will be such a sweet day when I get to reach out to you folks to share something great that we have used this amazing platform to build.

Thanks again for your dedication and expertise!

My very best,
Preston

1 Like

Can’t wait to see what you folks are building!

Actually I was doing an ORM checker texture, which I will probably add to the BJS repo later, to help users understanding RGB > ORM values. And I wasn’t understood why my result in the BJS scene doesn’t look like as it should… until I tweaked this roughness-from-alpha property :smiley:

Still WIP, but could already interest people maybe: texture - playground

2 Likes

Unfortunately I can’t be specific for now. But if my hopes come to fruition, there’s the possibility of using BabylonJS in something that would get a significant amount of exposure. We’re talking a matter of several months from now, but you can be sure that I will keep you aware.

Vinc3r,
I think that is a brilliantly insightful playground, and I would definitely surface a link to it in the documentation. Well done!

I know that I’ve been making the same mistake that many people make, which is not taking the time to master basic concepts and instead trying to learn just enough to accomplish what I’m trying to get done. This is a challenge for any team like yours when trying to provide easy ways to hook into a fully featured platform like BJS, especially for beginners such as myself who are coming to it with no previous 3D experience at all. The way that you’ve tagged how-tos and made them sortable, the guided and sequential set of short tutorials to get started, and, of course, the awesome playgrounds are all immensely valuable and effective. The incredibly response community is a huge asset (big thanks again to people like you!).

For what it’s worth, I came to the topic of PBR with no understanding, of course. After having found multiple images from a texture library site to use with PBR, I struggled to figure out how to use them in BJS. After you kindly provided the Playground example that you did, I dug deeper into the existing documentation and started to understand some of the the concepts better when I began permutations on your example. So the first time around I hadn’t spent as much time as I should have on the documentation. There are a lot of content there. If anything, I might suggest some examples of using multiple images as separate albedo, normal, roughness, and AO maps.

Which brings me to my last couple of questions. When I have a set images expressly generated by third party and with separate images for albedo, normal, roughness, and AO maps (and for something they are calling ‘height’), as I included in my post above, is there ever a benefit to using more than an albedo, bump, and separate channels of a red map? Certainly I’m happier as a web dev needing to serve fewer high-res images.

And finally, what image did you generate the red image from? I have some basic image editing skills, and tried just color saturation as well as a gradient replacement of a grayscale version, but couldn’t get quite what you did. Any pointers would be much appreciated.

Again, your newest playground is a great idea, and I thank you again for all of the help that you’ve given me. Have a great week!

Best regards,
Preston

1 Like

That’s a nice feedback :slight_smile: A good read about PBR could be the Allegorithmic PBR Guide. Do not hesitate also to look on other engine tutorials (PBR logic is the same everywhere), example in Unity3D.

And you’re right, we need first some separate metallic/roughness/ambient textures examples in the doc, then talking about the ORM. There is already little examples in playgrounds from this page but users may need more pratical examples (it seems there are some of them in the Maya to GLTF page, but as I’m not a Maya user I’ve never seen it before, so it have to be in How To pages).

is there ever a benefit to using more than an albedo, bump, and separate channels of a red map?

First, what you call a “red map” have not only a Red channel, but all RGB ones, and could be not red also :smiley: Maybe I’ve use ORM without explanation of the word: Occlusion Roughness Metallic for Red Green Blue channels (and so each maps are in grayscale).
Then, about the benefit, depends of your needs. ORM is useful because you’re using one map instead of 3. Bump may not be necessary on all your materials. Sometimes you will need an emissive texture, or also a lightmap.

what image did you generate the red image from?

  • using Substance Designer, here a setup I’ve made:

  • about Photoshop I’m not sure from where I’ve seen this tips, don’t remember if it’s even in the BJS doc, but:

Note that if you’re new to PBR process, or even to 3D, it will be a lot more easy for you to not use ORM right now, but separate textures (this will allow more try&retry, tweak&retweaks)

1 Like

Vinc3r,
That all completely makes sense, and thank you very much for the additional resources and detailed screen shots. For the next couple of weeks I’ll be playing with a few different textures and creating UIs that allow the surfaces to be tinted to different colors (the use case for my team). Thank you very much again for all of your help and expertise. PBR textures unlock the quality of experience that we need to deliver to our customers, and I’m frankly astonished at how performantly BJS renders them. What an incredible time to be a web dev!

Warmest regards,
Preston

2 Likes

Vinc3r,
Maybe one last question. I’m trying to work with a second texture and am trying to use separate grayscale images for each the ambient occlusion, metallness, and roughness. I like your suggestion to keep them separate for now so that I can explore the settings. And since one of the things that I want to do is allow users to dynamically adjust the AO and glossiness of a texture, that might be a perfect strategy. But I don’t seem able to set material properties the correct way to use separate grayscale images. I’m trying things like this:

groundMat.albedoTexture = new BABYLON.Texture("./wood/slats_albedo.jpg", scene);
groundMat.bumpTexture = new BABYLON.Texture("./wood/slats_normal.png", scene);
groundMat.metallicTexture = new BABYLON.Texture("./wood/slats_rough.jpg", scene);
groundMat.ambientTexture = new BABYLON.Texture("./wood/slats_ao.jpg", scene);
groundMat.metallicRoughnessTexture = new BABYLON.Texture("./wood/slats_rough.jpg", scene);
groundMat.specularGlossinessTexture = new BABYLON.Texture("./wood/slats_rough.jpg", scene);
groundMat.useAmbientOcclusionFromMetallicTextureRed = false
groundMat.useMetallnessFromMetallicTextureBlue = false
groundMat.useRoughnessFromMetallicTextureGreen = false
groundMat.useRoughnessFromMetallicTextureAlpha = false

The result is very much like the Playground that you created for me before applying the groundMat.useRoughnessFromMetallicTextureAlpha = false property, it’s very flat. As always, any suggestions would be much appreciated!

My best,
Preston

Hmmm… actually I maybe made a wrong suggestion (as I use the ORM way since the beginning :slight_smile: ). After rechecking the doc’ and the API, it seems you cannot set separates metallic & roughness textures. Sorry about that.

Note that in your example above, you’re using both specular and metallic workflow in your PBRMaterial, and so cancelling some values (take a look at Master Physically Based Rendering (PBR) - Babylon.js Documentation)

Vinc3r,
No worries and thanks for the additional instruction! I do have Photoshop and will try creating my own combination images tonight. Am I correct than, that I want is a total of three images: the albedo images, the bump (or normal) image, and an image that has the roughness image and AO image in separate
color channels. So that my statements would be something like this:

groundMat.albedoTexture = new BABYLON.Texture("slats_albedo.jpg", scene)
groundMat.bumpTexture = new BABYLON.Texture("slats_normal.png", scene)
groundMat.metallicTexture = new BABYLON.Texture("slats_red_large.jpg", scene);
groundMat.useAmbientOcclusionFromMetallicTextureRed = true;
groundMat.useRoughnessFromMetallicTextureGreen = true;
groundMat.useRoughnessFromMetallicTextureAlpha = false;

Thanks again!

My best,
Preston

Yep that should works :slight_smile:

Cause there is allready good info in this thread about the ORM texture.
I will go from here.

If we connect textures in Maya the Babylon exporter will compose the textures automatically into the channels. We get a combined roughness and metallic texture. But if we use the Arnold shader there is no way to get the occlusion part exported.

Is the only way todo that by hand in Photoshop/Substance?
Or using the Stingray shader?

Hope we get the custom Attributes working soon to create new ways of connecting all this stuff into the Arnold shader.

Cheers Oglu

Hi there, very useful thread.
I’m not so skilled in texturing so i try to figured out if i understand.
Referring to this thread Open Source Free Textures Library for Babylon and in particular referring to this material Free Mud Dirt Ground Texture Seamless Background PBR - 3Designer, what are the texture i’ve to use for PBRMaterial?
For albedoTexture and bump ok (color and normal GL). For Occlusion and ambient if i understand right i’ve to use the AO in the metallicTexture and then using Occlusion form Red and Roughness from Green. Is it right?
When am i supposed to use the other textures (ORM, spec, Detail)?

Thank’s in advance!

You can see what texture was used and toggle them on/off in the asset library like this screenshot:

.

Here is the Texture mapping to Babylon:

// Texture Key Mapper to Babylon.js PBR Material Attributes
const textureKeyMap = {
  [_MATERIAL.KIND.PBR._]: {
    [_TEXTURE.KIND.BASE._]: 'albedoTexture', // i.e. 'color' in the library
    [_TEXTURE.KIND.BUMP._]: 'bumpTexture', // a combined normal + height texture for Babylon Parallax mapping, height map is stored in `a` channel https://doc.babylonjs.com/divingDeeper/materials/using/parallaxMapping
    [_TEXTURE.KIND.NORMAL._]: 'bumpTexture',
    [_TEXTURE.KIND.METAL._]: 'metallicTexture',
    [_TEXTURE.KIND.ROUGH._]: 'microSurfaceTexture',
    [_TEXTURE.KIND.AO._]: 'ambientTexture', // this is Occlusion
    [_TEXTURE.KIND.EMISSIVE._]: 'emissiveTexture',
  },
  [_MATERIAL.KIND.STANDARD._]: {
    [_TEXTURE.KIND.BASE._]: 'diffuseTexture',
    [_TEXTURE.KIND.BUMP._]: 'bumpTexture',
    [_TEXTURE.KIND.NORMAL._]: 'bumpTexture',
    [_TEXTURE.KIND.METAL._]: 'metallicTexture',
    [_TEXTURE.KIND.ROUGH._]: 'microSurfaceTexture',
    [_TEXTURE.KIND.AO._]: 'ambientTexture',
  },
}
// ORM: Red: AO, Green: Roughness, Blue: Metallic - https://playground.babylonjs.com/#7YE1UY#2

The library did not use ORM (AO + ROUGH + METALLIC) for toggability, but in a game, you might consider combining those into one texture for performance reasons.

1 Like

Thank you! Last question about the bump texture. I understand that Babylon.js supports only height map stored in alpha channel of the normal map. So, in this case, am i supposed to compose normal+heightMap by myself?

yes, you can probably automate it with sharp.js - a feature planned for the 3Designer.app → automatically combine HEIGHT + NORMAL textures into a bump map for Babylon.js on upload.

Please note, that in the traditional nomenclature, a “bump” texture actually refers to a detail map, which in the asset Library is labeled as “Detail”, and in Babylon.js, it’s material.detailMap.texture. I was confused myself in the beginning with this odd naming conventions, hence the mapping constant above.

But you can use Babylon’s bumpTexture without height map, just as normal map.

1 Like