Need Help with Texture Setting

Online Model Viewer:

Three.js:


Screenshot 2024-07-17 at 00.41.02

Model with textures monitor_c2-v1.glb (6.1 MB)

UV:

Sandbox example:
https://codesandbox.io/p/sandbox/three-js-texture-trial-forked-2rjtwn

Hello, I am exporting my model through Blender’s Material section with the ‘no export’ option selected. I am trying to set textures in Three.js, but for some reason, I have tried many methods and have not succeeded. I am sharing the model with you, hoping you can give me some advice. Thank you.

1 Like

Hey, just wanted to thank you for posting a complete question with a sandbox. :smiley:

First off the model you linked in the post, has 3 materials applied and thus is composed of 3 separate meshes.
1 black material for the monitor bezel and back…
1 material for the shell
1 material + mesh for the screen itself.

The .glb being loaded in your codepen is different however, and contains the whole monitor and the bezel combined into a single mesh. A mesh called “monitor plug” which is an interior mesh.
and a mesh called “monitor cap”

So first off, you can’t just swap textures unless the texture exactly matches the meshes you are applying them to.

Secondly,
When exporting to GLTF, each mesh can only have 1 material, so the mesh has to be split into multiple meshes, each with 1 material. By exporting without materials+textures, the exporter doesn’t need to split the mesh into sub meshes based on material boundaries, so the bezel and the body of the monitor look to be merged into a single mesh, which means you won’t be able to re-assign the textures later, since the bezel + body meshes are fused together.

If you really need to follow the exact same workflow, I would suggest splitting the mesh apart in blender into separate meshes Before exporting with no-export materials. Then at least you should be able to get the monitor, bezel, and separate parts.

So I would have to ask on a higher level what are you trying to achieve? There may be a better approach.

Just one thing in addition to @manthrax post, you can also simply select Placeholder in Material export Tab:

grafik

So the mesh gets split into different meshes that have different materials. Those new meshes just get a placeholder material that you can then swap out in threejs.
This way The model stays the same in blender but you can use it in threejs without exporting the original materials.
Be aware, the meshes name could be different if you do that! (I check this in a glb viewer after the export)

1 Like

First of all, thank you for your messages. They have been really helpful and informative. I’m trying out something experimental here. I’ve developed a model loader with the goal to dynamically load and set all contents through a JSON. From the information I’ve gathered from you and my own research, I’ve realized that this task is quite complex. It definitely needs to be set up properly. Still, I have the energy for this; I think the model needs to be simplified, perhaps even stripped down to the basics.

Example model source.

const tableResource = {
    "type": "gltf",
    "path": "/assets/models/table.glb",
    "options": {
      "scale": [900, 900, 900]
    },
    "instances": {
      "meshes": [
        {
          "originalName": "left_leg",
          "clones": [
            {
              "cloneName": "right_leg",
              "options": {
                "position": { x: 7.5 }
              }
            }
          ]
        },
        {
          "originalName": "corner",
          "clones": [
            {
              "cloneName": "corner_left_back",
              "options": {
                "position": { x: 11 }
              }
            },
            {
              "cloneName": "corner_right_back",
              "options": {
                "position": { x: 11, z: 1.3 }
              }
            },
            {
              "cloneName": "corner_left_back",
              "options": {
                "position": { z: 1.3 }
              }
            }
          ]
        }
      ]
    },
    "materials": [
      {
        "appliedTo": ["top002", "leaf"],
        "settings": {
          "envMapIntensity": 1,
          "displacementScale": 0.02,
          "roughness": 1,
          "metalness": 0
        },
        "textures": [
          {
            "type": "color",
            "path": "/assets/texture/table2/wood_table_worn_diff_4k.jpg"
          },
          {
            "type": "displacement",
            "path": "/assets/texture/table2/wood_table_worn_disp_4k.png"
          }
        ]
      },
      {
        "appliedTo": ["left_leg", "corner"],
        "settings": {
          "envMapIntensity": 0.5,
          "displacementScale": 0.02,
          "roughness": 0.6,
          "metalness": 0
        },
        "textures": [
          {
            "type": "color",
            "path": "/assets/texture/handler/MetalCladdingFrame002_COL_1K.jpg"
          },
          {
            "type": "displacement",
            "path": "/assets/texture/handler/MetalCladdingFrame002_DISP_1K.jpg"
          },
          {
            "type": "roughness",
            "path": "/assets/texture/handler/MetalCladdingFrame002_GLOSS_1K.jpg"
          },
          {
            "type": "normal",
            "path": "/assets/texture/handler/MetalCladdingFrame002_NRM_1K.png"
          },
          {
            "type": "metallic",
            "path": "/assets/texture/handler/MetalCladdingFrame002_REFL_1K.jpg"
          }
        ]
      }
    ]
  }
1 Like


@kalabedo @manthrax

I’ve reviewed the code based on your suggestions, and many issues have been resolved, but the texture still doesn’t look right. Is there a delicate setting missing in this code?

Also, I suspected there might be an issue with the UVs, but when I used a basic model viewer I found online to open the model and only set the normal map, it looked correct. I’m missing something but can’t figure out what it is.

In the original model, the Body, Screen, and Bezel are 3 different materials.
By exporting without materials, the exporter is merging body,screen, and bezel into One mesh without a material.
Once a mesh is merged, it isn’t possible to unmerge it, so the model is basically broken at that point. Any single texture applied will be applied to all 3 of those parts that used to have their own textures.
@kalabedo 's excellent advice might do what you need though, since it will tell the exporter that the materials are important… which should keep the meshes separate, allowing you to assign the individual materials+textures again.

regarding your model loader… it actually looks very close to threejs native .toJSON() which is used for serialization internally. You might want to try using .toJSON on some objects and see if that saves your rolling some of your own serialization code.

1 Like

Thank you very much for your help and response. Setting texture.flipY = false; made my model appear correctly without any issues. If you want, you can observe it on CodeSandbox.
https://codesandbox.io/p/sandbox/three-js-texture-trial-wtv2tl?file=%2Fsrc%2Findex.js

1 Like

Ahh great, glad you got it working!