文章目录
- 前言
- 一、优化前是对使用了相同材质球的不同物体间shader分别设置,比较消耗性能
- 二、使用[PerRendererData]标签,可以在脚本中使用SetPropertyBlock()对使用同一材质球的不同物体进行修改其Shader属性
前言
Unity中Shader特性PerRendererData
一、优化前是对使用了相同材质球的不同物体间shader分别设置,比较消耗性能
这里在shader中使用一个Color属性进行测试
Shader"MyShader/P1_1_3"
{Properties{//命名要按标准来,这个属性才可以和Unity组件中的属性产生关联//比如说,在更改 Image 的源图片时,同时更改这个[PerRendererData]_MainTex("MainTex",2D) = "white"{}[PerRendererData]_Color("Color",color) = (1,1,1,1)}SubShader{//更改渲染队列(UI的渲染队列一般是半透明层的)Tags {"Queue" = "TransParent"}//混合模式Blend SrcAlpha OneMinusSrcAlphaPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"//存储 应用程序输入到顶点着色器的信息struct appdata{//顶点信息float4 vertex:POSITION;float2 uv : TEXCOORD;};//存储 顶点着色器输入到片元着色器的信息struct v2f{//裁剪空间下的位置信息float4 pos:SV_POSITION;float2 uv : TEXCOORD;};sampler2D _MainTex;fixed4 _Color;v2f vert(appdata v){v2f o;//把顶点信息转化到裁剪坐标下o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}fixed4 frag(v2f i) : SV_Target{fixed4 mainTex = tex2D(_MainTex,i.uv);return mainTex * _Color;}ENDCG}}
}
测试脚本
public class ShaderMaterialPropertyBlockTest : MonoBehaviour{[Header("生成的对象")] public GameObject gameObj;[Header("生成数量")] public int count = 100;[Header("生成范围")] public float range = 10;private GameObject [] gameObjects;private MaterialPropertyBlock prop;void Start(){gameObjects = new GameObject[count];prop = new MaterialPropertyBlock();for (int i = 0;i < count;i++) {//随机位置并生成对象Vector2 pos = Random.insideUnitCircle * range;GameObject go = Instantiate(gameObj, new Vector3(pos.x, 0, pos.y),Quaternion.identity);gameObjects[i] = go;}}void Update(){//优化前,直接修改Shader中暴露的属性for (int i = 0;i < gameObjects.Length;i++){float r = Random.Range(0f,1f);float g = Random.Range(0f,1f);float b = Random.Range(0f,1f);Color newColor = new Color(r, g, b, 1);gameObjects[i].GetComponentInChildren<MeshRenderer>().material.SetColor("_Color",newColor);}}}
效果(window->Analysis->Profilte):
二、使用[PerRendererData]标签,可以在脚本中使用SetPropertyBlock()对使用同一材质球的不同物体进行修改其Shader属性
测试脚本
public class ShaderMaterialPropertyBlockTest : MonoBehaviour{[Header("生成的对象")] public GameObject gameObj;[Header("生成数量")] public int count = 100;[Header("生成范围")] public float range = 10;private GameObject [] gameObjects;private MaterialPropertyBlock prop;void Start(){gameObjects = new GameObject[count];prop = new MaterialPropertyBlock();for (int i = 0;i < count;i++) {//随机位置并生成对象Vector2 pos = Random.insideUnitCircle * range;GameObject go = Instantiate(gameObj, new Vector3(pos.x, 0, pos.y),Quaternion.identity);gameObjects[i] = go;}}void Update(){//优化前,直接修改Shader中暴露的属性/*for (int i = 0;i < gameObjects.Length;i++){float r = Random.Range(0f,1f);float g = Random.Range(0f,1f);float b = Random.Range(0f,1f);Color newColor = new Color(r, g, b, 1);gameObjects[i].GetComponentInChildren<MeshRenderer>().material.SetColor("_Color",newColor);}*///优化后,使用MaterialPropertyBlock方案//该方案需要在Shader暴露属性中加上 [PerRendererData] 标签//这个是配合 SetPropertyBlock(prop);来使用的//这个可以用来更改同样材质球,都是不同物体的Shader属性for (int i = 0;i < gameObjects.Length;i++){float r = Random.Range(0f,1f);float g = Random.Range(0f,1f);float b = Random.Range(0f,1f);Color newColor = new Color(r, g, b, 1);var mr = gameObjects[i].GetComponentInChildren<MeshRenderer>();mr.GetPropertyBlock(prop);prop.SetColor("_Color",newColor);mr.SetPropertyBlock(prop);}}}
优化后效果: