GLTF/obj structure and modifying object loaded

Hi!!

I have been playing and having fun with Babylon.js for the past month or so.

I wanted to know if I am following it right and if so, I would like to share with everyone here.

From what I understood, GLTF comes with the followings:

(1) scene.bin
(2) scene.gltf
=> basic structure of an object
=> includes meshes in an object (0 index => rootMesh, others => different sides on object)
(3) textures => includes diffuse texture and normal/bump texture

If I drop this whole GLTF folder into Babylon.js Sandbox, an object is automatically mapped with textures in it.

“scene.gltf” specifies which image to apply to which part or type of texture. For example,

"images": [
    {
      "uri": "textures/sampleDiffuseTexture.jpeg"
    },
    {
      "uri": "textures/sampleNormal.jpeg"
    }
  ],

Building a 3D object with modeling softwares like Blender isn’t really my job, but I am kinda confused.
.
.

Question [1] Do all softwares export gltf file as same structure??

If I were to build an object in Blender (or whichever software I use), depending on the extension that I export, as far as the gltf file includes the above “images” key, it would automatically apply the textures, right?

So if I wanted to modify textures, I would only have to find the node that I want to apply texture to and use

loadedMeshes[node_I_want].material.diffuseTexture = new Texture(src, scene, false, false);
or
loadedMeshes[node_I_want].material.bumpTexture = new Texture(src, scene, false, false);
.
.

Question[2]
I noticed that normal map texture images are all colored in this color.

Screen Shot 2021-06-28 at 3.47.58 PM

However, when I built my own images for bumpTexture (one with white background and one with colored background), the white background one did not work and colored background one worked fine.

Is working with color #7a7df3 like a convention?

.
.

Question[3] OBJ structure

Unlike GLTF, OBJ file is written with numbers only. How does it know which images to apply then?? How are textures applied to the obj??
.
.

I hope everyone enjoys Babylon and share what we study!!

Have a great day!!

Hi @DOEHOONLEE

Yes, I think so. Once loaded, get the mesh from the scene and changing its material/texture will work.

Regarding the normal map, as its name implies, it contains normals encoded as colors. Normals are in the texture space that means the Z component of the vector is going forward. Hence the blue color. XYZ → RGB. normal components are in the range [-1…1] and converted to [0…255] to store as a color. So a color of #7F7FFF is treated as a vector of 0,0,1.

2 Likes

Here is GLTF reference guide - https://www.khronos.org/files/gltf20-reference-guide.pdf
In short, all software will export GLTF as file of GLTF format.
But results of this export may vary greatly since they depend on 3D tool and exporter settings.

2 Likes

You can read more about .obj files on Wikipedia. Basically, it uses a companion file format (.mtl) to specify material information, which can include textures. The .obj file itself only represents the 3D geometry, it doesn’t contain any information about materials.

1 Like

@Cedric , @labris Thanks! That clears up well!

I guess that properties like scene, mesh, camera are mandatory, but say that an object was created without properties like images (for textures), pbrMetallicRoughness, textures, or even animation. Will I still be able to add or manipulate those properties within my code? I am worried if an object have to be created with properties I want to include or it is still manage-able without pre-setting them.

I tried converting .obj to .gltf but the converted file required scene.bin file so I just copied and pasted previously used scene.bin and it worked fine (but of course, a little differently hmm).

Can you explain what the .bin file for?

Thank you again and have a wonderful coding day :smiley:

Hmm… so for an .obj file to load an object with textures, it would require an .mtl file, right?

but then the one that I downloaded does not include an .mtl file and is still able to load with textures.

I am not sure how an .obj file alone can interact with those images and apply them as textures :frowning:

While @DarraghBurke is correct that most of the time .obj files are used to simply represent 3D geometry, as I understand it, the file format was updated at some point to also allow for the embedding of vertex color information as well as texture references.

There’s a bit more detailed information in this article that you can reference:
https://all3dp.com/1/obj-file-format-3d-printing-cad/#:~:text=In%20a%20nutshell%2C%20the%20OBJ,as%20light%20position)%20or%20animations.

As I understand it, whether an .obj has references to textures or not completely depends on how the file was created. Some .obj export workflows involve textures while others do not. So an understanding of how the asset was created will help you understand it’s makeup.

3 Likes

