Chapter 2 – The Graphics Rendering Pipeline 图形渲染管线

2.5 像素处理

在这个阶段,我们认为所有的像素都位于一个三角形内部。而像素处理阶段被分为两个部分,像素着色(pixel shading)以及合并(merger),如下图所示。在像素处理阶段,我们会计算并操作每一个位于图元内部的像素或者采样点。

2.5.1 像素着色

任何基于每一个像素的计算都在这个阶段执行,并且使用插值后的着色数据作为输入。最后的结果将会是颜色值,并被传输至下一个阶段。三角形设置与三角形遍历这两个阶段都是由硬件完成,但是像素着色阶段则由可编程的GPU核心来处理。因此,程序员需要为像素着色器(在OpenGL中被称为fragment shader)提供代码与程序,其中可以包含任何我们需要的计算与处理。在这个阶段我们可以运用各种各样的技术,其中最重要的一个就是texturing(贴图技术)。我们将在第六章中更详细地学习这一知识点。简单来说,该技术就是将图像“黏贴”在物体上。而图像可以使一维,二维或者三维的,一般来说,我们会使用二维图像。而最简单的情况下,我们将会为每一个fragment生成一个颜色值,并将其传输至下一个子阶段。

2.5.2 合并

每个像素的信息被存储在color buffer中,一般来说该buffer是一个由颜色(分别由RGB三种颜色成员组成)组成的矩形数组。而合并阶段就是要将像素着色阶段所生成的fragment的颜色与存储在buffer中的颜色进行合并。该阶段也被称为ROP(raster operation pipline)或者render output unit。不同于像素着色阶段,该阶段中的操作并不是完全可编程的。但是,这一阶段可以通过我们不同的设置以达到不同的效果。

该阶段也会决定一个像素是否可见。也就是说,当整个场景被绘制完成后,color buffer应该之保存着场景中对于camera可见的图元中的像素的颜色。对于大多数图形硬件来说,这将由z-buffer(也被称为depth buffer)算法来完成。z-buffer与color buffer有着相同的尺寸与形状,对于每一个像素来说,其存储了距离camera最近的z轴的值。这意味着,当图元被绘制到某一个像素时,该图元位于该像素的z轴的值将与z-buffer中相同位置的像素的z轴的值进行比较。如果新像素的z轴的值小于z-buffer中像素的z轴的值,那么表示该图元要更靠近camera。因此,z轴的值以及该像素的颜色将被更新为图元中像素的z轴的值与颜色。如果相反,那么z-buffer中的值与color buffer中的值并不会被更新。z-buffer算法非常简单,且可以运用于任何需要被绘制的图元,只要我们能够计算出其像素的z轴的值。还有一点就是,该算法将允许我们以任何顺序去绘制大多数图元,这也是该算法被普遍采用的一个原因。然而,z-buffer只存储了屏幕中每一个点的单一深度值,所以其并不能用于带有透明度的物体。而这些物体需要在所有不透明图元被绘制后,并以“从后向前”的顺序进行绘制,或者我们使用另一个独立的算法进行处理。处理带有透明度的物体是z-buffer算法的一个主要弱点。

我们已经提到了color buffer用于存储每个像素的颜色,同时z-buffer用于存储每个像素的z轴坐标。然而,还有其他方法能够筛选并捕捉fragment的信息。color buffer中的alpha通道,其存储了每个像素的不透明度。在之前的API中,alpha通道还被用于alpha test,其决定是否舍弃一个像素。现在,我们可以在像素着色器中觉得是否舍弃一个像素,同时任何类型的计算都能触发这一特性。这一类型的检测可以确保完全透明的fragment不会影响z-buffer。

stencil buffer是另一个“屏幕后”的buffer,我们可以使用该buffer记录所绘制的图元的位置。通常,该buffer为每个像素保留一个8位的空间。图元可以被绘制到stencil buffer中,之后我们可以使用该buffer来决定某些像素是否能被绘制到color buffer与z-buffer。例如,一个实心圆已经被绘制到stencil buffer中。那么我们可以使用stencil buffer与一个运算符相结合,只允许绘制color buffer中位于实心圆区域的图元。stencil buffer能生成许多特殊的效果。所有这些位于管线结尾处的功能都被成为raster operation pipeline(ROP)或者blend operation(融合操作)。我们也可以将color buffer中某个像素的颜色与正在处理的相对应的像素的颜色进行融合。这就行车了透明度的效果,或者颜色采样累加的效果。正如我们之前提到的,blending融合一般来说是通过API进行设置,其并不是完全可编程的。然而,有一些API支持raster order views(光栅顺序),其也被成为像素着色器排序,其支持可编程的blending融合。

framebuffer一般指的是系统中所有的buffer。

当图元到达并通过光栅化阶段,那些对于camera可见的图元都会呈现在屏幕上。而屏幕将显示color buffer的数据。为了避免用户或者玩家看到图元被光栅化并被传输至屏幕的过程,我们会使用double buffering(双缓存)技术。这意味着绘制场景的过程将发生在“屏幕后”,在back buffer中。当场景被绘制到back buffer之后,back buffer的数据与front buffer的数据在呈现在屏幕上之前会进行调换。这个“调换”的过程通常发生在垂直回描(vertical retrace)

留下评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据