渲染管线笔记

整体流程

1.应用阶段:准备基本数据,加速算法和粗粒度剔除,进行渲染设置,输出到几何阶段
2.几何阶段:顶点着色器,曲面细分, 几何着色器,顶点裁剪,屏幕映射
3.光栅化:三角形(点/线)设置,三角形遍历,片段着色器

4.逐片元:(一般将这步归为光栅化里
裁剪测试,透明度测试,深度
5.后处理(游戏流程常见

经典的光栅化图形管线
灰色框是固定管线,黄色框是可编程管线。这个流程由图形编程接口(OpenGL、Vulkan等)抽象出给软件用户

应用阶段

[游戏开发][渲染篇][第二篇]渲染管线之应用程序阶段_Little丶Seven的博客-CSDN博客
应用阶段是再CPU进行

1.准备基本数据

· 场景物体数据
物体变化数据,空间变化矩阵,物体网格数据(顶点位置,uv贴图)
例如:

(.obj模型数据 v:顶点坐标 vt:纹理坐标 vn:法线 f:索引(v, vt, vn))

· 摄像机数据
即观察视角,位置,方向,近远裁剪平面,正交/透视,FOV,视口比例等
· 光源及阴影数据
光源类型(方向光,点光,聚光灯,平面光等) 位置,方向等
逐光源绘制阴影贴图(近平面偏移,逐级连等)

· 其他全局数据

2.加速算法和粗粒度剔除

· 碰撞检测
· 加速算法
· 遮挡剔除
· 其他算法

剔除:
1)可见光裁剪:点光聚光衰减与区域,灯光光锥体与视锥体不相交可剔除
2)可见场景物体裁剪:八叉树,K-D树,BVH
3)视锥体剔除:物体不在摄像机视锥体内可剔除
4)遮挡剔除:物体被完全遮挡可剔除
5)层级剔除

3. 设置渲染状态 准备渲染参数

