unity Bulid-in 渲染管线
图形渲染管线
图形渲染管线(Graphics Rendering Pipeline) - 知乎 (zhihu.com)
图形渲染管线是图形学知识考察最重要的一个问题,绝对是最高频的,必须掌握。问法有很多种,比如屏幕中一个像素是怎么绘制出来的,绘制出一幅图像的具体过程等。此外还有GPU渲染管线的问法,其实就是省去CPU阶段,直接从GPU阶段开始回答就行了,是一个意思。
什么是渲染管线
图形渲染管线实际上指的是一堆原始图形数据途经一个输送管道,期间经过各种变化处理最终出现在屏幕的过程,在概念上可以将图形渲染管线分为四个阶段:
应用程序阶段、几何阶段、光栅化阶段和像素处理阶段。
调用Render()
摄像机对象调用一个Render()
如同摄像机一样 调用渲染api 通知cpu开始渲染流程
CPU渲染管线-应用程序阶段
剔除
剔除:视椎剔除、遮挡剔除、层级等规则
视椎体剔除
层级剔除 遮挡剔除
渲染顺序-排序
渲染顺序:按距离、渲染队列等规则
- 渲染管线 Render Queue
- 不透明队列 (Render Queue<2500) - 按摄像机距离从前到后排序
- 半透明队列 (Render Queue>2500) - 按摄像机距离从后到前排序
(因为优化处理,防止OverDraw)
打包数据
模型信息:(最重要的)
顶点坐标 (Vertex Array)
法线(顶点法线)
UV
切线
顶点色
索引列表(Indices Array)
变换矩阵:
世界变换矩阵
VP矩阵:根据摄像机位置和fov等参数构建
灯光、材质参数:
- Shader
- 材质参数
- 灯光信息
OBJ文件 (图元)
- 顶点坐标 Position
1 | v -0.5000 0.0000 0.5000 |
- 法线 Normal
1 | vn 0.0000 -1.0000 0.0000 |
- 材质坐标(UV)
1 | vt 1.0000 0.0000 |
- 索引列表(三角面)
f 1/1/1=顶点坐标[1] / 法线[1] / UV[1]
1 | s 2 |
调用shader
SetPassCall DrawCall
1 3 是数据结构
2 4 是函数
综合
该阶段主要是在软件层面上执行的一些工作,包括空间加速算法、视锥剔除、碰撞检测、动画物理模拟等。
总体而言,这一阶段的任务是确保只渲染场景中需要的部分,并且以最优化的方式提交到GPU,从而实现高效的渲染。
GPU渲染管线
把3d的转换成2d的图像渲染到屏幕上
几何阶段- 顶点处理
包含顶点着色、投影变换、裁剪和屏幕映射阶段
模型空间:建模软件坐标系
世界空间坐标: 引擎内部坐标系
相机空间: 以相机为参考系的坐标系
裁剪空间:拍成平面图像,但是这个是一个规则的长方体
MVP矩阵:模型矩阵 视图矩阵 投影矩阵
光栅化阶段 - 图元装配及光栅化
片元可以理解成还没到屏幕的像素
裁剪空间:顶点处理阶段输出 坐标在-W~W之间
裁剪操作:
和剔除很像 但是剔除是模型视椎体剔除 丢弃模型
裁剪是三角面在视椎体裁剪的操作
只要判断顶点坐标是否在裁剪空间以内就可以了
透视除法-NDC标准化设备坐标 :
- 坐标范围-1~1 方便转到屏幕坐标
背面剔除
背对摄像机的三角面剔除掉
摄像机观察的轴是z轴 只要映射到x-y平面就可以
然后利用索引列表来观察x-y平面,逆时针分布那么是正面
顺时针背面
视口转换-屏幕坐标
- 把-1~1坐标转换成(1920,1080)
图元装配
- 把顶点连线
光栅化-片元生成
- 相当于把x-y-z坐标的z值舍弃,然后方便插值运算
- z值作为2d的深度计算,处理前后遮挡关系
光栅化过程
光栅化过程: (成色是片元shader)
取顶点坐标
计算一次函数经过的像素
边缘像素的插值成色
逐行扫描插值颜色
光栅化会产生锯齿
像素处理-片元处理 片元shader
片元计算 纹理映射 光线
纹理技术
纹理采样
通过UV坐标来计算纹素地址的坐标
纹理过滤机制
1
2
3x= 0.4*32=12.8= 13
y=0.4*32=12.8= 13
会失真Filter Mode =双线性插值
Mipmap -纹理链
- 映射区域大小 选择图像
- 会占用内存 生成额外对象
纹理寻址模式
- 超过UV范围的处理
- 纹理压缩格式
光照计算
光照组成
直接光照
间接光照
LightMap 光照贴图
Refletion Probe 反射球
IBL 基于图像的照明(Image Based Lighting)
Light Probe
球谐光照SH 低频环境光漫反射
光照模型
- BRDF
- Phong 光照模型
- 基本框架
- 基本框架=直接光漫反射+ 直接光镜面反射+间接光漫反射+间接光镜面反射
输出合并
最重要的任务:处理遮挡关系、处理半透明混合
通俗地讲:片元通过重重考验到达像素点位置的过程
帧缓冲区FrameBuffer
深度测试 Depth Test
混合Blending
Alpha 测试 : 检测Alpha值小于一个特定值就丢弃
深度测试 看Depth 深度哪个在前
- Zwrite 深度写入 :
- ZTest 深度测试
混合 把俩个颜色混合输出到页面上
- 从后向前
- 关闭ZWirte
- 半透明混合: Alpha Blend = SrcColor * SrcAlpha + DestColor* (1.0 - SrcAlpha)
- 柔和叠加变亮 Soft Additive = SrcColor * SrcAlpha + DestColor *1.0
帧缓冲
把2d的图像放入帧缓冲(FrameBuffer)中 类似一个画布的队列存储
颜色缓冲区 模板缓冲区 深度缓冲区
后处理
CPU后处理逻辑
GPU渲染管线
调色 Bloom 等后处理效果
渲染目标
多个摄像机机应该怎么办
对于多个摄像机会有个Clear Flags 渲染之前会有一个清屏操作
假设Clear Flags 选择不清屏
渲染顺序会看Depth数值 来判断渲染顺序 数值越小 越快渲染