I use batchrenderergroup to display a large number of instances.
And for me that’s a problem, because I need to allocate a large useless buffer of many IndirectDrawArgs, juste to have a different instancecount and set indirectArgsBufferOffset in my command.
Actually I even don’t need this visible feature, all I need is an offset and a count to set my command, because my batch is already well sorted in a quadtree with z-order curve sorting.
So my question is, is there a more optimized way to draw just a range of my batch in a command?
Using Unity 6.0 URP directx12 on Windows 11
Also tried visibleInstancesBufferWindowOffset and visibleInstancesBufferWindowSizeBytes, but it seems they can’t be used with raw buffer, only constant. And I don’t know how to put visibles in a constant buffer.
Hi! You’re right in saying there’s a CPU cost in sending the visibles array to GPU, as we send the rendering layer mask, flags and mesh bounds per visible instance to the GPU each frame, but the fact that it’s crashing for an instance count > 100000 is definitely a bug and I think you should file this with a repro project, if that’s not too much of a problem.
Let me try to rephrase your use case to be sure I understand correctly. You’ve created a number of instances in your batches in your BatchRendererGroup (BRG’s AddBatch) in a specific order using a quadree and z-order curve sorting. During the OnPerformCulling phase, the only thing to do is to determine the range of instances in each batch to use for drawing for a particular culling split, as there are no “holes” in that list. This is why the visibles array is not really necessary in your case. So ideally you would like a BRG draw command that only contains “I want to draw N instances in my batch starting at instance offset K”.
Unfortunately, just sending a range as you mentioned would imply that you create your own shaders to access a per instance properties as right now this always assumes there’s an indirection through the visibility buffer. So right out of the box, that’s not possible, unless you feel up to the task.
I would agree that BatchDrawCommandIndirect seems like the better option, although instead of allocating a large IndirectDrawArgs bug with all possible ranges and offet (which I understand is the intent), I would maybe try an option with a compute shader that updates a single element indirect draw args with the correct range in your visibilty buffer (or a modified shader, again, that shortcuts that). The question is now how to insert that compute shader dispatch before each view setup, especially during shadow rendering. If you are using a single camera, you could issue a Graphics.ExecuteCommandBuffer with a compute dispatch added in that command buffer, as this would issue the dispatch at each frame. But if you have multiple cameras or want to have correct “culling” for shadows as well, this will be complicated short of adding this before each meaningfull draw pass in URP / HDRP. Not mentioning that you might as well do just a simple Graphics.RenderMeshPrimitives instead of using a BRG in the case of having just a single camera and not wanting to do a special culling for shadows.
As for visibleInstancesBufferHandle only working with ConstantBuffers, that should not be the case. You can check out the InstanceOcclusionCuller class that is used why GPUResidentDrawer of an example using a structured buffer.
Thanks for the answer. You’ve perfectly understood my case. And my API need 
I appreciate your proposals, I though about things like that, for example using raw commandbuffer instead of BatchrenderGroup. But like you said it’s a bit more complicated (I need shadow mapping), and my time is not unlimited 
Perhaps later if can I’ll try writing my own shader for instancing. For now I’ll only modify the URP lit to manage large open world with scene offset (to avoid processing my matrix each time scene is offseted).
Is the batchrenderergroup source code where visibles is processed open and readable somewhere on github?
Or is there some documentation about writting a custom instanciation like batchrenderergroup?
However I in the mean time Unity decides to add this count/offset API as an alternative to the visible one, I would be very happy.
For the constant buffer problem, it only happens when visibleInstancesBufferWindowOffset or visibleInstancesBufferWindowSizeByt are not set to 0, Unity then log an error about buffer must be constant.
Unfortunately not on both these questions. BatchRendererGroup is in the C++ engine code and doing a similar mechanism purely in C# seems impossible if you want to cover shadow map rendering, short of modifying URP or HDRP, as mentioned before. Unless, and this would need to be checked by someone on the URP team, you could get away with adding some Scriptable Render Pass in URP. It’s definitely possible to draw objects from the camera view, but I’m not sure you can render to shadow maps. I’ll ask around. In which case, you could do everything by pushing some draw commands in command buffers without going through a BRG.
Yeah so it is indeed not possible to render to the existing shadow maps using Scriptable Render Passes, so you would have to implement your own system.