3d-sky-rays について
既存のレンダラーにスクリーンスペースの3D光芒を実装するためのスキルです。空マスク、太陽の投影サンプリング、合成、調整、性能確認を説明します。
主な機能
- 01遮蔽を考慮した空マスクの作成
- 02太陽のスクリーンスペース投影
- 03空のサンプルから光芒を蓄積
- 04線形シーンカラーへの合成
- 05サンプル数とバッファーサイズの調整
活用シーン
- 01屋根の隙間から差す光芒の追加
- 02葉の輪郭を使った光線の形成
- 03異なるカメラ視点での安定性確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mengto/ skills --skill 3d-sky-raysインストール後、Claude Code で/3d-sky-raysを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yamlREFERENCES.md
詳細
3D Sky Rays
光がシーンの隙間を通り抜けているように見せます。カメラの動きに合わせて、屋根の縁や葉が光の筋を形作るようにします。
既存のレンダラーに適合させる
レンダラーのバージョン、レンダーターゲット、アルファの使用方法、深度処理、トーンマッピング、ポストプロセスの順序を確認します。既存の WebGL または WebGPU バックエンドを維持します。以下のシェーダーの手順は WebGL のスクリーンスペースエフェクトを説明しています。WebGPU を使用する場合は、プロジェクトのノード/レンダーパイプラインで同等の処理を実装します。
空、光線の発生源、指向性ライティングには、太陽の方向を向く、正規化されたワールド空間の方向ベクトルを 1 つ使用します。アートディレクション上、見た目の太陽とライティングの太陽を意図的にずらす場合は、そのずれを 1 か所にまとめて記録し、制御できるようにします。
オクルージョンを考慮した光線パスを構築する
- シーンカラーをリニア HDR でレンダリングします。空を識別するマスクを用意し、空を白、不透明な遮蔽物を黒にします。葉が不透明な四角形にならないよう、マスクパスでも葉のアルファカットアウトと頂点の動きを再現します。
- 専用の空マスクを使うのが、幅広く対応できる標準的な方法です。シーンのアルファを再利用するのは、先行するすべてのパスでその意味が保たれる場合に限った最適化です。つまり、空のアルファは 0、不透明なジオメトリのアルファは 1 である必要があります。透明なガラス、パーティクル、キャンバスの合成、AO によって、この規則が崩れることがあります。マスクを直接確認してください。
- カメラから太陽方向に点を投影します。投影座標を使う前に、発生源がカメラの背後にある場合は除外します。
uv = ndc.xy * 0.5 + 0.5で NDC を UV に変換し、パイプラインのテクスチャの向きを考慮します。 - レイバッファーの各ピクセルについて、太陽の UV に向かってレイを進めます。空の可視度に、HDR 閾値を超える空の輝度を掛けた値をサンプリングします。減衰するサンプルを累積し、重みの合計で割ることで、サンプル数を変えても露出が変わらないようにします。
- マスクテクスチャの範囲外にある UV は除外します。太陽が画面から大きく外れるにつれてエフェクトをフェードアウトさせます。サンプルを端の値にクランプすると、明るい帯ができてしまいます。太陽が画面のすぐ外側にある場合は、小さなオーバースキャンマージンが役立ちます。
- 最終的なトーンマップ/出力変換の前に、レイの色をリニアなシーンカラーに加算合成します。後続のパスで必要な場合は、入力アルファを維持します。
累積処理の中核を擬似コードで示します。
step = (pixelUV - sunUV) * density / sampleCount
sampleUV = pixelUV - step * jitter
sum = 0; weightSum = 0; weight = 1
repeat sampleCount times:
sampleUV -= step
if sampleUV is inside the texture:
energy = max(luminance(scene(sampleUV)) - threshold, 0)
sum += min(energy, energyCap) * skyMask(sampleUV) * weight
weightSum += weight
weight *= decay
rays = sum / max(weightSum, epsilon)
放射状の減衰には、発生源からのアスペクト比を考慮した距離を使います。角度による変化は広く、控えめにします。構造の大部分はシーンのオクルージョンで表現します。不透明な前景面では、スクリーンスペースのオーバーレイを強く減衰させ、木や石のコントラストを保ちます。これは芸術的な近似であり、深度を積分したボリュメトリック散乱の代わりにはなりません。
負荷より先に見た目を調整する
太陽の位置を低くし、暖かみのあるニュートラルな色合い、見える隙間、控えめな強度から始めます。屋根の稜線の向こう側や、樹冠の間から見て調整します。白飛びが起きる場合は、ブルーム不足ではなく、通常は強度が高すぎるかマスクに問題があります。
最初の試行では、おおよそ 24~48 サンプルと半解像度のレイバッファーを使用します。見えるバンディングが問題になる場合にのみ増やしてください。Seijaku のリファレンスでは 72 サンプルを使用していますが、これは必須の品質基準ではなく、あくまで参考値です。滑らかなノイズジッターでバンディングを軽減できますが、アニメーションするジッターはちらつきの原因になります。時間方向の蓄積が利用できない場合は、静止画またはモーション低減表示では安定したノイズを使用してください。
寄与が 0 の場合はパスをスキップします。描画バッファーに合わせてバッファーをリサイズし、置き換えたターゲットを破棄します。レイの有効時と無効時を比較して、追加される GPU/フレームコストを測定します。レンダーループ内で同期 GPU 読み戻しを行わないでください。
検証
- 屋根や葉のシルエットが光の筋をはっきり遮り、葉の周囲に四角いハローが発生しないこと。
- 太陽に背を向けると、反転した発生源や閃光を生じさせずにエフェクトが消えること。
- 屋内に入っても表面のコントラストが保たれ、無関係な発光オブジェクトが太陽のように見えないこと。
- カメラのオービット、縦向きへのリサイズ、夕暮れ、モーション低減時の静止フレームで安定していること。
- デスクトップとモバイルで、シェーダーエラー、フレーム時間、実際のレイバッファーサイズを確認すること。
リファレンス
ソースとレンダラーのドキュメントについては、REFERENCES.md をお読みください。Seijaku では、GodRayShader、makePost、および投影ソースの更新を確認してください。アルファマスクの規約はレンダーパイプライン全体に依存するため、その前提だけをそのまま流用しないでください。