I initially tried using Graphics.RenderPrimitives with a custom shader and it worked perfectly.
Similar to what’s shown in the documentation for render primitives, setting the Graphic Buffers in MaterialPropertyBlock made the StructuredBuffer accessible via custom shader.
Now, I started porting it to Shader Graph with the #pragrma instance_options procedural:funcName hack to enable instancing in shader graph.
But even I added the required StructuredBuffers, nothing is shown. I see in the FrameDebugger that the buffer’s are not listed at all.
I even set the buffers via material but still same issue.
Any clues on how to proceed or debug this further?
Below code is the custom shader function added as a file in Shader Graph.
_Triangles, _Vertices, _Transforms all created from a GraphicsBuffer as StructuredData
var trianglesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Index, mesh.triangles.Length, sizeof(int));
...
rParams.matProps.SetBuffer("_Triangles", trianglesBuffer);
#include "./ConfigureInstancing.hlsl"
#ifndef SETUP_INSTANCE_DATA_FOR_RENDER_PRIMITIVES_INCLUDED
#define SETUP_INSTANCE_DATA_FOR_RENDER_PRIMITIVES_INCLUDED
StructuredBuffer<int> _Triangles; //Indices
StructuredBuffer<float3> _Vertices;
StructuredBuffer<float4x4> _Transforms;
StructuredBuffer<float> _RandomValues;
uint _StartIndex;
uint _BaseVertexIndex;
float _NumInstances;
//position in world space
//tag for giving a random value per instance
void GetInstanceData_float(in float vertexId, out float3 position, out float tag)
{
position = 0;
tag = 0;
#if UNITY_ANY_INSTANCING_ENABLED
float instanceId = unity_InstanceID;
float3 pos = float3(_Vertices[_Triangles[vertexId + _StartIndex] + _BaseVertexIndex]);
position = mul(_Transforms[instanceId], float4(pos, 1.0f)).xyz;
tag = _RandomValues[instanceId];
#endif
}
#endif
#ifndef CONFIGURE_INSTANCING_INCLUDED
#define CONFIGURE_INSTANCING_INCLUDED
// use #pragma instancing_options procedural:vertInstancingSetup to setup unity_InstanceID & related macro, what vertInstancingSetup do are actually not important
#if UNITY_ANY_INSTANCING_ENABLED
void ConfigureInstancing() {
}
#endif
#endif
I’ve made a procedural lightning effect before and passed colors and other attributes to shader graph per instance. Looks like the same of your method.
Thanks for sharing. How to you pass this data from c# script?
Also, I found few things related to GraphicsBuffer usage with ShaderGraph.
It’s attempting to Draw Mesh merging all vertices of the total instances instead of drawing primitives (as the FrameDebugger shows so) - This is a big problem
The final compiled graph is not having the included buffers leading to no data available in the shader - Not sure why its stripping without any warnings.
It’s unfortunate that the same code with the Graphic Buffers is working when I have a custom urp shader (but lots of code required to enable depth passes and lighting) compared to shader graph.
I double checked my code and found that I was using RenderMeshPrimitives API which is not the same as yours. And also i use the SetBuffer to pass the datas.
But I think its just the mesh difference.
My lightning seems like the same, but its not like merging all verts to one mesh, instead its normal instancing which is cheap and performancing.
I think the buffer you decleared should be included in the .hlsl file you used in graph, and if there is a #include for the file, the buffers will include into the final shader.
Finally got it working. Its because of a “_” prefix in a define. Now all the buffers export to the final shader as expected.
However, the big issue now is,
When I use Custom URP shader with RenderPrimitives, it uses DrawProcedural and not vertices merged, but when using Shader Graph it issues DrawMesh with all vertices merged! Both have same c# code for pushing buffers, just shader is different in the way its created.
Oh I see, maybe it’s because the shader model version. Shader graph only generate shader model 4.5 when using defered render path, other else will generate shader model 2.0.
Since I searched the documentation saids that draw procedual mainly used in shader model 4.5