自底向上的SRP教程 II
Draw Call
对 Catlike Coding 教程的解析与补充
1.防止重复声明
1 |
|
#include引入HLSL时会将所有内容插入,且允许多次或循环引用,这会导致编译错误,可以通过这种方式对着色器代码进行保护。在定义宏之前先判断时候定义过该标示符,如果定义过,直接调到#endif段后。这样就可以保证只有第一次#include时有效
2.SRP Batcher
- SRP批处理
目的是减少Set Pass Call,他将模型的坐标信息、材质信息、光源阴影等参数保存到不同的常量缓冲区(CBUFFER),只有CBUFFER发生变化时才会重新提交到GPU并保存1
2
3
4
5
6
7
8
9
10CBUFFER_START(UnityPerMaterial)
float4 _BaseColor;
CBUFFER_END
CBUFFER_START(UnityPerDraw)
float4x4 unity_ObjectToWorld;
float4x4 unity_WorldToObject;
float4 unity_LODFade;
real4 unity_WorldTransformParams;
CBUFFER_END
- UnityPerMaterial:所有材质相关的数据都应该在名为 UnityPerMaterial 的 CBUFFER 中声明,通常是指在着色器属性块声明的变量
- UnityPerDraw:该 CBUFFER 应当包含所有 Unity 的内置引擎变量
- 开启SRP合批一般写在构造函数中
1
2
3
4public CustomRenderPipeline()
{
GraphicsSettings.useScriptableRenderPipelineBatching = true;
}
Tips: real4只是个别名,具体可能是float4或half4,这取决于目标平台
3.同材质设置不同颜色
1 |
|
- DisallowMultipleComponent防止脚本被多次添加
- Shader.PropertyToID 获取着色器属性名称的唯一标示符(Unity为着色器的每个属性都分配唯一整数)
- MaterialPropertyBlock 绘制相同材质但属性不同的对象可以用该类 Renderer组件下有SetPropertyBlock方法来设置block
- OnValidate 在以下两种情况下被调用:
- 脚本被加载时
- Inspector中有值被修改时
4.GPU Instancing
- GPU多例化
能够在一个绘制调用中渲染多个具有相同网格的物体,CPU收集每个物体的材质属性和变换放入数组发送到GPU,GPU拿到数组后顺序遍历渲染 - 开启添加指令后材质面板就可以看到开关
1
#pragma multi_compile_instancing
- 应用
绘制许多网格小球(无需生成多个对象,只填充变换)1
2
3
4
5
6
7Matrix4x4[] matrices = new Matrix4x4[1023];
for(int i = 0; i < matrices.Length; i++)
{
matrices[i] = Matrix4x4.TRS(Random.insideUnitSphere * 10f, Quaternion.Euler(Random.value * 360f, Random.value * 360f, Random.value * 360f), Vector3.one * Random.Range(0.5f, 1.5f));
baseColors[i] = new Vector4(Random.value, Random.value, Random.value);
}
- Matrix4x4.TRS(Vector3 translation, Quaternion rotation, Vector3 scaling)创建平移、旋转、缩放矩阵
1
2
3
4
5
6
7
8
9private void Update()
{
if (block == null)
{
block = new MaterialPropertyBlock();
block.SetVectorArray(baseColorId, baseColors);
}
Graphics.DrawMeshInstanced(mesh, 0, material, matrices, 1023, block);
} - SetVectorArray 设置向量数组属性
- Graphics.DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material, Matrix4x4[] matrices, int count= matrices.Length, MaterialPropertyBlock properties = null) submeshIndex适用于若干材质构成的网格,选择要绘制网格的哪个子集。
5.混合模式
- Src 当前需要渲染的像素(上层图像)
- Dst 已在栈中的像素(已有图像)常用混合模式:
1
2
3
4
5
6// 设置混合模式
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend", Float) = 1
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend", Float) = 0
// 定义混合模式
Blend[_SrcBlend][_DstBlend] - BlendOp Min Blend One One(变暗)
- BlendOp Max Blend One One(变亮)
- Blend SrcAlpha OneMinusSrcAlpha(正常/透明度混合)
- Blend OneMinusDstAlpha One(滤色/柔和相加)
- Blend One OneMinusSrcAlpha(同上)
- Blend DstColor Zero(相乘/正片叠加)
- Blend DstColor SrcColor(两倍相乘)
- Blend One One(线性减淡)
(下接 自底向上的SRP教程 III)
自底向上的SRP教程 II
https://baifabaiquan.cn/2023/04/14/自底向上的SRP教程II/