前言

渲染管线其实就是基于管线架构的图像渲染,所谓的管线就是将一个工程分成好几个部分串联起来进行工作,每一部分的输出都会作为下一部分的输入进行计算。本文将会按照三个部分来理解管线渲染这一知识。

一.Architecture-架构

渲染管线的主要目的就是为了在给定虚拟相机,三维物体,光源,照明模式,以及纹理等诸多条件下,生成或绘制出一副二维图像。渲染管线是实时渲染的底层实现,且渲染管线的发展目的就是为了实现更好的实时渲染,实时渲染多使用于三维游戏中。

在概念上,图形渲染管线一共可以分为三个阶段:

  • The Application Stage-程序阶段
  • The Geometry Stage-几何阶段
  • The Rasterizer Stage-光栅化阶段

(图片来自于《Real-Time Rendering 3rd》)

可以看出,每个阶段自身也可能是一条管线,例如图中的几何阶段。并且,我们还可以对有的阶段进行并行化处理。比如光栅化阶段。图像的绘制速度受短板效应的影响,即由最慢的管线阶段来决定,我们通常看到的FPS就是实时渲染速度的体现,有时候也用HZ表示。

二.The Application Stage  应用程序阶段

应用程序阶段一般是图形渲染管线概念上的第一个阶段,这一阶段是通过软件方式来实现的,我们可以完全的去控制这一段我们想要发生行为。这也就意味着我们可以在这一阶段来对程序进行优化,之后的两个阶段则主要依托硬件的性能实现,很难去进行优化。

  1. 由于程序应用阶段是靠软件方式实现的,所以它的行为是封装在一起执行的,我们不能像几何,光栅化阶段那样切分成若干个子阶段来处理。不过,我们也可以通过使用处理器并行同时处理。在CPU上,这种形式称为超标量体系结构(超标量体系结构描述一种微处理器设计,它能够在一个时钟周期里执行行多个指令。)
  2. 在应用程序阶段,我们一般去实现一些逻辑方法,比如碰撞检测,加速算法,输入检测,动画,力反馈以及纹理动画,变换仿真,几何变形,以及一些不在其他阶段执行的计算,如层次视锥裁剪等加速算法。
  3. 应用程序阶段的主要任务就是将需要在屏幕上像是绘制出来的的几何体(也就是绘制图元)输如到绘制管线的下一个阶段。对于被渲染的每一帧,应用程序阶段都会将摄像机位置,光照和模型的图元输出到管线的下一个主要阶段--几何阶段。

三.The Geometry Stage  几何阶段

几何阶段主要是负责大部分多边形操作和顶点操作,这个阶段可以分为五个子阶段。

  • 模型视点变换   Model & View Transform
  • 顶点着色    Vertex Shading
  • 投影    Projection
  • 裁剪    Clipping
  • 屏幕映射    Screen Mapping

(图片来自于《Real-Time Rendering 3rd》)

由此,几何阶段也可以当作一条管线来看待(一些阶段在某些情况下也可以是并行的),其中,一些子阶段也可以在细化为更小的管线。整个几何阶段执行的计算量非常高,在只有一个光源的情况下,每个顶点大约需要计算100次左右精确的浮点运算操作。

下面对几何阶段进行拆解:

1.模型视点变换   Model & View Transform

  • 在屏幕上的显示过程中,模型通常需要变换到若干不同的空间或坐标中。模型变换的变换对象一般是模型的顶点和法线。物体的坐标一般称为模型坐标。世界空间是唯一的,所有的模型经过变换后都位于同一个空间。
  • 摄像机的可视体范围内的模型才需要绘制,所以需要在世界空间中有一个位置和方向来放置并校准摄像机。为了方便投影和裁剪,必须对相机和所有的模型进行视点变换。其目的是为了将相机放在原点,然后进行视点校准,使其朝向z轴的负方向,y轴指向上方,x轴指向右边(这其实是直接将模型的位置经过转换到摄像机视图空间中,摄像机的坐标并未实际与原点重合)。经过视点变换后,实际位置和方向就以来于当前的API。这个空间则被我们称为相机空间或者观察者空间。下图为视点变换示意图:

结论:模型变换是将是模型变换到合适的渲染空间中放置,视图变换是将摄像机的位置放置到原点,统一坐标,便于后续操作的计算。

2.顶点着色    Vertex Shading

渲染出物体的形状和位置以后,就需要对它进行建模。建模之后就会得到每个对象的材质,以及光照下的一些数据。光照与材质可以用任何数量的方式,从简单的颜色和复杂的物理描述来模拟。

