ThomagicRenderer/Runtime/Resources/ThoMagicRenderer.cginc

136 lines
4.4 KiB
HLSL

#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<InstanceData> trInstances;
StructuredBuffer<uint> trPerCamVisibleIndexesBuffer;
StructuredBuffer<InstanceMeta> 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