Skip to content

第04回 レイとカメラ、座標空間

前回: 第03回 プロシージャルノイズと FBM

今回の授業内容

  • Object、World、View、Clip、Screen の役割を整理する
  • レイの始点、方向、距離を式で表す
  • 画面 UV とカメラから視線レイを作る
  • レイと球、平面の交差を計算する
  • レイ方向、交点、法線を色で可視化する

座標空間を目的で使い分ける

座標空間基準主な用途
Object各モデルの原点モデル固有の変形
Worldシーンの原点カメラ、ライト、複数物体の関係
Viewカメラカメラから見た位置
Clip投影後の範囲透視投影とクリッピング
Screen画面ピクセル位置と全画面処理

レイと形状の計算は、参加するすべての位置と方向を同じ座標空間にそろえます。この授業では World Space を基準にします。

レイを式で表す

レイ上の位置 P(t) は、始点 O、正規化した方向 D、距離 t で表します。

P(t)=O+tD
hlsl
float3 positionOnRay = rayOrigin + rayDirection * distanceAlongRay;

rayDirection の長さが1であれば、t をワールド上の距離として扱えます。

画面 UV から視線レイを作る

透視投影カメラでは、カメラ位置をレイの始点とし、画面上の各位置へ向かう方向を作ります。

画面UVから視線方向を求める
Screen UV
画面上の位置へ対応させる
Near Clip上の位置
Near Clip上の位置
投影変換を戻す
Inverse Projection
Inverse Projection
View Spaceへ移す
View Space位置
View Space位置
カメラ変換を戻す
Inverse View
Inverse View
World Spaceへ移す
World Space位置
World Space位置
Camera Positionとの差を正規化する
視線方向

Shader Graph では Screen PositionCameraTransformation Matrix などを使えます。逆行列とプラットフォーム差を含むため、授業では配布する View Ray 用サブグラフまたは Fullscreen Shader Graph の View Direction を使い、結果の意味に集中します。

レイと球の交差

球の中心からレイ上の位置までの距離が半径と一致する点を求めます。

hlsl
bool IntersectSphere(
    float3 rayOrigin,
    float3 rayDirection,
    float3 sphereCenter,
    float sphereRadius,
    out float hitDistance)
{
    float3 oc = rayOrigin - sphereCenter;
    float b = dot(oc, rayDirection);
    float c = dot(oc, oc) - sphereRadius * sphereRadius;
    float discriminant = b * b - c;

    if (discriminant < 0.0)
    {
        hitDistance = 0.0;
        return false;
    }

    hitDistance = -b - sqrt(discriminant);
    return hitDistance > 0.0;
}

命中した場合、交点と法線は次のように求められます。

hlsl
float3 hitPosition = rayOrigin + rayDirection * hitDistance;
float3 normal = normalize(hitPosition - sphereCenter);

実習:レイの情報を可視化する

  1. Fullscreen Shader Graph を作成する
  2. 画面 UV を赤と緑のグラデーションとして表示する
  3. View Ray を direction * 0.5 + 0.5 で色に変換する
  4. World Space の球と交差判定する
  5. 命中したピクセルに法線色を表示する
  6. 命中しないピクセルに背景色を表示する
  7. カメラを移動し、球の見え方が連動することを確認する

授業内課題:平面を追加する

高さ planeHeight の水平面との交差距離を求めます。

hlsl
float t = (planeHeight - rayOrigin.y) / rayDirection.y;

rayDirection.y が0に近いときは平面とほぼ平行です。除算前に確認し、正の距離の交点だけを描画します。

完成条件

  • レイの始点、方向、距離を説明できる
  • 視線レイと球の交差を計算できる
  • 命中点の法線を色として表示できる
  • 球と平面の交差の違いを説明できる

今回のまとめ

画面の各ピクセルに対応する視線レイを作ると、メッシュを使わず数学的な形状との交差を描画できます。次回は交差方程式を形状ごとに解く代わりに、距離場を使ってレイを進めます。

次回: 第05回 3D SDF とレイマーチ