Files
Fishing2/Assets/KriptoFX/WaterSystem2/WaterResources/Shaders/Resources/Common/KWS_Instancing.cginc
2025-06-21 18:06:12 +08:00

190 lines
6.5 KiB
HLSL

#ifndef KWS_WATER_INSTANCING
#define KWS_WATER_INSTANCING
#if defined(KWS_USE_WATER_INSTANCING)
#ifndef KWS_WATER_VARIABLES
#include "..\Common\KWS_WaterVariables.cginc"
#endif
float4x4 inverseMatrix(float4x4 input)
{
float det = determinant(input);
float invDet = 1.0 / det;
float3x3 m1 = float3x3(input._22_23_24, input._32_33_34, input._42_43_44);
float3x3 m2 = float3x3(input._21_23_24, input._31_33_34, input._41_43_44);
float3x3 m3 = float3x3(input._21_22_24, input._31_32_34, input._41_42_44);
float3x3 m4 = float3x3(input._21_22_23, input._31_32_33, input._41_42_43);
float3x3 m5 = float3x3(input._12_13_14, input._32_33_34, input._42_43_44);
float3x3 m6 = float3x3(input._11_13_14, input._31_33_34, input._41_43_44);
float3x3 m7 = float3x3(input._11_12_14, input._31_32_34, input._41_42_44);
float3x3 m8 = float3x3(input._11_12_13, input._31_32_33, input._41_42_43);
float3x3 m9 = float3x3(input._12_13_14, input._22_23_24, input._42_43_44);
float3x3 m10 = float3x3(input._11_13_14, input._21_23_24, input._41_43_44);
float3x3 m11 = float3x3(input._11_12_14, input._21_22_24, input._41_42_44);
float3x3 m12 = float3x3(input._11_12_13, input._21_22_23, input._41_42_43);
float3x3 m13 = float3x3(input._12_13_14, input._22_23_24, input._32_33_34);
float3x3 m14 = float3x3(input._11_13_14, input._21_23_24, input._31_33_34);
float3x3 m15 = float3x3(input._11_12_14, input._21_22_24, input._31_32_34);
float3x3 m16 = float3x3(input._11_12_13, input._21_22_23, input._31_32_33);
float4x4 cofactors = float4x4(
determinant(m1), -determinant(m2), determinant(m3), -determinant(m4),
- determinant(m5), determinant(m6), -determinant(m7), determinant(m8),
determinant(m9), -determinant(m10), determinant(m11), -determinant(m12),
- determinant(m13), determinant(m14), -determinant(m15), determinant(m16)
);
return transpose(cofactors) * invDet;
}
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);
}
inline float GetFlag(uint value, uint bit)
{
return (value >> bit) & 0x01;
}
inline void UpdateInstanceSeamsAndSkirt(InstancedMeshDataStruct meshData, float2 uvData, inout float4 vertex)
{
float quadOffset = uvData.y;
uint mask = (uint)uvData.x;
vertex.x -= quadOffset * GetFlag(mask, 1) * meshData.downSeam;
vertex.z -= quadOffset * GetFlag(mask, 2) * meshData.leftSeam;
vertex.x += quadOffset * GetFlag(mask, 3) * meshData.topSeam;
vertex.z += quadOffset * GetFlag(mask, 4) * meshData.rightSeam;
float downSkirt = GetFlag(mask, 5);
float leftSkirt = GetFlag(mask, 6);
float topSkirt = GetFlag(mask, 7);
float rightSkirt = GetFlag(mask, 8);
if (KWS_MeshType == KWS_MESH_TYPE_FINITE_BOX)
{
//#ifdef KWS_PRE_PASS_BACK_FACE
vertex.y -= downSkirt * meshData.downInf;
vertex.y -= leftSkirt * meshData.leftInf;
vertex.y -= topSkirt * meshData.topInf;
vertex.y -= rightSkirt * meshData.rightInf;
//#endif
if (downSkirt && meshData.downInf == 0 ||
leftSkirt && meshData.leftInf == 0 ||
topSkirt && meshData.topInf == 0 ||
rightSkirt && meshData.rightInf == 0) vertex = NAN_VALUE;
}
else
{
vertex.zy += 1000 * downSkirt * meshData.downInf * float2(-1, 0);
vertex.xy += 1000 * leftSkirt * meshData.leftInf * float2(-1, 0);
vertex.zy += 1000 * topSkirt * meshData.topInf * float2(1, 0);
vertex.xy += 1000 * rightSkirt * meshData.rightInf * float2(1, 0);
}
}
inline void UpdateInstaceRotation(inout float4 vertex, float4x4 matrixM, float4x4 matrixIM)
{
//if (KWS_MeshType == KWS_MESH_TYPE_FINITE_BOX) vertex.xyz = mul((float3x3)KWS_InstancingRotationMatrix, vertex.xyz);
}
inline void SetMatrixM(float3 position, float3 size, inout float4x4 matrixM)
{
position.y += 0.001;
matrixM._11_21_31_41 = float4(size.x, 0, 0, 0);
matrixM._12_22_32_42 = float4(0, size.y, 0, 0);
matrixM._13_23_33_43 = float4(0, 0, size.z, 0);
matrixM._14_24_34_44 = float4(position.xyz, 1);
UNITY_BRANCH
if (KWS_MeshType == KWS_MESH_TYPE_FINITE_BOX)
{
float s = sin(-KWS_WaterYRotationRad);
float c = cos(-KWS_WaterYRotationRad);
float4x4 rotationMatrix;
rotationMatrix[0] = float4(c, 0, -s, 0);
rotationMatrix[1] = float4(0, 1, 0, 0);
rotationMatrix[2] = float4(s, 0, c, 0);
rotationMatrix[3] = float4(0, 0, 0, 1);
matrixM._14_24_34 -= KWS_WaterPosition;
float4x4 rotatedMatrix = mul(rotationMatrix, matrixM);
float4x4 newCustomMatrix = matrixM;
newCustomMatrix = rotatedMatrix;
newCustomMatrix._14_24_34 += KWS_WaterPosition;
matrixM = newCustomMatrix;
}
}
inline void UpdateInstanceMatrixM(InstancedMeshDataStruct meshData, inout float4x4 matrixM)
{
SetMatrixM(meshData.position.xyz, meshData.size.xyz, matrixM);
matrixM = UpdateCameraRelativeMatrix(matrixM);
}
inline void UpdateAllInstanceMatrixes(InstancedMeshDataStruct meshData, inout float4x4 matrixM, inout float4x4 matrixIM)
{
SetMatrixM(meshData.position.xyz, meshData.size.xyz, matrixM);
UNITY_BRANCH
if (KWS_MeshType == KWS_MESH_TYPE_FINITE_BOX)
{
matrixIM = inverse(matrixM);
}
else
{
matrixIM = matrixM;
matrixIM._14_24_34 *= -1;
matrixIM._11_22_33 = 1.0f / matrixIM._11_22_33;
}
matrixM = UpdateCameraRelativeMatrix(matrixM);
}
inline void UpdateAllInstanceMatrixes(uint instanceID, inout float4x4 matrixM, inout float4x4 matrixIM)
{
UpdateAllInstanceMatrixes(InstancedMeshData[instanceID], matrixM, matrixIM);
}
inline void UpdateInstanceData(uint instanceID, float2 uvData, inout float4 vertex, inout float4x4 matrixM, inout float4x4 matrixIM)
{
InstancedMeshDataStruct meshData = InstancedMeshData[instanceID];
UpdateInstanceSeamsAndSkirt(meshData, uvData, vertex);
UpdateInstaceRotation(vertex, matrixM, matrixIM);
UpdateAllInstanceMatrixes(meshData, matrixM, matrixIM);
}
#endif
#endif