1

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

dps27a
  • 101
  • 3
  • 11
  • A fiddle would be helpful. – gaitat Oct 12 '14 at 14:17
  • Having trouble with loading an external image as a texture – dps27a Oct 12 '14 at 15:55
  • I was working on that. Take a look at my fiddle so far: http://jsfiddle.net/v0grL1ay/ – gaitat Oct 12 '14 at 16:04
  • The texture you are using should not have border but that is secondary. – gaitat Oct 12 '14 at 16:05
  • nicely done, fiddle kept crashing when pasting in the huge base64 string, so I went for this approach - http://jsfiddle.net/b2zegeht/ – dps27a Oct 12 '14 at 16:05
  • wrong fiddle link before, updated it in comment above – dps27a Oct 12 '14 at 16:08
  • be careful; your fiddle is using three.js r54. we are at r68 currently. – gaitat Oct 12 '14 at 16:10
  • ok I was just using an old fiddle with some example code, its updated now - http://jsfiddle.net/b2zegeht/1/ – dps27a Oct 12 '14 at 16:18
  • Is this what you want? http://jsfiddle.net/bd58ydgt/ – gaitat Oct 12 '14 at 17:30
  • That's what I'm aiming for, but I'm using a texture loaded in to a shader - if you see the fiddle you can see I'm using ShaderMaterial. I have a feeling that's causing the texture mapping to behave slightly differently? – dps27a Oct 12 '14 at 17:44
  • The fiddle is not working for me. First I had to replace the three.js reference to http://mrdoob.github.io/three.js/build/three.js and now I am getting `THREE.WebGLProgram: Could not initialise shader.` – gaitat Oct 12 '14 at 17:57
  • Are you sure? here's the fiddle link: http://jsfiddle.net/b2zegeht/1/ – dps27a Oct 13 '14 at 10:22
  • I guess you are running on Firefox. On Chrome (even at my work machine) I get the errors above. – gaitat Oct 13 '14 at 13:10
  • You are correct, Chrome was complaining. It is updated again here: http://jsfiddle.net/b2zegeht/3/ – dps27a Oct 13 '14 at 13:15

1 Answers1

0

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/

gaitat
  • 12,449
  • 4
  • 52
  • 76