Files
ZHGD_Web/Assets/Art/Art Plugins/GPUInstancer/Shaders/Include/GPUInstancerSetup.cginc
2025-07-13 23:16:20 +08:00

88 lines
3.5 KiB
HLSL

#ifndef GPU_INSTANCER_INCLUDED
#define GPU_INSTANCER_INCLUDED
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
uniform uint gpui_InstanceID;
uniform float4x4 gpuiTransformOffset;
uniform float LODLevel; // -1 if crossFade disabled, 0-7 if cross fade enabled
uniform float fadeLevelMultiplier; // 1 no animation
#if GPUI_MHT_COPY_TEXTURE
uniform sampler2D gpuiTransformationMatrixTexture;
uniform sampler2D gpuiInstanceLODDataTexture;
uniform float bufferSize;
uniform float maxTextureSize;
#elif GPUI_MHT_MATRIX_APPEND
uniform StructuredBuffer<float4x4> gpuiTransformationMatrix;
#else
uniform StructuredBuffer<uint> gpuiTransformationMatrix;
uniform StructuredBuffer<float4x4> gpuiInstanceData;
uniform StructuredBuffer<uint4> gpuiInstanceLODData;
#endif
#ifdef unity_ObjectToWorld
#undef unity_ObjectToWorld
#endif
#ifdef unity_WorldToObject
#undef unity_WorldToObject
#endif
#endif // UNITY_PROCEDURAL_INSTANCING_ENABLED
void setupGPUI()
{
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
#if GPUI_MHT_COPY_TEXTURE
uint textureWidth = min(bufferSize, maxTextureSize);
float indexX = ((unity_InstanceID % maxTextureSize) + 0.5f) / textureWidth;
float rowCount = ceil(bufferSize / maxTextureSize) * 4.0f;
float rowIndex = floor(unity_InstanceID / maxTextureSize) * 4.0f + 0.5f;
float4x4 transformData = float4x4(
tex2Dlod(gpuiTransformationMatrixTexture, float4(indexX, (0.0f + rowIndex) / rowCount, 0.0f, 0.0f)), // row0
tex2Dlod(gpuiTransformationMatrixTexture, float4(indexX, (1.0f + rowIndex) / rowCount, 0.0f, 0.0f)), // row1
tex2Dlod(gpuiTransformationMatrixTexture, float4(indexX, (2.0f + rowIndex) / rowCount, 0.0f, 0.0f)), // row2
tex2Dlod(gpuiTransformationMatrixTexture, float4(indexX, (3.0f + rowIndex) / rowCount, 0.0f, 0.0f)) // row3
);
gpui_InstanceID = uint(transformData._44);
transformData._44 = 1.0f;
unity_ObjectToWorld = mul(transformData, gpuiTransformOffset);
#elif GPUI_MHT_MATRIX_APPEND
unity_ObjectToWorld = mul(gpuiTransformationMatrix[unity_InstanceID], gpuiTransformOffset);
#else
gpui_InstanceID = gpuiTransformationMatrix[unity_InstanceID];
unity_ObjectToWorld = mul(gpuiInstanceData[gpui_InstanceID], gpuiTransformOffset);
#endif // SHADER_API
// inverse transform matrix
// taken from richardkettlewell's post on
// https://forum.unity3d.com/threads/drawmeshinstancedindirect-example-comments-and-questions.446080/
float3x3 w2oRotation;
w2oRotation[0] = unity_ObjectToWorld[1].yzx * unity_ObjectToWorld[2].zxy - unity_ObjectToWorld[1].zxy * unity_ObjectToWorld[2].yzx;
w2oRotation[1] = unity_ObjectToWorld[0].zxy * unity_ObjectToWorld[2].yzx - unity_ObjectToWorld[0].yzx * unity_ObjectToWorld[2].zxy;
w2oRotation[2] = unity_ObjectToWorld[0].yzx * unity_ObjectToWorld[1].zxy - unity_ObjectToWorld[0].zxy * unity_ObjectToWorld[1].yzx;
float det = dot(unity_ObjectToWorld[0].xyz, w2oRotation[0]);
w2oRotation = transpose(w2oRotation);
w2oRotation *= rcp(det);
float3 w2oPosition = mul(w2oRotation, -unity_ObjectToWorld._14_24_34);
unity_WorldToObject._11_21_31_41 = float4(w2oRotation._11_21_31, 0.0f);
unity_WorldToObject._12_22_32_42 = float4(w2oRotation._12_22_32, 0.0f);
unity_WorldToObject._13_23_33_43 = float4(w2oRotation._13_23_33, 0.0f);
unity_WorldToObject._14_24_34_44 = float4(w2oPosition, 1.0f);
#ifdef UNITY_PREV_MATRIX_M
unity_MatrixPreviousM = unity_ObjectToWorld;
#endif
#endif // UNITY_PROCEDURAL_INSTANCING_ENABLED
}
#endif // GPU_INSTANCER_INCLUDED
// GPUInstancerInclude.cginc [do not delete needed for IsShaderInstanced check]