How to move from Graphics.DrawMeshInstanced to Graphics.RenderMeshInstanced

I am trying to convert a working Graphics.DrawMeshInstanced call to Graphics.RenderMeshInstanced.

I was hoping to eventually switch it to use a NativeArray that I populate from a burst Job, but I can’t get the RenderMeshInstanced call to work at all.

Anybody know the trick to it?

These 2 scripts results in exactly the same outcome while one is using Graphics.DrawMeshInstanced and the other Graphics.RenderMeshInstanced

194252-y5htj9io4hr9hhgrhiheuhp34hggj0w94340223465yohjidf

LetsDrawMeshInstanced.cs

using UnityEngine;

[ExecuteAlways]
public class LetsDrawMeshInstanced : MonoBehaviour
{
    [SerializeField] Mesh _mesh = null;
    [SerializeField] Material _material = null;
    Matrix4x4[] _matrices = new Matrix4x4[100];
    void Update ()
    {
        if( _mesh!=null && _material!=null )
        {
            UpdateMatrices();
            Graphics.DrawMeshInstanced( _mesh , 0 , _material , _matrices );
        }
    }
    void UpdateMatrices ()
    {
        Vector3 origin = transform.position;
        float time = Time.time;
        const float tau = Mathf.PI * 2f;
        int numMatrices = _matrices.Length;
        for( int i=0 ; i<numMatrices ; i++ )
        {
            float theta = (float)i / (float)(numMatrices-1) * tau;
            _matrices *= Matrix4x4.TRS(
                origin + new Vector3( 0 , Mathf.Sin(theta) , Mathf.Cos(theta) )*10f ,
                Quaternion.Euler( new Vector3(333f,10f,333f)*time ) ,
                Vector3.one
            );
        }
	}
}

LetsRenderMeshInstanced.cs

using UnityEngine;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using BurstCompile = Unity.Burst.BurstCompileAttribute;
 
[ExecuteAlways]
public class LetsRenderMeshInstanced : MonoBehaviour
{
	[SerializeField] Mesh _mesh = null;
	[SerializeField] Material _material = null;
	NativeArray<float4x4> _matrices;
	public JobHandle Dependency;
	void OnEnable ()
	{
		_matrices = new NativeArray<float4x4>( 100 , Allocator.Persistent );
	}
	void OnDisable ()
	{
		Dependency.Complete();
		if( _matrices.IsCreated ) _matrices.Dispose();
	}
	void Update ()
	{
		if( _mesh!=null && _material!=null )
		{
			// complete previous job
			Dependency.Complete();
 
			// render job results
			RenderParams rp = new RenderParams( _material );
			Graphics.RenderMeshInstanced( rp , _mesh , 0 , _matrices.Reinterpret<Matrix4x4>() );
 
			// schedule new job:
			var job = new UpdateMatrices{
				Origin			= transform.position ,
				Time			= Time.time ,
				NumMatrices		= _matrices.Length ,
				Matrices		= _matrices ,
			};
			Dependency = job.Schedule( _matrices.Length , 32 , Dependency );
		}
	}
 
	[BurstCompile]
	struct UpdateMatrices : IJobParallelFor
	{
		public float3 Origin;
		public float Time;
		public int NumMatrices;
		[WriteOnly] public NativeArray<float4x4> Matrices;
		void IJobParallelFor.Execute ( int i )
		{
			const float tau = math.PI * 2f;
			float theta = (float)i / (float)(NumMatrices-1) * tau;
			Matrices *= float4x4.TRS(
 				Origin + new float3( 0 , math.sin(theta) , math.cos(theta) )*10f ,
 				quaternion.Euler( math.radians(new float3(333f,10f,333f)*Time) ) ,
 				new float3(1,1,1)
 			);
 		}
 	}
 
 }

Ah, so I tried Built-In just now like you, and it’s working. I tried the same with URP and still no luck. I will dig around some more, but thank you for this and for including the job system example. I included a simplified version of LetsRenderMeshInstanced that works in Built-In but not URP for me.

using UnityEngine;

[ExecuteAlways]
public class LetsRenderMeshInstanced : MonoBehaviour
{
    [SerializeField] Mesh _mesh = null;
    [SerializeField] Material _material = null;
    Matrix4x4[] _matrices = new Matrix4x4[100];
    private RenderParams _renderParams;
    
    void Update()
    {
        if (_mesh != null && _material != null)
        {
            if (_renderParams.material != _material)
            {
                _renderParams.material = _material;
            }

            UpdateMatrices();
            Graphics.RenderMeshInstanced(_renderParams, _mesh, 0, _matrices);
        }
    }

    void UpdateMatrices()
    {
        Vector3 origin = transform.position;
        float time = Time.time;
        const float tau = Mathf.PI * 2f;
        int numMatrices = _matrices.Length;
        for (int i = 0; i < numMatrices; i++)
        {
            float theta = (float)i / (float)(numMatrices - 1) * tau;
            _matrices *= Matrix4x4.TRS(
                _origin + new Vector3(0, Mathf.Sin(theta), Mathf.Cos(theta)) * 10f,
                _Quaternion.Euler(new Vector3(333f, 10f, 333f) * time),
                Vector3.one
            );
        }
    }
}

Yep that fixed it and seems to have fixed my original project as well. Thanks!