Access SV_InstanceID (NOT unity_InstanceID) in Shader Graph when using RenderPrimitivesIndexedIndirect

Hi,

I am using Graphics.RenderPrimitivesIndexedIndirect to render meshes.
All mesh data is stored in de-interleaved GraphicsBuffers (position, compressed normals/tangents, UVs, etc.).
Culling is done on the GPU via compute shaders.
For the last 3 years we used a custom SRP but now i want to port our stuff over to URP.

I want to make use of ShaderGraph during the porting process, so our (tech-)artists can use it in the future.
However, as it turns out, i can’t access SV_InstanceID in ShaderGraph. The shadergraph’s InstanceID-Node uses unity_InstanceID, which is NOT what i want.
(When using Graphics.RenderPrimitivesIndexedIndirect, unity_InstanceID is not available and you have to directly use SV_InstanceID instead. At least thats how we did it for the last 3 years.)

How can i access SV_InstanceID in ShaderGraph?
My current workaround is to open the shader that is generated by shadergraph, then manually patch the shader to use SV_InstanceID instead of unity_InstanceID. This works, but is a VERY time consuming process as i have to redo it every time i touch a shadergraph-shader…

(Please don’t tell me this is impossible / still missing from shadergraph / planned … :melting_face: )

Hi,

Looks like you need to create your own Universal SubTarget with all features you need
like this: GitHub - Zallist/unity.zallist.universal-simple-lit-shadergraph-target: This plugin simply adds a Simple Lit material (SubTarget) to the Universal target for Shader Graph for URP

I went the hammer and crowbar way and wrote a small patcher/tool that adds support for:

  • SV_InstanceID instead of unity_InstanceID when using the InstanceID-node
  • nointerpolation attribute for Interpolators/Vertexshader output

If anyone needs it, you can get it here

I still hope that Unity will add these features to shadergraph in the future as Graphics.RenderPrimitivesIndexedIndirect is not useable with shadergraph without them.

2 Likes

Updated the patcher

Support for uint, int, min16uint and min16int vertex input attributes.
i.e. "float4 uv2 : TEXCOORD2;" becomes "min16uint4 uv2 : TEXCOORD2;".
NOTE: This will **ONLY** patch vertex INPUT!
All other nodes/code will not be affected. 

With a Custom function node, you can write hlsl function.
Maybe something like this in the vertex shader stage.

#if UNITY_ANY_INSTANCING_ENABLED
 out = UNITY_GET_INSTANCE_ID(input);
#else
 out = 0;
#endif