Rendering Pipeline "A chain is no stronger than its weakest link."
渲染流水线可粗分为4个阶段:
Application:程序阶段完全可控,由软件驱动,软件通常运行在通用CPU。
程序该阶段末尾,将要渲染的几何图元提交给下一阶段几何处理,这些被称为渲染基元(点、线、三角)。该阶段最重要的任务:提交几何图元(渲染基元)。如何正确按需提交成为关键。该阶段也可做其他事:碰撞检测、键鼠输入、头戴显示、剔除算法等
Geometry Processing:几何处理,变换、投影等,该阶段包括绘制内容,如何绘制,在哪绘制。通常在GPU上执行,可编程。
①顶点着色。1是计算顶点坐标,顶点坐标计算需要经过多次变换: 建模坐标->世界坐标->观察坐标(相机空间);2是计算顶点输出数据(如法线和纹理坐标)
② Projection:正交和透视投影。经过正交或透视变换过后,坐标转为clipping coordinate (也称齐次坐标决定相机是否可见) 。投影之后是可选Optional Process:
Tessellation:曲面细分,将一组顶点组成一个pitch,将一组pitch组成一个三角形集合。随着物体距离摄像机的远近,可以控制生成的三角形集合大小,近多远少。
Geometry Shading:常用于模拟粒子特效。
Stream output:常用于模拟粒子特效。
③ Clipping:使用投影阶段生成的齐次坐标进行裁剪,进行透视分割得到normalized device coordinates也被称为视口坐标或裁剪空间,是三维坐标。
④ Screen Mapping:将得到的视口坐标映射到屏幕得到屏幕坐标(x, y)加z_values,二维坐标。注意畸变控制
UnityShader坐标空间转换
建模坐标-(Model Transform)>世界坐标-(View Transform)>观察坐标-(Projection Transform)>视口坐标-(Screen mapping)>屏幕坐标
假定modelPos = (1,2,3).
Model Transform: float4 worldPos = mul(unity_ObjectToWorld, float4(modelPos, 1)) //也可用unity_WorldToObject回到模型坐标
View Transform: float4 projPos = mul(UNITY_MATRIX_V, worldPos)
/*也可用UNITY_MATRIX_MV一次性从模型空间转到观察坐标(相机空间)*/
Projection Transform: float4 viewPos = mul(UNITY_MATRIX_P, projPos )
/*也可用UNITY_MATRIX_MVP一次性从模型空间转到裁剪空间*/
Rasteriztion:光栅化GPU上执行,接收来自上一阶段所有经过变换和投影的顶点及其着色数据,找到基元内所有像素。可编程
①Triangle Setup(primitive assembly):在这个阶段执行三角形的差异化计算、边缘均分。
②Triangle Traversal:三角形遍历。Finding which samples or pixels are inside a triangle is often called triangle traversal
Pixel Processing: GPU执行。像素处理是对像素或图元内的采样点进行逐像素或逐采样点计算和操作的阶段。可编程
①Pixel Shading:可编程,所有的像素着色计算都在此阶段。
②Merging:像素颜色存储在color buffer,任务1是负责将像素着色阶段产生的片元颜色与当前缓冲区中颜色相合并;任务2是负责解决可见性问题
Unity's Rendering Path
“如何应用光照以及使用着色器哪个通道都取决于使用了哪个渲染路径,着色器内每个通道经由它的通道标签来传递光照类型"
Forward Rendering path
ForwardBase and ForwardAdd passes are used.
- ForwardBase通道会立即渲染环境光、光照贴图、主方向光和不重要的顶点光。
- ForwardAdd通道被用于增强逐像素光照,每个物体都被这样的光照亮。
如果着色器中没有上述两种合适的光照通道,则自动切换到Vertex Lit path。
在Forward渲染下,有三种光照:逐像素光照渲染;逐顶点光照渲染;SH(球谐函数)光照渲染。
那何时用何种光照模式呢?使用的判断规则是:
- 一些最亮的光(默认4个)总是逐像素计算
- 光的渲染模式设为Important总是逐像素
- 光的渲染模式设为Not Important总是逐顶点/SH;
- 如果场景中的最亮的光少于Quality Setting - Pixel Light Count,多余的光按逐像素渲染并按强度递减排序
如图:
示意图。假设A-H光的颜色和强度以及render model为auto,亮度排序基于距离了。
A-D为最亮的光采用per-pixel渲染(默认4个);D-G为per-vertex最多受到的4个光;G-H为SH。重叠为尽可能防止light popping,若过渡出现问题先查看光组件render model、intensity,以及Quality Setting pixel light count,然后查看代码。
场景中的可见光源数目和计算复杂度是成线性增长,会影响vertex shader效率
Base Pass
Base pass用逐像素渲染的方向光以及所有SH和逐顶点光,可以实现效果:
- 光照贴图,但不会接受SH光
- 环境光、
- 自发光
- 可以有方向光阴影
注意:需要开启multi_compile_fwbase计算光照衰减; Pass若指定了OnlyDirectional标签,只接受renders main directional light, ambient/lightprobe and lightmaps,拒绝了所有SH和per-vertex光.
Additional Passes
Additional passes 计算其他影响物体的逐像素光照渲染物体,开启multi_compile_fwdadd 计算光照衰减。默认不支持绘制阴影,除非开启multi_compile_fwdadd _fullshadows指令。
Performance Considerations
Spherical Harmonics lights(SH球谐光照)非常高效。对CPU的消耗极其微小,对于GPU来说不会有额外的负担(因为base pass原本就会一直计算SH Lighting;和球谐光照的机制有关,无论有多少球谐光的存在,消耗都是一样的)。
SH光照的缺点:
- 利用物体的vertices进行计算,而不是pixels。因此不支持法线贴图和Light Cookies。
- SH光照函数是种非常低频的照明函数,不会有非常锐利的照明过渡,另外也只会响应Diffuse Lighting(漫反射),对于Specular Highlight(镜面高光)而言其频率太低了。
- SH lighting is not local; point or spot SH lights close to some surface will "look wrong". 球谐照明不是局部的,点光源或聚光灯形式的SH Light在靠近一些表面时看上去会不正常。
Deferred Shading path
正交投影不支持Deffered Shading(自动切换至Forward path),
优缺点:
- 优点:1光照的处理开销与光照的像素数量成正比,所有的光都按照per-pixel计算,极大提升渲染效果;2所有的光能允许cookies and shadwos;
- 缺点:1是对抗锯齿支持有限,2是不能处理半透明,3是对网格渲染器接收阴影和剔除遮罩支持有限,4对显卡有要求(支持MRT且支持Shader Model 3.0及上且支持Depth render textures)
Note:2006年后的pc图形卡都支持。mobile要求OpenGL ES 3.0以上。
g-buffer纹理数据格式
- RT0, ARGB32 format: Diffuse color (RGB), occlusion (A)没被使用.
- RT1, ARGB32 format: Specular color (RGB), roughness (A)存储高光反射的指数部分.
- RT2, ARGB2101010 format: World space normal (RGB), unused (A).
- RT3, ARGB2101010 (non-HDR) or ARGBHalf (HDR) format: 自发光 + 光照贴图 + 反射探针.
- Depth+Stencil buffer.
- RT4, ARGB32 format: Light occlusion values (RGBA).
G-Buffer pass
g-buffer pass对每个GameObject光照渲染一次。存储了漫反射和高光色、表面平滑度、世界空间法线、自发光+环境光+反射光+光照贴图到g-buffer空间纹理。g-buffer被设置为全局属性,后续以便着色器访问(CameraGBufferTexture0 ..CameraGBufferTexture3 names)
Lighting pass
- Lighting pass根据g-buffer和depth计算光照。光照是在屏幕空间下计算的,因此处理所需的时间与场景的复杂性无关。光照结果被添加到emission-buffer。
- Point and spot lights that do not cross the Camera’s near plane are rendered as 3D shapes,而是改为渲染成fullscreen quads,性能廉价。
Deferred Lighting path (Legency)
- Base Pass: 主要目的是得到具有深度、法线和高光等信息的screen-space buffers
- Lighting pass: 使用前一步的buffer信息来计算光照信息
- Final pass: 使用前一步光照信息,合成纹理颜色、环境光、lighting-map、或自发光色
Base Pass
Lighting pass
Final pass
Vertex Lit Rendering path
硬件支持范围广,性能好效果差。例如不支持shadows, normal mapping, light cookies, and highly detailed specular highlights
待补充
Forward path渲染案例-已补充
Deferred Shading 深入分析补充
Deferred Lighting深入分析补充
Tessellation深入分析补充