确定材质上的光照效果的这种操作被称为着色,着色的过程涉及到对象上面各个点的计算着色方程,一般来说,这些计算中的一下会在几何阶段的模型顶点上执行,其他的计算可以在光栅化阶段执行。在这个过程中,我们可以在顶点中存储各种材料数据,例如点的位置,法线,颜色和计算着色方程以及其他的各种的数字信息。顶点着色的结构会被发送到光栅化阶段进行插值操作。

通常,我们认为着色阶段实在世界坐标中进行的,在实践中有时候我们也需要将相关实体(例如摄像机和光源)转换到一些其他的空间(比如模型空间或摄像机空间)中去计算,结果也是正确的。这是因为着色过程中的所有实体变换到了相同的空间,着色计算中所需要的光源,相机及模型之间的相对关系是不会改变的。

结论:顶点着色阶段是为了确定模型上顶点处材质的光照效果,并保存数据用于光栅化阶段的插值操作。

3.投影    Projection

在光照处理之后,渲染系统就开始进行投影操作,即将视体变化到一个一个对顶角分别是(-1,-1,-1)和(1,1,1)的单位立方体,也叫规范立方体,然后开始投影。

投影一般主要是两种方式

  • 正交投影(orthograohic  projection)(图左)
  • 透视投影(perspective projection)    (图右)

(图片来自于《Real-Time Rendering 3rd》)

  • 正交投影的可视体一般是一个矩形,正交投影可以把这个视体变换为单位立方体。正交投影的主要特性是平行线在变换之后彼此一九保持平行,这种变换是平移与缩放的组合。
  • 透视投影相比正交投影要复杂一些。在这种投影下,我们从摄像机中看会有近大远小的效果,这种就是模拟人类的视觉感知体系。
  • 这两种投影都可以使用4*4的矩阵来实现,在任何一种投影变换后,我们都可以认为模型位于归一化处理后的设备坐标系中。

我们可以认为这些矩阵变换是从一个可视体变换到了另一个可视体内,及相机空间到图像空间,这个空间中我们不在保存图像的Z轴,我们可以理解为我们将模型从三维空间内投影到了二维空间。

结论:投影阶段的作用就是将模型从三维空间投影到了二维空间。

4.裁剪    Clipping

投影完成后,我们就需要对规范立方体内的图元进行裁剪,因为图像中的图元并不是全部都完全投影在规范立方体内的。我们只有对其裁剪后才能把它输送到光栅化阶段,然后将其输送到屏幕上绘制。

图元先对规范立方体有三种情况

  • 完全位于可视体内部,不用处理可以直接输出。
  • 完全位于可视体外部,直接丢弃不用进行渲染。
  • 一半在内,一半在外,进行裁剪,裁掉外面的部分并且生成新的图元。

结论:裁剪阶段就是对可视体(规范立方体内部)的图元进行裁剪,保留到可用的图元。

5.屏幕映射    Screen Mapping

经过裁剪后的图元将会被输送到屏幕映射阶段,在这个阶段中,模型的坐标依旧是三维的(投影后没有保存Z轴的值,所以显示状态在我们看来已经是二维的),每个图元的坐标(x,y)会变换到屏幕坐标系中,屏幕坐标系连同z坐标一起称为窗口坐标系。

如果我们要在一个窗口里绘制图像,屏幕映射阶段会先将图像进行平移,在进行缩放,使其契合在窗口中,此过程中,z轴不受影响。新的x,y坐标称为屏幕坐标系,与z轴进入到光栅化阶段。

(图片来自于《Real-Time Rendering 3rd》)

结论:屏幕映射阶段的主要目的,就是将之前步骤得到得坐标映射到对应的屏幕坐标系中。

整个几何阶段就是将模型从世界坐标系--相机坐标系--图像坐标系--屏幕坐标系--窗口坐标系的转化。

四.The Rasterizer Stage-光栅化阶段

我们将经过变换和投影之后的顶点,颜色,以及纹理坐标,用来给每个像素正确配色绘制出整幅图像,这就是光栅化,也叫扫描变换,即从二维顶点所处的屏幕空间到屏幕上像素的转换。

与几何阶段相似,它也可以单独划分出一条管线。及以下几个阶段:

  • 三角形设定(Triangle Setup)阶段
  • 三角形遍历(Triangle Traversal)阶段
  • 像素着色(Pixel Shading)阶段
  • 融合(Merging)阶段

1.三角形设定(Triangle Setup)阶段

