10.补充知识-如何使用MaterialPropertyBlock
10.1 知识点
MaterialPropertyBlock的作用
- 在不复制、不改动共享材质资源的前提下,对某一个 Renderer 单独覆盖材质属性。
- 主要作用:
- 让同一材质的不同对象有不同的表现。
- 不会产生新的材质,节约内存。
- 并且如果和 GPU Instancing 的实例属性配合使用,可以做到表现不同 DrawCall 也不会增加。
注意
- MaterialPropertyBlock 的本质是让单个渲染器(Renderer)覆写材质参数。
- 从而避免新材质的实例化,从而节约一些内存,并且节约材质实例化和拷贝的开销。
- 相当于一份材质,多份参数。
- 具体它不和 DrawCall 的减少相关。
- 我们需要将它和 GPU Instancing 的实例属性配合使用才能做到不增加 DrawCall 的目的。
如何使用MaterialPropertyBlock
主要目的
- 能够在 C# 侧通过 MaterialPropertyBlock 设置材质属性,传递给 Shader。
主要思路
- 创建 MaterialPropertyBlock 对象,通过 Renderer 的 API 获取和设置属性块。
主要步骤
- new 一个 MaterialPropertyBlock 对象。
- 通过 Renderer 中的 API GetPropertyBlock 获取属性块。
- 利用 MPB 中的 Set 相关方法设置属性块中的变量。
- 通过 Renderer 中的 API SetPropertyBlock 将属性块传回 Renderer。
注意
- 属性块相关应用都是在 C# 侧完成的。
- 通过 C# 传递相关参数给到 Shader 中。
具体操作
new 一个 MaterialPropertyBlock 对象
//1.new 一个MaterialPropertyBlock对象
materialPropertyBlock = new MaterialPropertyBlock();
通过 GetPropertyBlock 获取属性块
- 通过 Renderer 中的 API GetPropertyBlock 获取属性块。
//2.通过Renderer中的API GetPropertyBlock获取属性块
Renderer renderer = this.GetComponentInChildren<Renderer>();
renderer.GetPropertyBlock(materialPropertyBlock);
利用 Set 方法设置属性块中的变量
- 可以直接传字符串,也可以传 id。
- 我们这样设置是因为我们在 Shader 中定义了 GPU 实例化属性缓冲区。
//3.利用MPB中的Set相关方法设置属性块中的变量 可以直接传字符串,也可以传id
materialPropertyBlock.SetVector("_Color", new Vector4(1, 1, 1, 1));
materialPropertyBlock.SetVector(_Pos_id, new Vector4(1, 1, 1, 1));
materialPropertyBlock.SetInt("_OffsetIndex", Random.Range(0, 50));
//注意 我们这样设置是因为我们在shader中定义了以下内容
// // ==================== GPU实例化属性缓冲区 ====================
// // 定义实例化参数组,每个物体实例可独立修改以下参数
// UNITY_INSTANCING_BUFFER_START(MrTao)
// // 实例化颜色:每个实例独立的颜色参数
// UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
// // 实例化位置:每个实例独立的位置偏移参数
// UNITY_DEFINE_INSTANCED_PROP(float4, _Pos)
// // 实例化偏移索引:用于区分不同实例的序号参数
// UNITY_DEFINE_INSTANCED_PROP(int, _OffsetIndex)
// UNITY_INSTANCING_BUFFER_END(MrTao)
通过 SetPropertyBlock 将属性块传回 Renderer
//4.通过Renderer中的API SetPropertyBlock将属性块传回Renderer
renderer.SetPropertyBlock(materialPropertyBlock);
10.2 知识点代码
MaterialPropertyBlockLearn.cs
using UnityEngine;
public class MaterialPropertyBlockLearn : MonoBehaviour
{
private MaterialPropertyBlock materialPropertyBlock;
int _Pos_id = Shader.PropertyToID("_Pos");
void Start()
{
#region 知识点一 MaterialPropertyBlock的作用
//在不复制、不改动共享材质资源的前提下
//对某一个Renderer单独覆盖材质属性
//主要作用:
//让同一材质的不同对象有不同的表现
//不会产生新的材质,节约内存
//并且如果和GPU Instancing的实例属性配合使用
//可以做到表现不同DrawCall也不会增加
//注意:
//MaterialPropertyBlock的本质是让当个渲染器(Renderer)覆写材质参数
//从而避免新材质的实例化,从而节约一些内存,并且节约材质实例化和拷贝的开销
//相当于一份材质,多份参数
//具体它不和DrawCall的减少相关
//我们需要将它和GPU Instancing的实例属性配合使用才能做到不增加DrawCall的目的
#endregion
#region 知识点二 如何使用MaterialPropertyBlock
//1.new 一个MaterialPropertyBlock对象
materialPropertyBlock = new MaterialPropertyBlock();
//2.通过Renderer中的API GetPropertyBlock获取属性块
Renderer renderer = this.GetComponentInChildren<Renderer>();
renderer.GetPropertyBlock(materialPropertyBlock);
//3.利用MPB中的Set相关方法设置属性块中的变量 可以直接传字符串,也可以现状id
materialPropertyBlock.SetVector("_Color", new Vector4(1, 1, 1, 1));
materialPropertyBlock.SetVector(_Pos_id, new Vector4(1, 1, 1, 1));
materialPropertyBlock.SetInt("_OffsetIndex", Random.Range(0, 50));
//注意 我们这样设置是因为我们在shader中定义了以下内容
// // ==================== GPU实例化属性缓冲区 ====================
// // 定义实例化参数组,每个物体实例可独立修改以下参数
// UNITY_INSTANCING_BUFFER_START(MrTao)
// // 实例化颜色:每个实例独立的颜色参数
// UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
// // 实例化位置:每个实例独立的位置偏移参数
// UNITY_DEFINE_INSTANCED_PROP(float4, _Pos)
// // 实例化偏移索引:用于区分不同实例的序号参数
// UNITY_DEFINE_INSTANCED_PROP(int, _OffsetIndex)
// UNITY_INSTANCING_BUFFER_END(MrTao)
//4.通过Renderer中的API SetPropertyBlock将属性块传回Renderer
renderer.SetPropertyBlock(materialPropertyBlock);
//注意:
//属性块相关应用都是在C#侧完成的
//通过C#传递相关参数给到Shader中
#endregion
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com