材质还是要开启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];#endifreturn o;}fixed4 frag (v2f i) : SV_Target{// sample the texturefixed4 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这个事情,可能用纹理可以绕过去