第2章 渲染流水线

2.1 综述

渲染流水线3阶段

在这里插入图片描述

应用阶段

准备好场景数据(摄像机位置, 视锥体, 场景中的模型, 场景中的光源)
粗粒度剔除(剔除不可见的物品)
设置好每个模型的渲染状态:材质(漫反射颜色,高光反射颜色, 纹理, 使用的shader)
输出渲染所需要的几何信息(渲染图元)给洗下一个阶段

几何阶段

把顶点坐标变换到屏幕空间, 再交给光栅器处理

光栅化阶段

决定每个渲染图元中哪些像素应该被绘制在屏幕上.
对上一阶段得到的逐顶点数据,进行插值.

2.3 GPU流水线

顶点着色器 (Vertex Shader)

顶点着色器的主要工作: 坐标变化 和逐顶点的光照

2.3.4 屏幕映射

屏幕映射得到的屏幕坐标决定了这个顶点对应屏幕上哪个像素以及距离这个像素有多远

2.3.5 三角形设置

这个阶段会计算光栅化买一个三角形网格所需要的信息.
因为上个阶段输出的都是三角网格的顶点,但是我们需要三角形边上的信息.
计算三角形网格表示的数据过程就叫做三角形设置

2.3.6 三角形遍历

检查每个像素是否被三角形覆盖, 并且使用顶点信息,对内部信息进行插值的处理.

2.3.8 逐片元操作

这个阶段首先要解决的问题是每个片元的可见性问题.
在这里插入图片描述

模版测试

通过将当前值与缓冲区模版的值比较.
一般开发者这样定义, 如果当前值< 缓冲区, 则通过测试. > 则不通过

深度测试

如果这个片元的深度值大于等于当前深度缓冲区中的值,那么就会舍弃它。这是因为, 我们总想只显示出离摄像机最近的物体,而那些被其他物体遮挡的就不衙要出现在屏幕上 。
而深度缓冲则决定 测试通过后, 是否需要将值写入缓冲区

混合

因为颜色缓冲区可能有上一次渲染的结果, 那么这次算出来的结果应该怎么处理呢?
对于不透明的物体, 可以关闭**混合(Blend)**操作, 直接覆盖上一次渲染的颜色结果.
半透明的物体, 则需要将缓冲区颜色与当前计算的颜色进行混合在这里插入图片描述

小结

虽然从逻辑上说, 这些测试是在片元着色器后面进行.
但是对于大多数的GPU, 它们会尽可能在执行片元着色前, 进行测试.
在片元着色器进行之前做的深度测试技术, 叫做Early-Z技术. (本书后面章节会提到)
但是但是, 提前测试又可能会和片元着色器操作冲突. 书本中提到, 提前进行透明度测试, 但后面这个片元又无法通过透明度测试. 两者就会冲突, 导致性能下降.
在这里插入图片描述

双重缓冲

前置缓冲是之前屏幕上的图像, 后置缓冲是正在渲染的图像, 为了一个图像中, 既有前一帧图像,又有当前图像.

GLSL, HLSL

GLSL, HSLSL, SG都是高级语言.
这些语言会被编译成与机器无关的汇编语言, 又称为中间语言.
这些中间语言再交给显卡驱动翻译成真正的机器语言, 即GPU可以理解的语言

GLSL

优点: 跨平台,由显卡驱动来完成着色器的编工作, 只要显卡驱动支持GLSL就可以运行.
缺点: GLSL编译结果取决于硬件供应商. 他们对GLSL编译结果不尽相同, 会造成编译结果不一致

HLSL

微软控制的着色器编译, 只能Win

Draw Call

就是CPU 往 GPU 发出的命令, 如果命令过于琐碎, 数量又多,会降低性能.
打个比方, 复制1000个1kb的文件和复制1M的文件, 前者相当于调用1000次draw call, 后者1次draw call. GPU处理渲染很快, 但cpu处理命令, 需要在执行命令之前做一些准备工作, 非常耗时.

如何避免

批处理, 将琐碎的draw call合并成一个批(Batch), 即一个大的draw call.

猜你喜欢

转载自blog.csdn.net/esjiang/article/details/114206188