目录

渲染管线(流水线,流程)

一、渲染任务

二、三个阶段

1、应用阶段

1-1:数据的准备

1-2:设置渲染状态

1-3:发送DrawCall

2、几何阶段

2-1:顶点着色器

2-2:裁剪

2-3:屏幕映射

3、光栅化阶段

3-1:三角形设置

3-2:三角形遍历

3-3:片元着色器

3-4:逐片元操作


渲染管线(流水线,流程)

声明:本文章参考自《Real-Time Rendering》书籍加以汇总并引用了其中部分图片

一、渲染任务

渲染的任务其实就是从一个三维场景出发,将其进行渲染生成一个二维图像供人眼观察。详细点说,就是CPU和GPU配合,将3D场景中各个对象的坐标,纹理,材质等信息经一系列转换生成人眼可以看见的图像映射到屏幕上。

二、三个阶段

渲染的三个阶段一般分为,应用阶段,几何阶段和光栅化阶段,其大致的流程参考下方图1

图1 渲染管线流程图

三个阶段的操作对象的流程图大致可以参考一下 图2

图2 渲染管线操作对象流程图

1、应用阶段

这一阶段由CPU处理,主要任务是为接下来GPU的渲染操作提供所需要的几何信息,即输出渲染图元(rending primitives)以供后续阶段的使用。渲染图元就是由若干个顶点构成的几何形状,点,线,三角形,多边形面都可以是一个图元。

1-1:数据的准备

第一步应先将不需要的数据剔除出去,如以包围盒为单位的视锥体(粗粒度)剔除,遮挡剔除,层级剔除等等。

第二步根据UI对象在Herachy面板深度值的顺序(DFS深度优先搜索)设置渲染的顺序,其余物体大体可以按照离摄像机先近后远的规则为后续循环绘制所有对象制定排队顺序。

第三步先将所有需要的渲染数据从硬盘读取到主存中,再把GPU渲染需要用到的数据打包发给显存(GPU一般没有对主存的访问权限,且与显存进行交换速度较快)。

打包的数据详细信息见图3

图3 打包的数据信息

1-2:设置渲染状态

渲染状态包括着色器(Shader),纹理,材质,灯光等等。

设置渲染状态实质上就是,告诉GPU该使用哪个Shader,纹理,材质等去渲染模型网格体,这个过程也就是SetPassCall。当使用不同的材质或者相同材质下不同的Pass时就需要设置切换多个渲染状态,就会增加SetPassCall 所以SetPassCall的次数也能反映性能的优劣。

1-3:发送DrawCall

当收到一个DrawCall时,GPU会按照命令,根据渲染状态和输入的顶点信息对指定的模(网格)进行计算渲染。