Here is one of the simplest examples - Babylon.js Playground
As you may see, only geometry is imported; all other things like materials and textures you may add according to taste :slight_smile:

4 Likes

Thanks for the clarification @PirateJC! Seems like the Wiki entry needs to be updated!

3 Likes

@labris My apology!! I was trying to convert .obj & .mtl to .bin & .glTF and for some reason, it kept failing and missing .bin file so I could not load an object then it messed up my mind @_@

I was looking into 3D model importing and found out that Three.js recommends glTF as the optimal format, but also supports .fbx, .obj, .collada, etc. However, .fbx is not supported in Babylon.js

I took a look at this forum question/answer and realized why it would be inefficient to load an .fbx type model.

I am betting on glTF, but If you were to pick the best format for a 3D model, what would it be?

Thanks @PirateJC !!
I have been doing some research on 3D object importing and a lot more confident now :slight_smile:
Thanks for the detailed explanation!!

2 Likes

Gltf/Glb would be the most sensible choice IMHO :slight_smile:

1 Like

@labris you implied that I am able to edit the textures and colors of the 3d model once it is loaded in can you please post a playground with an example of this or a quick snippet of code, thank you.

1 Like

Adding textures and colors to a mesh (3D Object) is a simple as modifying its materials.

For example, let’s say you have a sphere and you want to make it a different color, all that you’d have to do is to give it a material with the desired color:

var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2, segments: 32}, scene);
var sphereMat = new BABYLON.StandardMaterial("sp",scene);
// While this says 'White', it's actually a vector with the RGB values of 1, 1, 1
sphereMat.diffuseColor = BABYLON.Color3.White();
sphere.material = sphereMat;

You can also reference fields in the existing material to change the color. This can be useful if you only want to change one single thing but want to keep everything else intact. Here’s example PG: Color swap | Babylon.js Playground (babylonjs.com)
In this, we create a material for the sphere and we change its value when it’s clicked on (picked). Learning how to use materials will allow you to do a lot of things with color and textures, (especially on-the-fly). Check out the Materials section of our documentation: Materials | Babylon.js Documentation (babylonjs.com)

1 Like

@hadecolliday Hi!!

I am not sure if this will help you, but I created a example on PlayGround. Check it out and I hope you have some fun with it :stuck_out_tongue:

Yellow color is applied to the skull on the left and a texture is applied on the right one.

You may want to consider async/await for this.

Sometimes it takes some time to load an object so you would want to wait until it is loaded then apply whatever you want.

I am not too sure how many other ways there are, but these are two ways how I import meshes.

[1] Importing with ImportMesh

const createScene = async () => {
	const newMaterial = new BABYLON.StandardMaterial;
  newMaterial.name = "newMaterial";
  newMaterial.diffuseColor = new BABYLON.Color3.Blue;

	const sphere = await BABYLON.SceneLoader.ImportMeshAsync("", "https://raw.githubusercontent.com/BabylonJS/MeshesLibrary/master/", "shaderBall.glb", scene);
	sphere = scene.getMeshByName("simpleSahderBall");
	sphere.material = newMaterial;
}

[2] Importing with assetsManager

const assetsManager = new AssetsManager(scene);

const meshTask = assetsManager.addMeshTask(taskName, meshName, url, fileName);

meshTask.onSucess = function() {
	const rootMesh = task.loadedMEshes[0];
}
1 Like

Thanks for your opinion!! glTF is my favorite too! haha

I have been contacting some companies and asking if they can build objects for me, but some of them have never even heard of glTF and I was so surprised :frowning:

Thanks for sharing!!

Often they work with generic formats and happy with that :slight_smile:
Also, one should has some knowledge how to optimize GLTF for the Web use.
(If you need to build some 3D objects, you may PM me).

1 Like

Khronos published some guidelines for this recently as part of the 3D Commerce effort. It might be worth checking out.

Blog:
3D Commerce Working Group Releases Real-time Asset Creation Guidelines to Assist Artists Create Efficient, Reliable Models for Retail and E-Commerce - The Khronos Group Inc

Guideline Documention:
3DC-Asset-Creation/RealtimeAssetCreationGuidelines.md at main · KhronosGroup/3DC-Asset-Creation (github.com)

2 Likes

@labris Thank you for your thoughtful gesture!! :smiley:

@bghgary Thanks!!

This Reference Guid that @labris provided and your link to the Khronos Github page were most helpful!!

3 Likes