《unity shader入门精要》阅读笔记
建议与 B 站录播的 Games 101 图形学入门 课程同步学习
什么是 shader
shader 着色器
shader 是整个渲染流程的子部分,我们需要对渲染流程有所了解,才能写 shader 实现想要的效果
渲染流程——在屏幕上生成或绘制一张二维纹理的过程
unity shader 在原有的渲染流程上做了封装,对 shader 更进一步做了一层抽象,方便人们快速使用
什么是渲染流水线
由一个三维场景或物体出发,最终生成一张二维图像的过程
大体上,就是 CPU 把数据加载到显存、CPU 设置渲染状态、CPU 调用 Draw Call 让 GPU 在屏幕上绘制图形
将一系列的顶点数据、纹理等信息转化为屏幕上显示的二维图像,由 CPU 和 GPU 共同完成
另一种简单地划分,就是分为三个阶段:应用阶段、几何阶段、光栅化阶段
调用 Draw Call 之前,都是 CPU 在组织需要绘制的数据,就是应用阶段
调用 Draw Call 后,GPU 如何将渲染状态、顶点数据绘制成屏幕上的像素,就是几何阶段、光栅化阶段。这一步骤又叫 GPU 的渲染流水线
- 应用阶段(准备阶段)–最终输出的,渲染所需的几何信息称为图元
- 准备场景数据(摄像机位置、模型位置)
- 剔除不可见物体
- 设置每个模型的渲染状态(材质、纹理、shader)
- 几何阶段–最终输出图元对应的屏幕空间的顶点坐标、每个顶点的着色信息等
GPU 绘制图元,逐顶点、逐多边形操作
- 将顶点坐标变换到屏幕空间
- 光栅化阶段
根据上一步骤中产生的数据,决定屏幕上的每个像素如何绘制
小结
准备阶段:CPU把场景数据转化为渲染图元(点/线/三角面),传递给几何阶段
几何阶段:进行顶点、多边形的操作,将顶点坐标转化为屏幕空间坐标,计算顶点的着色信息等
光栅化阶段:对顶点数据进行插值,生成屏幕上的像素
shader 实现原理
在 几何阶段 和 光栅化阶段,又可以划分为多个子阶段,不同阶段有各自的可配置性、可编程性
因此,在了解渲染过程后,我们可以通过一些配置或编程控制其中的某些子阶段,让 GPU 最终渲染我们想要的图像
几何阶段细分的子阶段
顶点着色器–可编程–第一个子阶段
GPU 在每个顶点上,调用顶点着色器,决定顶点坐标变换 (从模型空间转化为齐次裁剪空间) 和顶点颜色
这一步也就是《 GAMES101 图形学入门》课程中提到的,将模型坐标,经过矩阵乘法,变换到 (1,1,1)^3 的小立方体空间中。
曲面细分着色器–可选的、可编程
几何着色器–可选的、可编程
裁剪–可配置–剔除相机视野外的顶点
经过上一步将模型坐标,变换到小立方体空间中,有一些顶点在小立方体空间的外面,属于不可见的,应该被舍弃
三角形与小立方体空间相交时,空间内的保留,空间外的舍弃
屏幕映射–不可配置、不可编程–最后一个子阶段
将小立方体空间,映射到屏幕的二维空间中,经过矩阵变换为屏幕坐标系(窗口坐标系)
光栅化阶段细分的子阶段
三角形设置–不可配置、不可编程
计算三角形网格覆盖了哪些像素,对每一个像素采样
判断像素的中心,是否落在三角形内部(计算点积,某点与三角形的三条边,都在同一侧,则说明该点在三角形内)
三角形遍历–不可配置、不可编程
又叫扫描变换阶段,计算出每个像素点是否落在三角形网格中
对于落在三角形网格的像素,生成一个 片元 来记录像素的屏幕坐标、深度信息、顶点信息等
片元着色器–可编程
又叫像素着色器 ,根据上一步计算好 片元 信息后,对顶点信息插值计算,可以实现很多重要的效果
这一阶段的缺陷在于,片元着色器只能影响自身 一个片元 。
逐片元操作–可配置
又叫 输出合并 阶段,计算片元的可见性、颜色混合,最终输出到颜色缓冲区,由 GPU 将缓冲区的图像输出
总结
shader 就是在渲染流水线上的一些可高度编程的阶段,包括顶点着色器、片元着色器等,我们通过编写着色器代码,控制图像渲染的细节
shader 也指 GPU 渲染流水线中,可编程的子阶段,如顶点着色器、片元着色器