《Unity Shader入门精要》读书笔记01
第 2 章 渲染流水线
概念流水线
从一系列的顶点数据、纹理等信息出发,把这些信息最终转换成图像。这个工作由CPU和GPU共同完成。
《Real-Time Rendering, Third Edition》中将渲染流程分为3个阶段:应用阶段(Application Stage),几何阶段(Geometry Stage),光栅化阶段(Rasterizer Stage)
应用阶段由 CPU 负责,开发者准备场景数据,粗粒度剔除(culling),设置每个模型的渲染状态(材质、纹理、Shader)。这一阶段最重要的输出是渲染所需要的几何信息,即渲染图元(rendering primitives)
几何阶段通常在 GPU 上进行,处理每个渲染图元,进行逐顶点、逐多边形的操作。输出屏幕空间的二维顶点坐标、每个顶点对应的深度值、着色等相关信息。
光栅化阶段在GPU上运行,决定每个渲染图元中哪些像素应该被绘制在屏幕上。对上一阶段得到的逐顶点数据(例如纹理坐标、顶点颜色等)进行插值,然后再进行逐像素处理。
CPU 和 GPU 之间的通信
应用阶段:
(1)把数据加载到显存中。硬盘(Hard Disk Drive, HDD)-›系统内存(Random Access Memory,RAM)->显存(Video Random Access Memory, VRAM)
(2)设置渲染状态。例如使用哪个顶点着色器(Vertex Shader)/片元着色器(Fragment Shader)、光源属性、材质等。
(3)调用Draw Call。
GPU 流水线
顶点数据->
—>(几何阶段)顶点着色器(->曲面细分着色器)(->几何着色器)->裁剪->屏幕映射->
—>(光栅化阶段)三角形设置->三角形遍历(->片元着色器)->逐片元操作->
屏幕图像
//可编程 可配置 (可选)
顶点着色器(Vertex Shader)
逐顶点调用,无法得知顶点与顶点之间的关系。主要工作:坐标变换和逐顶点光照。坐标变换是从模型空间转换到齐次裁剪空间,顶点坐标转变为归一化的设备坐标(Normalized Device Coordinates, NDC)裁剪(Clipping)
根据NDC下的顶点位置,保留/舍弃/裁剪图元。屏幕映射(Screen Mapping)
把每个图元的x、y坐标转换到屏幕坐标系(Screen Coordinates)。屏幕坐标系和z坐标一起构成了窗口坐标系(Window Coordinates)。
注意屏幕坐标系在 OpenGL 和 DirectX 之间的差异:OpenGL 把屏幕的左下角当成最小的窗口坐标值,而DirectX则定义了屏幕的左上角为最小的窗口坐标值。三角形设置(Triangle Setup)
输入:三角网格每条边的两个端点;
输出:三角形网格表示数据(?还不太懂)三角形遍历(Triangle Traversal)/ 扫描变换(Scan Conversion)
检查每个像素是否被一个三角网格覆盖,被覆盖就生成一个片元(fragment)。使用三角网格 3 个顶点的顶点信息对整个覆盖区域的像素进行插值。最后输出一个片元序列。
一个片元对应的是一个像素!
一个片元并不是真正意义上的像素,而是包含了很多状态的集合,这些状态用于计算每个像素的最终颜色。这些状态包括了(但不限于)它的屏幕坐标、深度信息,以及其他从几何阶段输出的顶点信息,例如法线、纹理坐标等。
片元着色器(Fragment Shader)/ 像素着色器(Pixel Shader)
输入:上个阶段对顶点信息插值得到的结果。
输出:一个或多个颜色值。
在此阶段可以做纹理采样。它只能影响单个片元。除非可以访问导数信息(gradient,or derivative)逐片元操作(Per-Fragment Operations)/ 输出合并阶段(Output-Merger)
(1)决定每个片元的可见性。如深度测试、模板测试
(2)若片元通过测试,就需要把这个片元的颜色值和已经存储在颜色缓冲区的颜色进行合并/混合。模板测试(Stencil Test)——模板缓冲(Stencil Buffer)
GPU 会首先读取(使用读取掩码)模板缓冲区中该片元位置的模板值,然后将该值和读取(使用读取掩码)
到的参考值(reference value)进行比较,这个比较函数可由开发者指定。开发者可以设置不同结果下的修改操作,例如,在失败时模板缓冲区保持不变,通过时将模板缓冲区中对应位置的值加 1 等。模板测试通常用千限制渲染的区域。另外,模板测试还有一些更高级的用法,如渲染阴影、轮廓渲染等。深度测试(Depth Test)
GPU 会把该片元的深度值和已经存在于深度缓冲区中的深度值进行比较。这个比较函数也是可由开发者设置的,例如小于时舍弃该片元,或者大于等于时舍弃该片元。混合(Blend)——半透明物体会用到。可以高度配置。
Early-Z 技术:将深度测试提前到片元着色器之前。尽可能早地知道哪些片元是会被舍弃的,对于这些片元就不需要再使用片元着色器来计算它们的颜色。
但是!如果将这些测试提前的话,其检验结果可能会与片元着色器中的一些操作冲突。为了避免我们看到那些正在进行光栅化的图元,GPU 会使用双重缓冲 (Double Buffering) 的策略。这意味着,对场景的渲染是在幕后发生的,即在后置缓冲(Back Buffer) 中。一旦场景已经被渲染到了后置缓冲中,GPU 就会交换后置缓冲区和前置缓冲(Front Buffer) 中的内容,而前置缓冲区是之前显示在屏幕上的图像。由此,保证了我们看到的图像总是连续的。
术语解释
OpenGL/DirectX
图像应用编程接口,用于渲染二维或三维图形,架起了上层应用程序和底层 GPU 的沟通桥梁。一个应用程序向这些接口发送渲染命令,而这些接口会依次向显卡驱动 (Graphics Driver) 发送渲染命令。HLSL、GLSL、CG
着色语言(Shading Language)。DirectX 的 HLSL (High Level Shading Language)、 OpenGL 的 GLSL (OpenGL Shading Language) 以及 NVIDIA 的CG(C for Graphic)。Draw Call
CPU 调用图像编程接口,如 OpenGL 中的 glDrawElements 命令或者 DirectX 中的 DrawlndexedPrim itive 命令 ,以命令 GPU 进行渲染的操作。Draw Call 中造成性能问题的是 CPU。
减少Draw Call 开销的方法:(1)避免使用大量很小的网格。无法避免时考虑能否合并。(2)避免使用过多的材质。尽量在不同的网格之间共用一个材质。固定管线渲染(Fixed-Function Pipeline)
通常是指在较旧的 GPU 上实现的渲染流水线。这种流水线只给开发者提供一些配置操作。
- 标题: 《Unity Shader入门精要》读书笔记01
- 作者: 铁名_IronName
- 创建于 : 2026-01-10 09:38:13
- 更新于 : 2026-01-20 13:47:30
- 链接: https://blog.ironname.top/2026/01/10/《Unity-Shader入门精要》读书笔记01/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。