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]的归一化的设备坐标,最后映射到屏幕或者视口上。

  【补充:CC_MVPMatrix是一个mat4类型的uniform,在shader代码被编译之前,由cocos2d-x框架插进来的。3D物体从建模到最终显示到屏幕上面要经历以下几个阶段:

  • 对象空间(Object Space)
  • 世界空间(World Space)
  • 照相机空间(Camera Space)
  • 裁剪空间(Clipping Space)
  • 视口空间(Viewport)  

  从对象空间到世界空间的变换叫Model-To-World变换,从世界空间到照相机空间的变换叫World-To-View变换,而从照相机空间到裁剪空间的变换叫做View-To-Projection。gl_Position = P * MV * ObjectPosition; 合起来,即常提到的MVP变换。】

  三,片段着色器。【先补充一点,其实在光栅化之前,要判断图元的朝向,是面向还是背对观察者,以决定是否需要丢弃图元。在OpenGL可通过glFrontFace指令来决定哪个方向为正,并通过glCullFace决定需要保留哪一面(别忘了要先打开剔除状态设置才可以调用指令 glEnable(GL_CULL_FACE);)。这样设计的好处是能减少一些不必要的绘制,并减少对GPU的浪费。】  回到正题,片段着色器同上述的顶点着色器,只是它作用的对象是每一片段,对其进行着色贴图。片元着色器的输入是根据那些从顶点着色器中输出的数据插值得到的,其中最重要的渲染技术之一是纹理采样。在顶点着色器阶段输出每一顶点对应的纹理坐标,然后经过光栅化阶段对三角网格的3个顶点各自纹理坐标进行插值运算后便得到其覆盖片元的纹理坐标,从而在片元着色器中进行纹理采样。如下图:

  

  四,逐片元操作。这里篇幅原因不一一分析每种测试操作,大家可以通过看书了解对应的用途。下面举混合操作来分析一下。下图是简化流程图:

  

  对于不透明的物体,可以直接关闭混合Blend操作,这样片元着色器计算得到的颜色值直接覆盖更新缓冲区的颜色值。但对于半透明物体就必须开启使用混合操作从而让物体看起来是透明的。开发过程中无法得到透明效果的原因,往往有可能是没有开启混合功能的原因。

小强学渲染之OpenGL的GPU管线的更多相关文章

  1. 小强学渲染之OpenGL的CPU管线

    读到这里,应该对OpenGL渲染管线有了初步简单了解.下面着重分析CPU管线,即逻辑控制中心做了什么,这部分还是容易理解的.如下图: 一,将数据加载到显存中. 这是由GPU是访问显存中的数据决定的.因 ...

  2. 小强学渲染之OpenGL渲染管线详析

    什么是OpenGL? OpenGL是一套图形硬件的软件API接口库,它直接和GPU交互,将3D场景渲染绘制到2D屏幕上.总结说,OpenGL的功能是将程序中定义的各种2D或3D模型绘制到帧缓存中,或者 ...

  3. 小强学渲染之OpenGL状态机理解

    状态机是理论上的一种机器,呃这个说法非常非常的抽象.通俗一点理解,状态机描述了一个对象在其生命周期内所经历的各种状态,状态间的转变,发生转变的动因,条件及转变中所执行的活动.或者说,状态机是一种行为, ...

  4. 小强学渲染之Unity Shader边缘描边加强

    项目开发遇到一个需求,就是当坦克的准心瞄准敌方(enemy tank 或 item box)时,要让选中的对象的轮廓高亮起来,这实际上是接下来要讲解的实时渲染中轮廓线的渲染应用.实现方式有多种,下面逐 ...

  5. 小强学渲染之Unity Shader噪声应用

    之前玩Tencent的仙剑4手游时,杀死boss会看到boss有“消融”的效果,就是身体上有多个洞洞然后往四周扩散直至尸体完全消失,但效果是没有关闭背面剔除的“穿帮”效果,可能也是考虑性能因素. em ...

  6. 小强学渲染之Unity Shader编程HelloWorld

    第一个简单的顶点vert/片元frag着色器   1)打开Unity 5.6编辑器,新建一个场景后ctrl+s保存命名为Scene_5.默认创建的场景是包含了一摄像机,一平行光,且场景背景是一天空盒而 ...

  7. 把Android原生的View渲染到OpenGL Texture

    http://blog.csdn.net/u010949962/article/details/41865777 最近要把Android 原生的View渲染到OpenGL GLSurfaceView中 ...

  8. 小菜学Chromium之OpenGL学习之二

    在这个教程里,我们一起来玩第一个OpenGL程序.它将显示一个空的OpenGL窗口,可以在窗口和全屏模式下切换,按ESC退出.它是我们以后应用程序的框架. 在CodeBlock里创建一个新的GLUT ...

  9. iOS离屏渲染的解释:渲染与cpu、gpu

    重开一个环境(内存.资源.上下文)来完成(部分)图片的绘制 指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作 意为离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作. ...

随机推荐

  1. c# .net 面试总结

    一. sql优化 . 写明查询具体某几列,减少*的使用,表名过长时,尽量使用表的别名 *和列名一样 ,在业务密集的SQL当中尽量不采用IN操作符,用EXISTS 方案代替. in 和 exists的区 ...

  2. 再见了我热爱的ACM赛场

    随着2017EC-Final结束,我的ACM生涯也真正结束了,区域赛三铜三银三金,没有打铁,对我来说算是很满足了. 为什么打了ACM?我记得进入大学之后大概认真上课两三周,我就开始对大学讲课失望,开始 ...

  3. 排序算法练习--JAVA(:内部排序:插入、选择、冒泡、快速排序)

    排序算法是数据结构中的经典算法知识点,也是笔试面试中经常考察的问题,平常学的不扎实笔试时候容易出洋相,回来恶补,尤其是碰到递归很可能被问到怎么用非递归实现... 内部排序: 插入排序:直接插入排序 选 ...

  4. crontab定时任务第一个周期未完成下一个周期执行就来了

    一.现象 有一个定时任务,每分钟执行一次,前一分钟还没有执行完成,下一个分钟就来了,怎么解决. 二.模拟 #!/bin/bash echo "开始 `date` " >> ...

  5. Day 10 函数的形参,实参

    今日内容 '''实参:调用函数,在括号内传入的实际值,值可以为常量.变量.表达式或三者的组合​*****形参:定义函数,在括号内声明的变量名,用来接受外界传来的值​'''​'''注:形参随着函数的调用 ...

  6. Android批量验证渠道、版本号(windows版)

    功能:可校验单个或目录下所有apk文件的渠道号.版本号,此为windows版,稍后整理Linux版使用说明:1.copy需要校验的apk文件到VerifyChannelVersion目录下2.双击运行 ...

  7. centos下vi的用法大全

    vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的任何版本,vi编辑器是完全相 ...

  8. UML 序列图详解

    现在是二月,而且到如今你或许已经读到.或听到人们谈论UML 2.0 —— 包括若干进步的 UML 的新规范,所做的变化.考虑到新规范的重要性,我们也正在修改这个文章系列的基础,把我们的注意力从 OMG ...

  9. PAT 甲级 1041 Be Unique (20 分)

    1041 Be Unique (20 分) Being unique is so important to people on Mars that even their lottery is desi ...

  10. C++Primer第五版——习题答案详解(六)

    习题答案目录:https://www.cnblogs.com/Mered1th/p/10485695.html 第7章 类 练习7.1 class Sales_data { public: std:: ...