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

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: unwrapped cube
  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.

Additional question (!!!):

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?

  • 2
    \$\begingroup\$ 3D Max probably hides extra vertices from you for simplicity sake. \$\endgroup\$
    – Kromster
    Feb 24 '14 at 7:42
  • \$\begingroup\$ So a little bit of cheating from 3ds max? ;) \$\endgroup\$
    – PolGraphic
    Feb 24 '14 at 10:54
  • \$\begingroup\$ 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. \$\endgroup\$
    – Kromster
    Feb 24 '14 at 11:08
  • 1
    \$\begingroup\$ Do you also account for normals and surface smoothing? That alone might require 24 separate vertices. \$\endgroup\$
    – Kromster
    Feb 24 '14 at 11:14
  • \$\begingroup\$ 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. \$\endgroup\$
    – 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.

enter image description here

  • \$\begingroup\$ 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. \$\endgroup\$
    – PolGraphic
    Feb 24 '14 at 10:53
  • \$\begingroup\$ @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? \$\endgroup\$
    – Kromster
    Feb 24 '14 at 11:12
  • \$\begingroup\$ 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. \$\endgroup\$
    – PolGraphic
    Feb 24 '14 at 11:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.