首页 > 代码库 > OpenGL渲染管线概览

OpenGL渲染管线概览

翻译自OpenGL Wiki:http://www.opengl.org/wiki/Rendering_Pipeline_Overview,如有错误还请赐教

管线

OpenGL渲染管线按以下方式工作:

1. 准备顶点数组数据并渲染

2. 顶点处理:

        1. 每个顶点都要经过顶点着色器处理。每个顶点按所在数据流中的             顺序依次处理为输出顶点;

        2. 可选的图元曲面细分阶段;

        3. 可选的图元几何着色器处理,输出为一系列基本图元;

3. 顶点后处理,上一阶段的输出被调整或移位到不同的位置

        1. 变换反馈在此处进行;

        2. 图元裁切,齐次正规化以及视口到窗口的变换;

4. 图元装载

5. 扫描转换与图元参数差值(译注:即光栅化),生成一系列片段

6. 片段着色器处理每一个片段,每个片段生成一系列输出

7. 逐采样点处理

        1. 剪刀测试

        2. 模板测试

        3. 深度测试

        4. 混合

        5. 逻辑运算

        6. 写蒙版

顶点规格化

在顶点规格化的过程中,应用建立一个有序的顶点表并送入管线中。这些顶点定义了图元的边界。

图元是基本的绘图形状,比如三角形、直线和点。具体顶点表如何被解释为图元交于下一阶段处理。

管线的此部分处理一些对象,例如顶点数组对象和顶点缓冲区对象。顶点数组对象定义了每个顶点的数据,而顶点缓冲区对象存储实际的顶点数据。

一个顶点的数据是一系列属性,每个属性是一小集数据,将在下一阶段进行运算。尽管一系列属性确实能够确定一个顶点,但没有规定说明顶点的属性集必须包括位置或者法线。属性数据是完全任意的,在顶点处理阶段才会赋予其唯一的意义。

顶点渲染

一旦顶点数据规格化结束,就通过渲染指令被渲染成为图元。

顶点处理

每一个从原始数据采集来的顶点都必须被处理,这是顶点着色器的职责。它接收来自前一阶段的属性输入,根据一个任意的、由用户定义的程序,将每一个输入顶点转化为单个输出顶点。

不像输入顶点的信息,输出顶点数据要求较少,顶点着色器只必须填写一个位置值,以便送出一个有效的顶点。

顶点处理的一个限制是每个输入顶点必须对应一个特定的输出顶点。又因为顶点着色器的调用不能共享状态,输入属性与输出顶点数据是一一对应的。也就是说,如果在同样的图元中,你用同样的属性输入同样的顶点着色器,就会得到同样的输出顶点数据。这给了着色器优化顶点处理的权利,如果它们能探测出即将处理一个之前处理过的顶点,则可以使用变换后数据缓冲区中已经处理好的数据,从而避免对该顶点重复进行顶点处理。

图元装配

图元装配是收集一系列来自顶点着色器的顶点数据输出,并且将其合成为一个可行的基本图元的过程。用户用来渲染的图元类型决定了处理的方式。

这一处理的输出是一个有序的简单图元(点、线或三角形)序列。例如,如果输入是一个包含12个顶点的三角形条带图元,则输出的是10个三角形。

曲面细分

通过两个着色器阶段和之间的一个固定函数细分器,图元可以被曲面细分化。

几何着色器

除普通的图元装配步骤之外,你还可以使用一个几何着色器。这是一个用户定义的程序用于处理每个输入图元,并返回零或多个输出图元。

几何着色器的输入图元是图元装配的输出图元,故如果你输入一个三角形条带作为一个图元,则几何着色器会将其视为一系列三角形。

然而,还有一些输入图元种类是为几何着色器专门定制的,这些邻接图元给几何着色器一个关于这些图元的更广阔的视角:它们提供了邻接顶点的信息。

几何着色器的输出是零个或多个简单图元,和图元装配的输出类似。几何着色器可以移除图元,或者将单个输入细分成多个输出图元。几何着色器同样可以用来处理顶点值,包括替顶点着色器做一定工作,或者在细分的同时进行插值。几何着色器甚至还能将图元转换为不同的种类:输入点图元可转化为三角形,或者直线转化为点。

变换反馈

几何着色器或图元装配的输出结果被写入一系列专门为此设置的缓冲区对象中,这就称为变换反馈模式:它允许用户通过顶点和几何着色器进行数据变换,并可将结果保存供之后使用。

输出到变换反馈缓冲区的数据是由此步每个图元发出的。

通过放弃光栅化结果,渲染管线至此可以高效地结束。这使变换反馈可能成为了渲染过程的唯一输出。

裁剪和剔除

图元接着被裁剪和适当地剔除。

裁剪意味着处于可见区域内外边界的图元被分割成几个图元。同时,顶点着色器可以在保护空间中定义一些裁剪框并作用于图元,这些裁剪框将对穿过其上的图元进行额外裁剪。

三角形的表面剔除同样发生在此阶段,具体实现可以自由地立即剔除任意不在视区或者完全落于裁剪框边界内部的图元。

通过齐次正规化和视口变换,顶点的位置从裁剪空间转换到了窗口空间,

光栅化

到达此阶段的图元按输入顺序被光栅化,输出是一系列片段。

片段是一个状态集合,用于计算在输出帧缓冲区中的最终数据像素(或者采样点,如果允许多重采样的话)。片段的状态包括它在屏幕中的位置、在允许多重采样情况下采样的覆盖情况,以及一列来自先前顶点或几何着色器输出的任意数据。

最终的数据集通过片段顶点间的数据插值得到,插值的方式通过输出这些值的着色器定义。

片段处理

由光栅化阶段得到的每个片段的数据都被片段着色器处理,其输出是一列要写向颜色缓冲区的颜色值、深度值和模板值。片段着色器不能设定片段的模板数据,但是可以控制颜色及深度值。

逐采样点处理

接着,由片段处理输出的片段数据又历经了一系列步骤。

第一步是不同的剔除检测。如果有模板检测或深度检测则进行,如果失败了,此片段被剔除并不加入到帧缓冲。如果这些检测任意一个失败了,此片段被剔除并不加入到缓冲区。

        注意:如果你的片段着色器不填写深度值,也就是使用一般计算得到的深度值,具体实现中可以使用一种称为提早深度测试的优化策略。它在片段处理         前就执行深度(以及模板)检测,因此如果一个片段被剔除了,则无需运行片段着色器。

再次之后,进行混合。对每一个片段颜色值,有一个特定的混合操作,用于其与帧缓冲中对应位置的已经存在的颜色值。

最后,片段数据被写入帧缓冲。蒙版操作允许用户避免写入特定值。颜色、深度、模板写入均可选择开启或关闭蒙版,独立的颜色通道同样可以使用蒙版。

OpenGL渲染管线概览