ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Metalレイトレーシングによるハイブリッドレンダリング
レイトレーシングをラスタライズエンジンと組み合わせることで、シンプル化されたグラフィックス技術を実装し、Appやゲームのビジュアルを向上させる方法を説明します。自然なアルゴリズムを使用して光の相互作用を正確にシミュレートする方法を紹介して、レイトレースしたシーンのキャプチャ、検査、デバッグにXcodeの最新ツールを活用する方法を確認します。
リソース
- Accelerating ray tracing using Metal
- Applying realistic material and lighting effects to entities
- Managing groups of resources with argument buffers
- Metal
- Metal Shading Language Specification
- Rendering reflections in real time using ray tracing
関連ビデオ
WWDC23
WWDC22
WWDC21
-
ダウンロード
♪ (Metalレイトレーシングによる ハイブリッドレンダリング) WWDC21へようこそ 私は Ali de Jongです AppleのGPUソフトウェアエンジニアです 本日は David Núñez Rubioと一緒に Metalレイトレーシングによる ハイブリッドレンダリングについて 説明します 最初に レイトレーシングが ビジュアルにもたらす 改善の例を紹介します 次に「ハイブリッドレンダリング」 という手法により レイトレーシングパスを ラスタライゼーションに 取り込む方法について説明します それから Davidが レイトレーシングの実装に役立つ 新しいツールを紹介します では レイトレーシングの 代表的なユースケースを いくつか紹介します ゲームや動画では さらなるリアル感の実現が 常に追求されています また 長年にわたり グラフィックスの手法では ラスタライゼーションが主流です ラスタライゼーションは 美しい画像をリアルタイムで 作り出す上で優れた手法です しかし 私たちが 実現できることには限りがあります レイトレーシングは シェーダから ワールドスペースへの クエリを実現するメカニズムであり 刺激的な新しい手法の可能性を広げます また ラスタライゼーションと 組み合わせることで ビジュアルを 大幅に改善できます いくつか 例をご紹介します ラスタライゼーションで 常に問題となるのが 反射です ラスタライゼーションでは ピクセルに影を付ける場合 シーンの他の部分の コンテキストがないため 反射を正確に表現できないからです そこで その情報を生成するために 余分な作業をしなければなりません レイトレーシングを利用すれば 影を付けるピクセルから 光線を追跡することができ 環境にあるものを 見つけられます それだけでなく そのプロセスを 再帰的に利用して 影を付けたり 反射の中での反射さえも 表現したりできます その他に レイトレーシングが 有効な要素は 影です ご覧のように ラスタライゼーションの場合 モペッドの湾曲面では シャドウマップの 解像度のため 影の輪郭がぼやけ エイリアシングが発生することがよくあります レイトレーシングの場合 影は より鮮明であり シャドウバイアスなどの パラメータを 必要とせずに エイリアスの問題に対処します ソフトな影も より正確に 実物に近く表現できます 遮蔽物との近さに応じて 影をシャープにしたり ソフトにしたりして 自然な表現が可能です ラスタライゼーションでは サンプリング時に シャドウマップのフィルタリングに 頼らざるを得ません しかし レイトレーシングでは円錐内の 光線を追跡するだけで済みます 最後に レイトレーシングが ビジュアルを向上できる点として 透過性が挙げられます 従来のラスタライゼーションでは 透過性を 正確に表現するのは非常に困難です この画像では 窓に差し込む日光に 着目してください ガラス上の半透明の文字の 影がありません 従来のシャドウマッピング法で よく見られるのが 透明な物体に関する問題です レイトレーシングでは 透明な素材の カスタムインターセクション関数を 作成できます その関数を使用して 素材を通過する光線と 通過しない光線を 定義することができます このように 自然に文字の影が 胸像に投影されます そして全体的に すべての影が シャープになっています では なぜ レイトレーシングは ビジュアルを大幅に 改善できるのでしょうか? 説明のため まずは 既存のラスタライゼーションが どのように機能するか確認しましょう ラスタライゼーションプロセスでは メッシュがMetalに送られて レンダリングされます 頂点シェーダによって それをワールドスペース内や カメラの前に配置します それから それらのプリミティブを ラスタライザーで ピクセルやフラグメントに 配置します それらのピクセルに フラグメントシェーダで 影を付け それを出力画像に 組み込みます ご存じのように 各ピクセルには 個別に影を付けられるので 並行処理により ラスタライゼーションプロセスで GPU効率が向上します ただし その代わり 影を付けるときに シーンのその他のコンテキストが 完全に失われます ピクセルに関連付けられている ポイントの周囲に どのようなオブジェクトがあるか わかりません そのような場合 高度なゲームエンジンでは 中間情報を生成する 余分なレンダーパスが追加されます 次に フラグメントシェーダが そのデータを利用して ポイントが配置される ジオメトリコンテキスト情報の 近似値を計算します この処理について もう少し 詳しく確認してみましょう この手法では シーンのジオメトリ情報を シーンに直接ラスタライズせず 中間テクスチャにラスタライズします アルベド 深度 法線などが 当てはまります これは 一般的に ジオメトリバッファパス 略してG-Bufferパスと 呼ばれています 中間テクスチャは 光線近似パスへの 入力として 光がどのようにシーンの オブジェクトに作用するか 近似値を得るため 使用されます 例として スクリーン空間における アンビエントオクルージョンや 反射が挙げられます 最後に 多くの場合 ノイズを除去または 若干ぼかしをかけることにより なめらかな画像が作り出されます すべての要素が1つにまとめられて 最終的な画像が完成します これらの手の込んだ手法は 画像の改善に 役立つこともありますが やはり 正確性には欠けます 一方 レイトレーシングの手法は まったく異なります より正確なビジュアルを 簡潔な方法で実現できます メッシュを1つずつ 処理する代わりに シーン全体の アクセラレーション構造を 構築します すると GPUがポイントから所定の方向へ 光線を追跡して 交点を見つけます シーンの すべてのコンテキスト情報に アクセスできるようになります レイトレーシングでは 光線の相互作用をモデル化するので レンダリングを超える用途が 見込まれます 音声および 物理学的シミュレーション 衝突判定 AIおよび 経路探索に利用できます レイトレーシングは 極めて有効な手法なので ラスタライゼーションと 組み合わせて それぞれの独自のメリットを 活用してみましょう この手法は 「ハイブリッドレンダリング」と呼ばれます ハイブリッドレンダリングされた フレームの作成方法とユースケースで この手法を見てみましょう 最初にラスタライズされたフレームの ダイアグラムから始める場合 レイトレーシングを使用して 光線近似パスの 一部または全部を 置き換えることができます プライマリ光線の役割を持つ G-Bufferをラスタライズします そしてレイトレーシングで シーンの他の部分にクエリして 光の特性を より現実に 近い形でシミュレーションします 従来どおり ノイズを除去し 光を補正しますが 仕上がりはシーンのデータに対して より正確なものになります このフレームアーキテクチャは ハイブリッドレンダリングの さまざまな手法を模索するための 基盤を提供します このようなフレームの Metalを使用した エンコード方法を紹介しましょう 最初に G-Bufferを埋め込みます そのためには レンダーパスを作成して G-Bufferを書き込みます 次に そのテクスチャをパスの アタッチメントとして設定します 後続のパスで使用できるように 画像がメモリに保存されたことを 確認します パスを開始し レンダリングをエンコードして レンダーパスを終了します レイトレーシングコンピュート ディスパッチをこれに追加します 中間テクスチャを作成した後は レイトレーシングパスを エンコードしましょう 同じコマンドバッファから コンピュートパスを作成し G-Bufferテクスチャが入力として 設定されていることを確認します デフォルトで 読み取り/書き込み 依存関係をMetalが追跡するので 同期を心配せずに アルゴリズムに集中できます これはコンピュートパスなので レイトレーシングの結果を書き込む ための出力テクスチャを設定します PipelineStateオブジェクトが 設定されています コンピュートシェーダの スレッドごとに ピクセルやリージョンのレイトレーシング の結果が計算されます 最後に 2Dグリッドを ディスパッチしてパスを終了します このパスをエンコードした後 引き続き 光線累積パスなどの 他の要素を エンコードすることができます または フレームの残りの部分を エンコードする間 GPUが稼働を開始できるように コマンドバッファを送信することも できます 2つのパスに分かれて グラフィックをエンコードしたので 中間レンダーアタッチメントを システムメモリに保存して パスが相互に通信できる ようにする必要があります AppleシリコンとiOSデバイスであれば ここに さらなる改善の余地があります Apple GPUでは ハードウェアが タイルメモリを使用して 作業中のピクセルデータを保持します パスの最後で タイルメモリがシステムメモリに 移されるので 次のパスの開始時にデータを 再読み込みする必要があります しかし理想的には システムメモリとの往復を 回避して コンピュートパスを タイルメモリで 直接利用できる方が望まれます 今年から レイトレーシングの成果物を レンダーパイプラインから送信して これを実現する機能が 新たに追加されました タイルシェーダにより レンダーとコンピュートを 1つのパスに混在させて オンタイルメモリを利用できます 使用帯域幅と メモリ消費が減るので ユーザーのデバイスの温度上昇を 抑えるのに役立ちます ぜひ 2019年の「Metalによる最新の レンダリング」セッションで レンダーとコンピュートの 効率的な組み合わせ方を確認し レンダーからレイトレーシングに 適用できるようにしてください また 今年の 「Metalレイトレーシングによる Appの強化」 では Metalの レイトレーシングにおける その他の改善について確認できます ハイブリッドレンダリングの エンコードを確認したところで レイトレーシングによって 改善できる手法を いくつか紹介します ここでは 影 アンビエントオクルージョン 反射に絞り込んで説明します まずは 影です 影は シーン要素の相互の 距離感を 示すのに役立ちます 影を付ける場合 ラスタライゼーションでは シーンのコンテキストが 失われることが 問題となります シャドウマッピングを 利用することもできますが 光源ごとに余分なレンダリングが 必要になります ラスタライゼーションでは 最初に 光源を起点として シーンをレンダリングします 一連の深度マップが作成され それを光源ごとの 変換マトリックスと共に 保存する必要があります それから メインカメラを 起点としてレンダリングします 各ピクセルに影を適用するには ポイントを光源の座標に 変換する必要があります マップを基に深度を サンプリングし 深度の値を比較して 光源ごとに 影を付けるか 光を当てるか 判断します この手法には デメリットがいくつかあります 第1に 光源ごとに シーンをレンダリング しなければなりません つまり シーンを何回も 処理するということです 第2に シャドウマップの 解像度が決まっているため 影にエイリアシングが発生します それだけでなく 画像に収まらなかったピクセルの 情報も取得できません レイトレーシングによる 影の処理と比較してみましょう レイトレーシングで 影を計算する場合は ポイントから光源の方向に 光線を追跡し 光路を遮るオブジェクトが あるか確認するだけです 遮るオブジェクトがなければ シャドウイングで その光源を考慮します 遮るオブジェクトがある場合は その光源を光の計算から 除外するだけです 遮蔽オブジェクトの シルエットに対して 自然な影が作られていることに 着目してください さらに 深度マップの情報のみを 頼らなくても 済むようになります 光の錐台の外や カメラの死角にあるポイントの 影を判別できます レイトレーシングでは シャドウイングを どのように簡単にできるか 確認してみましょう 最初に メインカメラを起点に レンダリングします 次に アクセラレーション構造と カメラ位置からレンダリングした 深度マップを レイトレーシングカーネルに 取り込みます ピクセルの位置を計算したら 後は 光源に向かって光線を 追跡するだけです それから 遮蔽オブジェクトとの 交点の有無に応じて ライティングまたは シャドウイングします こうして作成された シャドウテクスチャを レンダーパスの結果と組み合わせて 最終的な画像を作成します これをMetalのシェーダで コーディングしてみましょう このシェーダコードでは まず 深度とthread_idから 各スレッドが処理する位置を 計算します 位置を基に影の光線を作成し それを光源に向かって 追跡するように設定します ポイントライトや スポットライトなど エリアライトなど 大抵の場合 最大値と最小値を設定して ポイントから光源まで追跡します 方向性シャドウの場合は 最大値を「無限」に設定します また コーンレイトレーシングを使用して 影をソフトにする場合は shadowRayにジッタを追加することを お勧めします 次に インターセクター オブジェクトを作成します 交点があるということは 影があるということなので 交点を受け入れるように インターセクターを構成します 最後に アクセラレーション構造に 交点を適用します この交点の結果に基づいて ポイントのライティングを決めます このようにして シーンに対してより精度の高い シャドウテクスチャを作り出します テクスチャを適用してみると 影が とてもリアルで エイリアシングも ないことがわかります レイトレーシングでは 非常に自然な手法で 影を作り出すことができます 光線を追跡して 点から光源に対する遮蔽物が あるか確認するだけです 中間深度マップを 作成しなくても済み 光源ごとに いくつも レンダーパスを作成する 必要はありません この手法は 深度のみに依存するので 遅延レンダラや前方レンダラに 簡単に実装できます そのうえ カスタムのインターセクション関数を 半透明の素材に 利用することもできます 次に アンビエントオクルージョン について説明します 概念上は ジオメトリに囲まれている場合 周囲の光は大量には当たりません アンビエントオクルージョンでは 近接物の密度に基づいて ポイントの環境光が決定されます 隙間の影がより自然になり より深みのある画像に仕上がります 同じことを ラスタライゼーションで行う場合は ポイントの近接物の深度と法線を サンプリングして 周囲に遮蔽物となり得る オブジェクトがあるかどうかが 判別されます 近接オブジェクトの数を基に 減衰係数を計算して 環境光を弱め テクスチャを作成して 画像に適用します しかし 深度バッファや 表面法線などの スクリーン空間情報に依存するため 画像の境界線外にある 見えない遮蔽物やオブジェクトの 情報が欠落します レイトレーシングでは スクリーン空間情報ではなく シーンの実際の ジオメトリデータを利用します 半球空間内で 影を付けるピクセルごとに ランダム光線を生成し オブジェクトとの交点を探します 交点が見つかったら それを アンビエントオクルージョンの 要素として考慮します ここでも アクセラレーション 構造から始めます この手法では 深度と法線のデータが必要なので それらを G-Bufferパスで収集します 深度と法線を使用して 半球空間内に ランダム光線生成します 次に 光線を追跡して 減衰係数を計算します そうすることで 隙間に自然な影が付いている 画像を作成できます では Metalのシェーダを アンビエントオクルージョンに 使用してみましょう まず ランダム光線を生成します ここでは 各スレッドで cosineWeightedRayを 法線と共に使用します この例では ごく近い範囲しか関係ないので max_distanceを 小さい値に設定します 次に インターセクターを作成して アクセラレーション構造に 交点を適用します 結果に応じて 減衰係数に累積します 並べて見比べてみましょう 明らかに レイトレーシングの方が 見栄えの良い仕上がりです スクリーン空間手法の エフェクトの限界がわかる 場所を見てみましょう ご覧のように 限られたスクリーン空間情報のため 表現が不正確になっています これは 実際のジオメトリが カメラに対してほぼ垂直であるため この角度では 深度バッファにないからです 同じ問題が画像全体で見られ 特にモペッドの部分で明らかです この角度からは モペッドの下の部分が 深度バッファで欠落しています そのため スクリーン空間手法では 光の減衰が一切無視されます レイトレーシング版では 地面のピクセルで モペットの下の部分との交点が 正確に特定されています 他にも 画像の境界線付近の 問題がよくわかる例があります 遮蔽ジオメトリが画面外であるため そのコントリビューションが スクリーン空間法では無視されます しかし レイトレーシングでは それが考慮されています ご覧のように ハイブリッドレンダリングでは シーンの 実際のジオメトリを使用して 画像の質を大幅に 向上させることができます スクリーン空間情報の 制限が解消されます 最後に 反射の例を見てみましょう ラスタライゼーションでは 反射は処理が非常に難しい要素です リフレクションプローブを 利用することもできますが 解像度が限られ フィルタリングが必要であるため 動的なジオメトリでは 有効な手法であるとは言えません スクリーン空間法では 反射はスクリーン空間情報によって 制限されます リフレクションプローブでは カメラをシーン全体に沿って 戦略的に配置し 周囲の色情報を 取得する必要があります リフレクションプローブを 使用するには シーンの別の場所から キューブマップを取得します そのためには 基本的に シーンを同じ場所から 6方向でレンダリングします ピクセルに影を付ける場合は プローブとの相対位置を計算し キューブマップをサンプリングして 反射による陰影を表現します 通常 リアルな画像を作るには 多数のプローブをシーン全体に 分散して配置する必要があります 動的なオブジェクトは シーン全体を移動するので 複数のキューブマップを サンプリングして 反射による色を手動で 補間する必要があります また 照射を正確に表現するために キューブマップを事前に フィルタリングしなければならず 解像度が制限されます スクリーン空間リフレクションでは 既にフレームバッファに 配置されているピクセルを 基準にして反射を作成することで これらの問題の一部は解消されます フラグメントシェーダは 法線を使用して徐々に外側に進み 深度マップで隣接オブジェクトが あるかどうかを確認します 何かある場合は フレームバッファから 色を直接サンプリングして 出力画像に適用します ただし 既に述べたように スクリーン空間の制限があります この例をご覧ください フレームバッファに存在する 路面のタイルに対して 再現されている反射は ほんの一部であることがわかります シーンの残りの部分は 失われています さらに 黄色で示されている フェンダー部分の情報はなく カメラに面していない部分が どのように見えるか知る方法が ありません また レイマーチングの場合は 計算コストが高くなりがちです レイトレーシングでは アクセラレーション構造で 実際のシーン情報を利用できるので 前に示した問題を 解消するのに役立ちます 完璧な鏡がどのように 機能するか見てみましょう 最初に カメラからポイントまでの インシデントレイを 作成します 次に それをポイントに 関連付けられている法線に 反映させます これにより 光線を 追跡する方向が決まり 反射オブジェクト を見つけられるようになります そのためには レイトレーシング リフレクションカーネルに G-Bufferの法線と深度を 指定します このカーネルはカメラから 各ポイントまでの ビューベクトルを計算して それを反映し ポイントからその方向に 光線を追跡します 最後に 反射を正確に表現するため レイトレーシングカーネルで 見つけられた交点に 直接 シェーディングします このシェーダの コーディングを見てみましょう ここでも 最初に ポイントの深度を取得して その位置を再構成します 今回は ワールドスペースに配置するので calculatePosition関数で ビューマトリックスの逆行列を 乗算する必要があります それから 法線の 反射インシデンベクターを計算して その方向に光線を作成します 次に インターセクターを作成して reflectedRayを追跡します オブジェクトに当たった場合は そのポイントにシェーディングして 反射を作ります どのオブジェクトとも 交点が無い場合は 単にスカイボックスを サンプリングして その色を返し 空の反射をシミュレーションします この手法では シェーディングがコンピュート カーネルで直接実行されます リフレクションプローブとレイトレーシング の反射を比べてみましょう 右側ではハイブリッド レンダリングが使用され 路面のタイルの細部が よりクリアになっています 建物があり モペッドの フロントパネルに 反射する影まで見えます レイトレーシングでは 反射が自然に再現されます 鏡のような反射と不鮮明な反射が 適切に処理されます これらは 多数の光線を 円錐に沿って追跡し その結果をフィルタリングして 実現できます レイトレーシング リフレクションでは アクセラレーション構造からの 完璧な情報を利用するので スクリーン空間の アーチファクトは発生せず シーンの動的ジオメトリと 静的ジオメトリの 両方を処理できます ここで 重要なこととして 反射の場合 コンピュートカーネルで 直接 シェーディングする必要があります この他にも 頂点データや Metalのリソースに コンピュートカーネルから 直接アクセスする必要がある 手法がいくつかあります その場合は シェーディングの 計算式を 適用するために必要なデータに GPUがアクセスできることを 確認する必要があります その場合は Metalで 引数バッファと呼ばれている バインドレスバインディング モデルを使用してください 詳細については 今年の 「Metalでのバインドレスレンダリング の詳細」でご確認ください 以上 ハイブリッドレンダリングと 別の手法を組み合わせる方法を 実用例と共に紹介しました この方法は より自然な アルゴリズムによる より正確な 表現というメリットをもたらします 場合によっては 従来のラスタライゼーションと比べ レンダーパスが不要になるので メモリと帯域幅を節約できます レンダーからレイトレーシングを 追加すれば すべての作業データをチップに 保存することも可能になります レイトレーシングの導入は 大変な作業です そのため Appleでは 導入プロセスに役立つ 優れたツールを用意しています これらの新しいツールは レイトレーシングデータの取得 アクセラレーション構造のチェック Visible関数とインターセクション関数 のチェック機能などを提供します 次に これらのツールを Davidが紹介します こんにちは David Núñez Rubioです GPUソフトウェアエンジニアです レイトレーシングのサポートは 昨年から開始されています しかし 複雑なAppの開発は 容易ではありません そこで AppleではMetal Debuggerを 提供しています 今年は Metal Debuggerで レイトレーシングのサポートが 提供されるようになりました ハイブリッドレンダリングにより これまで以上にビジュアルが 整えられています レイトレーシングによる ソフトな影 反射 アンビエントオクルージョンは 素晴らしい表現を実現します 私たちは デモの開発中に 問題に直面しました その際に ツールがどのように 役立ったか 紹介します この以前のバージョンのデモでは レイトレーシングによる影が 既に適用されています しかし よく見ると 木の葉の影が 地面に 落ちていないことがわかります 参考版と比べると 違いがより明らかにわかります 2つを比べてみましょう Xcodeを使用して この問題をデバッグするために ツールがどのように役立つかを 確認してみましょう ボタンと をクリックします 静的オブジェクトの問題なので シングルフレームだけを使用します デバッガーで API呼び出しが 左側のデバッグナビゲータに 並んで表示されています オフスクリーンの コマンドバッファを展開して シャドウエンコーディングを 見てみましょう コンピュートコマンド エンコーダには 「Raytrace Shadows」という ラベルが付いています Metalオブジェクトにはラベルを 付けることをお勧めします そうすれば Metal Debuggerで 簡単に見つけられます サムネイルもヒントになます 間違いなく これが 探していたエンコーダです dispatch Threadgroups API 呼び出しをクリックすると 帯域リソースが表示されます これが 現在のカーネルディスパッチに 関連付けられている 全オブジェクトのリストです ここで アクセラレーション構造 を確認できます わかりやすいように ラベルが付いています このカーネルでは アクセラレーション構造を使用して 光線を投影しています これは 通常 バウンディング ボリューム階層 (BVH) つまり 光線が交差する3D空間を表わす ツリー型のデータ構造として 実装されます ここで アクセラレーション構造 ビューアーを開きます
Metal Debuggerに組み込まれた 新しいツールです 構造の概要をご紹介しましょう 右側には3Dビューがあります カスタムのジオメトリ関数や インターセクション関数を含む レイトレーシングされた3Dシーンの ビジュアルが表示されます これは 髪の毛などの カスタムジオメトリや アルファテストで非常に役立ちます 使い慣れたコントロールによって カメラを動かして周囲を見渡します ここで スクロールしながら キーを押すと ズームイン/アウトができます シーンのより詳細な情報を 取得できるように 役立つ視覚化ツールを いくつか構築しました ハイライトされたメニューを クリックして 各種のモードを 試してみましょう 例えば バウンディングボリューム トラバースを視覚化できます これは 1本の光線が 面に当たるまでに横切るために 必要なノードの数を示す ヒートマップです 濃い色は 横切るために より多くのノードが必要であり インターセクションテストに 時間がかかることを示します また アクセラレーション構造 ジオメトリ インスタンス インターセクション関数に基づいて シーンを色分けすることもできます
少しツールに慣れたと思いますので 先ほどの問題に戻りましょう 3Dビューにより ジオメトリがあることが 確認できました ですから 別の原因があるはずです 左側にナビゲータエリアがあります ここでは アクセラレーション構造の 上下の階層を確認できます 任意のアクセラレーション構造を 展開して 元のジオメトリのリストを 確認できます また 透明度やプリミティブの数など ジオメトリのプロパティを 確認することもできます このアクセラレーション構造の インスタンスのリストも 確認できます 木の葉をクリックして それらのインスタンスを ナビゲータに表示し プロパティを調べてみましょう マトリックスに問題はなく フラグは設定されていません しかし マスクで 何か足りないようです このデモでは インターセクション マスクを使用しています マスクの最下位ビットを使用して 影をつくっているオブジェクトに フラグを設定しています 次に Appleのインターセクターで ビット単位と演算を使用して このマスクをテストすると テストが失敗した場合は マスクが拒否されます この動作を 3Dビューで そのまま視覚化できます インターセクターの ヒントメニューを開きます ここで 視覚化のための 光線横断オプションを 構成できます カリング演算を変更するか カスタムインターセクション関数を 無効にするか または インターセクターの マスクを変更することができます デフォルトでは あらゆるものと交差します 影に使用する値に 変更してみましょう シャドウマスクを使用した場合の シーンの正確なビジュアルが 表示されるようになります ご覧のとおり 木の葉が欠けていることが 確認できました 問題を特定したら ソースに戻り マスク値が正しいことを 確認する必要があります これが 影の最初の状態です マスク値の修正後は このようになります 以上が レイトレーシングAppの デバッグに役立つ ワークフローの例です ツールの詳細については 今年度の 「Metalのデバッグ、プロファイリング、 アセット作成ツール」 セッションをご覧ください このセッションでは レイトレーシングによる ビジュアル改善方法を紹介しました ハイブリッドレンダリングは ラスタライゼーションと レイトレーシングの組み合わせです 光線近似法に代わるものとして より正確な表現を よりシンプルに実現します また Appleでは レイトレーシングの導入に役立つ 新しいツールも提供しています ここでご紹介したのは ラスタライゼーションと レイトレーシングの 組み合わせがもたらす 新たな可能性の ほんの一部に過ぎません みなさんが これらのテクノロジーを どのように活用して グラフィックスの 画期的な手法を展開されるのか 待ちきれません ありがとうございました 残りのWWDCもお楽しみください ♪
-
-
6:32 - Hybrid rendering in Metal 1
// Create render pass MTLRenderPassDescriptor* gbufferPass = [MTLRenderPassDescriptor new]; gbufferPass.depthAttachment.texture = gbuffer.depthTexture; gbufferPass.depthAttachment.storeAction = MTLStoreActionStore; gbufferPass.colorAttachments[0].texture = gbuffer.normalTexture; gbufferPass.colorAttachments[0].storeAction = MTLStoreActionStore;
-
6:50 - Hybrid rendering in Metal 2
// Create render pass id< MTLRenderCommandEncoder > renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:gbufferPass]; encodeRenderScene( scene, renderEncoder ); [renderEncoder endEncoding];
-
7:06 - Hybrid rendering in Metal 3
// Dispatch ray tracing via compute id< MTLComputeCommandEncoder > compEncoder = [commandBuffer computeCommandEncoder]; [compEncoder setTexture:gbuffer.depthTexture atIndex:0]; [compEncoder setTexture:gbuffer.normalTexture atIndex:1]; [compEncoder setTexture:outReflectionMap atIndex:2]; [compEncoder setComputePipelineState:raytraceReflectionKernel]; encode2dDispatch( width, height, compEncoder ); [compEncoder endEncoding];
-
11:54 - Ray-traced shadow kernel
// Calculate shadow ray from G-Buffer float3 p = calculatePosition( depth_texture, thread_id ); ray shadowRay( p, lightDirection, 0.01f, 1.0f ); // Trace for any intersections intersector< triangle_data, instancing > shadowIntersector; shadowIntersector.accept_any_intersection( true ); auto shadowIntersection = shadowIntersector.intersect( shadowRay, accel_structure ); // Point is in light if no intersections are found if ( intersection.type == intersection_type::none ) { // Point is illuminated by this light }
-
15:07 - Ray-traced ambient occlusion kernel
// Generate ray in hemisphere ray ray = cosineWeightedRay( thread_id ); ray.max_distance = 0.5f; // Trace nearby intersections intersector< triangle_data, instancing > i; auto intersection = i.intersect( ray, accel_structure ); if ( intersection.type != intersection_type::none ) { // Point is obscured by nearby geometry }
-
19:34 - Ray-traced reflection kernel
// Calculate shadow ray from G-Buffer float3 p = calculatePosition( depth_texture, thread_id ); float3 reflectedDir = reflect( p - cameraPosition, normal ); ray reflectedRay( p, reflectedDir, 0.01f, FLT_MAX ); // Trace for any intersections intersector< triangle_data, instancing > refIntersector; auto intersection = refIntersector.intersect( reflectedRay, accel_structure ); // Shade depending on intersection if ( intersection.type != intersection_type::none ) { // Reflected ray hit an object: perform shading } else { // No intersection: draw skybox }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。