How can I use a .png image to display on one face of a 3d tile object loaded from a .obj file

I’m trying to use a .png image as a material for the top face of a tile in a board game. The object is loaded as a .obj file that was exported from Blender. I can get the tile to display properly, but when I try to edit one of the materials, it only displays the bottom left pixel of the .png file on the face.

Since I want to use the same 3d model for all tiles, I create a “prototype” tile that is cloned. Then I want to just edit the top face to show the type of tile that it is.

I searched for hours and I couldn’t find how to properly do this so that’s why I’m asking. It seems like it should be simple.

I know I can access an object’s materials with this, but it doesn’t display the .png properly. It does change the correct face, but not to what I want.

myTile.children[0].material[1] = myPng;

The dark tiles are the ones that I’m trying to display the .png’s on, but it’s just showing the bottom left pixel of the .png file.


Shouldn’t it be myTile.children[0].material[1].map = myPng;?

I shall try this once I get back home to my computer! I only started using three.js last week, so I know pretty much nothing about how it works yet.

I tried that out and it’s giving me this error:

Uncaught TypeError: Cannot read property 'elements' of undefined

I know that the image is loaded properly since I can make a cube that displays it on all sides like this:

var myPng = new THREE.MeshStandardMaterial( { map: texture} );
var cube = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1), 

My tiles are all clones of a tile object that I load using

var loader = THREE.OBJLoader;

I’m not sure if this is a problem. Maybe it’s a problem with how I’m loading the object. I wanted to get the material filename that is used by the object before I load the object because I have to do


before calling the


function, otherwise the materials wouldn’t display on the object at all. This lead me to do a temporary solution like this… Note that I have loaded all .mtl files and stored them in BG.MaterialsData earlier.

 //Loop through all .obj files to load
objectFiles.forEach(file => {
//I don't understand why I need a new OBJLoader for each object.
let loader = new THREE.OBJLoader(); 
//Load the file so we can see what materials to use
loader.load(file, function(object){
    //Set the materials using the object's material file that it uses.
    //Load the file again since the materials are set properly
    loader.load(file, function(obj){
        let split = file.split("/");
        //Save the obj to create the tiles later.
        BG.ObjectData[split[split.length - 1]] = obj;
        if(objFilesLoaded === objectFiles.length){

As you can see, I have no clue what I’m doing :upside_down_face:

I’m still leaning towards the problem being how I’m setting the material. Isn’t there some kind of setter function in three.js for this kind of thing?

I figured out that the problem was my exported 3d model from Blender didn’t have Cube Projection UV Mapping. This answer from Jostein fixed my problem. texturing - Add UV Mapped texture coordinates to OBJ file? - Blender Stack Exchange