-
-
Save unitycoder/c6e1cd29ceccbcef89d1e18b2ca07855 to your computer and use it in GitHub Desktop.
Revisions
-
Refsa revised this gist
Oct 12, 2021 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -11,4 +11,6 @@ The output from this goes into position output of vertex stage. It needs to be c Shader Graph should now work just as normal, just that it uses data passed from ComputeBuffers. Do note that the example code in Render.cs is sub-optimal and is mostly there as an example of how to use it from the C# side. You can find a sample unitypackage [here](https://github.com/Refsa/RendererEx/files/7304926/ShaderGraph_InstancedIndirect.zip) -
Refsa revised this gist
Oct 8, 2021 . No changes.There are no files selected for viewing
-
Refsa revised this gist
Oct 7, 2021 . 1 changed file with 6 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -34,6 +34,12 @@ void Awake() SpawnExample(); } void OnDestroy() { argsBuffer?.Release(); drawDataBuffer?.Release(); } void LateUpdate() { // Only needs to be called if "instances" changed -
Refsa revised this gist
Oct 7, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,5 @@ First is a passthrough custom function node that loads the hlsl code.  Second custom function node contains the code to setup procedural instancing. It needs to be implmeneted in a custom function node or else it wont work. -
Refsa revised this gist
Oct 7, 2021 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,13 +1,13 @@ First is a passthrough custom function node that loads the hlsl code.  Second custom function node contains the code to setup procedural instancing. It needs to be implmeneted in a custom function node or else it wont work. Important bits is the `#pragma instancing_options procedural:setup` where "procedural:setup" calls a function in the included code in the previous node.  The output from this goes into position output of vertex stage. It needs to be connected for shader graph to compile it.  Shader Graph should now work just as normal, just that it uses data passed from ComputeBuffers. -
Refsa revised this gist
Oct 7, 2021 . 1 changed file with 49 additions and 32 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,53 +1,70 @@ #ifndef SHADER_GRAPH_SUPPORT_H #define SHADER_GRAPH_SUPPORT_H // You could also upload the model matrix struct DrawData { float3 position; float4 rotation; float3 scale; }; StructuredBuffer<DrawData> _DrawData; inline float4x4 TRSMatrix(float3 position, float4 rotation, float3 scale) { float4x4 m = 0.0; m[0][0] = (1.0 - 2.0 * (rotation.y * rotation.y + rotation.z * rotation.z)) * scale.x; m[1][0] = (rotation.x * rotation.y + rotation.z * rotation.w) * scale.x * 2.0; m[2][0] = (rotation.x * rotation.z - rotation.y * rotation.w) * scale.x * 2.0; m[3][0] = 0.0; m[0][1] = (rotation.x * rotation.y - rotation.z * rotation.w) * scale.y * 2.0; m[1][1] = (1.0 - 2.0 * (rotation.x * rotation.x + rotation.z * rotation.z)) * scale.y; m[2][1] = (rotation.y * rotation.z + rotation.x * rotation.w) * scale.y * 2.0; m[3][1] = 0.0; m[0][2] = (rotation.x * rotation.z + rotation.y * rotation.w) * scale.z * 2.0; m[1][2] = (rotation.y * rotation.z - rotation.x * rotation.w) * scale.z * 2.0; m[2][2] = (1.0 - 2.0 * (rotation.x * rotation.x + rotation.y * rotation.y)) * scale.z; m[3][2] = 0.0; m[0][3] = position.x; m[1][3] = position.y; m[2][3] = position.z; m[3][3] = 1.0; return m; } inline void SetUnityMatrices(uint instanceID, inout float4x4 objectToWorld, inout float4x4 worldToObject) { #if UNITY_ANY_INSTANCING_ENABLED DrawData drawData = _DrawData[instanceID]; objectToWorld = mul(objectToWorld, TRSMatrix(drawData.position, drawData.rotation, drawData.scale)); float3x3 w2oRotation; w2oRotation[0] = objectToWorld[1].yzx * objectToWorld[2].zxy - objectToWorld[1].zxy * objectToWorld[2].yzx; w2oRotation[1] = objectToWorld[0].zxy * objectToWorld[2].yzx - objectToWorld[0].yzx * objectToWorld[2].zxy; w2oRotation[2] = objectToWorld[0].yzx * objectToWorld[1].zxy - objectToWorld[0].zxy * objectToWorld[1].yzx; float det = dot(objectToWorld[0].xyz, w2oRotation[0]); w2oRotation = transpose(w2oRotation); w2oRotation *= rcp(det); float3 w2oPosition = mul(w2oRotation, -objectToWorld._14_24_34); worldToObject._11_21_31_41 = float4(w2oRotation._11_21_31, 0.0f); worldToObject._12_22_32_42 = float4(w2oRotation._12_22_32, 0.0f); worldToObject._13_23_33_43 = float4(w2oRotation._13_23_33, 0.0f); worldToObject._14_24_34_44 = float4(w2oPosition, 1.0f); #endif } void passthroughVec3_float(in float3 In, out float3 Out) { Out = In; } void setup() { #if UNITY_ANY_INSTANCING_ENABLED -
Refsa revised this gist
Oct 7, 2021 . 3 changed files with 82 additions and 67 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using UnityEngine; class Render : MonoBehaviour { struct DrawData @@ -7,8 +11,8 @@ struct DrawData public Vector3 Scale; } public Mesh mesh; public Material material; List<DrawData> instances; @@ -20,28 +24,54 @@ struct DrawData void Awake() { instances = new List<DrawData>(); argsBuffer = new ComputeBuffer(5, sizeof(uint), ComputeBufferType.IndirectArguments); // Meshes with sub-meshes needs more structure, this assumes a single sub-mesh args[0] = mesh.GetIndexCount(0); mpb = new MaterialPropertyBlock(); SpawnExample(); } void LateUpdate() { // Only needs to be called if "instances" changed PushDrawData(); mpb.SetBuffer("_DrawData", drawDataBuffer); args[1] = (uint)instances.Count; argsBuffer.SetData(args); Graphics.DrawMeshInstancedIndirect( mesh, 0, material, new Bounds(Vector3.zero, Vector3.one * 1000f), argsBuffer, 0, mpb ); } void PushDrawData() { if (drawDataBuffer == null || drawDataBuffer.count < instances.Count) { drawDataBuffer?.Release(); drawDataBuffer = new ComputeBuffer(instances.Count, Marshal.SizeOf<DrawData>()); } drawDataBuffer.SetData(instances); } void SpawnExample() { instances.Clear(); for (int i = 0; i < 4096; i++) { instances.Add(new DrawData() { Pos = Random.insideUnitSphere * 100f, Rot = Random.rotation, Scale = Vector3.one * Random.Range(1f, 10f) }); } } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,8 +2,13 @@ First is a passthrough custom function node that loads the hlsl code.  Second custom function node contains the code to setup procedural instancing. It needs to be implmeneted in a custom function node or else it wont work. Important bits is the `#pragma instancing_options procedural:setup` where "procedural:setup" calls a function in the included code in the previous node.  The output from this goes into position output of vertex stage. It needs to be connected for shader graph to compile it.  Shader Graph should now work just as normal, just that it uses data passed from ComputeBuffers. Do note that the example code in Render.cs is sub-optimal and is mostly there as an example of how to use it from the C# side. This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,78 +1,58 @@ #ifndef SHADER_GRAPH_SUPPORT_H #define SHADER_GRAPH_SUPPORT_H #include "./Common.hlsl" void calculatePos_float(in float4 vpos, out float4 worldPos) { #if UNITY_ANY_INSTANCING_ENABLED DrawData drawData = _DrawData[unity_InstanceID]; worldPos = TRS(drawData.position, drawData.rotation, drawData.scale, vpos); #else worldPos = vpos; #endif } void getData_float(out float3 position, out float4 rotation, out float3 scale) { #if UNITY_ANY_INSTANCING_ENABLED DrawData drawData = _DrawData[unity_InstanceID]; position = drawData.position; rotation = drawData.rotation; scale = drawData.scale; #else position = 0; rotation = 0; scale = 1; #endif } void getInstanceID_float(out float instanceID) { #if UNITY_ANY_INSTANCING_ENABLED instanceID = rex_id; #else instanceID = 0; #endif } void passthroughVec4_float(in float4 In, out float4 Out) { Out = In; } void passthroughVec3_float(in float3 In, out float3 Out) { Out = In; } void setupDummy() { } void setup() { #if UNITY_ANY_INSTANCING_ENABLED SetUnityMatrices(unity_InstanceID, unity_ObjectToWorld, unity_WorldToObject); #endif } #endif -
Refsa created this gist
Oct 7, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,47 @@ class Render : MonoBehaviour { struct DrawData { public Vector3 Pos; public Quaternion Rot; public Vector3 Scale; } Mesh mesh; Material material; List<DrawData> instances; ComputeBuffer drawDataBuffer; ComputeBuffer argsBuffer; uint[] args = new uint[5]; MaterialPropertyBlock mpb; void Awake() { instances = new List<DrawData>(); argsBuffer = new ComputeBuffer(5, sizeof(uint), ComputeBufferType.IndirectArguments); // Meshes with sub-meshes needs more structure, this assumes a single sub-mesh args[0] = mesh.GetIndexCount(0); } void LateUpdate() { if (drawDataBuffer == null || drawDataBuffer.count < instances.Count) { drawDataBuffer?.Release(); drawDataBuffer = new ComputeBuffer(instances.Count, Marshal.SizeOf<DrawData>(); } drawDataBuffer.SetData(instances); materialPropertyBlock.SetBuffer("_DrawData", drawDataBuffer); args[1] = instances.Count; argsBuffer.SetData(args); Graphics.DrawMeshInstancedIndirect( mesh, 0, material, argsBuffer, 0, materialPropertyBlock ); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,9 @@ First is a passthrough custom function node that loads the hlsl code.  Second custom function node contains the code to setup procedural instancing. It needs to be implmeneted in a custom function node or else it wont work.  The output from this goes into position output of vertex stage. It needs to be connected for shader graph to compile it.  This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,78 @@ #ifndef SHADER_GRAPH_SUPPORT_H #define SHADER_GRAPH_SUPPORT_H // You could also upload the model matrix struct DrawData { float3 position; float4 rotation; float3 scale; // A custom instance id, useful for culling and other flags int id; }; StructuredBuffer<DrawData> _DrawData; void setup() { #if UNITY_ANY_INSTANCING_ENABLED SetUnityMatrices(unity_InstanceID, unity_ObjectToWorld, unity_WorldToObject); #endif } inline float4x4 TRSMatrix(float3 position, float4 rotation, float3 scale) { float4x4 m = 0.0; m[0][0] = (1.0 - 2.0 * (rotation.y * rotation.y + rotation.z * rotation.z)) * scale.x; m[1][0] = (rotation.x * rotation.y + rotation.z * rotation.w) * scale.x * 2.0; m[2][0] = (rotation.x * rotation.z - rotation.y * rotation.w) * scale.x * 2.0; m[3][0] = 0.0; m[0][1] = (rotation.x * rotation.y - rotation.z * rotation.w) * scale.y * 2.0; m[1][1] = (1.0 - 2.0 * (rotation.x * rotation.x + rotation.z * rotation.z)) * scale.y; m[2][1] = (rotation.y * rotation.z + rotation.x * rotation.w) * scale.y * 2.0; m[3][1] = 0.0; m[0][2] = (rotation.x * rotation.z + rotation.y * rotation.w) * scale.z * 2.0; m[1][2] = (rotation.y * rotation.z - rotation.x * rotation.w) * scale.z * 2.0; m[2][2] = (1.0 - 2.0 * (rotation.x * rotation.x + rotation.y * rotation.y)) * scale.z; m[3][2] = 0.0; m[0][3] = position.x; m[1][3] = position.y; m[2][3] = position.z; m[3][3] = 1.0; return m; } inline void SetUnityMatrices(uint instanceID, inout float4x4 objectToWorld, inout float4x4 worldToObject) { #if UNITY_ANY_INSTANCING_ENABLED DrawData drawData = _DrawData[instanceID]; rex_id = drawData.id; objectToWorld = mul(objectToWorld, TRSMatrix(drawData.position, drawData.rotation, drawData.scale)); float3x3 w2oRotation; w2oRotation[0] = objectToWorld[1].yzx * objectToWorld[2].zxy - objectToWorld[1].zxy * objectToWorld[2].yzx; w2oRotation[1] = objectToWorld[0].zxy * objectToWorld[2].yzx - objectToWorld[0].yzx * objectToWorld[2].zxy; w2oRotation[2] = objectToWorld[0].yzx * objectToWorld[1].zxy - objectToWorld[0].zxy * objectToWorld[1].yzx; float det = dot(objectToWorld[0].xyz, w2oRotation[0]); w2oRotation = transpose(w2oRotation); w2oRotation *= rcp(det); float3 w2oPosition = mul(w2oRotation, -objectToWorld._14_24_34); worldToObject._11_21_31_41 = float4(w2oRotation._11_21_31, 0.0f); worldToObject._12_22_32_42 = float4(w2oRotation._12_22_32, 0.0f); worldToObject._13_23_33_43 = float4(w2oRotation._13_23_33, 0.0f); worldToObject._14_24_34_44 = float4(w2oPosition, 1.0f); #endif } void passthroughVec3_float(in float3 In, out float3 Out) { Out = In; } #endif