I think this demonstrates the point. Can anyone spot any obvious mistakes and/or is it reproducible on other systems?
It follows the pattern of the example if you want to try it for yourselves.
With iArgOffset set to 0, I expect to see a green and red mesh, set to 1 a green and cyan mesh if unityInstanceID is behaving as expected but I actually get green and red in both cases.
TestBehaviourScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestBehaviourScript : MonoBehaviour {
public Mesh instanceMesh;
public Material instanceMaterial;
public int iArgOffset = 0;
private ComputeBuffer argsBuffer;
private uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
// Use this for initialization
void Start () {
argsBuffer = new ComputeBuffer(2, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
UpdateBuffers();
}
// Update is called once per frame
void Update () {
int argsOffset = iArgOffset * 4 * 5;
Graphics.DrawMeshInstancedIndirect(instanceMesh, 0, instanceMaterial, new Bounds(Vector3.zero, new Vector3(10000.0f, 10000.0f, 10000.0f)), argsBuffer, argsOffset);
}
void UpdateBuffers()
{
uint[] argssum = new uint[2 * 5];
// indirect args
uint numIndices = (instanceMesh != null) ? (uint)instanceMesh.GetIndexCount(0) : 0;
argssum[0] = numIndices;
argssum[1] = 2;
argssum[2] = 0;
argssum[3] = 0;
argssum[4] = 0;
argssum[5] = numIndices;
argssum[6] = 2;
argssum[7] = 0;
argssum[8] = 0;
argssum[9] = 1;
argsBuffer.SetData(argssum);
}
void OnDisable()
{
if (argsBuffer != null)
argsBuffer.Release();
argsBuffer = null;
}
}
TestInstancedSurfaceShader.shader
Shader "Instanced/TestInstancedSurfaceShader" {
Properties{
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
}
SubShader{
Tags{ "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model
#pragma surface surf Standard addshadow
#pragma multi_compile_instancing
#pragma instancing_options procedural:setup
sampler2D _MainTex;
float4 col;
struct Input {
float2 uv_MainTex;
};
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
#endif
void setup()
{
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
col = float4(0, 0, 1, 1.0);
if (unity_InstanceID == 0)
{
col = float4(1, 0, 0, 1.0);
unity_ObjectToWorld._14_24_34_44 = float4(0, 1, 4, 1.0f);
}
else if (unity_InstanceID == 1)
{
col = float4(0, 1, 0, 1.0);
unity_ObjectToWorld._14_24_34_44 = float4(1.5, 1, 4, 1.0f);
}
else
{
col = float4(0, 1, 1, 1.0);
unity_ObjectToWorld._14_24_34_44 = float4(-1.5, 1, 4, 1.0f);
}
unity_ObjectToWorld._11_21_31_41 = float4(1, 0, 0, 0.0f);
unity_ObjectToWorld._12_22_32_42 = float4(0, 1, 0, 0.0f);
unity_ObjectToWorld._13_23_33_43 = float4(0, 0, 1, 0.0f);
float3x3 w2oRotation;
w2oRotation[0] = unity_ObjectToWorld[1].yzx * unity_ObjectToWorld[2].zxy - unity_ObjectToWorld[1].zxy * unity_ObjectToWorld[2].yzx;
w2oRotation[1] = unity_ObjectToWorld[0].zxy * unity_ObjectToWorld[2].yzx - unity_ObjectToWorld[0].yzx * unity_ObjectToWorld[2].zxy;
w2oRotation[2] = unity_ObjectToWorld[0].yzx * unity_ObjectToWorld[1].zxy - unity_ObjectToWorld[0].zxy * unity_ObjectToWorld[1].yzx;
float det = dot(unity_ObjectToWorld[0], w2oRotation[0]);
w2oRotation = transpose(w2oRotation);
w2oRotation *= rcp(det);
float3 w2oPosition = mul(w2oRotation, -unity_ObjectToWorld._14_24_34);
unity_WorldToObject._11_21_31_41 = float4(w2oRotation._11_21_31, 0.0f);
unity_WorldToObject._12_22_32_42 = float4(w2oRotation._12_22_32, 0.0f);
unity_WorldToObject._13_23_33_43 = float4(w2oRotation._13_23_33, 0.0f);
unity_WorldToObject._14_24_34_44 = float4(w2oPosition, 1.0f);
#endif
}
half _Glossiness;
half _Metallic;
void surf(Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = col.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = 1.0f;
}
ENDCG
}
FallBack "Diffuse"
}