はじめに
こんにちは。Unityエンジニアのゆんと申します。
皆さん、自分が書いたシェーダーの描画コストが重くてボトルネックになったことはありませんか?
凄くリアルな物理の挙動を再現できたと思ったらカクカクだったことはありませんか?
そんなお悩みを解決できる手法を紹介させていただきたく、記事を書かせていただきました!
今回は自分が実装したカー・ブラックホールのシェーダーを例に、物理シミュレーションのテクニックについて説明していきます。
例に出したブラックホールの物理演算ですが、ちゃんとやるなら一般相対性理論の数式に基づいて計算する必要があり、とても難解な処理になります。
しかもリアルタイムで毎フレーム演算すると重くて仕方がない処理です。
それをたった3行に圧縮し、高速に描画できるテクニックがあるのです。

こちらが実際紹介する手法で作られたシェーダーで、テクスチャなしでブラックホールから観測できる物理現象を再現しています。
それではその作り方を紹介していこうと思います!
レイマーチングとは
物理テクニックの話に入る前に、まずは描画の土台となる レイマーチング について簡単に説明いたします。
通常のUnityの描画では、3Dモデルのポリゴンをカメラに映して色を塗ります。
しかしブラックホールは「形」があるわけではありません。光の曲がり方そのものがビジュアルを作り出しています。
そこで使うのがレイマーチングという手法です。
レイマーチングでは、画面の各ピクセルからカメラの方向に「光線(レイ)」を飛ばし、少しずつ進めながら何にぶつかるかを調べます。
普通のレイマーチングではレイはまっすぐ進みますが、
ブラックホールは光すら曲げてしまうほどの質量を持つので、重力によってレイの進路が曲げる必要があります。
この「レイの曲がり方」を物理法則に基づいて計算するのが、今回のシェーダーの核心となります。
レイの飛ばし方
画面のピクセル座標からワールド空間のレイ方向を復元するには、C#側で計算した 逆View-Projection行列 を使います。
// スクリーンUVをNDC座標に変換
float2 ndc = uv * 2.0 - 1.0;
// NDCからワールド座標を復元
float4 clipPos = float4(ndc, 1.0, 1.0);
float4 worldPos = mul(_InvVPMatrix, clipPos);
float3 rayDir = normalize(worldPos.xyz / worldPos.w - _CameraWorldPos.xyz);
これで各ピクセルに対応するレイの方向が求まりました。
ここからはこのレイをブラックホールの重力に従って曲げながら進めていきます。
重力レンズ効果
ブラックホールの周囲では、巨大な重力が光の経路すら曲げてしまいます。
ブラックホールの裏側にある星の光が曲げられて私たちに届く。
この現象を重力レンズ効果と言います。
本来の計算方法
この光の経路を正確に求めるには、一般相対論の シュバルツシルト計量 における 測地線方程式を解く必要があります。
シュバルツシルト計量とはブラックホール周囲の時空の歪みを表す式で、ここから導かれる式は数十項にもなる連立常微分方程式となります。
論文を見ても難しい話ばかりでそもそもシェーダーの式に落とし込むのが難しい…
しかもフルHD解像度の各ピクセルで数百ステップ、それを毎フレーム……これを真面目に解くのは到底リアルタイムでは高負荷な処理になります。
シェーダー向けの近似式
そこで今回使ったのが、有効ポテンシャル法 から導かれる近似式です。
これならたった3行で重力レンズを再現できます!
// diff: ブラックホール中心からの変位ベクトル
// rayDir: レイの現在の進行方向
// Rs: シュバルツシルト半径
float3 h = cross(diff, rayDir); // 角運動量ベクトル
float h2 = dot(h, h); // 角運動量の2乗
float3 accel = -1.5 * Rs * Rs * h2 / pow(r, 5.0) * diff; // 重力加速度
ポイントは 角運動量ベクトル h を使っている点です。
位置ベクトルと進行方向の外積を取ることで、レイがブラックホールをどれだけ「かすめて」通るかがわかります。
…
記事の続きは下のURLをクリック!
https://rightcode.co.jp/blogs/55780
もっと上を目指したあなたへ
現在、ライトコードでは「WEBエンジニア」「データエンジニア」「ゲーム・XRエンジニア」「UI/UXデザイナー」「PM/PMO」などのポジションで積極採用中です!
ライトコードは、技術力に定評のある受託開発をメインにしているIT企業。
有名WEBサービスやアプリの受託開発などの企画、開発案件が目白押しの状況です!
- もっと大きなことに挑戦したい!
- エンジニアとしてもっと成長したい!
- モダンな技術に触れたい!
現状に満足していない方は、まずは一度、【Wantedly内の弊社ページ】をのぞいてみてください。