材质还是要开启enable instance,这是上一次的写法
https://dbbh666.blog.csdn.net/article/details/136644181
最近发现更适合我个人的习惯的写法
就是代码控制这个整个过程
C#代码是这样的,获取一个mesh,获取每个mesh的transform,核心就完了,我这里是场景里的cube的mesh取来直接使用
using UnityEngine;
public class DrawMeshInstancedDemo : MonoBehaviour
{
// Material to use for drawing the meshes.
public Material material;
private Matrix4x4[] matrices;
//private MaterialPropertyBlock block;
private Mesh mesh;
private void Setup()
{
float range = 100.0f;
int population = 1023;
//Mesh mesh = CreateQuad();
GameObject gameObject = GameObject.Find("Cube");
MeshFilter mf = gameObject.GetComponent<MeshFilter>();
this.mesh = mf.mesh;
matrices = new Matrix4x4[population];
//Vector4[] colors = new Vector4[population];
//block = new MaterialPropertyBlock();
for (int i = 0; i < population; i++)
{
Vector3 position = new Vector3(Random.Range(-range, range), Random.Range(-range, range), Random.Range(-range, range));
Quaternion rotation = Quaternion.Euler(Random.Range(-180, 180), Random.Range(-180, 180), Random.Range(-180, 180));
Vector3 scale = Vector3.one;
matrices[i] = Matrix4x4.TRS(position, rotation, scale);
}
// Custom shader needed to read these!!
//block.SetVectorArray("_Colors", colors);
}
private void Start()
{
Setup();
}
private void Update()
{
// Draw a bunch of meshes each frame.
Graphics.DrawMeshInstanced(mesh, 0, material, matrices, 1023 /*block*/);
}
}
然后就是shader,有几点要注意的
pragma这里有个#pragma multi_compile_instancing
宏有这几个
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_SETUP_INSTANCE_ID(i)
#ifdef UNITY_INSTANCING_ENABLED //o.color = _Colors[instanceID];
#endif
这几个宏,都要放在对的位置,才能获取正确的变量
`Shader “Unlit/instance”
{
Properties
{
_MainTex (“Texture”, 2D) = “white” {}
}
SubShader
{
Tags { “RenderType”=“Opaque” }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
// make fog work
//#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float2 uv : TEXCOORD0;
//UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
// float4 _Colors[1023]; // Max instanced batch size.
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata_t i, uint instanceID: SV_InstanceID) {
// Allow instancing.
UNITY_SETUP_INSTANCE_ID(i);
v2f o;
//UNITY_TRANSFER_FOG(o,o.vertex);
o.vertex = UnityObjectToClipPos(i.vertex);
o.uv = i.uv;
// If instancing on (it should be) assign per-instance color.
#ifdef UNITY_INSTANCING_ENABLED //o.color = _Colors[instanceID];
#endif
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);
col.gb=fixed2(0.2,0.2);
return col;
}
ENDCG
}
}
}
`
这样创建一个空对象,把C#脚本挂上去即可
看效果,最中间那个是原始cube,其他的都是instance搞出来的
需要注意的地方是1023这个事情,可能用纹理可以绕过去