· 绘制设置(比如对于不同的物体用不同的shader渲染
· 绘制顺序(比如先不透明再渲染半透明物体
· 渲染目标(比如渲染完成后结果导入RenderTexture还是FrameBuffer
· 渲染模式(比如延迟渲染和前向渲染

unity里当渲染切换渲染材质球时,会发生SetPassCall,不同网格的物体引用材质相同则不会发生SetPass。

4.调用DrawCall 输出渲染图元到显存

这个词直白点的中文翻译就是绘制呼叫,CPU呼叫GPU开始干活啦

实际上发生的事情是:CPU调用图像编程接口命令,如OpenGL 中的glDrawElements 命令或者DirectX 中的DrawlndexedPrimitive命令,通过硬件总线把渲染数据传输到GPU后命令GPU 进行渲染的操作

DrawCall作为性能优化重点,一种解决方法是 批处理优化技术
后续会有单独的笔记,上面的 应用阶段 文章链接也有提及

几何阶段

1.顶点着色

· 视图变换【重要
OpenGL的设备坐标,z分量(-1, 1),Driect3D是(0, 1)

· 顶点着色

2.可选顶点处理

· 曲面细分(可选
· 几何着色器(可选
基于图元操作,通过给定的图元生成更多的图元

3.投影

把视锥中的顶点变换到CVV(规范立方体)中就称为投影

· 正交
· 透视

4.裁剪

· CVV(规范立方体
· 正面或背面剔除(可配置

5.屏幕映射

· 从连续到离散
· 坐标系差异(OpenGL/D3D

几何阶段变换的详细过程

GPU渲染过程 - 知乎 (zhihu.com)
opengl 中的透视除法和NDC_Captain--Jack的博客-CSDN博客_ndc 图形学

· 从Object到World到View的变换的都可以用四阶矩阵(即模型变换和视变换

· 视角坐标的坐标系是摄像机为原点,朝向-z轴看,y轴向上,x轴向右()应用视图转换后的实际位置和方向取决于基础应用程序编程接口 (API)

· 把视锥中的顶点变换到CVV(规范立方体)中就称为投影
· 规则观察体CVV(Canonical View Volume) 也叫做齐次裁剪空间
· 从视角坐标系 通过 投影变换(透视或正交)变换到 CVV

· 在CVV中进行裁剪
然后再进行透视除法

· why:在视锥体中进行裁剪是很困难的,所以引入了CVV
这文章注意的第3点
透视投影变换之CVV (细讲了CVV的实现)

· 在3D计算机图形学中,透视是通过投影矩阵变换,改变每一个向量中 W 分量的值来实现透视的,投影矩阵用 Z 分量的值改变 W 分量的值

· 透视除法(或称齐次除法)
透视除法只是将齐次坐标中的 W 分量转换为1的专用名词

· 这文章生动讲解了 齐次和投影 以及 对于投影到透视除法的详细讲解
写给大家看的“透视除法” —— 齐次坐标和投影 - 简书 (jianshu.com)

· 透视除法后得到的坐标就叫NDC空间坐标(归一化的设备坐标空间)
NDC是一个x,y,z取值范围为(-1,1)的立方体
·NDC空间(归一化的设备坐标空间)整理记录_zhangj1110的博客-CSDN博客_ndc空间

· 视口变换(屏幕映射

ScreenZ的值通常为Clipz/Clipw,存入深度缓冲,但也不是必须。

注意:
1.顶点着色器的输出就是齐次裁剪空间(就是一般所说的输出的positionCS)
2.Fragment Shader的输入是屏幕空间
3.其实透视除法和视口变换是在GPU在Vertex Shader之后,Fragment Shader之前进行的

4.齐次坐标有一个额外的维度叫 W 分量,用来缩放X, Y, Z三个分量的值
5.平移和透视投影的矩阵变换只能在齐次坐标中使用,所以在3D计算机图形学中,当 W=1时,X, Y, Z 分量被称为“正确的”。
6.当 W=0 时,这个坐标表示无穷远的一个点(或者表示无限长的一个向量),通常用于表示平行光的方向。

7.

光栅化阶段

光栅化(也称为扫描转换)是从屏幕空间中的二维顶点(每个顶点具有 z 值(深度值)和与每个顶点关联的各种阴影信息)转换为屏幕上的像素

三角形设置和遍历

1.三角形设置

· 三角形设置的任务是计算三角形的一些参数供后续步骤用
· 计算图元的边界信息叫做三角形设置
· 这阶段计算三角形的微分、边方程和其他数据。这些数据可用于三角形遍历

2.三角形遍历

· 检查其中心(或样本)被三角形覆盖的每个像素,并为与三角形重叠的像素部分生成一个片段
· 查找三角形内的样本或像素通常称为三角形遍历
· 每个三角形片段的属性都是使用在三个三角形顶点之间插值的数据生成的
· 这些属性包括片段的深度,以及几何阶段的任何着色数据
· 正是在这里对三角形进行了透视校正插值

2.5 抗锯齿

· SSAA 渲染到一个分辨率放大n倍的buffer,对其采样
· MSAA 光栅化阶段,对每个像素设置多个子采样点,然后对每个子采样点进行覆盖测试和遮挡测试

3.逐片元操作

片元着色
· 此处使用插值着色数据作为输入执行任何每像素着色计算
· 像素着色阶段由可编程 GPU 内核执行

RTR4中将片元着色后的阶段称为 Merging(合并

4.帧缓冲操作

参考:GPU图形微架构学习笔记(三)帧缓冲操作 - 知乎 (zhihu.com)
RTR4

帧缓冲通常由系统上的所有缓冲器组成

帧缓冲操作模块在NVIDIA的GPU文档中叫ROP(Render Output Unit),AMD的GPU中叫RB(Render Backend)
2个子模块

· 色彩模块 对色彩缓冲
· 深度模块 对深度缓冲
分别负责对显存中的色彩缓冲和深度缓冲进行读写,同时完成读写过程中的计算任务

带宽计算

带宽计算
访问色彩/深度缓冲的带宽:
· 渲染一个场景每个像素的绘制次数是不同的,图中颜色越亮表示绘制次数越多
· 一个像素会被不同深度的多个三角形覆盖,每个三角形都会去绘制一次这个像素。这称为重复绘制(overdraw)

测试顺序:

这部分知识本人水平有限,未彻底弄明白,故贴上原链接和部分观点
渲染管线 - Bob的博客 | Bob Blog (chenanbao.github.io)

1.像素测试
2.裁剪测试
3.Alpha测试
4.模板测试
5.深度测试
6.混合 :
7.Dithering
8.逻辑运算

RTR4中提到管线末端的所有这些函数称为栅格运算 (ROP) 或混合运算,可以将颜色缓冲区中当前的颜色与三角形内正在处理的像素的颜色混合。

Early-Z

引用: https://zhuanlan.zhihu.com/p/433303673
在图形渲染管线概念里,深度测试发生在最后的帧缓冲操作里:写入一个像素前,读取深度缓冲里相同位置之前渲染图形的深度信息,如果当前写入的图形更近,写入就能成功,深度信息也更新为当前图形的,反之则什么都不做。在什么都不做的时候,这个像素之前的像素着色计算就浪费了。所以我们引入一个优化就是将深度测试提前到决定这个像素需不需要被着色的时候,也就是三角形遍历阶段。

在遍历三角形覆盖的像素时,插值计算三角形在该像素位置的深度,然后和该像素的深度缓冲信息比较来判断当前图形是否被遮挡。如果是就不需要加入着色器;不是的话就加入着色器同时更新深度缓冲。所以在Early-Z优化下,帧缓冲操作模块需要和光栅化模块交互以读写深度缓冲信息。

Early-Z能减少很多像素着色任务,是现代GPU的必备优化之一。想要达到最大效果,用户最好是按由近及远的顺序绘制,从而让近的图形尽早屏蔽掉远方图形的绘制任务。当然即使注意绘制顺序,完全屏蔽无效绘制也不容易做到,我们会在后续的延迟渲染一文中再次讨论。

最后要注意的是Early-Z在有些情况下是实效的,比如像素着色器中使用"discard"丢弃当前计算像素,或者开了Alpha Blend。这些操作都是在光栅化之后才影响深度缓冲的,所以如果有这些操作,光栅化里的Early-Z就应该被关闭。

参考:

https://www.bilibili.com/video/BV1L54y1s7xw
视频ppt链接:1100-渲染管线简介-v4 (qq.com)
[游戏开发][渲染篇][第二篇]渲染管线之应用程序阶段_Little丶Seven的博客-CSDN博客

透视投影变换之CVV - 知乎 (zhihu.com)
https://zhuanlan.zhihu.com/p/135308055
opengl 中的透视除法和NDC_Captain--Jack的博客-CSDN博客_ndc 图形学
写给大家看的“透视除法” —— 齐次坐标和投影 - 简书 (jianshu.com)
NDC空间(归一化的设备坐标空间)整理记录_zhangj1110的博客-CSDN博客_ndc空间

GPU图形微架构学习笔记(一)前言 - 知乎 (zhihu.com)
GPU图形微架构学习笔记(二)光栅化 - 知乎 (zhihu.com)
GPU图形微架构学习笔记(三)帧缓冲操作 - 知乎 (zhihu.com)
渲染管线 - Bob的博客 | Bob Blog (chenanbao.github.io)

posted @ 2022-11-15 23:19  Zxcrock  阅读(168)  评论(0)    收藏  举报