设为首页 加入收藏

TOP

OpenGL超级宝典学习笔记——新的模式(一)
2015-02-25 22:42:49 来源: 作者: 【 】 浏览:61
Tags:OpenGL 超级 宝典 学习 笔记 模式

在传统上,图形硬件设计的目标是快速地执行相同的硬编译的计算指令集。计算的步骤可以被跳过,参数可以被调整,但计算本身却是固定的。所以旧式的GPU设计被称为是“固定功能”的。现在的趋势是朝着通用图形处理器的方向发展。就像CPU一样,GPU也可以用任意的指令序列来执行图形计算。GPU和CPU最大的区别是,GPU的浮点数计算能力更强。


在OpenGL2.0之前是固定函数渲染管线,在OpenGL2.0之后就是可编程函数渲染管线了。


?


在替换掉旧的模式之前,我们来回顾一下传统的OpenGL渲染管线是如何运作的。在第一阶段的是基于顶点操作,然后是图元的光栅化产生片段,最后在写到帧缓冲区前,执行片段的纹理,雾和其他的操作。如下图,下面分别讨论基于顶点和基于片段的操作。


Image[1]


?


? ? 基于顶点的阶段以一系列顶点的属性作为输入。这些输入包括物体空间坐标,法线,主颜色,辅助颜色,纹理坐标。最终处理输出的结果为裁剪空间坐标,正面和背面的主颜色和辅助颜色,雾坐标,纹理坐标,以及点的大小。这个处理过程被分为四个阶段。


?


? ? 在传统的固定函数管线中,顶点坐标从物体空间转换到裁剪空间。首先乘以模型视图矩阵转换到视觉空间,然后再乘以投影矩阵变换到裁剪空间。与者两个矩阵相乘是固定的程序,要“跳过”这个过程,就是把这两个矩阵都通过glLoadIdentity设置为单位阵。这样就不会产生影响,输出的结果与输入的结果相同。


? ? 为了光照的处理,每一个顶点的法线也需要进行变换,从物体空间变换到视觉空间。法线乘以倒转置的模型视图矩阵,在此之后可能需要重新调整尺寸或者规格化。光照需要的法线是单位长度的,所以除非你传入的法线是单位向量而且模型视图矩阵不会改变它的长度,否则你需要对其调整尺寸或者规格化。


?


? ? 光照把顶点的颜色、法线和坐标作为它的原始数据输入。它的输出是主颜色和辅助颜色、在某些情况下正面和背面的颜色也不一样。通过材料的属性,光照的属性和一些glEnable/glDisable的开关来控制这个过程。


? ? 光照是高可配置的。我们可以开启多个光源,每一个又可以通过大量的参数来设置器位置,颜色,类型,也可以通过材料属性来模拟不同的表面。


? ? ? 我们可以关闭光照来跳过这个阶段。但只要光照被开启了固定的方程式就会被使用。详细的参考光照那一节。


?


? ? 在这个阶段我们可以选择让OpenGL为我们生成纹理坐标。有几种生成公式可以选择。我们可以为每个纹理坐标成分选择不同的生成方式。如果关闭纹理自动生成,那么手工附加在顶点上的纹理坐标将其作用。随后纹理坐标会经过纹理矩阵的变换。如果纹理矩阵是单位阵则纹理坐标不会改变。


?


? ? 如果经过上面的变换之后,顶点落在了可视区域之外,则将被裁剪掉。被裁减掉的顶点将被丢弃,然后根据图元的类型生成与裁剪边缘相交的顶点。颜色、纹理坐标和其他的顶点属性将通过插值的方式重新赋予到新的顶点上。


Image(1)


?


? ? 在这个阶段把片段和关联的数据作为输入。这些关联的数据由插值后的线和三角形,一个或多个纹理坐标,主颜色和辅助颜色,雾坐标组成。每个片段处理后的结果是单一的颜色值,然后被传送到随后的深度测试,alpha混合,模板测试等操作中。这个阶段也被分为四个部分。


?


? ? 纹理应用是最重要的片段操作。在这里你把所有片段的纹理坐标和它的主颜色作为输入,输出是一个新的主颜色。这个过程将受启用那个纹理单元,纹理单元绑定的是什么图片,以及纹理环境。


? ? 对于每个被启用的纹理单位,绑定到这个单位的1D、2D、3D或立方体贴图纹理作为纹理查找的来源。基于单元上的纹理格式和指定的纹理函数,查找出来的纹理结果将替换或者与片段的主颜色进行混合。


