从“1”开始3D编程
上QQ阅读APP看书,第一时间看更新

2.4 顶点、三角形、片元

用户输入的物体,是以顶点的形式描述的,而顶点是以三角形的形式装配起来的。这里的三角形,就是原语(primitive)。

GL和Vulkan使用了类似的方法来描述三角形。先看GL的情况。GL提供了下面三个方式来描述三角形。

(1)GL_TRIANGLES,将所有的顶点,每三个一组形成一个三角形,n个顶点形成n/3个三角形。可能的索引序列是:[0 1 2],[3 4 5],[6 7 8],…。

(2)GL_TRIANGLE_FAN,第0个顶点是所有的三角形共享的,n个顶点形成n-2个三角形。其可能的索引序列是:[0 1 2],[0 2 3],[0 3 4],…。

(3)GL_TRIANGLE_STRIP也是n个顶点形成n-2个三角形,但是要复杂一些。三角形的三个顶点索引中,如果最大的索引是偶数i,组成三角形的顶点排列顺序:[i-2 i-1 i],i≥2。如果当前三角形的序号是奇数,组成三角形的顶点排列顺序:[i-1 i-2 i],i≥2。一个例子是:

[0 1 2],最大索引2,偶数

[2 1 3],最大索引3,奇数

[2 3 4],最大索引4,偶数

之所以有这些规定,是为了保证所有的三角形都是按照相同的方向绘制的。所谓方向,就是顺时针或者逆时针(GL和Vulkan都由自己的接口来描述是顺时针还是逆时针)。在有些场景,三角形顶点的顺序非常重要,颠倒了顺序可能导致三角形被剔除。

相应地,Vulkan也实现了三个对应的枚举变量:

     VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
     VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
     VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN

除了三角形之外,有些图形系统里面(例如Chromium的合成器)还会使用到原语QUAD。QUAD其实就是两个三角形组成的一个矩形。

输入顶点经过原语组装(primitive assembly)得到三角形。光栅化(rasterization)引擎对三角形的顶点进行插值,生成三角形区域里面每一个点的信息。在没有多重采样的情况下,片元着色器(fragment shader)会给三角形区域里面的每一个点贴上相应的颜色。片元着色器每次操作的三角形的点,就是一个片元(fragment),这时候片元就是一个像素。如果有应用多重采样,则一个像素可能对应到多个片元(样本)。除非特别指出,本书讨论的都是没有使用多重采样的情况。

在GL里面,片元着色器输出到内置变量gl_FragColor。而Vulkan的一种可能的输出是:layout(location=0)out vec4 outFragColor。

如图2-6所示,顶点就是用xyz坐标描述的点。三角形是由三个顶点组成的。片元则是通过对三角形的顶点进行插值,生成的用来填充三角形内部区域的小方块。小方块经过片元着色器上色后,有了自己的颜色。

图2-6 顶点-三角形-片元