Last active
December 16, 2024 14:23
-
-
Save outsidecontext/6083f490d4bd56b3e34b7893e6a34480 to your computer and use it in GitHub Desktop.
HLSL Maths Utils
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| float4x4 GetRotationDir(float3 direction, float3 up = float3(0, 1, 0)) | |
| { | |
| float4x4 result; | |
| float3 xaxis = normalize(cross(up, direction)); | |
| float3 yaxis = normalize(cross(direction, xaxis)); | |
| result._11 = xaxis.x; | |
| result._12 = yaxis.x; | |
| result._13 = direction.x; | |
| result._14 = 0; | |
| result._21 = xaxis.y; | |
| result._22 = yaxis.y; | |
| result._23 = direction.y; | |
| result._24 = 0; | |
| result._31 = xaxis.z; | |
| result._32 = yaxis.z; | |
| result._33 = direction.z; | |
| result._34 = 0; | |
| result._41 = 0; | |
| result._42 = 0; | |
| result._43 = 0; | |
| result._44 = 1; | |
| return result; | |
| } | |
| float4x4 GetRotationDir(float3 direction, float3 xaxis, float3 yaxis) | |
| { | |
| float4x4 result; | |
| result._11 = xaxis.x; | |
| result._12 = yaxis.x; | |
| result._13 = direction.x; | |
| result._14 = 0; | |
| result._21 = xaxis.y; | |
| result._22 = yaxis.y; | |
| result._23 = direction.y; | |
| result._24 = 0; | |
| result._31 = xaxis.z; | |
| result._32 = yaxis.z; | |
| result._33 = direction.z; | |
| result._34 = 0; | |
| result._41 = 0; | |
| result._42 = 0; | |
| result._43 = 0; | |
| result._44 = 1; | |
| return result; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| float dotfloat4(float4 a, float4 b) | |
| { | |
| return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Returns inverse matrix of specified matrix | |
| 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); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| float4 quat_from_axis_angle(float3 axis, float angle) | |
| { | |
| float4 qr; | |
| float half_angle = (angle * .5); // * 3.14159 / 180.0; // stick to radians | |
| qr.x = axis.x * sin(half_angle); | |
| qr.y = axis.y * sin(half_angle); | |
| qr.z = axis.z * sin(half_angle); | |
| qr.w = cos(half_angle); | |
| return qr; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// Converts a Quaternion rotation to a 4x4 matrix | |
| float4x4 quaternion_to_rotation_matrix(float4 quat) | |
| { | |
| float4x4 mReturn; | |
| mReturn._11 = 1.0f - 2.0f*quat.y*quat.y - 2.0f*quat.z*quat.z; | |
| mReturn._12 = 2.0f*quat.x*quat.y - 2.0f*quat.w*quat.z; | |
| mReturn._13 = 2.0f*quat.x*quat.z + 2.0f*quat.w*quat.y; | |
| mReturn._14 = 0; | |
| mReturn._21 = 2.0f*quat.x*quat.y + 2.0f*quat.w*quat.z; | |
| mReturn._22 = 1.0f - 2.0f*quat.x*quat.x - 2.0f*quat.z*quat.z; | |
| mReturn._23 = 2.0f*quat.y*quat.z - 2.0f*quat.w*quat.x; | |
| mReturn._24 = 0; | |
| mReturn._31 = 2.0f*quat.x*quat.z - 2.0f*quat.w*quat.y; | |
| mReturn._32 = 2.0f*quat.y*quat.z + 2.0f*quat.w*quat.x; | |
| mReturn._33 = 1.0f - 2.0f*quat.x*quat.x - 2.0f*quat.y*quat.y; | |
| mReturn._34 = 0; | |
| mReturn._41 = 0; | |
| mReturn._42 = 0; | |
| mReturn._43 = 0; | |
| mReturn._44 = 1; | |
| return mReturn; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| float4 slerp(float4 v0, float4 v1, float t) | |
| { | |
| // Compute the cosine of the angle between the two vectors. | |
| float dot = dotfloat4(v0, v1); | |
| const float DOT_THRESHOLD = 0.9995; | |
| if (abs(dot) > DOT_THRESHOLD) | |
| { | |
| // If the inputs are too close for comfort, linearly interpolate | |
| // and normalize the result. | |
| float4 result = v0 + t * (v1 - v0); | |
| normalize(result); | |
| return result; | |
| } | |
| // If the dot product is negative, the quaternions | |
| // have opposite handed-ness and slerp won't take | |
| // the shorter path. Fix by reversing one quaternion. | |
| if (dot < 0.0f) | |
| { | |
| v1 = -v1; | |
| dot = -dot; | |
| } | |
| clamp(dot, -1, 1); // Robustness: Stay within domain of acos() | |
| float theta_0 = acos(dot); // theta_0 = angle between input vectors | |
| float theta = theta_0 * t; // theta = angle between v0 and result | |
| float4 v2 = v1 - v0 * dot; | |
| normalize(v2); // { v0, v2 } is now an orthonormal basis | |
| return v0 * cos(theta) + v2 * sin(theta); | |
| } | |
| // https://blog.demofox.org/2016/02/19/normalized-vector-interpolation-tldr/ | |
| float3 slerp(float3 start, float3 end, float percent) | |
| { | |
| // Dot product - the cosine of the angle between 2 vectors. | |
| float slerpDot = dot(start, end); | |
| // Clamp it to be in the range of Acos() | |
| // This may be unnecessary, but floating point | |
| // precision can be a fickle mistress. | |
| slerpDot = clamp(slerpDot, -1.0, 1.0); | |
| // Acos(dot) returns the angle between start and end, | |
| // And multiplying that by percent returns the angle between | |
| // start and the final result. | |
| float theta = acos(slerpDot) * percent; | |
| float3 RelativeVec = normalize(end - start * slerpDot); // Orthonormal basis | |
| // The final result. | |
| return ((start * cos(theta)) + (RelativeVec * sin(theta))); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment