How to create a PBR from multiple images

I am trying to create a PBR surface of wood planks using the flat map images that I downloaded from textures.com (specifically, the maps on this page: Strip Parquet Hardwood Floor - PBR0027). The site provides multiple images that I’m assuming should be combined to create a PBR material, including an “ao” version, a “height” version, a “normal” version, and a “height” version. The URL that I included shows previews of each image.

I read the BJS documentation on PBR materials, but I’m not clear on how I should use these multiple images to create the PBR. Should I use the Lys app (I have a Mac, so I don’t think that I can use the IBL Baker app)? I read the BJS documentation on using normal images to create bump maps, maybe that is all that I can do with these images?

Thanks so much for your help and time!
Best regards,
Preston

Which 3D modeler are you using?
On the BJS side, you can use:

  • the albedo map… for the albedoTexture :smile:
  • the normal map to the bumpTexture channel
  • manually create an ORM texture linked to the metallicTexture channel:
    • Red channel for Ambient Occlusion
    • Green channel for Roughness
    • Blue channel for Metallic (here, full black)

For the ORM, Allegorithmics software can be a great help, but you can also check Blending options of Photoshop for example.

Vinc3r,
Thank you very much for your help and patience! If I’m understanding you correctly, I would use the albedo and normal images to properties of my material like this:
mat1.albedoTexture = new BABYLON.Texture(“path-to-my-albedo-image”, scene);
mat1.bumpTexture = new BABYLON.Texture(“path-to-my-bump-image”, scene);

I would also combine my “height,” “ao,” and “roughness” images in a tool like Allegorithmics or Photoshop (I do have the latter) and then set that image to my BJS material as so:
mat1.metallicTexture = new BABYLON.Texture("<path-to-my-metallic-image>", scene);

Here are what each of those source images looks like. Again, thank you very much for your insight!:
Albedo:
image

AO:
image

Height:
image

Normal:
image

Roughness:
image

Warmest regards,
Preston

That made me thinking that adding example ORM textures for the playground could be a nice idea.

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