I'm developing a simple 3D engine for education purposes. I'm wondering whether a mesh contains a color of each vertex? Because I saw somewhere that mesh does not contain a color at all. If so, then where the color of a 3D model is stored? For example, if I have the mesh of a cube, how do I know in what color to paint each face of the cube, if they have different colors?
-
\$\begingroup\$ You may be looking for vertex colours, which are an optional channel of information you could store in a mesh, but are not required to. These can be used not just for colouring or tinting a model, but also for storing weight and offset parameters for various shader effects. \$\endgroup\$– DMGregory ♦May 24, 2022 at 15:14
-
\$\begingroup\$ @DMGregory, but if the color is optional, how then game engines know how to render a model or geometric shape if its vertices do not contain a color? \$\endgroup\$– sshdMay 24, 2022 at 15:20
1 Answer
A mesh can contain colours, but it is not required to.
The most common way to apply colour information to a model is using an image called a texture map (or just a "texture" for short). This lets you include tons of fine surface detail - limited only by the number of pixels in the image - even if the model itself has very few vertices or polygons.
To support texture mapping, each vertex of the mesh will store not just its position in 3D space, but also its position in the texture image - what we call a texture coordinate. This is normally a 2D vector whose horizontal component is called "u" and vertical component is called "v" (to distinguish them from the xyz we use for world space coordinates), so you'll also hear these referred to as "UV coordinates". The pattern of how a 3D mesh is unfolded to lie flat in the 2D coordinate space of the image is called a "UV unwrap" for this reason.
Here's an example of a 3D modelled barrel, and its corresponding texture map. You can see the surface of the barrel has been unfolded, like a papercraft model, to sit flat in the square space of the texture. And the texture allows us to paint or render-in super fine detail like wood grain, even given a coarse low-poly model.
The texture map - or maps, if the model uses several textures for different aspects of its appearance - will usually be stored in a separate image file, alongside the model data, rather than being encoded into the same file as the mesh. It's up to the game code to know which texture(s) to load for each mesh, and render them together appropriately - engines will usually have a "materials" system to handle this.
When rendering a triangle onto the screen, the texture coordinates from each corner of the triangle are interpolated over all the screen pixels covered by the interior of the triangle, and the pixel or fragment shader uses those interpolated coordinates to look up the colour from the corresponding location in the texture map, and use that in its shading calculations. This is called texture sampling.
It is also possible however to encode colours inside a mesh directly. These are called vertex colours, and they're just an extra channel of data stored for each vertex, just like the texture coordinates, but representing an RGB triplet or RGBA quartet instead.
These can be used directly to colour the model, or as a tint to apply on top of a texture as above. Or they can be repurposed entirely for all kinds of exotic effects - as varied as the shader programs that use them.
The problem with storing colours inside the mesh this way is you get only one colour data point per vertex. That means you can't make a point or line or other shape show up in the middle of a triangle this way, without subdividing the triangle to put more vertices in the middle. This makes vertex colours best-suited for information that changes in a slow / low-frequency way across the surface of a model, or where fine detail isn't needed. So you'll see it used to apply ambient occlusion shading or other global illumination effects, or doing things like tinting the bottom of grass quads to blend into the terrain underneath. For finer surface detail like the woodgrain above, you really need a texture - or several!
It is also possible to procedurally synthesize surface detail purely within the math of the shader program, but this is more complex to set up and can be more costly in performance for realistic-looking results, so this tends to be used more sparingly, in specialized applications.