渲染管线
大的流程
- 数据资源
- 渲染管线
- 2d图像
Unity内置的渲染管线分类
- CPU应用程序段渲染逻辑
- GPU渲染管线
Unity渲染的流程:
Camera组件调用Renderer()
剔除操作
- 视椎体剔除:根据field of view,近裁面和远裁面构成的锥体。剔除指会跟视椎体做一个碰撞检测,有相交的部分就表明应该被绘制,如果没有的话就应该剔掉。这里可以通过包围盒进行加速和优化。
- 遮挡剔除:根据在相机中的先后关系进行
- 层级剔除:根据特定层级的物体进行剔除,Culling mask操作
渲染顺序:
- 按距离
- 按渲染队列:Render Queue越小越先被渲染,不透明队列<2500,半透明队列>2500
- 不透明物体默认是2000
- 半透明物体默认是3000
- 相等情况:不透明队列从前向后排序(优化方便剔除),半透明队列从后向前排序(渲染效果正确性)
打包数据:
- 模型信息:顶点坐标、法线(会合并相同的)、UV(会合并相同的,是一个二维数据,只有前两个分量有用)、顶点色、索引列表
- 变换矩阵:MVP
- 灯光、材质参数:Shader、材质参数、灯光信息
调用Shader: 告诉渲染管线现在要渲染哪些模型数据,要用哪个shader
- SetPassCall():设置好渲染状态,使用哪种shader,哪种混合模式,设置好背面剔除
- DrawCall():使用哪些模型数据进行渲染
GPU渲染管线:25min
- 顶点处理:从模型空间到裁剪空间,见顶点shader
- 图元装配和光栅化:
- 裁剪操作:对三角面的操作而不是物体的剔除(通过判断顶点坐标进行操作)
- NDC标准化设备坐标:透视除法(同时除以w)
- 背面剔除:引用模型的索引列表,如果索引排列顺序呈顺时针就留下,逆时针就是背面
- 屏幕坐标:通过视口转换(只针对x,y坐标),z坐标用来判断前后关系
- 图元装配:连线,形成三角形(Bresenham画线)
- 光栅化:通过插值算法生成片元,z坐标变成深度值
- 片元处理:见片元shader
- 输出合并:片源数据->alpha测试->模板测试->深度测试->混合->帧缓冲区
- 最重要任务处理遮挡关系、处理半透明混合
- 帧缓冲区
- 深度测试
- zwrite 深度写入 即使通过深度测试也不会刷新缓冲区,并不影响颜色缓冲区的写入
- ztest 深度测试
- Early-z发生在片元shader之前或者顶点shader之后
- 混合:从后到前,关闭ZWrite
帧缓冲区:一个跟屏幕大小一样的临时画布,等场景里的物体渲染完成后,屏幕就能从这个缓冲区里拿到图像
后处理逻辑:这个阶段可再次调用逻辑
再次GPU渲染管线
多个摄像机
每一个摄像机都会调用上述的流程
Unity摄像机:
- 摄像机在清屏之前会调用clean flag,可以选择不清屏
- depth可以选择先后顺序,越小越先渲染
Shader
- 顶点shader:主要处理投影成像操作,并不会完成2D成像,主要完成对3D场景的变形
- 放置物体:模型空间->世界空间
- 摆好相机:世界空间->相机空间
- 摁下快门:相机空间->裁剪空间
- 片元shader:最重要任务,上色
- 纹理技术
- 纹理采样:根据采样公式给片元上色
- 纹理过滤机制 – 对应到Unity就是filter mode:
- 四舍五入(不好用)
- 采样周围的四个插值进行计算(双线性插值)
- Mipmap:纹理链 – Unity可以生成Mipmap
- 纹理寻址模式:超出纹素范围的地址该怎么操作(uv坐标超过1怎么操作)
- 纹理压缩格式:RGBA,ASTC,ETC2,PVRTC
- 光照计算
- 光照组成
- 光照模型
- Phong光照模型 – 基于经验的光照模型 max(NL,0.0)+pow(max(RV,0.0),smoothness)+ambient = Phong
- 漫反射 – 点乘得到cos值
- 高光反射 – 光滑度决定衰减范围,光滑度越小,衰减越大
- 环境光 – Lightmap、Reflection Probe、Light Probe
- 基本思路:直接光漫反射+直接光镜面反射+间接光漫反射+间接光镜面反射
- Phong光照模型 – 基于经验的光照模型 max(NL,0.0)+pow(max(RV,0.0),smoothness)+ambient = Phong
- 纹理技术