# 頂点カラーとは何ですか？

31

3D空間上の頂点は単純な点ではありませんか？もしそうなら、どのようにポイントに色を付けることができますか？それとも、この「色」は何か他のものを意味していますか？

アンリアルエンジンのマテリアルエディタには「頂点カラー」ノードがあります。

2
In geometry a vertex is just a point in space. But for 3D rendering you want things to look nice, which might mean attaching more information to each vertex, like a colour, or a texture coordinate, or skeletal weights so you can animate the mesh more easily, or a normal direction to use in lighting calculations.
user253751

3
I think a big part of your confusion is because of the frequent conflating of terms “vertex” and “position” in 3D/graphics. Mathematically, your statement “Isn't a vertex simple point on 3D space?” is correct, but in the realm of game engines & graphics, no, a position is a simple point in 3D space; and a (mesh) vertex is a piece of data that almost always has a position, but may also have a normal, tangent, texture coordinate, color, and/or any of numerous other pieces of data. A mesh vertex is really just a chunk of data that's processed at the vertex stage of rendering.
Slipp D. Thompson

29

Vertex colors aren't that relevant when you have a fully textured 3d mesh. But it gets interesting when you have an untextured but colored mesh. In that case you assign a color to every vertex. The shader would then color each pixel of a polygon by interpolating between the colors of the three vertices.

Vertex colors can also sometimes be interesting in combination with textures. When you want to use a shading algorithm like Gouraud Shading, you just calculate the light intensity on each vertex, assign the light color to the vertex as a vertex color, and when you render the texture you multiply the color value of each texture pixel with the interpolated colors. This allows you to calculate light sources in the vertex shader instead of the pixel shader. This is usually far faster, because the vertex shader is usually executed far less frequently.

2
btw, vertex color was used in some older games that didn't have any dynamic lightning/shadows. For example Richard Burns Rally from 2004 is using vertex color to create different looking textures and apply shadows.
martin

The Witness is a recent game that makes extensive use of vertex colours and lightmaps, but not many textures.
user253751

@Philipp "because the vertex shader is usually executed far less frequently" Why? Isn't the vertex shader part of the rendering pipeline and thus executed each frame? Why so less frequently? Wouldn't the vertex "color" have to be calculated every frame as well, just as if it was in the pixel shader?
Nikos

1
@Nikos A vertex shader is called once per vertex. A pixel shader is then called once per pixel. A polygon with 3 vertices usually results in more than 3 on-screen pixels (if your game ends up calculating a lot of polygons which cover less than 3 pixels, you might want to look into what you can do regarding culling and LOD).
Philipp

25

In theory, Vertex Color allows to color a model without having to bother with textures. This is quite common in CAD.

In practice, it's just one more slot you can use to push data into the vertex, which you then use in the vertex shader to do crazy stuff.

"Isn't a vertex simple point on 3D space?"

That's what I used to think, when I first started with 3D. I learned quickly that I was wrong.

You can think of a vertex as a data blob that makes up a corner of a triangle you want to paint on screen (and neither the "corner" part nor the "triangle", "paint", or "screen" parts are always true). Position is one -optional - aspect of that data blob we call Vertex.

There is a lot you can do by attaching additional data to the vertex. The most famous example is that you can add uv coordinates to draw a texture on that triangle. You (usually) can't decide what part of a texture to draw on the triangle if you just have a point - you need texture coordinates too.

Other standars examples of what's in that blob are normals, and tangents. What's important is that all of them are optional, including the position. Vertex Color is just one of these optional inputs that you can use or abuse to create a pretty picture on the screen.

2
".. as a data blob that makes up an edge of a triangle" even that is not necessarily. Vertexes could be rendered as points just fine.
Kromster says support Monica

3
For some great examples of the shader effects you can achieve using vertex colours, I highly recommend checking out Natalie Burke's GDC talk from last year, "Animating With Math" (video is members-only at the moment, but the slides are free here). She shows how many of the animations in Destiny's gear, character hair and cloth, and even parts of their enemies and environments were achieved using vertex shaders, shaped and controlled with vertex colour channels.
DMGregory

5
I'd argue, that those were not vertex colors, but vertex attributes shown as colors for easier perception.
Kromster says support Monica

There are some similarly inventive uses of vertex shaders in this talk about FortNite, although if I recall correctly I think they mostly used the vertices' UV channels rather than colour channels.
DMGregory

3
Strictly speaking from a geometry/maths-based point of view a vertex is just a point in space. The 'vertex colour' is an attribute applied to the vertex by the 'idea' of a vertex used by GPUs. It's the same as a circle having a colour or not. The geometric/mathematical 'idea' of a circle does not have a colour but the rendering software 'idea' of a circle associates a colour to the circle. Thus @Kromster's argument is more technically correct.
Pharap

8

Vertices can have colors, it's a property just like the normal of it.

In 3d enviroments a triangle gets colored based on their vertices' color information. The closest fragments to vertex A get the color of it, the closesr to vertex B get the colornof B, and the color interpolates between the 2.

It works the same way as per-vertex lighting

It's an easy way to add colors to a model without using a texture.

+1 for giving a (hopefully) familiar example of another similar vertex attribute
A C

The problem with vertex colors and normals is that they assume the vertex is part of a mesh (an approximation of a curved surface). If you want sharp edges or different colored faces (such as on a cube), you need separate vertices for each face, which greatly increases memory usage (and slows rendering).
amI

@aml You can use the flat "operator" in glsl to output make the shading look flat. It's not completeley the same, but it works.
Bálint

other interpolated attribute : texture coordinate and z-buffer ! we have the vertex shader computing some data for each of the 3 vertices of the triangle, those are interpolated when drawing the triangle on the screen (or in some buffer), and the pixel shader is called with the interpolated value for each drawn pixel
user1952009

@aml Of course x2 isn't a bottleneck. And geometry shaders are made for that, I'd say (e.g. : transforming a depth texture into triangles)
user1952009

2

There are solid answers here already - I just want to chime in with one more common way you'll see vertex colours used:

Varying object colours (or other attributes) within a single batch / draw call.

You'll see this used in rendering particle systems, text, and batched (usually atlassed) sprites.

Imagine you have a particle emitter that spawns particles with a random start colour, or that fade to 0 alpha over the particles' lifetime. If we were to use shader uniforms to send this colour data, we'd need to draw each differently-coloured particle in its own draw call, making the particle system much more expensive. Instead, we can bake these colours into the vertex data for the particles, and render the whole batch together in a single call.

Unity appears to use this technique for particle colour variation, as well as for colouring individual characters in a TextMesh or Sprites rendered together in a batch.

I believe you can do something similar with geometry instancing, but I don't know how the two compare in performance. It's possible that today doing this type of instanced tweaking through vertex colours is more of a hold-over to support pre- OpenGL 3.1 / DX9 hardware like some mobile devices, rather than a best practice for modern PCs. I'd welcome comments from folks who've done more performance tuning with batches & instancing to help clear up whether these techniques have superseded vertex colours for this purpose. :)