在网格中的每一个面都有一个垂直于它的单位法向量,这个向量的方向取决于顶点定义的顺序和使用了左手坐标系还是右手坐标系。面法向量的方向与多边形正面的朝向一致,在Direct3D仅有多边形的正面是可见的。一个多边形正面的顶点是以顺时针的方向定义的。
图见对应DX文档
一个面不是正面就是背面,Direct3D一般不渲染背面,因此,背面被剔除。如果你想的话可以改变剔除模式去渲染背面。如果想了解更多的信息,请看Culling state。
Direct3D为了格劳德着色,灯光和纹理效果而使用顶点单位法向量。
当对一个多边形应用格劳德着色,Direct3D使用顶点法线去计算面和光源的夹角。它为每个顶点计算颜色和强度值并且对所有多边形表面的点进行插值。Direct3D通过角度计算灯光强度值,角度越大,照在表面上的光越少。
如果你定义的是一个平面,那么就设置顶点的法线垂直于这个表面,就像下图所表明的那样。这就定义了一个由两个三角形组成的平面。
图见对应DX文档
大概就是这样的,然而,如果你的对象是由一些不共面的三角形组成的,有一个简单的方法可以实现为这个条带中的三角形平滑着色。首先计算与这些顶点相关联的多边形的面法线。顶点的法向量可以被设置成与它相关联的面的法线的平均值。然而,也许对于复杂图形这种方法并不高效。
这个方法通过下面的图表示出来,有两个面,S1和S2在上方相交,他们的面法向量用蓝色表示,顶点的法向量用红色显示,它可由S1和S2的法向量的夹角求平均值得出,当这两个面用格劳德在明暗之间过渡时,会有平滑的效果,平滑地过渡它们之间的边。
图见相应DX文档
如果顶点法线往与这个顶点相关联的这些面之一倾斜,将导致照在这个表面上的光照强度增强或者减弱,这取决于光源的角度,下图说明了一个例子,这两个表面相交,顶点法线向S1倾斜,导致顶点法线与光源方向夹角小于两个面的法向量夹角平均值。
图见相应DX文档
你能够使用格劳德显示在3D场景中的对象的清晰边界,要这么做,复制这些需要清晰边界的面的交叉点的法线向量,像下面图中说明的一样。
图见相应DX文档
如果你使用DrawPrimitive methods去渲染你的场景,应该把要显示清晰边界的对象定义为一个三角形列表而不是一个三角形条带。当你把一个对象定义成三角形条带,Direct3D会认为它是由多个面合成的多边形,格劳德着色模式会应用到这个多边形的面两个相邻的面之间。结果是一个面到面之间平滑过渡的对象。因为一个三角形列表是由一连串的互不相连的三角形面组成的,Direct3D应用格劳德着色到多边形的每一个面上,然而,并不是从面到面的平滑过渡。如果三角形列表的两个或者更多的面相邻,它们之间会有一个清晰的边界 。
另一个办法是当渲染对象的时候改用平面着色,它是最有效的计算方法,但结果也许不如使用格劳德着色来得真实。
原文
Face and Vertex Normal Vectors
Each face in a mesh has a perpendicular unit normal vector. The vector's direction is determined by the order in which the vertices are defined and by whether the coordinate system is right- or left-handed. The face normal points away from the front side of the face. In Direct3D, only the front of a face is visible. A front face is one in which vertices are defined in clockwise order.
图见对应DX文档
Any face that is not a front face is a back face. Direct3D does not always render back faces; therefore, back faces are said to be culled. You can change the culling mode to render back faces if you want. See Culling State for more information.
Direct3D uses the vertex unit normals for Gouraud shading, lighting, and texturing effects.
图见对应DX文档
When applying Gouraud shading to a polygon, Direct3D uses the vertex normals to calculate the angle between the light source and the surface. It calculates the color and intensity values for the vertices and interpolates them for every point across all the primitive's surfaces. Direct3D calculates the light intensity value by using the angle. The greater the angle, the less light is shining on the surface.
If you are creating an object that is flat, set the vertex normals to point perpendicular to the surface, as shown in the following illustration. A flat surface composed of two triangles is defined.
图见对应DX文档
It is more likely, however, that your object is made up of triangle strips and the triangles are not coplanar. One simple way to achieve smooth shading across all the triangles in the strip is to first calculate the surface normal vector for each polygonal face with which the vertex is associated. The vertex normal can be set to make an equal angle with each surface normal. However, this method might not be efficient enough for complex primitives.
This method is illustrated by the following figure, which shows two surfaces, S1 and S2 seen edge-on from above. The normal vectors for S1 and S2 are shown in blue. The vertex normal vector is shown in red. The angle that the vertex normal vector makes with the surface normal of S1 is the same as the angle between the vertex normal and the surface normal of S2. When these two surfaces are lit and shaded with Gouraud shading, the result is a smoothly shaded, smoothly rounded edge between them.
图见对应DX文档
If the vertex normal leans toward one of the faces with which it is associated, it causes the light intensity to increase or decrease for points on that surface, depending on the angle it makes with the light source. An example is shown in the following figure. Again, these surfaces are seen edge-on. The vertex normal leans toward S1, causing it to have a smaller angle with the light source than if the vertex normal had equal angles with the surface normals.
图见对应DX文档
You can use Gouraud shading to display some objects in a 3D scene with sharp edges. To do so, duplicate the vertex normal vectors at any intersection of faces where a sharp edge is required, as shown in the following illustration.
图见对应DX文档
If you use the DrawPrimitive methods to render your scene, define the object with sharp edges as a triangle list, rather than a triangle strip. When you define an object as a triangle strip, Direct3D treats it as a single polygon composed of multiple triangular faces. Gouraud shading is applied both across each face of the polygon and between adjacent faces. The result is an object that is smoothly shaded from face to face. Because a triangle list is a polygon composed of a series of disjoint triangular faces, Direct3D applies Gouraud shading across each face of the polygon. However, it is not applied from face to face. If two or more triangles of a triangle list are adjacent, they appear to have a sharp edge between them.
Another alternative is to change to flat shading when rendering objects with sharp edges. This is computationally the most efficient method, but it may result in objects in the scene that are not rendered as realistically as the objects that are Gouraud-shaded.