IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【学习总结】快速的渲染管线相关知识回顾(入门向) -> 正文阅读

[游戏开发]【学习总结】快速的渲染管线相关知识回顾(入门向)

这两天实习中被指派的新活是将项目的渲染流程和渲染管线做一个整理,写成一篇提供给新人看的入门文档(我也是新人啊喂!新人写给新人看的文档真的好吗,hhhh)
然后我摘抄了不涉及保密协议的部分出来,同时对照着之前学习的内容做了一个整理,希望能帮到同样是需要回顾或者入门的同学们

另外:如果文中有错漏的地方,十分欢迎在评论区或者私信指出(怕误人子弟)

渲染管线概述

渲染管线一般指的是一个物体从场景中被渲染到屏幕像素上并且最终显示出来的这么一个流程。因为在显卡内部这个过程是并行运算的,步骤又大致相同,所以这个过程又叫做渲染流水线。一般来说,很多教材(LearnOpenGL,Unity Shader入门精要,游戏引擎架构等)都将渲染管线的主要步骤分为三大阶段:应用阶段(CPU)几何阶段(GPU)光栅化阶段(GPU),有些书会将屏幕后处理阶段归为第四大阶段,但是由于这个阶段不是必须的,所以这里就不放入一起讨论了。

应用阶段

应用阶段最关键的步骤就是准备GPU所要用到的各种各样的数据,这个阶段是CPU发送数据给GPU的阶段。在CPU准备好了一系列的数据之后,调用DrawCall将图元数据发送到显存,之后交由GPU处理

在这里插入图片描述

1.在应用阶段,会进行一个粗粒度的提出,将那些摄像机看不到的物体(比如背对摄像机的)剔除掉不进行渲染,同时会设置一系列的渲染状态,比如配置是否开启背面剔除,混合函数怎么选择,同时还会准备顶点数据,光照数据,纹理数据等关键数据传递给GPU使用。在OpenGL中,有些关键数据是通过uniform关键字进行传递的,通过uniform关键字传递的数据会存放在GPU的常数寄存器中供GPU快速读取并运算。总之,这个阶段最主要的工作就是将需要的数据通过DrawCall输出到显存让GPU进行下一步的渲染

几何阶段

几何阶段所做的工作概括起来就是将顶点处理过后装配成图元变为NDC(标准化设备坐标),再做一次裁剪之后,将NDC映射到屏幕上(此时还不是真正的像素)

在这里插入图片描述

  1. 这个阶段开始就是在GPU上进行工作了。GPU从显存中拿到应用阶段准备好的数据,输入到从第一个可编程的渲染阶段–顶点着色器
  2. 顶点着色器:是可编程阶段,此阶段的输入是单个顶点(实际上GPU会使用着色器并行处理多个顶点)。顶点位置和法向量通常使用模型空间或者世界空间表示。此阶段也会进行透视投影、每顶点光照、纹理计算、以及为动画角色计算蒙皮等步骤。此阶段的输出是完成变换以及逐光照计算后的顶点,其位置和法向量是使用齐次裁剪空间表示的。
  3. 图元装配此阶段将顶点着色器输出的所有顶点作为输入(如果在OpenGL中指明是GL_Points,那么就是一个顶点),并且根据这些顶点数据装配好对应的图元
    注:在《游戏引擎架构》一书中,图元装配阶段在顶点着色器的前面,但是这里我觉得应该参照LearnOpenGL的说法,放在顶点着色器之后。按游戏引擎,放在顶点着色器前面的图元装配阶段个人理解是指定图元装配的类型(点,线,三角形,四边形瓦片等等)
  4. 几何着色器:图元装配阶段的输出会传递给几何着色器。此阶段是可选编程阶段,不加也没有关系。此阶段的几何着色器会把图元形式的一系列顶点的几何作为输入,它可以产生新的顶点来构造出新的图元用以生成其他形状
  5. 流输出流输出允许将到达此管道阶段的数据写回内存,数据能从这里回到渲染管线的开头。比较典型的例子是渲染头发。头发通常使用三次样条线的集合表示的,以往头发在CPU上进行模拟,然后再在CPU上把样条线镶嵌为线段,最后由GPU渲染那些线段。有了流输出,GPU就可以在顶点着色器内,在头发样条的控制点上进行物理模拟。几何着色器将样条线镶嵌成线段,并用流输出功能把镶嵌后的顶点写入内存。最后那些线段被重新流入渲染管线开始的地方进行渲染
  6. 裁剪:经过顶点着色器处理过后的顶点坐标变成标准化设备坐标(NDC)。标准化设备坐标是一个x,y和z值在-1.0到1.0的一小段空间。任何落在范围外的坐标都会被丢弃/裁剪。该阶段提供有限的配置
  7. 屏幕映射:字面意思,将裁剪后的NDC映射到屏幕上面成为片段。转换为NDC坐标有两个比较明显的好处,第一个是方便裁剪,超过NDC之外的物体就可以直接丢弃不用渲染,减少渲染成本。(毕竟最好的渲染优化就是不渲染,hhhhh),第二个是方便屏幕映射,由于物体的坐标被标准化到-1到1,所以做屏幕映射也十分方便