我们都知道三角形是最基本的图元,因为它可以保证是一个平面并且容易判断一个点在不在三角形内部,而且其他的多边形也可以打碎成三角形。

三角形设定阶段就是用来计算三角形表面的差异和三角形表面的其他相关数据。该数据主要是用于扫描转换,以及由几何阶段处理各种着色数据的插值操作所用。该过程在专门为其设计的硬件上执行。

2.三角形遍历(Triangle Traversal)阶段

三角形遍历阶段就开始检查每个像素的中心是否由三角形覆盖,对于三角形重合的部分,会在重合部分生成片段。这一步也叫扫描转换。每个三角形片段属性都由三个顶点的数据插值生成,这些属性包括片段的深度,以及来自几何阶段的着色数据。

3. 像素着色(Pixel Shading)阶段

所有逐像素的着色计算都在像素着色阶段进行,使用插值得来的着色数据作为输入,输出的结果为一种或多种将被传输到下一阶段的颜色信息。纹理贴图就是在这一阶段进行的。

像素着色阶段是在可编程GPU中进行,在这一阶段可以使用大量的技术,其中最常见也最重要的技术之一便是纹理贴图。纹理贴图从字面上理解,就是将图片“贴到”模型物体上。如下图示例所示:

结论:像素着色阶段的主要目的是计算所有需要逐像素操作的过程。

4.融合(Merging)阶段

每个像素的信息都存储在颜色缓冲器中,而颜色缓冲器是一个颜色的矩阵(每中颜色包含红绿蓝三个分量)。融合阶段的主要任务是合成当前存储与缓冲器中之前像素着色姐u但产生的片段颜色。不像其他着色阶段,通常运行该阶段的GPU子单元并非完全可编程的,但是其高度可配置,可支持多种特性。

此外,这个阶段还负责可见性问题的处理。这意味着当绘制完整场景的时候,颜色缓冲其应该还包含从相机视点处出发可以看到的场景图元,对于大多数图形硬件来说,这个过程是通过z缓冲(深度缓冲器)算法实现的,这个算法非常简单,具有O(n)复杂度(n是需要绘制的图元),只要计算出每个图元相应像素的z值,就可以使用这种方法,大体内容如下:

       z缓冲器和颜色缓冲器形状大小样,每个像素都存储着一个z值,这个z值是从相机到最近图元之间的距离。每次将一个图元绘制为相应像素时,需要计算像素位置处图元的z值,并与同一像素处的z缓冲内容比较。如果新计算出的z值,远远小于z缓冲器中的z值,那么说明即将绘制的图元与相机的距离比原来距离相机最近的图元还要近,就更新为这个图元的值。否则便不做改变。

除了z缓冲器,还有其他的缓冲器可以  用来过滤和捕获片段信息。如alpha通道,模板缓冲器,帧缓冲器,累计缓冲器等,在此不做介绍。

当图元经过光栅化阶段后,从相机视点处看到的东西就可以在荧幕上显示出来。为了避免观察者体验到图元被处理并发送到屏幕上的过程,图形系统一般使用双缓冲的机制。这就意味着屏幕绘制是在一个后置缓冲器中以离屏的方式进行的,一旦屏幕已在后置缓冲器中的内容中绘制,就将后置缓冲器中的内容与已经在屏幕上显示过的前置缓冲器中的内容进行交换,只有在不影响显示的时候才进行交换。

结论:融合阶段的主要任务是合成当前储存在缓冲器中像素着色阶段产生的片段颜色,此外,融合阶段还负责可见性(z缓冲相关的处理)。

五.总结

图形渲染管线分为三个阶段:应用程序阶段,几何阶段,光栅化阶段。这样的管线结果是API和图形硬件十几年来以实时渲染应用程序为目标进行演化的结果。需要注意的是这个进化不仅仅是在我们所说的渲染管线中,离线渲染也是一种进化的路径。且电影产品的渲染通常使用微多边形管线(性能需求高)。而学术研究和预测的渲染一般采用的是光线跟踪渲染器(以屏幕上的每个点做射线,通过射线与多边形的交点来提取像素等技术)。

原文来自于浅墨大佬的笔记《Real-Time Rendering 3rd》,本篇只是解读学习使用,若有疑问可以转到原文地址:文章链接: http://blog.csdn.net/poem_qianmo/article/details/70544201

