DrawMeshInstanced not working with transparent

Guessing it’s not getting injected correctly as it is making it into the pipeline in some form. Wireframe shading shows it. If I set transparent depth prepass I see depth written. Otherwise no evidence it’s there. Frame debugger isn’t showing any draw calls for it that I can see. Nothing in forward or transparent sections.

Like this in both Lit/Unlit templates.

HDRP 10.3, Unity 2020.2.7f1.

Ok so found another thread going back a year same issue.

Just tested instanced indirect also same issue.

Seriously Unity wtf. The hoops I’m going to have to jump through here to get transparent water I really shouldn’t have to. This is staple stuff in PC games.

Hi, we are aware that Transparent Material are not working with drawMeshInstanced at the moment.
It is a weird side effects related to transparent motion vector which discard the object in this pass in HDRP. We are working on fixing this issue.

I just spent an hour trying to figure out why my mesh is only rendering shadows using Graphics.DrawMeshInstanced with HDRP. When I call Graphics.DrawMesh, everything works fine (but it’s slow), but with DrawMeshInstanced I only get shadows. On a lark, I thought “hey, what happens if I switch the material from Transparent to Opaque?”. Bam! Suddenly my meshes start showing up with Graphics.DrawMeshInstanced. I thought, “that’s bizarre…” A quick Google search for “unity drawmeshinstanced transparent” lands me on this post.

It’s been over 3 months since @SebLagarde said that Unity was aware of the issue and they’re working on a fix. Is this fixed yet? Or is this still broken? It looks like it’s still broken for 2020.3.12f1 / HDRP 10.5, but perhaps I’m experiencing a totally different but very similar bug? Or maybe it just hasn’t been fixed yet.

Also, if it isn’t fixed yet, is it going to be fixed for 2020.3 LTS (i.e. HDRP 10.x) or only 2021.x (HDRP 11/12)? And is there a timeline for when it might get fixed? I’m not looking for a date, just an idea of whether I might need to wait a few weeks or if I should start looking for a totally different solution to what I’m trying to do.

@snacktime Did you ever end up with a work around/solution for this? If you did it would be great if you don’t mind sharing it. Thanks!

Is there a bug ticket for this so that we can track it?

I’m using 2019.4.17 and HDRP 7.5.2 and this bug is still not fixed. It’s over 5 months.

Hi this bug have been fixed for 21.2b1 but not backport are plan (the fix is not trivial).
Fogbugzz is here: https://fogbugz.unity3d.com/f/cases/1244719/ (not sure if it is publicly accessible).

If it’s not gonna be backported, could you please maybe suggest some workaround for us? What’s some other ways to draw large amount of the same mesh with transparent material in HDRP?

I can provide some details, maybe there is a workaround but haven’t tested it.

The root cause of the issue is (copy/pasting information from the fogbugzz:

"In order to render transparent motion vectors, we always request PerObjectData.MotionVectors on the render list. This is regardless of whether the option is set on the material or not; the reason is that we cannot control that at a granular level.

This in turns disables instancing on transparent objects and because we cannot control what the user calls (i.e. DrawMeshInstanced) we cannot disable it on HDRP side and it will result in nothing rendering in those cases.

This is because when creating a BatchRenderer in C++ instancing is disabled if we are in a loop writing motion vectors
, kInstancingEnabled(instancingEnabled && !motionVectorLoop && Instancing::IsEnabled())"

So to solve the issue we have currently implemented the support of instance motion vector in Unity (for builtin and srp) thus why it is not trivial to backport, it is a feature.

Now for the workaround. If we disable the addition of PerObjectData.MotionVectors to renderList, then it should works.

in our latest code this is control like this:

if (NeedMotionVectorForTransparent(hdCamera.frameSettings))
{
m_CurrentRendererConfigurationBakedLighting |= PerObjectData.MotionVectors; // This will enable the flag for low res transparent as well
}

So disabling motion vector support for transparent objects in FrameSettings should works. But I haven’t tested it.

I tested this. And it’s not working. I disabled the “Transparent Object Motion” in Frame Settings Overrides, but the meshes were not drawn.

I tried another way by calling drawmeshinstanced in custom pass with an opaque material. And use an injection point after opaque so that I can sample the camera color buffer to fake transparency. The problem is, according to frame debugger, although the meshes are drawn, they are not instanced, which significantly lower the frame rate. Is there any rules to drawmeshinstanced as to where in the render pipeline it must be called, or else it won’t actually instance the meshes?

hmm… Random thinking, you may have to disable SRP batcher for GPU instancing to work.
GraphicsSettings.useScriptableRenderPipelineBatching = m_Asset.enableSRPBatcher;

It doesn’t feel like it’s SRP batcher related. Because if I call Graphics.Drawmeshinstanced in update, it works fine (except for that transparency bug and not being able to sample scene color behind). But if I call Graphics.Drawmeshinstanced in a custom pass, then the meshes are not instanced at all.

@SebLagarde , is there any progress or update on this? This has been fixed in 2021.2b1 as per your post in August?
Are there still no plans for backporting this to 2020.3 LTS?

I’m on 2020.3.17f1 and this also does not work.

I upgraded to Unity 2021.2.7f1, HDRP+Shader Graph 12.1.2, and can confirm that DrawMeshInstanced does work for Transparent materials now.

For those that can afford to upgrade, doing so seems to be a clean fix.

2 Likes

I am Using 2022.3.25f1 Still GPU instancing for transparent materials is not working