Understanding Texture Coordinates and Vertex Colors

In 3ds Max, texture and vertex color information is stored in so-called texture vertices resp. color vertices. They build a mesh which also has texture faces resp. colorPreVertex faces referencing these vertices. This matter often leads to misunderstandings and requires a detailed explanation:

Mesh Vertices and Faces

Mesh vertices are Point3 values representing points in three-dimensional space, labeled X, Y and Z. Mesh faces reference 3 of these points to define a surface in space. There can be any number of faces referencing the same vertex. For example, the pole of a Sphere is shared by a large number of faces.

Texture Vertices and Faces

Texture vertices are Point3 values representing points in texture space – U, V and W. Since bitmap textures are two-dimensional, the W value is often not used, but it is always stored. The U and V values correspond to a location in the bitmap plane, in other words, to a pixel in the bitmap. This means that the coordinates tell the mesh which pixel of the image should appear at a certain point of the actual mesh.

In the case of 3D procedural textures, all 3 values can be used to define a point inside the texture space. Texture faces connect these vertices and build a separate mesh which represents the object in texture space. Each texture face references 3 vertices. There can be any number of texture faces referencing the same texture vertex.

Color Vertices and Faces

Color vertices are Point3 values representing points in color space – R, G and B. If you imagine a cube with side of 1 unit where Red goes along the local X axis, Green along the Y and Blue along the Z axis, the lower left corner would be 0.0,0.0,0.0 completely black, the opposite corner would be 1.0,1.0,1.0 completely white, and each point inside the cube would stand for any of the colors that can be represented by a Point3 value with components between 0.0 and 1.0.

Color vertices are basically a variation of texture vertices. Historically, early versions of 3ds Max could use either two texture channels or one texture and one color channel. (in other words, the one texture channel could be used in two different ways). Thus, ColorPerVertex faces are used to connect the Color Vertices to a separate mesh just like in the case of texture coordinates.

But how do they fit together?

It is very important to note that

A - There can be more or less texture and color vertices than there are mesh vertices

B – There are always exactly as many mesh faces as there are texture and color faces!

So there is no one-to-one correspondence between mesh vertices and texture and color vertices. You cannot take vertex number 10 from the mesh and expect that texture vertex 10 will store the information about its texturing or color vertex 10 would define its vertex color.

As mentioned in B, the number of faces is always identical. Not only this, the indices of the mesh and texture resp. color faces have a one-to-one correspondence! If face 5 has 3 mesh vertices you are interested in, their corresponding texture vertices will be the 3 vertices referenced by the texture face number 5.

This is the key to access to texture and color information in 3ds Max!

Finding the corresponding vertices

In order to find out which texture vertex corresponds to a mesh vertex, you have to do the following:

  1. Take the index of the mesh vertex.

  2. Find out which faces reference the index of the face.

  3. Note the number of the vertex (1 st , 2 nd or 3 rd - .x, .y or .z) inside each face.

  4. For each face referencing the vertex, get the texture face with the same index.

  5. Get the index of the respective texture vertex from the face - 1 st , 2 nd or 3 rd / .x, .y or .z

  6. The vertex you got corresonds to the mesh vertex we started with.

  7. Repeat steps 3 to 6 for all faces found.

    Same applies to color vertices.

Why so complicated?

Historically, Autodesk 3D Studio for DOS supported only one texture vertex per mesh vertex and no color vertices. This means there was a simple one-to-one correspondence between mesh and texture vertices, but this also led to problems still visible in the .3DS file format.

Let's take a look at a textured Sphere. Spherical mapping coordinates mean that the horizontal row of texels running through the middle of the mapped image is applied to the equator, all top texels meet together at the north pole, and the bottom texels meet at the south pole of the sphere. At the pole, there is only one vertex, but there are a large number of faces using it, and a large number of texels that should meet there. In the case of the .3DS style texture coordinates, only one texture vertex would be allowed at the pole. This would lead to a severe distortion around the pole.

In 3ds Max, each face indexing the pole vertex has a texture face counterpart referencing a different texture vertex pointing at a different texel of the texture. The image gets wrapped around correctly and there are no artifacts near the pole.

Same applies to the seam where the texels of the left and right side of the image meet. The underlying mesh vertices should be able to reference two different texels – one for each side of the seam. In .3DS, only one value could be stored. In 3ds Max, both values can be referenced through the corresponding texture faces.

You can visualize this by creating a Sphere with texture coordinates and exporting to .3DS without preserving the texture coordinates. The number of texture vertices will be reduced to fit the old format. Read back the .3DS file, apply the same material to both objects (original Sphere and imported mesh) and compare the mapping:

What does the Preserve Max Texure Coordinates checkbox in the 3DS Exporter do? It duplicates the mesh vertices to achieve the one-to-one correspondence required by the .3DS format. This means that the pole vertex of a sphere will be split into multiple vertices, one for each face referencing it and using a different texture vertex. While this will preserve the coordinates, it destroys part of the mesh smoothing as there can be no smoothing between elements not sharing common vertices/edges. (see left sphere on the image)

Color Vertices At Work

The above thoughts are more or less valid for Vertex Colors except they cannot be exported to .3DS at all. But there are some interesting implications.

Let's take the Sphere again and apply Vertex Colors to it. Other than the texture vertices, the pole vertex will most probably require only one single color – despite the fact there are multiple faces sharing the pole vertex, there is only one vertex normal used when calculating lighting. This means that all faces could reuse the same value.

Now let's do the same with a Box. There are multiple faces sharing each corner vertex. The difference to a Sphere is that each side of the Box has its own normal since the Box is flat-shaded. This also means that the lighting is calculated differently for each side, but is stored in the same vertex. Just like with texture vertices, we need more than one color vertex in order to achieve the flat look. Reusing a single color value for all sides of the Box would make the shading smooth!

Many game engines still support just one color vertex per mesh vertex. Using MAXScript, it is possible to develop a utility to reduce the numbers and achieve a one-to-one correspondence, but at cost of a overly smooth look with no flat shading.

Another interesting example – let's say you have a Teapot and want to paint it all Red. While you could store a single color vertex for each mesh vertex or even more, it would be possible to create a single color vertex and reference it in each of the 3 vertex indices of each color face! Changing this single color vertex value would change the vertex color of the complete object instantly!

Note that using the Unwrap_UVW modifier, it is possible to animate the values of texture and color vertices over time! Remembering that the 3 values correspond to the Red, Green and Blue channel, you could move a vertex in the Unwrap Editor around in the XY plane and thus control its RG color, while using the third value spinner to move up / down along the Blue axis. Placing a Red-Green gradient as Editor background image (black in the lower left corner, red in the lower right corner, green in the upper left corner, yellow in the upper right corner) would give you a visual editor for animated vertex colors!