渲染管线的理解与学习相关推荐

  1. 关于VAO,VBO和EBO的理解-OpenGL学习笔记

    本文章首发于我的个人博客,希望大家多多支持! Hi! This is Showhoop Studio! 如果要从代码层面去理解渲染管线的工作,学习使用OpenGL编程可以说是一个不错的选择.这里我将记 ...

  2. 由线性回归来理解深度学习的理论基础

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 这会是一篇比较长的文章,本来应该是分几次来po,但考虑到这个话题的 ...

  3. 干货合集 | 带你深入浅出理解深度学习(附资源打包下载)

    作者:Shashank Gupta 翻译:倪骁然 校对:卢苗苗 本文约2300字,建议阅读10分钟. 本文提供资源帮助你在放置一个conv2d层或者在Theano里调用T.grad的时候,了解到在代码 ...

  4. 让 PM 全面理解深度学习

    让 PM 全面理解深度学习 本文汇总了深度学习相关的重要知识点. 下面是内容结构和长图: 一文看懂深度学习(白话解释+8个优缺点+4个典型算法) 一文看懂卷积神经网络-CNN(基本原理+独特价值+实际 ...

  5. 前沿丨DeepMind提出神经元删除法:通过理解每个神经元来理解深度学习

    近日,DeepMind 发表博客介绍其对神经网络可解释性的最新研究成果.受神经科学启发,他们通过删除神经元来探索其对网络性能的影响.研究发现,和过去的经验直觉相反,选择性神经元(如「猫神经元」)对于网 ...

  6. 理解深度学习中的学习率及多种选择策略

    学习率是最影响性能的超参数之一,如果我们只能调整一个超参数,那么最好的选择就是它.相比于其它超参数学习率以一种更加复杂的方式控制着模型的有效容量,当学习率最优时,模型的有效容量最大.从手动选择学习率到 ...

  7. 从Image Caption Generation理解深度学习

    作者:李理 from: http://geek.csdn.net/news/detail/97193 Part I 从Image Caption Generation理解深度学习(1) 0. 前面的话 ...

  8. 细节满满!理解对比学习和SimCSE,就看这6个知识点

    ‍‍‍‍‍‍©PaperWeekly 原创 · 作者 | 海晨威 研究方向 | 自然语言处理‍‍‍‍‍‍ 2020 年的 Moco 和 SimCLR 等,掀起了对比学习在 CV 领域的热潮,2021 ...

  9. 线性Frequency Principle动力学:定量理解深度学习的一种有效模型

    关于作者:本文的作者是来自上海交通大学致远学院 08 级理科班的四位研究人员.本文由许志钦执笔,张耀宇修改,罗涛和马征审阅校正.这个小组的研究兴趣主要是深度学习理论. 深度学习的广泛成功吸引了大量的科 ...

最新文章

  1. [原创]微软拼音输入法2007(含64位版)
  2. bzoj 1597 土地购买
  3. 用英文单词模拟数字计算c语言,C语言程序设计用英文单词模拟数学计算
  4. 2017.5.3 博客园自动生成章节目录
  5. 统计学基础一:基础概念
  6. 蔬菜名称大全500种_96种室内盆栽植物图片及名称,室内植物品种大全
  7. Sersync实时备份服务部署实践
  8. Windows 环境下配置 Oracle 11gR2 Data Guard 手记
  9. 电子相册系统(一)Dao的组件设计
  10. IBM PowerAI编程大赛Q2场来袭!探秘金融语料大数据识别
  11. Spring Cloud Alibaba Sentinel之流控规则篇
  12. 汉罗塔(河内塔)问题的数学模型
  13. heic照片格式怎么转换jpg?heic转换成jpg方法分享
  14. 单视图几何Vanish Point(消失点/灭点)计算方法——Robert_T_Collins(罗伯特·柯林斯)算法
  15. Kibana:改善地理位置数据摄入 - 7.10
  16. (转)Linux下管道的原理
  17. 层(Overlays)
  18. Windows 环境下查看 Redis 版本号命令
  19. 微信公众号第三方授权开发——推送component_verify_ticket协议
  20. c语言计算所有3000以内的基数和序数

热门文章

  1. c语言strtod()函数详解
  2. 复现SCI论文图表:棒棒糖图|渐变|legeng设置
  3. Python控制手机,五排上分
  4. antd-table结合react-resizable实现多级表头可拖拽表格
  5. PPTP协议、L2TP协议和SSTP协议的介绍
  6. pythonic风格_如何编写高质量的Pythonic风格代码
  7. 2008年 新的一年!
  8. Spring事务回滚失败
  9. Nacos8# 集群中节点之间健康检查
  10. 宁德时代麒麟电池将落地AITO问界系列新车型;雅辰酒店集团5个项目年内登陆上海 | 美通企业日报...