Search code examples
three.jsuv-mapping

UV mapping in THREE.js


I'm trying to use SDF fonts in THREE.js, they come with a PNG map of characters and some character data such as each letters x offset, y offset, width, height and so on.

Before I start using the character data with the offsets and widths and things for each character, I just wanted to simply try out mapping only a part of one of the example UV textures from the three.js/examples.

JSFiddle: http://jsfiddle.net/b2zegeht/3/

uv mapping on quad

So the image above is being rendered onto a quad, with the following code from inside a loop:

        var i=0;

        geo.vertices.push(new THREE.Vector3(x-halfWidth, y+halfWidth, 0));      // TL
        geo.vertices.push(new THREE.Vector3(x-halfWidth, y-halfWidth, 0));      // BL
        geo.vertices.push(new THREE.Vector3(x+halfWidth, y-halfWidth, 0));      // BR
        geo.vertices.push(new THREE.Vector3(x+halfWidth, y+halfWidth, 0));      // TR

        // create two triangle faces for geom
        // all face coordinates must match vertice indexes
        // 0,1,2,3 start in the top left and go round the quad anti-clockwise
        var j = i*4;
        geo.faces.push(new THREE.Face3(
            j,                              // TL
            j+1,                            // BL
            j+3                             // TR
        ));
        geo.faces.push(new THREE.Face3(
            j+1,                            // BL
            j+2,                            // BR
            j+3                             // TR
        ));

        var k = i*2;

        // x, y+height
        // x, y
        // x+width, y+height    
        geo.faceVertexUvs[0][k] = [

            new THREE.Vector2(  0,  1  ),    // TL
            new THREE.Vector2(  0,  0  ),    // BL
            new THREE.Vector2(  1,  1  )     // TR

        ];

        // x, y
        // x+width, y
        // x+width, y+height
        geo.faceVertexUvs[0][k+1] = [

            new THREE.Vector2(  0,  0  ),    // BL
            new THREE.Vector2(  1,  0  ),    // BR
            new THREE.Vector2(  1,  1  )     // TR

        ];

Now to display part of the texture on the quad, I assume I need to adjust the UV coordinates. Problem is, some of them do what I expect, and some of them don't. For example, to move the texture across by three, so it displays from 0.3 to 1 works as expected:

        geo.faceVertexUvs[0][k] = [
            new THREE.Vector2(  0.3, 1  ),      // TL
            new THREE.Vector2(  0.3, 0  ),      // BL
            new THREE.Vector2(  1,   1  )       // TR
        ];
        geo.faceVertexUvs[0][k+1] = [
            new THREE.Vector2(  0.3, 0  ),      // BL
            new THREE.Vector2(  1,   0  ),      // BR
            new THREE.Vector2(  1,   1  )       // TR
        ];

enter image description here

Then I want to move the top two corners of the quad down by two to 0.8,

        geo.faceVertexUvs[0][k] = [
            new THREE.Vector2(  0.3, 0.8  ),    // TL
            new THREE.Vector2(  0.3, 0  ),      // BL
            new THREE.Vector2(  1,   0.8  )     // TR
        ];
        geo.faceVertexUvs[0][k+1] = [
            new THREE.Vector2(  0.3, 0  ),      // BL
            new THREE.Vector2(  1,   0  ),      // BR
            new THREE.Vector2(  1,   0.8  )     // TR
        ];

enter image description here

But this doesn't work, it seems to have actually affected the U/X coordinate and shifted the top half of the texture to the left. The faceVertexUvs don't seem to exhibit the same properties as X,Y coordinates would, can anyone explain what I'm missing here? And how to display a single square such as the one at 0.7, 0.7?

Once I've figured this out, I'll be able to render a letter on a quad from a texture like this:

enter image description here


Solution

  • The problem was not in the code you have listed above but in the shaders. The question should be more clear I think. Anyway if you remove this code it works (both in Chrome and Firefox).

    if(uv.y != 0.0)
    {
        textureCoord.w *= (uv.y);
    }
    

    Fiddle at: http://jsfiddle.net/47j8g71a/