Files
ZHGD_Web/Assets/Art/Art Plugins/GPUInstancer/Resources/Compute/Include/Matrix.hlsl
2025-07-13 23:16:20 +08:00

144 lines
4.0 KiB
HLSL

#ifndef __matrix_hlsl_
#define __matrix_hlsl_
// Sets the rotation of a translation matrix "m" by the quaternion value "q".
float4x4 SetMatrixRotationWithQuaternion(float4x4 m, float4 q)
{
// See e.g. http://www.geometrictools.com/Documentation/LinearAlgebraicQuaternions.pdf .
float x = q.x;
float y = q.y;
float z = q.z;
float w = q.w;
m[0][0] = 1 - 2 * (y * y + z * z);
m[0][1] = 2 * (x * y - z * w);
m[0][2] = 2 * (x * z + y * w);
m[1][0] = 2 * (x * y + z * w);
m[1][1] = 1 - 2 * (x * x + z * z);
m[1][2] = 2 * (y * z - x * w);
m[2][0] = 2 * (x * z - y * w);
m[2][1] = 2 * (y * z + x * w);
m[2][2] = 1 - 2 * (x * x + y * y);
return m;
}
/// https://www.3dgep.com/3d-math-primer-for-game-programmers-matrices/
/// n : axis
/// a : angle in radians
/// A 3D rotation about an arbitrary axis n by an angle of a
float4x4 MatrixRotate(float3 n, float a)
{
float cosa = cos(a);
float sina = sin(a);
return float4x4(
n.x * n.x * (1 - cosa) + cosa,
n.x * n.y * (1 - cosa) - n.z * sina,
n.x * n.z * (1 - cosa) + n.y * sina,
0,
n.x * n.y * (1 - cosa) + n.z * sina,
n.y * n.y * (1 - cosa) + cosa,
n.y * n.z * (1 - cosa) - n.x * sina,
0,
n.x * n.z * (1 - cosa) - n.y * sina,
n.y * n.z * (1 - cosa) + n.x * sina,
n.z * n.z * (1 - cosa) + cosa,
0,
0, 0, 0, 1
);
}
// m: matrix to scale
// angle: angles for x,y,z
// returns rotation matrix
float4x4 MatrixRotateXYZ(float3 angle)
{
// rotate at x axis
float4x4 mX = MatrixRotate(float3(1, 0, 0), radians(angle.x));
// rotate at y axis
float4x4 mY = MatrixRotate(float3(0, 1, 0), radians(angle.y));
// rotate at z axis
float4x4 mYmX = mul(mY, mX);
float4x4 mZ = MatrixRotate(float3(mYmX[0][2], mYmX[1][2], mYmX[2][2]), radians(angle.z));
// return result
return mul(mul(mZ, mY), mX);
}
// Scales the matrix "m" by "scale" scales for x,y,z.
float4x4 SetScaleOfMatrix(float4x4 m, float3 scale)
{
m._m00_m10_m20_m30 = m._m00_m10_m20_m30 * scale.x / length(m._m00_m10_m20_m30);
m._m01_m11_m21_m31 = m._m01_m11_m21_m31 * scale.y / length(m._m01_m11_m21_m31);
m._m02_m12_m22_m32 = m._m02_m12_m22_m32 * scale.z / length(m._m02_m12_m22_m32);
return m;
}
// Scales the matrix "m" by "scale" scales for x,y,z.
float4x4 SetScaleOfMatrixPercentage(float4x4 m, float3 scale)
{
m._m00_m10_m20_m30 = m._m00_m10_m20_m30 * scale.x;
m._m01_m11_m21_m31 = m._m01_m11_m21_m31 * scale.y;
m._m02_m12_m22_m32 = m._m02_m12_m22_m32 * scale.z;
return m;
}
// Generates a Matrix4x4 from position, rotation and scale.
float4x4 TRS(in float3 position, in float4x4 rotationMatrix, in float3 scale)
{
// start with rotation matrix and set scale
float4x4 result = SetScaleOfMatrix(rotationMatrix, scale);
// set position
result._m03_m13_m23 = position;
// return result
return result;
}
// Returns a quaternion that represents a rotation of "angle" degrees along "axis".
float4 AngleAxis(float3 axis, float angle)
{
// Calculate the sin( theta / 2) once for optimization
double factor = sin(angle / 2.0);
// Calculate the x, y and z of the quaternion
double x = axis.x * factor;
double y = axis.y * factor;
double z = axis.z * factor;
// Calcualte the w value by cos( theta / 2 )
double w = cos(angle / 2.0);
return normalize(float4(x, y, z, w));
}
// Quaternion Multiplication.
float4 QuatMul(float4 q1, float4 q)
{
float w_val = q1.w * q.w - q1.x * q.x - q1.y * q.y - q1.z * q.z;
float x_val = q1.w * q.x + q1.x * q.w + q1.y * q.z - q1.z * q.y;
float y_val = q1.w * q.y + q1.y * q.w + q1.z * q.x - q1.x * q.z;
float z_val = q1.w * q.z + q1.z * q.w + q1.x * q.y - q1.y * q.x;
q1.w = w_val;
q1.x = x_val;
q1.y = y_val;
q1.z = z_val;
return q1;
}
// Returns a quaternion that represents a rotation from "from" to "to" vectors.
float4 FromToRotation(float3 from, float3 to)
{
float4 q;
float3 a = cross(from, to);
q.xyz = a;
q.w = sqrt((length(to) * length(to))) + dot(from, to);
q = normalize(q);
return q;
}
#endif