Albedo texture not applying properly

Hey,

My materials aren’t being correctly applied to my .obj model and I’m not entirely sure why. I load the texture, traverse the object and apply the texture to the children (meshes) but it doesn’t seem to properly apply them at all.

objLoader.load("./berd_006_u.obj", function(object) {
    object.traverse(function(child) {
        if (child instanceof THREE.mesh) {
            const txt = new THREE.TextureLoader().load("./berd_diff_006_a_uni.png");
            const phongMaterial = new THREE.MeshPhongMaterial({ map: txt });

            child.material = phongMaterial;
            child.material.opacity = 100;
        }
    });
});

This is what it looks like in threeJS;

And this is what it looks like in Windows 3D Viewer with the “Albedo” texture ticked (this is correct);

(there are two meshes by the way, the hair and the actual “horse”)

There is obviously some sort of property that I’m not utilizing for it to not render like it should but I have no idea which one.

I zipped up the files if anybody would like to take a look.

horse.7z (395.1 KB)

IMO, the MTL file looks strange:

# V 0.13

newmtl berd_006_u_0
map_Kd berd_diff_006_a_uni\berd_diff_006_a_uni.png
map_bump berd_006_u\berd_normal_006.png
map_Ks berd_006_u\berd_spec_006.png

newmtl berd_006_u_1
map_Kd berd_diff_006_a_uni\berd_diff_006_a_uni.png
map_bump berd_006_u\berd_normal_006.png
map_Ks givemechecker

newmtl berd_006_u_2
map_Kd berd_diff_006_a_uni\berd_diff_006_a_uni.png
map_bump *NULL*
map_Ks *NULL*

First of all entries like the following are not valid and can’t be processed by MTLLoader:

map_bump *NULL*
map_Ks *NULL*

Besides, the textures berd_normal_006.png and berd_spec_006.png are missing in your 7z archive.

When textures are located in the same directory like your OBJ/MTL files, the paths should look different. Instead of:

map_Kd berd_diff_006_a_uni\berd_diff_006_a_uni.png

it should be just

map_Kd berd_diff_006_a_uni.png

BTW: When using MTLLoader with OBJLoader like in webgl_loader_obj_mtl, there is no need to manually load textures and create materials. So please refactor your code and use both loaders.

BTW: The valid range of opacity is [0,1].

Hey thanks for your reply!

The MTL file looks weird because its been auto-generated by my own program that converts models from a specific game to Wavefront compatible files, including the .mtl’s. I repacked everything and now the folder structure looks like this;

|-- berd_006_u
|   |-- berd_006_u_high.mesh
|   |-- berd_006_u_low.mesh
|   |-- berd_006_u_med.mesh
|   |-- berd_normal_006.otx
|   |-- berd_normal_006.png
|   |-- berd_spec_006.otx
|   `-- berd_spec_006.png
|-- berd_006_u.mtl
|-- berd_006_u.obj
`-- berd_diff_006_a_uni
    |-- berd_diff_006_a_uni.otx
    `-- berd_diff_006_a_uni.png

The .mtl file contains this now;

# V 0.13

newmtl berd_006_u_0
map_Kd berd_diff_006_a_uni\berd_diff_006_a_uni.png
map_bump berd_006_u\berd_normal_006.png
map_Ks berd_006_u\berd_spec_006.png

I load the materials like this, which works for multiple .obj files but just not this one for some reason;

objLoader.setMaterials(mats);

mtlLoader.load("./berd_006_u.mtl", function(mats) {
    mats.preload();

    objLoader.setMetarials(mats);

    objLoader.load("./berd_006_u.obj", function(object) {
        object.traverse(function(child) {
            if (child instanceof THREE.mesh) {
                child.material.opacity = 1;
            }
        });

        ...scene add stuff
    });
});

It still is white which is strange because if I upload the .mtl, the .obj and just the berd_diff_006_a_uni.png to one of the 3d viewer websites it loads the albedo texture perfectly fine. So there’s definitely some property not getting set which I don’t know about.

horse.rar (879.7 KB)

“It still is white which is strange because if I upload the .mtl, the .obj and just the berd_diff_006_a_uni.png to one of the 3d viewer websites it loads the albedo texture perfectly fine. So there’s definitely some property not getting set which I don’t know about.”

Btw, just based on this I don’t even think I need the spec & normal png files?

Your MTL file interprets the normal map as a bump map which is not correct. The entry in the MTL file should look like so:

norm berd_006_u\berd_normal_006.png

I then get this:

If you have the maps, use them. The result will look better.

BTW: Specular maps in three.js are supposed to be grayscale maps. You can use a color map but it the final result might look a bit different compared to other rendering software (because only the red channel is used).

# V 0.13

newmtl berd_006_u_0
map_Kd berd_diff_006_a_uni\berd_diff_006_a_uni.png
map_Ks berd_006_u\berd_spec_006.png
norm berd_006_u\berd_normal_006.png

Not sure what I’m doing wrong, this still is white for some reason.

Nevermind, I had the “alpha” set to true in the WebGLRender, is there any way that I could keep it set at true and have the model rendered properly?

new THREE.WebGLRenderer({
    alpha: false,
    antialias: true,
    preserveDrawingBuffer: true
});

Makes it appear; brave_sA0LiwKufv

new THREE.WebGLRenderer({
    alpha: true,
    antialias: true,
    preserveDrawingBuffer: true
});

Setting the alpha to true makes it disappear;

Why do you have to set preserveDrawingBuffer and alpha to true? In most cases, users don’t have to touch these configuration parameters. Especially preserveDrawingBuffer should only be used in just a few use cases.

I tend to make a screenshots of a bunch of .obj models inside a folder and I need the transparent background, that’s why I have the alpha set to true.

Does it work if you manually set the format property of the diffuse texture to THREE.RGBFormat?

I assume you mean manually loading the png texture and applying it to the mesh, unfortunately setting format to THREE.RGBFormat doesn’t seem to work with alpha set to true :frowning:

texture = new THREE.TextureLoader().load("path/to/texture/png");
texture.format = THREE.RGBFormat;

It is not necessary to load the texture again. You can change the existing ones of the loaded materials.

Just for testing: Does it work if you convert the PNG to JPG?

I see thanks for the info, I basically did this;

child.material.map.format = THREE.RGBFormat;

Together with converting the PNG to JPG and the alpha set to true, it does appear now which is a start I guess but the texture is white now;

brave_cE9wgEnGrb

It also looks like the right part of the face is darker than the left which is strange. I also tried converting the normal maps and the spec ones to JPG too but that didn’t work. By the way I really appreciate you trying to help me sort this out :slight_smile:

This seemed to fix it, I have no idea why it didn’t work the first 5 times I tried maybe some kind of browser cache issue? No idea.

Anyways, thanks a bunch for helping me figure it out!