UV coordinate basics
Posted by Dennis on Aug 26, 2007 in 3D • 3 commentsThis post is all about UV coordinates and how to use them in Sandy 3.0, although the theory applies to other engines like Papervision3D too. There’s a little bit of theory involved and some hands-on coding.
About UV coordinates
In simple words: UV coordinates are 2D coordinates that are mapped onto a 3D model. UV coordinates are a texture’s x and y coordinates and always range from 0 to 1. Let’s take for example a 800×600 image. When we use a UV coordinate with u=0.5 and v=0.5 then the pixel at x=400 and y=300 is targeted. So what about a UV coordinate with u=1 and v=1? As you’ve already guessed, that one’s the bottom right pixel.
Default UV
coords on a Sandy Box
The standard way Sandy applies a texture on a Box is putting the complete image on each side of the Box. When we use this texture:

We get the following result:
Looks nice, but is not what we want. When you take a look at the texture you can see there’s a square for each side of the Box. To enable us to make use of this texture file correctly, we first need to find out what the UV coordinates are. The image below specifies them (click to see a bigger version): 
How to tweak the UV coordinates of a Box
Let’s first take a look at the current UV settings. We can find them in the generate() method of
sandy.primitives.Box. First an array is filled with UV coordinates:
l_geometry.setUVCoords( 0, 0, 0 );
l_geometry.setUVCoords( 1, 1, 0 );
l_geometry.setUVCoords( 2, 0, 1 );
l_geometry.setUVCoords( 3, 1, 1 );
The first parameter is the index, the next two parameters are the UV coordinates. These values are used a few lines further on in a call to the __tesselate() method:
//Front Face
__tesselate(l_geometry,
l_nID0, l_nID1, l_nID2, l_nID3,
0, 2, 3, 1,
_q - 1 );
I won’t go into all of these parameters, you’ll just have to take my word for it when I say that the parameters “0, 2, 3, 1″ are the indexes of the UV coordinates array. When you take a look at the UV coordinates and the order in which they’re passed to the __tesselate method you can see
that they’re ordered counterclockwise. Let’s take a look again at our skin and its coordinates:

First, we’ll put all of these coordinates in the UV coordinates array:
// -- top row
l_geometry.setUVCoords( 0, 0, 0 );
l_geometry.setUVCoords( 1, 0.33333333, 0 );
l_geometry.setUVCoords( 2, 0.66666666, 0 );
l_geometry.setUVCoords( 3, 1, 0 );
// -- middle row
l_geometry.setUVCoords( 4, 0, 0.5 );
l_geometry.setUVCoords( 5, 0.33333333, 0.5 );
l_geometry.setUVCoords( 6, 0.66666666, 0.5 );
l_geometry.setUVCoords( 7, 1, 0.5 );
// -- bottom row
l_geometry.setUVCoords( 8, 0, 1 );
l_geometry.setUVCoords( 9, 0.33333333, 1 );
l_geometry.setUVCoords( 10, 0.66666666, 1 );
l_geometry.setUVCoords( 11, 1, 1 );
Now it’s time to pass the right UV coordinates to the
__tesselate method. First, the front face:
/Front Face
__tesselate(l_geometry,
l_nID0, l_nID1, l_nID2, l_nID3,
0, 4, 5, 1, // these are the UV coordinates
_q - 1 );
You can see that the UV coordinates are ordered counterclockwise:
- top left: 0, 0
- bottom left: 0, 0.5
- bottom right: 0.33, 0.5
- top right: 0.33, 0
Now we can do the same with the other faces:
//Back Face
__tesselate(l_geometry,
l_nID4, l_nID7, l_nID6, l_nID5,
1, 5, 6, 2,
_q - 1 );
//Top Face
__tesselate(l_geometry,
l_nID2, l_nID6, l_nID7, l_nID3,
2, 6, 7, 3,
_q - 1 );
//Bottom Face
__tesselate(l_geometry,
l_nID0, l_nID4, l_nID5, l_nID1,
4, 8, 9, 5,
_q - 1 );
//Left Face
__tesselate(l_geometry,
l_nID0, l_nID3, l_nID7, l_nID4,
5, 9, 10, 6,
_q - 1 );
//Right Face
__tesselate(l_geometry,
l_nID1, l_nID5, l_nID6, l_nID2,
6, 10, 11, 7,
_q - 1 );
This will give us the desired result:
For a Box object, it’s this simple … other primitives are a whole different ballgame though.
Download the source code
- UVCoords.as: Basic Sandy 3D scene,
creates an instance of our modified Box - TweakedBox.as: The modified version
of a Sandy Box, with new UV coordinates




Thanks so much for this! This is exactly what I was looking for.
It was pointed out today that sandy docs are incorrect and confusing about UV mapping, so I had to link to this post for now, ha
[...] texture. When he applied this texture it was distorted. This indicated a problem with incorrect UV coordinates. Fixing this problem might seem like a daunting task for someone who is unfamiliar with UV [...]