2
\$\begingroup\$

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: 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?

\$\endgroup\$
5
  • 2
    \$\begingroup\$ 3D Max probably hides extra vertices from you for simplicity sake. \$\endgroup\$
    – Kromster
    Feb 24, 2014 at 7:42
  • \$\begingroup\$ So a little bit of cheating from 3ds max? ;) \$\endgroup\$
    – PolGraphic
    Feb 24, 2014 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, 2014 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, 2014 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, 2014 at 14:00

2 Answers 2

2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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

\$\endgroup\$
3
  • \$\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, 2014 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, 2014 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, 2014 at 11:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .