处理器/DSP
GPU渲染流水线,是硬件真正体现渲染概念的操作过程,也是最终将图元画到2D屏幕上的阶段。GPU管线涵盖了渲染流程的几何阶段和光栅化阶段,但对开发者而言,只有对顶点和片段着色器有可编程控制权,其他一律不可编程。如下图:
简单总结GPU管线,这阶段中主要是对图元进行操作。首先,将由应用阶段加载到显存中的顶点数据(由drawCall指定后)作为输入传递给顶点着色器。接着,顶点着色器首先对图元的每个顶点设置模型视图变换及投影变换(即右乘MVP矩阵),然后将变换后的顶点按照摄像机视椎体定义(即透视投影,或正投影)进行裁剪,将不在视野内的顶点去掉并剔除某些三角面片。最后到几何阶段的屏幕映射,负责把修改过的图元的坐标转换到屏幕坐标系中(即投影到屏幕上)。
到光栅化阶段,这一阶段主要目的是将每个图元转换为多个片段,并生成多个片段的位置,由片段着色器负责计算每个片段的颜色值。同时,在这阶段片段着色器通常会要求输入纹理,从而对每个片段进行着色贴图。每个片段在被发送到帧缓冲区之前,还会经历一些操作,这些操作可能会修改片段的颜色值,其中包括深度测试,模板测试,像素所有权测试,与当前缓冲区相同位置颜色混合等等。
最后,帧缓冲区内容被交换到屏幕进行显示。
下面会对各个阶段每个知识点进行详细的分析理解。
一、顶点着色器
顶点着色器是一段类似C语言的程序(即OpenGL的GLSL,或只支持微软的HLSL,或Unity的Cg),由程序员提供并在GPU上执行,对每个顶点都执行一次运算。顶点着色器可以使用顶点数据来计算改顶点的坐标,颜色,光照和纹理坐标等。在渲染管线中,每个顶点都独立的被执行。原因在于顶点着色器本身不能创建或删除顶点,也无法得到顶点与顶点之间的关系,如无法知道两个顶点是否属于同一个三角网格。正因这独立性,GPU可以并行化处理每一个顶点,提高处理速度。
顶点着色器最重要的功能是执行顶点的坐标变换和逐顶点光照。坐标变换是改变顶点的位置,把顶点坐标从模型空间转换到齐次裁剪空间(即将本地坐标系转换为裁剪坐标系)。通过改变顶点位置可以实现很多酷炫的shader效果,如模拟水面,布料等等,这里后面添加实例学习例子再详细说明。 顶点着色器的另一功能是向后续阶段的片段着色器提供一组易变(Varying)变量,用于插值计算。
二、图元装配
在顶点着色器程序输出顶点坐标之后,各个顶点按照绘制命令(DrawArrays或DrawElements)中的图元类型参数和顶点索引数组被组装成一个个图元,并对其进行如下图的图元操作:
裁剪,处于视椎体以外的图元将被丢弃,若该图元与视椎体相交则会发生裁剪产生新图元,如下图:
注意一点,透视裁剪是比较影响性能的过程,因为每个图元都需要和6个裁剪面进行相交计算并产生新图元。所以一般在x轴,y轴超出屏幕(由glViewPort定义)的部分,这些顶点在视口变换的时候被更高效的直接丢弃,无须产生新图元。
视椎体在OpenGL中可以通过gluPerspective来定义对应的大小结构,在Cocos2dx引擎中,Director类的setProjection方法就定义了cocos的渲染用到的视椎体,大家可以阅读对应的代码了解学习下。
经过视椎体裁剪后的顶点坐标经过透视分离(指由硬件做透视除法),得到范围是[0,1]的归一化的设备坐标,最后映射到屏幕或者视口上。
三、片段着色器
【先补充一点,其实在光栅化之前,要判断图元的朝向,是面向还是背对观察者,以决定是否需要丢弃图元。在OpenGL可通过glFrontFace指令来决定哪个方向为正,并通过glCullFace决定需要保留哪一面(别忘了要先打开剔除状态设置才可以调用指令 glEnable(GL_CULL_FACE);)。这样设计的好处是能减少一些不必要的绘制,并减少对GPU的浪费。】
回到正题,片段着色器同上述的顶点着色器,只是它作用的对象是每一片段,对其进行着色贴图。片元着色器的输入是根据那些从顶点着色器中输出的数据插值得到的,其中最重要的渲染技术之一是纹理采样。在顶点着色器阶段输出每一顶点对应的纹理坐标,然后经过光栅化阶段对三角网格的3个顶点各自纹理坐标进行插值运算后便得到其覆盖片元的纹理坐标,从而在片元着色器中进行纹理采样。如下图:
四、逐片元操作
这里篇幅原因不一一分析每种测试操作,大家可以通过看书了解对应的用途。下面举混合操作来分析一下。下图是简化流程图:
对于不透明的物体,可以直接关闭混合Blend操作,这样片元着色器计算得到的颜色值直接覆盖更新缓冲区的颜色值。但对于半透明物体就必须开启使用混合操作从而让物体看起来是透明的。开发过程中无法得到透明效果的原因,往往有可能是没有开启混合功能的原因。
由于计算机图形的性质,最图形管线已构造为计算状态与数据流动作为它们之间的数据流。每个阶段工作在一组元素,如顶点,三角形或像素。下图1 [ Shr99 ]给出了典型的OpenGL固定管道。
图1: 在OpenGL的固定管道。
人们很容易看到这种体系结构如何类似于中描述的流计算模型上一节。这种类型的固定结构的是,直到最近,计算机图形卡制造商的标准可循。虽然类似流计算模式,它提供了很少或没有编程的用户,因此,它是不可用于比处理图形指令的其他任何任务。2000年[ Owe05 ],GPU 小号允许管道的关键部位的可编程性一定程度。
当前GPU 小号允许用户在形式的图形流水线的两个阶段几乎任何类型的功能进行编程顶点程序和片段的方案。这些允许用户分别写在顶点和片段数据的程序。图2 示出了更近的映射的OpenGL可编程管线到流模型。
图2: 图形流水线作为流模型。
该顶点处理器
顶点处理器输入的顶点值和其相关的数据进行操作。它的目的是执行传统的图形操作,如:顶点变换,正常转化和规范化,纹理坐标生成和改造,照明和颜色计算[ Ros04。因为顶点处理器是能够改变输入的顶点数据的位置,从而影响最终图像的要绘制。由于图像是,在本质上,的存储器阵列,顶点处理器能够分散状操作。另外,最近的处理器能够从纹理存储器读出,从而产生一种特殊的延迟收集动作。我们称之为延迟,因为顶点不能直接从其他顶点元件读取的信息,但它可以读取的任何数据从先前的计算结果,如果它是在纹理存储器编码。在后面的章节中,我们将看到如何利用这一点来执行简单的计算。
顶点处理器可以在SIMD(单指令多数据)或MIMD(多指令多数据)模式下运行; 因此,允许两个,一个处理器单元中的指令和任务并行。由于现代GPU 小号包含多个顶点处理器(最新的NVIDIA 和ATI卡有多达六个),我们可以开始欣赏并行这些体系结构上实现的水平。
该碎片处理器
该片段处理器上的片段和它们相关联的数据进行操作。一些传统上与片段着色器相关联的操作是:质地接入和应用,雾,颜色和与上内插值一般操作。如同顶点着色器,片段着色器可用于在GPU上执行几乎任何种类的计算。因为片段处理器可以访问纹理存储器的随机这是很容易的片段程序内执行聚集操作。实际上,这是很常见的使用纹理信息进行依赖于其他纹理查找窗口; 功能移植算法的流计算模型时来真的很方便。
虽然在目前的GPU架构碎片处理器可以在SIMD模式下运行,是非常严格的那种,他们允许我们将看到,他们还是很容易执行一般的计算操作。加,由于片段的处理片段的处理器数量的计算频率比顶点处理器的数目越高。当前顶级的线卡有十六岁左右的片段处理器。
全部0条评论
快来发表一下你的评论吧 !