CPU通过调用图形API接口( glDrawElements (OpenGl中的图元渲染函数) 或者 DrawIndexedPrimitive (DirectX中的顶点绘制方法) 命令GPU对指定物体进行一次渲染的操作即为DrawCall。此过程实质上就是在告诉GPU该使用哪个模型的数据(图形API函数的功能就是将CPU计算出的顶点数据渲染出来)。

在应用阶段有三个衡量性能指标非常重要的名词 下面我将再次叙述一下

DrawCall:CPU每次调用图形API接口命令GPU进行渲染的操作称为一次DrawCall。

SetPassCall:设置/切换一次渲染状态。

Batch:把数据加载到显存,设置渲染状态,CPU调用GPU渲染的过程称之为一个Batch。

注:一个Batch包含至少一个DrawCall

2、几何阶段

几何阶段由GPU进行处理,其几乎要处理所有和几何相关的绘制事情。如绘制的对象,位置,形状。几何阶段处理的对象时渲染图元,进行逐顶点和逐多边形的操作。主要任务是把顶点坐标变换到屏幕空间中,以供给接下来的光栅器进行处理。具体输出的信息有,变换后的屏幕二位顶点坐标,顶点的深度值,着色,法线等等信息。

接下来对几何阶段的主要流水线阶段进行一下解释:

2-1:顶点着色器

流水线的第一个阶段,其可以通过编程进行控制。输入来自CPU发送的顶点信息,每个顶点都会调用一次顶点着色器。其主要工作为:坐标转换和逐顶点光照(可选,计算输出顶点的颜色值)。坐标转换是必须完成的一个任务。其把顶点坐标从模型空间转换到齐次裁剪空间。(齐次裁剪空间不是屏幕空间,是xyz均放缩到-1到1的空间),具体过程可以参考图4

(提一下:此时GPU处理的顶点并不清楚顶点之间的关系,只是无差别的对待每个顶点,能             很好的体现各个部件的分离,降低耦合性)

图4 坐标转换

2-2:裁剪

顾名思义,就是将不需要的数据对象剔除出去的过程。由于场景一般很大,摄像机的视野范围可能不会覆盖所有的场景物体,裁剪就是为了将那些在摄像机视野范围外的物体剔除出去而被提出来的。

一个图元和摄像机的关系有三种:完全在视野内、部分在视野内、完全在视野外。完全在视野内的就传递给下一个流水线阶段,完全在视野外的就不会向下传递,而部分在视野内的就需要进行一次处理,就是裁剪。

下图(图5)展示了一个裁剪的过程:

图5 裁剪过程

由图5可清楚的看出,除完全在空间内外的图元被保留和舍弃以外,部分在空间内的图元(黄色三角形)会被裁剪,新的顶点将在空间的边界处生成,原来在外部的顶点会被舍弃 。

2-3:屏幕映射

通过计算将实际场景的对象映射到屏幕上,实质上就是对坐标的放缩,参考图6

图6 屏幕映射

3、光栅化阶段

此阶段仍然由GPU进行处理。这一阶段将会使用上个阶段传递的数据(屏幕坐标系下的顶点位置以及和它们相关的额外信息,如深度值(z坐标)、法线方向、视角方向等。)来产生屏幕上的像素,并渲染出最终的图像。光栅化的主要任务是决定渲染图元中的哪些像素应该被绘制在屏幕上,然后对其颜色进行合并混合。

3-1:三角形设置

其主要任务是为后续光栅化提供所需要计算的信息。例如,后续阶段需要判断像素点是否被三角形网格覆盖,只靠上个阶段得到的顶点信息无法确定边界的覆盖情况,还需要三角形网格边的信息,所以在这个阶段需要计算出边的表达式以供后续判断的使用。其输出都是为了给下一阶段做相应的准备。

3-2:三角形遍历

三角形遍历阶段会根据上一个阶段的计算结果判断一个三角形网格覆盖了哪些像素,并使用三角网格三个顶点的顶点信息对整个覆盖区域进行插值。详细过程见下方介绍:

此阶段会遍历所有的像素点,判断其是否被三角网格所覆盖 (用3-1计算的结果) ,如果被覆盖,则在此像素点上生成一个片元。片元不是单纯的像素点,其还包含很多状态的集合,这些状态用来最终计算检测筛选每个像素点最终的颜色。(部分状态包括:屏幕坐标,深度值,从几何阶段继承来的法线,纹理等等)。

片元状态的信息是由其所在三角形网格的三个顶点的信息的插值得到的,例如计算三角形网格重心位置片元的深度 如下图(图7)

图7 片元状态信息插值

最终输出的是包含多个片元的片元序列

3-3:片元着色器

非常重要的可编程着色器阶段。片元着色器的输入是上一个阶段对顶点信息插值得到的结果,输出为每个片元的颜色值。这一阶段可以按需完成很多重要的渲染技术,最重要的技术之一就是纹理采样。

纹理采样

为了在片元着色器中进行纹理采样,先在顶点着色器阶段输出每个顶点对应的纹理坐标,然后经过光栅化阶段对三角形网格的三个顶点对应的纹理坐标进行插值后,就可以得到其覆盖的片元的纹理坐标了。其局限在于仅可以影响单个片元。即执行片元着色器时,不能将结果直接发给旁边的邻居。片段着色器输出颜色的具体过程如下图(图8)

图8 计算输出颜色

3-4:逐片元操作

这是OpenGL中的说法,在DirectX中,这阶段被称为输出合并阶段(Output-Merger)。

该阶段是对每一片 片元 进行操作,主要任务有:

①决定每个片元的可见性,如深度测试、模板测试。

②如果一个片元通过了所有测试,就把这个片元的颜色值和已经存储在颜色缓冲区的颜色进             行合并,混合。

该阶段是高度可配置的,我们可以设置每一步的操作细节。该阶段首先解决的是,每个         片元的可见性问题。这需要进行一系列测试,只有通过了才能和颜色缓冲区进行合并。没通            过任何一 个测试,片元都会被丢弃。见图(9)

图9 片元测试及合并

测试过程是很复杂的,不同接口实现细节也不同,下面笔者将讲述一些常用的测试:

         模板测试

开启了模板测试,GPU就会使用读取掩码读取模板缓冲区中该片元的模板值,将该值和读取到的参考值进行比较。这个比较函数可以是开发者指定的,例如小于模板值时则舍弃该片元或者大于模板值时舍弃该片元。片元无论有没有通过模板测试都可以根据模板测试和下面的深度测试结果来修改模板缓冲区。这个修改操作也是由开发者指定的。模板测试通常用于限制渲染的区域。

        深度测试

通过模板测试后,片元就会进行深度测试。其同样是高度可配置的。

开启后,GPU会把该片元深度值和已存在与深度缓冲区的深度值进行比较,这个比较函数也是开发者设置的。例如小于缓冲区深度值时舍弃该片元,或者大于缓冲区深度值等于时舍弃该片元。通常人们更希望显示离摄像机最近的物体,所以一般比较函数设置为当前片元深度值要小于缓冲区深度值,深度值大无法通过测试。如果片元没有通过测试,则会被丢弃掉。

与模板测试不同,只有通过之后开发者才能指定是否用该片元的深度值覆盖原有缓冲区的深度值。这是通过开启/关闭深度写入做到的。

        合并操作

通过了所有测试后,片元就来到了合并操作。

每个像素的信息被存储在一个名为颜色缓冲区的地方,因此执行此次渲染时,颜色缓冲区中往往已经有了上次渲染之后的结果。所以需要合并的方式使其达到一种均衡状态。

对于不透明物体,开发者可以选择关闭混合操作。这样片元着色器计算得到的颜色值就会直接覆盖原来颜色缓冲区中的像素值。

对于半透明物体,需要使用混合操作来让这个物体看起来是透明的。

混合操作也是可以高度配置的。开启了混合,GPU会取出源颜色和目标颜色将两者混合。

源颜色是片元着色器得到的颜色,目标颜色是已经存在于颜色缓冲区中的颜色值。

        提前测试

        提前测试的目的主要是为了提高性能

虽然逻辑上这些测试是在片元着色器之后进行的,但对于大多数GPU来说,他们会尽可能在执行片元着色器之前进行这些测试。

尽可能早知道哪些片元会被舍弃可以提高性能,比如unity的渲染流水线中的深度测试就在片元着色器之前。这种将深度测试提前的技术被称为Early-Z技术。

但将这些测试提前其检验结果可能会与片元着色器中一些操作产生冲突。

        至此Unity的渲染管线的大致过程就已经介绍完毕啦~,这是笔者第一次攥写博客部分绘制的流程图和解释还较为粗糙,后续还会继续编写有关Unity的内容,希望能对大家有所帮助(.^◡^.)

Unity3D 渲染管线全流程解析相关推荐

  1. 《响应式Web设计全流程解析》一1.2 静态设计稿舒适区

    本节书摘来异步社区<响应式Web设计全流程解析>一书中的第1章,第1.2节,作者: [美]Stephen Hay 译者: 余果 , 等 责编: 赵轩,更多章节内容可以访问云栖社区" ...

  2. 如何把控产品 — 产品管理全流程解析

    如何把控产品 - 产品管理全流程解析 最近发生了一些事情,促使自己静下心对这些年的工作沉淀和知识积累做系统性的总结与分享.主要是希望通过总结,加深自己对产品把控认知上的理解,强化各个环节中的具体细节, ...

  3. 基于神策用户画像,在线教育企业线索标签体系搭建及培育全流程解析

    作者介绍:TigerHu,环球网校大数据营销产品 leader,主导数据产品线和营销 CRM 产品线. 本文内容均从作者真实实践过程出发,结合作者公司与神策数据合作真实场景,从神策用户画像产品出发,全 ...

  4. 经纬M300赛尔102S航测全流程解析

    前方高能干货!经纬M300&赛尔102S航测全流程解析在这里~ 一. 测试前准备 硬件准备: 1)M300 飞机 1 台: 遥控器 1 台: 电池 2 组: 测绘相机 1 台: 电池充电箱 1 ...

  5. 不会画建筑CAD图纸?建筑CAD设计全流程解析打包送给你!

    建筑CAD图纸通常比较复杂,但千里之行始于足下,当我们要绘制一张建筑CAD图纸时,应当怎么着手呢?本CAD教程整理了相关绘图流程解析打包送给你! 从建筑CAD图纸内容上来划分,图纸的空间设计包括平面图 ...

  6. 红蓝对抗-红队攻防全流程解析

    红队攻防全流程解析 文章目录 红队攻防全流程解析 基础设施架构设计部署 选择域名 邮件钓鱼之前期信息收集与侦查 钓鱼样本制作 内网横向移动 文件感染与横向移动 基础设施架构设计部署 普通架构:红队人员 ...

  7. 社区团购小程序怎么做,全流程解析

    在当前的电商市场中,社区团购已经成为了一股强劲的力量.社区团购小程序作为社区团购的重要组成部分,已经成为了商家和消费者不可或缺的工具.社区团购小程序以其方便.快捷.实惠的特点,受到越来越多的用户的青睐 ...

  8. 智能硬件产品开发全流程解析

    本文通过十八个流程点详解,为大家分享了智能硬件产品研发生产的全流程. 上篇文章我们聊了下软硬件产品经理的那些区别,这篇文章主要分享下硬件产品研发生产的相关流程. 上图所示的是一个智能硬件生命周期内所需 ...

  9. MaskFormer 在 MMDtection 中复现全流程解析

    熟悉我们的小伙伴肯定知道 MMDetection 已经支持了全景分割算法 MaskFormer 啦!今天我们就以 MaskFormer 为例,和大家一起学习在 MMDetection 复现算法的全流程 ...

  10. android 关机 流程_Android系统关机的全流程解析

    在PowerManager的API文档中,给出了一个关机/重启接口: public void reboot (String reason) 对于这个接口的描述很简单,就是几句话. 接口的作用就是重启设 ...

