跳到主要内容
← Vertex Transformations

Vertex Transformations

Clip Plane - Dissolve

shader-learning 自学第 23 课:Clip Plane - Dissolve

实时渲染 · 2D 片段 HLSL

第 23 课:Clip Plane - Dissolve

实现

cbuffer Transform : register(b0) {
  float4x4 viewMatrix;
  float4x4 modelMatrix;
  float4x4 projectionMatrix;
  float iTime;
};

struct VSInput {
  float3 position : Position;
  float3 normal   : NORMAL0;
};

struct VSOutput {
  float4 position : SV_Position;
  float3 worldPos : POSITION1;
  float3 normal   : NORMAL0;
  float4 clipPlane: NORMAL1;
};

float4x4 inverse4x4(float4x4 m);
float3x3 extractFloat3x3(float4x4 m);

VSOutput main(VSInput input) {
  VSOutput output;

  float3x3 nm = extractFloat3x3(transpose(inverse4x4(modelMatrix)));
  output.normal = normalize(mul(nm, input.normal));

  float  clipPlaneDistance = cos(iTime * 0.8) * 2.0;
  float3 clipPlaneNormal = normalize(modelMatrix[0].xyz * -1.0);
  output.clipPlane = float4(clipPlaneNormal, clipPlaneDistance);

  float4 worldPos = mul(modelMatrix, float4(input.position, 1.0));
  float4 viewPos  = mul(viewMatrix, worldPos);
  output.position = mul(projectionMatrix, viewPos);
  output.worldPos = 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
  );
}