3
$\begingroup$

I'm new to the graphics area, and when it comes to the light part, the concept of vertex normals confuses me a lot.

First, I cannot imagine how a vertex could have a normal, and second, when calculating the reflection lights, shouldn't I use the normal of a face?

So, can someone help me understand what a vertex normal is, what it is used for, and how it compares to a face normal?

$\endgroup$
4
$\begingroup$

First, I cannot imagine how could a vertex have a normal,...

Welcome to the exciting field of computer graphics. The first thing that might lead to your confusion is to think about a vertex too much as a point in space in a geometrical way. ---> A 3d point can't have normal since it does not have a face. But the way you should think about it is more like a checkpoint that contains all information of an arbitrary 3d curve at a certain position.

... and second, when calculate the reflection lights, shouldn't I use the normal of a face?

What happens if you want to render a perfect sphere that can only be represented by a limited set of triangles? It will look like the one in the middle in this question. The flat surfaces are clearly visible, but that is not what you want. You can improve this by drastically increasing the triangle count, but that comes with a huge performance impact and memory footprint.

The solution here is using vertex normals. To understand, why this is a solution, you need to know a little bit about how the render pipeline works. The most important parts for your understanding are vertex processing, rasterization, and the pixel/fragment shader.

Vertex processing is the first programable (in modern APIs) step in the pipeline and is mostly used to reposition your vertices so that your 3d world is displayed correctly on a 2d display. Therefore you apply some mathematical corrections (perspective for example) to your vertex positions. You can do a lot more, but that is not important here. What is important is, that the vertex processor does not know to which triangle a vertex belongs. He sees it in total isolation. Therefore, he can not calculate any face normals, so you have to provide it in some way, for example by adding it as vertex attribute.

After some optional pipeline steps, you get to the rasterizer. Its job is to turn your triangles into actual pixels on your screen. The information he gets are three vertices that form a triangle. Now here is, where the magic happens. For each pixel, he interpolates the properties of the three vertices and passes them to the final step, the pixel shader (also programable in modern APIs). So if your vertices had normals, you will have an interpolated normal for each pixel of your triangle. This enables you to render perfectly smooth surfaces (or at least fake them) since you can perform the lighting calculation for each pixel with individual normals in the pixel shader.

This is why you need vertex normals. The vertices are checkpoints that hold information about your surfaces at specific points. You connect these points to triangles. The information in between is interpolated by the rasterizer. So you essentially describe a whole triangle-shaped field of normals with its three edge values.

However, even if you want to render flat surfaces, you might still need vertex normals. As I said before, the vertex processor does not know anything about triangles, so you can not calculate any surface normals there. So you have to pass them in somehow. There are other ways, but attaching the normals to the vertices is usually the best and easiest solution.

Additional note: You do not necessarily need to perform the lighting calculation in the pixel shader. You can also do this in the vertex stage. So you need vertex normals again ;). This is called Gouraud Shading and gives you a performance boost since you do not need to perform the light calculations per pixel. However, the visual quality of curved surfaces suffers from that. For flat surfaces, you should not see any differences.

| improve this answer | |
$\endgroup$
  • $\begingroup$ So, if I take a vertex, and assign it a "average" normal which calculate by all the faces it connect, then use this to do the lighting calculation, the result will be more smooth, right? Does tools like blender use vertex normal to make a low poly looks more smooth? $\endgroup$ – ravenisadesk May 29 at 8:15
  • $\begingroup$ As your suggestion, can I understand that vertices in graphics (for example glsl) are data somehow related to the geometry points, so it can represent any thing, that why I always see colors put into a VBO? $\endgroup$ – ravenisadesk May 29 at 8:20
  • $\begingroup$ First question: I don't know for sure how blender does it since I haven't really worked with it, nor have I looked into the code, but I guess they do it that way. However, calculating the "average normal" is not as trivial as you might think. See for example this question. $\endgroup$ – wychmaster May 29 at 9:14
  • $\begingroup$ Second question: To my understanding, a vertex is just a data point with arbitrary attributes. Not sure if this is the correct technical definition. However, as you said, the data can be anything. Everything attribute you add to your vertex will be available in the vertex processing step of the graphics pipeline (assuming you coded it correspondingly). You can use and modify this data there and optionally pass it down the pipeline. For example, the color attribute you mentioned is a common tutorial to render a triangle with smooth color transition. Every vertex there has a different color... $\endgroup$ – wychmaster May 29 at 9:27
  • 1
    $\begingroup$ @ravenisadesk If you're interested in this stuff, it might be fun to check out the .OBJ file format for some details on how these things actually get stored. Basically, an .OBJ stores a series of points (as X,Y,Z coordinates), then a series of faces (as triangles between the previously defined points). From those, renderers can pre-calculate the normal vector for each face and, subsequently, each point. $\endgroup$ – Josh Eller May 29 at 12:02

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.