最新文章

  1. linux线程有什么用,在linux下查看一个进程它有多少个线程是用什么命令?
  2. Python ln_Python入门教程(三):史上最全的Numpy计算函数总结,建议收藏!
  3. Linux 操作系统原理 — 网络 I/O 虚拟化
  4. 【微信小程序】java中类和对象的区别
  5. c++获取sqlite3数据库表中所有字段的方法
  6. node.js 设置 淘宝 镜像
  7. 使用FPGA进行加速运算
  8. python 写入excel 打开时暂停_Python 解决中文写入Excel时抛异常的问题
  9. javacpp-opencv图像处理系列:国内车辆牌照检测识别系统(万份测试准确率79.7%以上)...
  10. MyBioSource丨人Hif1αelisa试剂盒解决方案
  11. 联想ERP项目实施案例分析(9):工作方法总结
  12. 【毕业设计_课程设计】基于Python的南京二手房数据采集及可视化分析
  13. opencv cvFindContour 轮廓 freeman链码
  14. ####好好#####利用各种信息作为因子的股票价格预测模型研究过程
  15. 别只会搜日志了,求你懂点原理吧(超详细)
  16. 书籍推荐!张磊首部力作《价值》
  17. 杜克大学计算机专业本科入学条件,杜克大学录取条件
  18. EasyGBS摄像机网页直播之问题解决:海康设备通过TCP接入到EasyGBS, 设备不推流问题解析
  19. liftover 转换不同版本的GRCh
  20. Windows的一键安检脚本

热门文章

  1. cad2004教程_CAD卸载教程
  2. c++ 开源grid控件
  3. sony手机刷linux,索尼Z3 Z3C 5.0系统刷recovery教程_Sony Z3第三方recovery
  4. PHP无损调整照片大小,怎么无损放大图片,批量修改图片大小而不失真,照片无损放大软件...
  5. Web前端开发配色表及标准颜色表
  6. 基于三维冲击波的变分理论--交通运输工程(一)
  7. 淘宝 NPM 镜像解决软件下载速度慢的问题
  8. css3波,CSS3 声波
  9. 三星s9 港版android 9.0,国行三星Galaxy S9/S9+更新One UI正式版,基于安卓9.0
  10. Linux安装vim命令