そこで、F# の足を伸ばすために、レイ トレーシングのチュートリアルを行っています。チュートリアルは C++ で書かれているため、機能的な方法で概念を適用する方法を理解するのはかなり楽しい課題です。最終的にはレイトレーサーを並行して実行するつもりなので、すべてをできるだけ機能的な方法で書きたいと思います。しかし、それは私を次のような状況に陥らせました。その核心は、レイ トレーシング以外のトピックに現れると確信しています。
Engine
(とりわけ)Scene
オブジェクト(オブジェクトのコレクション)を格納するオブジェクトがありPrimitive
ます。現在、そのScene
中Primitive
の と は完全に不変です。
レンダリング時間を改善するために、通常の 3 次元グリッドを実装しています。効果的な方法でグリッドをトラバースするために、このチュートリアルでは、トラバーサル アルゴリズムと、グリッド境界をまたぐプリミティブの交差テストの数を減らすために、このペーパーを参照しています。後半部分の仕組みは次のとおりです。
- それぞれ
Ray
に固有のrayID
- それぞれ
Primitive
にlastRayID
フィールドがあります。 Ray
が との交差をチェックするときPrimitive
、- のが
rayID
のRay
と等しい場合、交差テストはスキップされます。lastRayID
Primitive
- それ以外の場合、テストが実行され、
rayID
のが のフィールドにRay
格納されます。lastRayID
Primitive
- のが
これは、交差テストをキャッシュするための優れた方法ですが、シーケンシャル レイ トレーサ用に設定されており、2 つの同時レイに対してもまったく機能しません。したがって、フィールドを使用mutable
してこのアルゴリズムを実装することはできますが、本質的に並列化可能なレイ トレーサーという最終目標を達成することはできません。
私には1つの考えがあります。各プリミティブで変更可能な状態を保存する際の問題は、レンダリング アルゴリズムに関して、シーンがグローバル エンティティであることです。一方、各光線は完全に自己完結型です。そのため、各レイで、既にテスト済みのプリミティブのセットを構築できると考えました (このセットは、lastRayID
上記のフィールドに相当します)。これに関する問題は、各レイの寿命が非常に短く、常に多くのレイが存在する可能性があるため、各レイにそのようなデータ構造を設定するとコストがかかる可能性があることです ((デ) 割り当て時間とメモリ消費コストがすぐに加算される可能性があります)
この種の状況に対処するためのアドバイスはありますか? 共有された可変状態をローカルの可変状態などに変換することが一般的なアイデアであったとしても、それは私を大いに助けると確信しています。必要に応じて何かを明確にしていただければ幸いです。