使用Graphics.DrawMeshInstanced进行gpu instancing绘制

先上效果图,绘制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(这么简单,不用说了吧)

 

参考https://zhuanlan.zhihu.com/p/34499251

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值