レイトレーシングの原理
反射や影が自然に描ける理由を、光線とオブジェクトの交差計算からたどれます。屈折・シャドウレイ・再帰、そしてラスタライズとの計算コストの違いまで一気に掴めます。
- 1.各ピクセルからシーンへ光線を飛ばし、球や三角形との最も近い交点を代数的に解いて可視面を決める。
- 2.交点で反射・屈折・シャドウレイを再帰的に生成することで、鏡・ガラス・影といった大域的な光の効果が自然に得られる。
- 3.ラスタライズが幾何を画面へ投影するのに対し、レイトレーシングは光線ごとに全シーンを問い合わせるため、原理的に交差判定の総数が計算コストを支配する。
レイトレーシングは「光線を追いかける」レンダリング
レイトレーシングは、カメラから見えるシーンを描くために 仮想的な光線(レイ)を飛ばし、それがどの物体に当たるかを幾何学的に解く 手法です。現実の光は光源から出て物体で反射・屈折し目に届きますが、目に届かない光線を全て追うのは無駄が多い。そこで実用的なレイトレーシングは経路を逆にたどり、視点(カメラ)から画面の各ピクセルへ向けて光線を発射 します。これを一次光線(primary ray)と呼びます。
一次光線がシーン中で最初に当たった面が、そのピクセルに見える点です。当たった点の色は、そこに届く光(直接光・反射・屈折)を評価して決めます。ラスタライズが「三角形を画面に塗る」発想なのに対し、レイトレーシングは「ピクセルからシーンへ問い合わせる」発想で、これが影・反射・屈折を自然に扱える根本理由になります。
基本ループ(ホイッテッド型レイトレーサー):
各ピクセル (x, y) について:
ray = カメラ位置から (x, y) 方向へ生成
color = trace(ray, depth = 0)
フレームバッファ[x, y] = color
光線は「原点 O と方向ベクトル D」で表され、パラメータ t を用いて P(t) = O + t・D と書けます。t は原点からの距離に対応し、t が 0 より大きい範囲だけが視点の前方です。交差判定とは、この直線と物体表面の方程式を連立し、条件を満たす最小の正の t を求める作業に他なりません。
交差判定 ── 球と三角形
球との交差 は代数的に解けます。中心 C、半径 r の球面は「点と中心の距離が r」という条件で表せます。ここに P(t) = O + t・D を代入すると、t についての二次方程式が得られます。
球との交差(中心 C, 半径 r):
|O + t・D − C|² = r² を展開すると
a・t² + b・t + c = 0
a = D・D (D を正規化すれば 1)
b = 2・D・(O − C)
c = (O − C)・(O − C) − r²
判別式 disc = b² − 4・a・c
disc < 0 → 交差なし(光線は球を外れる)
disc >= 0 → t = (−b ± √disc) / (2・a)
正で最小の t が最初の交点
判別式の符号が「当たるか当たらないか」を決め、二つの解のうち小さい正の t が「入射側の交点」を与えます。(・) はベクトルの内積を表します。
三角形との交差 は、まず三角形を含む平面と光線の交点を求め、その点が三角形の内側かを判定します。実装では Möller–Trumbore 法が広く使われ、平面計算を経ずに交差の有無と重心座標 (u, v) を同時に求めます。重心座標は「頂点でのデータ(法線・UV・色)を交点で補間する重み」で、そのままテクスチャや陰影計算に使えます。
三角形との交差の判定条件(重心座標 u, v):
交点が三角形内部にある ⇔ u >= 0 かつ v >= 0 かつ u + v <= 1
(u, v, 1−u−v が3頂点の重み)
さらに t > 0 で視点の前方
現実のシーンは数百万の三角形を含むため、全三角形と総当たりすると破綻します。そこで BVH(Bounding Volume Hierarchy) などの空間データ構造で光線が通り得ない領域をまとめて枝刈りし、交差判定の回数を対数的に減らすのが必須です。GPU の RT コアはこの BVH 探索と三角形交差をハードウェアで加速します(関連: /hardware-components/、/semiconductor/)。
反射・屈折・シャドウレイ
交点が見つかったら、そこでの色を決めるために新しい光線を生成します。ここがレイトレーシングの表現力の源です。
| 二次光線 | 生成方向 | 目的 |
|---|---|---|
| シャドウレイ | 交点 → 各光源 | 光源との間に遮蔽物があるか調べ、影を判定する |
| 反射レイ | 入射方向を法線で鏡面反射 | 鏡・金属に映り込む像を得る |
| 屈折レイ | スネルの法則で屈折方向へ | ガラス・水など透明体を透過する光を得る |
シャドウレイ は交点から光源へ向けて発射し、その経路に別の物体があれば交点は影の中にあると判断して、その光源からの寄与を落とします。影が「別途影を描く処理」ではなく交差判定の副産物として出るのが、レイトレーシングが影に強い理由です。
反射レイ の方向は、入射方向 D と面法線 N から R = D − 2・(D・N)・N で求まります。屈折レイ はスネルの法則(媒質の屈折率比 n1/n2 で入射角と屈折角が関係づく)に従って方向を曲げます。入射角が臨界角を超えると屈折が起きず全反射になる点も、この式から自然に導かれます。
交点からシャドウレイや反射レイを飛ばすとき、原点をちょうど交点に置くと浮動小数点誤差で光線が自分自身の面と再交差し、表面がまだらに暗くなる自己交差(シャドウアクネ)が生じます。実装では交点を法線方向へ微小量 epsilon だけずらして発射するか、交差判定の下限を t > epsilon にして回避します。
再帰的レイトレーシング
反射面や透明体では、二次光線が当たった先でさらに反射・屈折が起こります。これを扱うのが 再帰 です。trace 関数が自分自身を呼び出し、鏡に映った鏡、ガラス越しの反射といった多段の効果を自然に積み上げます。
trace(ray, depth):
if depth > MAX_DEPTH: return 背景色 # 再帰の打ち切り
hit = 最も近い交点を探す(ray)
if hit なし: return 背景色
color = 0
各光源について:
if not シャドウレイが遮られる(hit, 光源):
color += 直接光の陰影(hit, 光源) # 拡散・鏡面反射
if 反射性(hit):
color += kr * trace(反射レイ(hit), depth + 1)
if 透明(hit):
color += kt * trace(屈折レイ(hit), depth + 1)
return color
再帰は必ず打ち切りが要ります。向かい合う鏡は理論上無限に反射するため、最大深度(MAX_DEPTH) で強制終了します。深度を上げるほど鏡の中の鏡が深く描けますが、光線数は分岐のたびに増えるため、コストと品質のトレードオフになります。
上記の古典的(ホイッテッド型)レイトレーシングが正確に扱うのは鏡面反射・屈折・硬い影までです。ざらついた面での拡散相互反射(色にじみ)、面光源による柔らかい影、被写界深度などは、交点から多数の光線を確率的に飛ばして積分する パストレーシング/モンテカルロ法 が必要です。現代のフォトリアルなレンダリングやリアルタイムのハイブリッド手法は、この確率的積分を土台にしています。
ラスタライズとの根本的な違い
同じ「3D を 2D 画像にする」処理でも、両者は問いの向きが逆です。
| 観点 | ラスタライズ | レイトレーシング |
|---|---|---|
| 基本発想 | 幾何(三角形)を画面へ投影して塗る | ピクセルから光線を飛ばしシーンへ問い合わせる |
| ループの外側 | 三角形ごと | ピクセル(光線)ごと |
| 可視面の決定 | Zバッファで深度比較 | 最小の正の t を持つ交点 |
| 影・反射 | シャドウマップ等の別手法で近似 | シャドウレイ・反射レイで直接得られる |
| 計算量の支配項 | 三角形数 × 画面被覆 | 光線数 × 交差判定コスト |
| 得意分野 | リアルタイム・高スループット | 写実・大域照明 |
ラスタライズは各三角形を一度だけ画面へ変換し、ピクセルを塗る過程で Zバッファにより手前の面だけ残します。GPU のパイプラインに最適化され、極めて高速で、ゲームなど実時間描画の主役です。ただし反射・影・屈折といった「他の物体との相互作用」は本質的に扱えず、シャドウマップや環境マップなどの近似技法を継ぎ足す必要があります。
レイトレーシングは可視判定も影も反射も同じ交差判定の枠組みで統一的に扱えるため写実に強い一方、画面の全ピクセルからシーン全体へ光線を問い合わせる ため計算コストが大きい。1 ピクセルあたり一次光線に加え、シャドウ・反射・屈折・(パストレーシングなら)多数のサンプル光線が生じ、その各々が交差判定を要します。だからこそ BVH による枝刈りと、RT コアによるハードウェア加速が実用化の鍵になりました。
「なぜレイトレーシングは影や反射が自然なのに重いのか」を一言で説明できることが要点です。答えは、可視・影・反射・屈折を全て光線とオブジェクトの交差判定に還元でき統一的に解ける反面、ピクセル×光線本数×シーン規模の交差判定が計算量を支配するから。ラスタライズが幾何を前方投影する O(三角形) 寄りの処理であるのと対照的です。
まとめ
- レイトレーシングは 視点から各ピクセルへ一次光線を飛ばし、P(t) = O + t・D と物体の方程式を連立 して最も近い交点(最小の正の t)を可視面とする。
- 球は二次方程式、三角形は重心座標 で交差を解く。現実規模では BVH 等の空間分割で交差判定を枝刈りするのが前提。
- 交点から シャドウレイ・反射レイ・屈折レイ を生成し、影・鏡・ガラスを統一的に表現。反射屈折の連鎖は 再帰(最大深度で打ち切り)で扱う。
- 古典的(ホイッテッド型)は鏡面反射・硬い影までで、柔らかい影や大域照明には パストレーシング/モンテカルロ積分 が要る。
- ラスタライズは幾何を画面へ投影する高速処理、レイトレーシングは光線ごとにシーンへ問い合わせる写実処理 で、コストは光線数 × 交差判定に支配される。GPU 側の背景は /hardware-components/ を参照。
グラフィックス Article
レイトレーシングの原理を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
レイトレーシング
比較で見る軸
難易度: advanced / カテゴリ: グラフィックス / タグ数: 5
導入後に効く点
交点で反射・屈折・シャドウレイを再帰的に生成することで、鏡・ガラス・影といった大域的な光の効果が自然に得られる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- グラフィックス
- タグ数
- 5
判断チェックリスト
- 自社の用途が「レイトレーシング / グラフィックス」に近いか確認する。
- 強みである「各ピクセルからシーンへ光線を飛ばし、球や三角形との最も近い交点を代数的に解いて可視面を決める。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。