前言:只记录自己需要的内容
深度测试 (Z buffer or Depth buffer)

把深度视为无限远,然后遍历每一个山脚行,再遍历每一个三角形的光栅化过程,同时记录光栅化的深度信息。如果光栅化后当前像素点的深度信息小于之前记录过的信息,则替换原本的像素点信息。

Z-buffer:对每个像素多存一个深度
复杂度:O(n) for n triangles 并不是排序,而是只要最值
需要保证三角形进入顺序和结果无关
无法处理透明物体
Blinn-Phong Reflectance Model 光照模型 着色模型
Diffuse
- $$ L_{d}=k_{d}\left(I / r^{2}\right) \max (0, \mathbf{n} \cdot \mathbf{l}) $$
可以简化为:
K_d 漫反射系数
I/r2 衰减后的灯光,LightColor * AttenuationLight
Max(0, normal dot LightDirction)
Specular

p一般100~200,控制高光大小
Ambient
$$ L_{a}=k_{a} I_{a} $$一般可以认为ambient为一个常数,要计算真实光照要考虑GI
Combine
$$ \begin{aligned} L &=L_{a}+L_{d}+L_{s} \\ &=k_{a} I_{a}+k_{d}\left(I / r^{2}\right) \max (0, \mathbf{n} \cdot \mathbf{l})+k_{s}\left(I / r^{2}\right) \max (0, \mathbf{n} \cdot \mathbf{h})^{p} \end{aligned} $$— 2022.12.20 更新 —
URP实现
|
|
效果如下

Real Time Rendering

应用阶段:CPU传递数据给GPU(包括纹理,材质,着色器,是否Culling)。Drawcall 即CPU每调用一次GPU就计算一次Drawcall
几何阶段:顶点着色器,几何着色器,曲面细分着色器,可编程。几何阶段还进行投影,裁切和屏幕映射等操作。
几何着色器常见应用:法线可视化,绘制图形(增加删除点)。曲面细分着色器常见应用: displacement 置换
投影:观察空间转换到裁剪空间(又被称为齐次裁剪空间)裁切:对透视裁剪空间来说,GPU需要对裁剪空间中的顶点执行齐次除法(其实就是将齐次坐标系中的w分量除x、y、z分量),得到顶点的归一化的设备坐标(Normalized Device Coordinates, NDC)屏幕映射:最终转化为屏幕空间,Z分量即Z-buffer
光栅化阶段:包括图元组装(三个点组成一个三角形),三角形遍历(参考光栅化笔记),片元着色器,逐片元操作包括裁剪测试(Scissor Test)、透明度测试(Alpha Test)、模板测试(Stencil Test)以及深度测试(Depth Test),可自定义。
通过测试的片元可以进入合并,考虑是否颜色混合 (alpha blend)在经过上面的层层测试后,片元颜色就会被送到颜色缓冲区。GPU会使用双重缓冲(Double Buffering)的策略,即屏幕上显示前置缓冲(Front Buffer),而渲染好的颜色先被送入后置缓冲(Back Buffer),再替换前置缓冲,以此避免在屏幕上显示正在光栅化的图元。
纹理映射
纹理映射即漫反射系数k_d

每一个3D模型的表面展开都是1个2d平面,2d平面的x y坐标用来查询纹理的uv坐标
$$ \begin{aligned} \alpha &=\frac{-\left(x-x_{B}\right)\left(y_{C}-y_{B}\right)+\left(y-y_{B}\right)\left(x_{C}-x_{B}\right)}{-\left(x_{A}-x_{B}\right)\left(y_{C}-y_{B}\right)+\left(y_{A}-y_{B}\right)\left(x_{C}-x_{B}\right)} \\ \beta &=\frac{-\left(x-x_{C}\right)\left(y_{A}-y_{C}\right)+\left(y-y_{C}\right)\left(x_{A}-x_{C}\right)}{-\left(x_{B}-x_{C}\right)\left(y_{A}-y_{C}\right)+\left(y_{B}-y_{C}\right)\left(x_{A}-x_{C}\right)} \\ \gamma &=1-\alpha-\beta \end{aligned} $$投影前后的重心坐标可能会变化,所以需要在对应时间计算对应的重心坐标来做插值,不能随意复用!
纹素
每张纹理贴图的一个像素点。
如果纹素太小,把多个pixel 映射同一个纹素
- 解决:
- Nearest
- Bilinear
- Bilinear 插值 lerp
- 水平+竖直插值→双线性插值
- 最近的四个点插值
- Bicubic 双向三次插值
- 周围16个点做三次插值
- 运算量更大,结果更好
如果纹素太大,会产生摩尔纹

用Mipmap降低纹理精度

各向异性过滤
把贴图的xy方向分别使用不同的mipmap,比如1024x1024的贴图可以变成128 x 256或者64 x 128
- 怎么知道层数D?约为相邻pixel的映射uv之间的距离取2的对数
- 如果计算出来需要的D是整数,就很方便,直接查找
- 如果计算出来需要的D不是整数→Trilinear Interpolation三线性插值