#pragma multi_compile _LOD_FADE_CROSSFADE #ifndef NODE_THOMAGIC_RENDERER_INCLUDED #define NODE_THOMAGIC_RENDERER_INCLUDED #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED #define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs #include "UnityIndirect.cginc" #define Use_Macro_UNITY_MATRIX_M_instead_of_unity_ObjectToWorld unity_ObjectToWorld #define Use_Macro_UNITY_MATRIX_I_M_instead_of_unity_WorldToObject unity_WorldToObject #define LOD_FADE_CROSSFADE struct InstanceData { // position.xyz : position.xyz // position.w : rotation.x // scale.x : scale.xz // scale.y : scale.y // scale.zw : rotation.yz float4 position; float4 scale; uint prefabId; int3 padding; }; struct InstanceMeta { uint visibleLod; uint fadeOutLod; float fadeAnim; // The scale of the instance can be adjusted float Scale; }; StructuredBuffer trInstances; StructuredBuffer trPerCamVisibleIndexesBuffer; StructuredBuffer trPerCamMeta; float4x4 trInstanceMatrix; int trLodNr; float4x4 TRS(float3 t, float4 r, float3 s) { float4x4 result = (float4x4)0; result[0][0] = (1.0f - 2.0f * (r.y * r.y + r.z * r.z)) * s.x; result[1][0] = (r.x * r.y + r.z * r.w) * s.x * 2.0f; result[2][0] = (r.x * r.z - r.y * r.w) * s.x * 2.0f; result[3][0] = 0.0f; result[0][1] = (r.x * r.y - r.z * r.w) * s.y * 2.0f; result[1][1] = (1.0f - 2.0f * (r.x * r.x + r.z * r.z)) * s.y; result[2][1] = (r.y * r.z + r.x * r.w) * s.y * 2.0f; result[3][1] = 0.0f; result[0][2] = (r.x * r.z + r.y * r.w) * s.z * 2.0f; result[1][2] = (r.y * r.z - r.x * r.w) * s.z * 2.0f; result[2][2] = (1.0f - 2.0f * (r.x * r.x + r.y * r.y)) * s.z; result[3][2] = 0.0f; result[0][3] = t.x; result[1][3] = t.y; result[2][3] = t.z; result[3][3] = 1.0f; return result; } void DecompressInstanceMatrix(inout float4x4 m, InstanceData instanceData, InstanceMeta meta) { float3 position = instanceData.position.xyz; float4 rotation = float4(instanceData.position.w, instanceData.scale.zw, 0); float3 scale = instanceData.scale.xyx * meta.Scale; rotation.w = sqrt(1.0 - rotation.x * rotation.x - rotation.y * rotation.y - rotation.z * rotation.z); m = TRS(position, rotation, scale); } float4x4 inverse(float4x4 input) { #define minor(a,b,c) determinant(float3x3(input.a, input.b, input.c)) float4x4 cofactors = float4x4( minor(_22_23_24, _32_33_34, _42_43_44), -minor(_21_23_24, _31_33_34, _41_43_44), minor(_21_22_24, _31_32_34, _41_42_44), -minor(_21_22_23, _31_32_33, _41_42_43), -minor(_12_13_14, _32_33_34, _42_43_44), minor(_11_13_14, _31_33_34, _41_43_44), -minor(_11_12_14, _31_32_34, _41_42_44), minor(_11_12_13, _31_32_33, _41_42_43), minor(_12_13_14, _22_23_24, _42_43_44), -minor(_11_13_14, _21_23_24, _41_43_44), minor(_11_12_14, _21_22_24, _41_42_44), -minor(_11_12_13, _21_22_23, _41_42_43), -minor(_12_13_14, _22_23_24, _32_33_34), minor(_11_13_14, _21_23_24, _31_33_34), -minor(_11_12_14, _21_22_24, _31_32_34), minor(_11_12_13, _21_22_23, _31_32_33) ); #undef minor return transpose(cofactors) / determinant(input); } #endif void SetupThoMagicRenderer() { #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED InitIndirectDrawArgs(0); uint instanceID = GetIndirectInstanceID_Base(unity_InstanceID); uint instanceIndex = trPerCamVisibleIndexesBuffer[instanceID]; InstanceMeta meta = trPerCamMeta[instanceIndex]; DecompressInstanceMatrix(unity_ObjectToWorld, trInstances[instanceIndex], meta); unity_ObjectToWorld = mul(unity_ObjectToWorld, trInstanceMatrix); unity_WorldToObject = inverse(unity_ObjectToWorld); if (meta.visibleLod == trLodNr) unity_LODFade.x = (1.0f - meta.fadeAnim); else unity_LODFade.x = -(1.0f - meta.fadeAnim); // {% hd %} // Instances are static so the previous matrix is the same as the current one. // These matrices are required for correct motion vectors in HDRP. #if SHADERPASS == SHADERPASS_MOTION_VECTORS && defined(SHADERPASS_CS_HLSL) unity_MatrixPreviousM = unity_ObjectToWorld; unity_MatrixPreviousMI = unity_WorldToObject; #endif // {% endhd %} #endif } #endif