? ? 有许多的可配置的参数影响着纹理的查找,例如纹理的环绕模式,边界颜色,过滤器,mipmap,深度纹理等。


?


? ? 颜色求和阶段有两个输入:主颜色和辅助颜色,输出是单一的颜色。如果启用了颜色求和或者启用了光照,那么主颜色和辅助颜色的红、绿、蓝成分将会相加,然后截取在范围[0,1]。如果颜色求和未被启用,那么主颜色及其alpha值将直接输出,辅助颜色值和alpha值将不会被使用。


?


如果开启了雾。那么片段的颜色将会和雾的颜色进行混合。雾颜色取决于雾因子以及三个硬编码的公式:线性的,指数的,二次指数的。这些公式根据当前雾坐标和雾因子来计算出雾颜色。


?


? ? 最后,如果片段所属的图元开启了反走样例如glEnable(GL_LINE_SMOOTH)等。那么会有一段关联的数据是覆盖值。这个值通常是1.0。但在光滑的点,线,面,这个覆盖值是0.0到1.0之间,片段的alpah值和这些覆盖值相乘,然后进行混合来产生光滑的边缘。


?


? ? 自OpenGL2.0之后就引入了新的方式来替换就到固定函数管道——着色器。着色器其实就是一段自定义的程序来替换掉固定函数管道的各阶段。


下图是用新的可编程的着色器替换掉硬编码的固定阶段。


Image(2)


?


? ? 现在顶点以及顶点的属性将作为顶点着色器的输入。顶点着色器产生纹理坐标,颜色,点的大小,雾坐标,然后传到裁剪器中。一个顶点着色器替换掉了固定的顶点变换,光照,纹理坐标处理。


?


? ? 顶点的变换将不再是固定的函数,要做什么完全取决于你。你可以什么都不做不输出任何东西(也不会画任何东西),如果要画物体,那么最小的操作是输出裁剪坐标。通常情况下,模拟固定的函数管道的话,我们会把顶点乘以投影矩阵和模型视图矩阵。但这些不是必须的,如果你输入的已经是计算好的裁剪坐标,那么我们就不需要执行这些操作,把输入位置拷贝到输出位置就行了。我们也可以在这里把笛卡尔坐标转换成极坐标,然后进行计算。


?


? ? 如果你并不关心顶点的颜色属性(例如你只需要这些顶点做遮挡查询)那么你可以不进行光照计算的步骤,不输出任何颜色,在此之后都不使用这些数据(PS:如果后面使用到了这些数据,则行为是未定义的,因为是垃圾数据)。 如果颜色不需要光照计算,我们可以直接把输入的颜色拷贝到输出的颜色。


? ? 在这里也可以有无穷多种方式进行颜色的变换,这取决于你的程序。


?


? ? 如果不需要生成纹理坐标,则不用再顶点着色器对纹理坐标进行编程。 如果不需要进行任何纹理坐标的变换,那可以把输入的纹理坐标拷贝到输出的部分。这个过程可以尽量的精简,不浪费资源去做无用功。例如 你的GPU支持8个纹理坐标,但再后面的管道中,你只用到其中三个,但我们就没必要输出另外的五个。


经过上面的介绍,大概了解了,顶点着色器的输入和输出,以及其中的处理环节。顶点着色器与固定函数管道相比,提供了极大的灵活性,通过良好的着色器编程,我们可以节省资源,提高性能,并得到我们想要的效果。


?


?


? ? 在顶点着色器和片段着色器之间,还有一组固定的功能阶段,来连接着两个着色器。在执行顶点着色器之后,需要对其输出进行裁剪,在裁剪的过程中,去移除在可视区域之外的顶点,并添加一些顶点。然后进行透视除法,把坐标变成规格化坐标,然后进行视口变换和深度范围的变换,最后产出屏幕空间的坐标。然后进行光栅化。


? ? 光栅化是一个固定的阶段,把处理后的图元上的顶点光栅化成片段。无论点,线或多边形图元都会在这个阶段产出片段,并插入合适的颜色和纹理坐标到片段中。


Image(3)


在高度分挌化的物体中,可以一个小三角形会被映射为一个片段。在绝大多数情况下,片段数总是比顶点数多的。但凡事都有例外。光栅化也负责制造有宽度的线和点。它也会应用

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇OpenGL超级宝典学习笔记——深度.. 下一篇OpenGL超级宝典学习笔记——GLSL..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: