跳到主要内容
← Math

Math

Lines Intersection

shader-learning 自学第 14 课:Lines Intersection

实时渲染 · 2D 片段 HLSL

第 14 课:Lines Intersection

我的解

cbuffer Uniforms : register(b0) {
  float2 iResolution;
  float iTime;
};

struct PSInput {
  float4 position : SV_Position;
};

// HLSL does not provide a built-in inverse() function.
// This function manually computes the inverse of a 2×2 matrix.
float2x2 inverse2x2(float2x2 m) {
  // Compute determinant
  float det = m[0][0] * m[1][1] - m[0][1] * m[1][0];

  // Compute inverse
  float invDet = 1.0 / det;
  return invDet * float2x2(
    +m[1][1], -m[0][1],
    -m[1][0], +m[0][0]
  );
}

float4 main(PSInput input) : SV_Target {
  float2 uv = input.position.xy / iResolution.xy;
  uv *= 2.0;
  uv -= 1.0;
  uv.x *= iResolution.x / iResolution.y;

  // LINE 1
  float2 a1 = float2(1.0, 0.0);
  float2 b1 = a1 + float2(cos(iTime), sin(iTime));

  float2 l1 = b1 - a1;
  float2 n1 = normalize(float2(l1.y, -l1.x));
  float  d1 = -dot(n1, a1);

  float line1 = 1.0 - smoothstep(0.04, 0.05, abs(dot(uv, n1) + d1));

  // LINE 2
  float2 a2 = float2(-1.0, 0.0);
  float2 b2 = a2 + float2(cos(-iTime * 0.25), sin(-iTime * 0.25));

  float2 l2 = b2 - a2;
  float2 n2 = normalize(float2(l2.y, -l2.x));
  float  d2 = -dot(n2, a2);

  float line2 = 1.0 - smoothstep(0.04, 0.05, abs(dot(uv, n2) + d2));
  float2x2 normalMatrix = float2x2(float2(n1.x, n2.x),
    float2(n1.y, n2.y));
  float2 intersectionPoint = mul(inverse2x2(normalMatrix), float2(-d1,-d2)); // FIX IT

  float2 circleCenter = intersectionPoint;
  float  circle = 1.0 - smoothstep(0.24, 0.25, distance(circleCenter, uv));

  float3 shapeColor = lerp(
    float3(0.38, 0.12, 0.93),
    float3(1.0, 0.3, 0.3),
    circle
  );

  float3 backColor = float3(0.12, 0.12, 0.12);

  float3 result = lerp(
    backColor,
    shapeColor,
    clamp(line1 + line2 + circle, 0.0, 1.0)
  );

  return float4(result, 1.0);
}