Search code examples
three.jstypescriptcreatejs

Mesh basic materials not rendering a textured quad


I'm just starting out learning some Three.js. I have got a basic webgl example working. But now that I want to get a similar example working within the THREE.js framework I have ran into trouble with texturing.

The texture is loaded with createjs preloader.

I have tried appending the htmlImageElement to the document to check that it has loaded before the material is created. And this appears fine. So I don't think my problem is creating the material before the texture has completed loading. As has been the problem for others.

Also I have tested a texture from my previous webgl example and this throws the same error, so I don't think the image used is invalid.

The quad in the example below will render as a blue square ok, but the moment I add my texture to the material is throws the error. GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1.

I have little experience with Three.js so I think the problem is around how I create the material, scene or geometry. Though I really have ran out of ideas.

I am using TypeScript.

private createPaper(): THREE.Mesh {
        var paperGeo = new THREE.Geometry();
        paperGeo.vertices.push(new THREE.Vector3(1, 1, 0));
        paperGeo.vertices.push(new THREE.Vector3(3, 1, 0));
        paperGeo.vertices.push(new THREE.Vector3(3, 3, 0));
        paperGeo.vertices.push(new THREE.Vector3(1, 3, 0));

        paperGeo.faces.push(new THREE.Face3(0,1,2));
        paperGeo.faces.push(new THREE.Face3(2,3,0));

        var img: HTMLImageElement = m.getAsset("paper0");

        this.paperTex = new THREE.Texture(img, THREE.UVMapping,THREE.ClampToEdgeWrapping, THREE.ClampToEdgeWrapping,
            THREE.LinearFilter, THREE.LinearFilter, THREE.RGBAFormat, THREE.UnsignedByteType, 0);

        var paperMaterial = new THREE.MeshBasicMaterial({
            map:this.paperTex, color: 0x0000dd, side: THREE.DoubleSide
        });

        var paper = new THREE.Mesh(paperGeo, paperMaterial);


        return paper;
    }

Solution

  • At a minimum, you need to specify UVs in geometry.faceVertexUvs[ 0 ]. But first, get it working with THREE.PlaneGeometry.

    If you are creating a texture using texture = new THREE.Texture(), you need to set texture.needsUpdate = true; The alternative is to use THREE.ImageUtils.LoadTexture();

    three.js r.61