第 22 课:Clip Plane
实现
cbuffer Transform : register(b0) {
float4x4 modelViewMatrix;
float4x4 modelMatrix;
float4x4 projectionMatrix;
float iTime;
};
struct VSInput {
float3 position : Position;
float3 normal : NORMAL0;
};
struct VSOutput {
float4 position : SV_Position;
float3 modelPos : POSITION0;
float3 normal : NORMAL0;
float dist: POSITION1;
};
float4x4 inverse4x4(float4x4 m);
float3x3 extractFloat3x3(float4x4 m);
VSOutput main(VSInput input) {
VSOutput output;
output.modelPos = input.position;
float3x3 nm = extractFloat3x3(transpose(inverse4x4(modelMatrix)));
output.normal = normalize(mul(nm, input.normal));
float clipPlaneDistance = -cos(iTime) * 0.51;
float3 clipPlaneNormal = float3(1.0, 0.0, 0.0);
output.dist = dot(clipPlaneNormal, output.modelPos) + clipPlaneDistance;
float4 worldPos = mul(modelViewMatrix, float4(input.position, 1.0));
output.position = mul(projectionMatrix, worldPos);
return output;
}
// HLSL does not provide a built-in inverse() function.
// This utility manually computes the inverse of the
// upper-left 3×3 portion of a 4×4 matrix, assuming
// the bottom row and rightmost column are identity.
float4x4 inverse4x4(float4x4 m) {
float a00 = m._11, a01 = m._12, a02 = m._13;
float a10 = m._21, a11 = m._22, a12 = m._23;
float a20 = m._31, a21 = m._32, a22 = m._33;
float det = a00 * (a11 * a22 - a12 * a21)
- a01 * (a10 * a22 - a12 * a20)
+ a02 * (a10 * a21 - a11 * a20);
float invDet = 1.0 / det;
float4x4 inv;
inv._11 = (a11 * a22 - a12 * a21) * invDet;
inv._12 = -(a01 * a22 - a02 * a21) * invDet;
inv._13 = (a01 * a12 - a02 * a11) * invDet;
inv._21 = -(a10 * a22 - a12 * a20) * invDet;
inv._22 = (a00 * a22 - a02 * a20) * invDet;
inv._23 = -(a00 * a12 - a02 * a10) * invDet;
inv._31 = (a10 * a21 - a11 * a20) * invDet;
inv._32 = -(a00 * a21 - a01 * a20) * invDet;
inv._33 = (a00 * a11 - a01 * a10) * invDet;
inv._44 = 1.0;
return inv;
}
float3x3 extractFloat3x3(float4x4 m) {
return float3x3(
m._11, m._12, m._13,
m._21, m._22, m._23,
m._31, m._32, m._33
);
}