光栅化阶段

光栅化阶段的工作概括起来就是得到正确的像素颜色并且将它输入到帧缓冲区中

在这里插入图片描述

  1. 三角形设置:简单来说就是输出一个三角形边的数据交给下一个阶段
  2. 三角形遍历:将三角形分解为片段,即光栅化,注意,这里还不是最终的像素
  3. Early-Z:也就是所谓的提前深度测试阶段,由于片段着色器的计算其实非常消耗时间,要对每一个片对都进行一次,所以对被遮挡的片段,通过这个阶段可以直接跳过片段着色器阶段以节省渲染性能
  4. 片段(像素)着色器:第二大可编程的阶段,主要工作就是替每一个片段着色。可以说片段着色器是整个渲染管线中最重要的步骤,因为他决定了最终可以在屏幕上看到什么。片段着色器还会执行片段插值的操作,根据顶点的数据信息,以及当前的片段位置对各种数据做插值。
  5. 合并:这个阶段要做的事情有点多,是片段转变为像素的最后一个阶段。首先,片段需要依次通过一些测试,主要有深度测试,模板测试和alpha测试。
    a)深度测试:所有的深度信息都位于一个Z缓冲(Z-buffer)当中,也被称为深度缓冲(Depth
    -Buffer)。引擎底层的图形接口会自动为你生成这样一个缓冲(就像也有颜色缓冲来生成颜色,目标缓冲生成渲染纹理一样)。深度值存储在每个片段里面(作为片段的Z值),当片段想要输出它的颜色时,引擎会将它的深度值和Z缓冲比较,如果当前的片段在其它片段之后,它将会被丢弃,否则会和当前像素做混合或者是单纯覆盖,这个过程被称为深度测试,他是由底层图形接口自动完成的。但是也是属于可以配置的。
    b)Apha测试:就是测试每一个像素的Alpha值是否满足一个特定的个条件,如果满足,则该像素会被绘制,如果不满足则不会绘制,这个跟深度测试的机制是一样的。只不过深度参考的是像素的"深度"属性,Alpha测试考虑的则是像素的"Alpha"属性。可以通过这个方法对物体做裁剪。
    c)模板测试:就像使用值班和喷漆一样精确的混图一样,当启动模板测试的时候,通过模板测试的片段像素点会被替换到颜色缓冲中,从而被显示出来,未通过的则不会被保存到颜色缓冲区中,从而达到了过滤的功能,有一点像是提供了一层这招
    6.帧缓冲区:当片段被真正输出到帧缓冲区之后,就代表这个像素被正式渲染出来了。走到这一步整个光栅化流程的工作其实就已经进行完了。之后根据需要采取三重缓冲或者双重缓冲策略来交换上一帧和下一帧即可。具体采用多少这里涉及到游戏设计和屏幕刷新率的相关问题
    7.这里粗浅的介绍一下可选的屏幕后处理阶段,这个阶段其实说是可选,但还是挺重要的。在Unity中有提供PostPocessing的组件(可见我毕业设计初步场景优化的文章),可以添加边角亚暗,Bloom等效果。屏幕后处理其实是展现游戏画面十分重要的一个阶段,但是具体的效果就需要自行学习了。

大致的渲染管线流程就是以上这样

关于渲染管线中的剔除

我初学渲染管线的时候,其实对场景中有多少次剔除有一点傻傻分不清楚,于是就上网找资料,总结然后添加了一点内容,希望可以帮助到同样有困惑的同学们入门,同样,如果有纰漏,欢迎指出,我会及时查证修改

主要参考以下这篇博客:
几种剔除的归纳对比

视锥体剔除(平截头体剔除)

  1. 视锥体剔除一般发生在应用阶段,运行在CPU上,一般由游戏引擎内部实现或者是自己编写的对应算法来实习
  2. 视锥体剔除的主要依据是根据摄像机视野以及近裁剪面和远裁剪面的距离,将可视范围外的物体排除出渲染,被剔除的物体将不会进入到渲染的几何阶段
  3. 视锥体剔除是减少渲染消耗的最有效的手段之一,可以在不影响渲染效果的情况下大幅减少渲染涉及到的顶点数和面数

遮挡剔除

  1. 也发生在应用阶段,由游戏引擎实现,运行在CPU上
  2. 就如同字面意思,该阶段所做的工作就是剔除掉那些被遮挡的物体
  3. 随着硬件技术的提升,现在的GPU已经可以在没有应用阶段额外的数据的支持的情况下在硬件侧实现遮挡剔除(在光栅化之后,像素着色器之前)。根据我的查证,这里所说的技术是Early-Z,即Early-Z不是通过深度缓冲得到的,而是通过Check primitive的插值得到的Z。这一段来自于NIVIDA官方的文档,有一篇博客对此有转载,链接附在下方:
    Early-Z硬件支持

裁剪

  1. 裁剪阶段发生在几何阶段的后期,投影变换之后的屏幕映射之前,是渲染管线所必要的一环
  2. 只有当图元完全或部分存在于NDC内部的时候,才会将其发送到光栅化阶段
  3. 其中,对于完全位于NDC内部的图元,则会直接进行下一阶段;完全处于NDC外部的图元则会被完全舍弃;部分处于NDC内部的图元,会根据摄像机视野进行裁剪,在这一过程中可能会产生新的顶点
  4. 通过裁剪Clipping可以将摄像机视野外的图元舍弃掉从而减少光栅化阶段的消耗

背面剔除

1.背面剔除即是将背向视点的图元剔除,因为他们对最终渲染的图像没有贡献
2.一般是根据图形的缠绕方向决定是不是背面的(OpenGL以逆时针方向的三角形为正向三角形,顺时针的为背面,一般会被直接剔除)
3.背面剔除阶段一般是在光栅化阶段运行,执行在Vertex Shader之后,在Fragment Shader片元着色器之前,通过Shader中的CUll指令来控制背面剔除的开启和关闭

深度剔除

1.在Fragment Shader之后,光栅化阶段末期的融合阶段执行,又叫做深度检测
2.每次将一个图元绘制为相应的像素时,都会计算像素位置处图元的深度值,和深度缓冲中对应的像素值进行比较,如果新计算出的深度小于缓存中的深度,则更新深度缓存中的值
3.如果深度值大于深度缓冲中的值,则计算结果被舍弃,深度缓冲中的值也无需更新(更新的这个步骤被称为深度写入)

内存访问

一般来说,着色器程序时不能够直接读写内存的(PS4平台可以通过着色器资源表,使用“大蒜”总线去访问主内存)。取而代之,其内存访问只限于两个方法:寄存器和纹理贴图

着色器寄存器

着色器可以用寄存器间接的存取内存。所有GPU寄存器都是128位SIMD格式的。每个寄存器能保存4个32位浮点数或4个32位整数。这些寄存器能包含一个齐次坐标的四维矢量,或者是一个RGBA格式的颜色,其中每个分量为32位浮点数格式。矩阵可以由一组3或4个寄存器表示。GPU寄存器也可以用来保存单个32位标量,这样用的时候,通常会把该值复制至所有4个32位字段。有些GPU能在16位字段上运算,这种数据类型称为half。
寄存器有以下四大类:

  • 输入寄存器:这些寄存器是着色器的主要数据输入来源。在顶点着色器中,输入寄存器含有顶点的属性数据。在像素着色器中,输入寄存器含有对应某片段的顶点属性插值数据。在调用着色器之前,GPU会自动设置这些输入寄存器的值。
  • 常数寄存器:常熟寄存器的值是由应用程序设置的,应用程序按不同图元会设置不同的值。所谓常数,只是对着色器而言。常数寄存器是着色器的另一种输入。其典型内容包括模型观察矩阵、投影矩阵、光照参数,以及其他着色器所需但顶点属性不包含的数据
  • 临时寄存器:这些寄存器只供着色器程序内部使用,通常用于存储中间计算结果
  • 输出寄存器:这些寄存器的内容由着色器填充,作为着色器仅有的输出形式。在顶点着色器中,输出寄存器含有顶点属性。例如,以齐次裁剪空间表示的已变换的位置及法矢量、可选的颜色、纹理坐标等。在像素着色器中,输出寄存器包含正在着色的片段的最终颜色

当提交几何图元渲染的时候,应用程序要提供常数寄存器的值。在调用着色器程序之前,GPU会从显存将顶点或片段属性数据自动复制至适当的输入寄存器;当程序执行完成时,GPU会把输出寄存器的内存写入显存,使数据能够传递到下一个管道阶段。

纹理

着色器也可以直接读取纹理贴图。纹理数据是以纹理坐标寻址的,而不是使用绝对内存地址。GPU的纹理采样器会自动过滤纹理数据,适当的混合相邻纹素及相邻渐远纹理级数的值。也可以关上纹理过滤,以直接存取某纹素的值。当纹理贴图作为查找表之用时,关上过滤功能就很有用。
着色器只能用间接方法将数据写进纹理——把场景渲染至屏幕外帧缓冲,再在后续的渲染阶段把该帧缓冲当作纹理贴图使用。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-04 11:32:18  更:2021-08-04 11:33:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 6:09:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码