Unity DrawMeshInstancedIndirect not working in Hololens2 with Single Pass Instanced Rendering

Matt Bolger 6 Reputation points
2022-03-07T02:00:50.18+00:00

Using the DrawMeshInstancedIndirect sample code from the Unity docs on a clean 2020.3.30f1 OpenXR project following the recommended Hololens2 project setup and the instance geometry is only rendered in the left eye while normal models are rendered correctly in both. Appears to be an issue with the Single Pass Stereo Rendering being used with this. Any suggestions on how to fix this (without resorting to slow multi-pass rendering)?

HoloLens Development
{count} votes

1 answer

Sort by: Most helpful
  1. Matt Bolger 6 Reputation points
    2022-03-09T11:02:05.487+00:00

    Thanks for the response again @Hernando Ren , you were correct that the DrawMeshInstancedIndirect sample code was missing a couple of the macros for Single-Pass Instanced but even with these added the behaviour was consistent with the issue in my original StackOverflow post that was using a custom shader including the required macros.
    After digging into what UNITY_SETUP_INSTANCE_ID (https://github.com/TwoTailsGames/Unity-Built-in-Shaders/blob/master/CGIncludes/UnityInstancing.cginc) was doing and much painful experimentation, it turns out I was correct that the note in the docs “Therefore you will have to manually double the instance count contained in your compute buffers.” was indeed a clue (aka the answer). In the case of stereo instance rendering, the per-instance buffers need to be twice as long and duplicated (interlaced) to render for each eye (for each instance of the geometry being rendered). The unity_StereoEyeIndex is calculated as inputInstanceID & 0x01 so you need

    Computebuffer[0] // matrix for instance 0 left eye  
    Computebuffer[1] // matrix for instance 0 right eye (ie. Duplicate of Computebuffer[0])  
    Computebuffer[2] // matrix for instance 1 left eye  
    Computebuffer[3] // matrix for instance 1 right eye (ie. Duplicate of Computebuffer[2])  
    …  
    Computebuffer[instanceCount *2]  
    

    The call to DrawMeshInstancedProcedural or the count buffer argument to DrawMeshInstancedIndirect should also use a count 2 * the number of instances you’re rendering in the scene.

    This is at least the conclusion I've drawn from looking at the macro code and having made these changes to my buffer generation code which has resulted in the instances all rendering correctly in single-pass which is great! Having said that, do let me know if any aspect of this doesn't sound correct.

    1 person found this answer helpful.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.