先上效果图,绘制5000个随机颜色的cube
Graphics.DrawMeshInstanced接口主要是需要传入(只说几个重要的)
1.mesh,模型,这里测试使用了预制件里面的MeshFilter.sharedMesh
2.material, 材质,使用了MeshRenderer.sharedMaterials
3.int count,这里是绘制mesh数量的意思
4.Matrix4x4[] matrices,需要绘制的count个数量的模型的Matrix4x4,可以理解为Matrix4x4[count]
5.MaterialPropertyBlock properties,count个数量的模型的材质属性,传入shader使用
//使用SetFloatArray传入到shader中, 使用3个数组 _testRed, _testGreen _testBlue
//C#代码
matPropBlock.SetFloatArray("_testRed", testRed);
matPropBlock.SetFloatArray("_testGreen", testGreen);
matPropBlock.SetFloatArray("_testBlue", testBlue);
/*---------我是坑爹的分割线---------*/
//unlit shader 要注意的地方
//...省略
#pragma multi_compile_instancing
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
//添加一处
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
//添加一处
UNITY_VERTEX_INPUT_INSTANCE_ID
};
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_DEFINE_INSTANCED_PROP(float, _testRed)
#define propTestRed Props
UNITY_DEFINE_INSTANCED_PROP(float, _testGreen)
#define propTestGreen Props
UNITY_DEFINE_INSTANCED_PROP(float, _testBlue)
#define propTestBlue Props
UNITY_INSTANCING_BUFFER_END(Props)
v2f vert (appdata v)
{
v2f o;
//这里添加
UNITY_SETUP_INSTANCE_ID(v);
//这里添加
UNITY_TRANSFER_INSTANCE_ID(v, o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
// 这里添加,UNITY_SETUP_INSTANCE_ID调用是为了使用INSTANCE_ID作为数组下标访问
// 类似propTestRed[INSTANCE_ID],不然死活访问不到数组的其他元素,只能访问第一个
UNITY_SETUP_INSTANCE_ID(i);
float r = UNITY_ACCESS_INSTANCED_PROP(propTestRed, _testRed);
float g = UNITY_ACCESS_INSTANCED_PROP(propTestGreen, _testGreen);
float b = UNITY_ACCESS_INSTANCED_PROP(propTestBlue, _testBlue);
fixed4 color;
color.r = r;
color.g = g;
color.b = b;
color.a = 1.0f;
return col * color;
}
如果是surface shader的话就可以不用设置
UNITY_VERTEX_INPUT_INSTANCE_ID,UNITY_SETUP_INSTANCE_ID,UNITY_TRANSFER_INSTANCE_ID
就可以通过设置定义UNITY_DEFINE_INSTANCED_PROP, 通过UNITY_ACCESS_INSTANCED_PROP访问了
其实都是比较简单的原理,就是通过setfloatarry把数据传到shader里面,但怎么才能生效才是比较坑,参考一下官方示例就好了
Graphics.DrawMeshInstanced最大进行1023个绘制, MaterialPropertyBlock 最大也是1023个,
如果是5000个的话绘制的话,需要自己按1023个分割,多调用几次Graphics.DrawMeshInstanced(这么简单,不用说了吧)