# Texture coordinates for a 3D box

I have a box model in my DirectX application, stored as 8 vertices:

MyVertex vertices[] =
{
{ DirectX::XMFLOAT3(  - 1.0f,  + 1.0f,  - 1.0f ), /*,tex coord...*/}, //0
{ DirectX::XMFLOAT3(  + 1.0f,  + 1.0f,  - 1.0f ), /*,tex coord...*/}, //1
{ DirectX::XMFLOAT3(  + 1.0f,  + 1.0f,  + 1.0f ), /*,tex coord...*/}, //2
{ DirectX::XMFLOAT3(  - 1.0f,  + 1.0f,  + 1.0f ), /*,tex coord...*/}, //3

{ DirectX::XMFLOAT3(  - 1.0f,  - 1.0f,  - 1.0f ), /*,tex coord...*/}, //4
{ DirectX::XMFLOAT3(  + 1.0f,  - 1.0f,  - 1.0f ), /*,tex coord...*/}, //5
{ DirectX::XMFLOAT3(  + 1.0f,  - 1.0f,  + 1.0f ), /*,tex coord...*/}, //6
{ DirectX::XMFLOAT3(  - 1.0f,  - 1.0f,  + 1.0f ), /*,tex coord...*/}, //7
};


And for the index buffer I use:

WORD indices[] = {
3,1,0,2,1,3, //top
0,5,4,1,5,0,
3,4,7,0,4,3,
1,6,5,2,6,1,
2,7,6,3,7,2,
6,4,5,7,4,6,
};


It works just fine, but now I want to add a texture to the faces of my box.

## Which would be the best approach?

The options I see:

1. Use 24 instead of 8 vertices -- four for each of the box's six faces. Some of these will have the same position/normals, but different texture coordinates.
2. Use 8 vertices and texture coordinates like here:
3. MAYBE there is a way to provide different sets of texture coordinates for a single vertex, so I can provide different texture coordinates on different faces of the box? If so, how can I do that?

The disadvantages (for the options with the same numbers):

1. 16 additional vertices (3 as many), all the benefits of using a index buffer to have less vertices are wasted - maybe this means I shouldn't use an index buffer at all, under this approach?
2. Texture with odd proportion (2:3), texture must be six times the size for the same resolution.
3. None?

In option 2. I can use one texture to create different images on each box's face, but I'm not interested in that benefit.

How is this done in 3d software and mesh formats?

When I create a box in 3ds Max, create a material with a texture and apply it to the box, each side of box has the same texture (like option #1), with good texture coordinates (impossible to achieve with 8 vertices and a single square texture?), and the statistics says "8 VERTEXES".

How is it possible? Did they achieve option #3?

• 3D Max probably hides extra vertices from you for simplicity sake. – Kromster Feb 24 '14 at 7:42
• So a little bit of cheating from 3ds max? ;) – PolGraphic Feb 24 '14 at 10:54
• I'm more familiar with Lightwave 3D and it does cheat in such a way. There are also texture mapping modes (planar, cubic, spherical, etc) which are converted to UVs before render without user noticing. Why is that - to let 3D designers work without thinking about implementation details. Under the hood it could be all sorts of approaches. – Kromster Feb 24 '14 at 11:08
• Do you also account for normals and surface smoothing? That alone might require 24 separate vertices. – Kromster Feb 24 '14 at 11:14
• I can confirm that common mesh tools and formats quietly duplicate vertices wherever multiple texture coordinates or normals meet. You can test this by loading the model of your choice into a shader prototyping tool, and randomly displacing the vertices in a vertex shader - you'll see the polygons peel apart at uv and smoothing splits, because it's really multiple vertices which just happen to occupy the same position. For a cube with sharp shading edges, you're correct that you need 24 vertices. – DMGregory Apr 25 '14 at 14:00

A vertex is not just a spatial position, but a whole bag of attributes.

• A position p is a point in some spatial space or a homogeneous coordinate.
• A texcoord tc is a point in texture space.
• A normal n is a bivector, and so on.

If you represented a vertex with multiple indices, a vertex V_k could be represented by a tuple of indices {p_a, tc_b, n_c}. In a single-indexed environment like Direct3D or OpenGL, you can only have one index. This means that your index values will be {p_i, tc_i, n_i}, or in short, i.

If you've got multi-indexed geometry like in the former case, the way you can make it single-indexed is to for each unique tuple of indices, generate a new set of vertex attribute data with the same single-indexed index. If you've seen the tuple before, reuse the index; otherwise generate a new vertex.

If you have ever loaded the Wavefront OBJ file format, this will be painfully familiar to you as OBJ stores separate streams for each attribute and uses multi-indexed tuples like outlined above.

Other file formats use other approaches like pre-baked deduplicated single-indexed attribute streams, or completely non-indexed attribute streams, which is equivalent to deduplication without actual deduplication, just repeating the data for each vertex in each face.

I'd use a cube map. That way you can still only 8 vertices. You'll have to rework your texture that your sampling from and your texture coordinates will be three values instead of two.

• But then I would have to use another shader for boxes and another for other models (with non-cube maps). And switching between shaders can be even more expensive than changing vertexes' count from 8 to 24. Still it's some option, I would say #4. – PolGraphic Feb 24 '14 at 10:53
• @axlemke: You show an UV unwrap of the cube, how do you explain it uses only 8 vertices when I can clearly count 14 corners/intersections? – Kromster Feb 24 '14 at 11:12
• The box has 8 vertex, the corners on the texture map don't matter. And it's a cube map, not sure if you consufe UV unwrap. – PolGraphic Feb 24 '14 at 11:40