Dreams Engineメモ

Dreams Engineの仕組みについてメモ

データ表現

CSG

アーティストはCSG(Constructive Solid Geometry)でモデルなどを作る
CSGのEdit-Listという形で管理される
Edit-Listは100kのEditまでサポート
1000^3のグリッド空間でそれぞれのセルについてEdit-Listを評価することで表面を決定する
空間を4x4x4単位で分割していき、局所空間毎のEdit-Listがなるべく短くなるようにする
形状の表面はなるべく分割し、空であったり完全に埋まっている部分は分割しないようにする
分割するかどうかの判断はCSGから計算されたSDFの値を利用する
実験の結果、SDFはL1距離やL2距離ではなく、Lmax距離(Max-Norm Distance)を用いるのが良いとわかった

PointCloud

様々な検証の後に、メッシュ化やVolumeRenderingではなく、CSG表面へPoint Cloudの生成することを試した
SDFは中間表現扱いとなり、Pointを生成する際の評価に利用される
Edit-Listの空間分割の際にSDFの表面上を詳細に分割するようにしており、空間は4x4x4で分割されている
4x4x4=64スレッドでLeafVoxelにSDFのゼロ境界が交差するかチェックし、交差する場合はPointを生成する
LeafVoxelひとつにつきPointは一つとする

LeafVoxelは4x4x4単位でBrickとして管理されている
Brickはヒルベルト曲線で空間充填するように並んでいる
256点毎に1クラスターとしてまとめて処理をする
ヒルベルト順で空間的にジャンプがある場合はバウンディングボックスがタイトになるように調整(よくわからない)

クラスター毎にバウンディングボックスと、法線の境界情報(クラスタ内法線の上限下限?)を持つ
クラスター内のPointは位置、法線、ラフネスをdword(32bit?)にパックしたものと32bitカラーを持つ
クラスター内のPointの情報はDXT1で圧縮される

また、LOD毎に独立したクラスターを計算してミップピラミッドクラスタとそのPointCloudを生成する

レンダリング

モデルのPointCloudを描画をする
各モデルのクラスターをBVHに配置(グローバルではなくモデル一つがBVHでクラスターを管理している?)
LOD間の遷移を滑らかにするために、ロシアンルーレットで25%までPointを間引く(クラスタ毎に256->64まで滑らかに間引かれる)
どうもPointをComputeShaderでAtmicに"Splat"描画をしているらしい

メモ

Brickは4x4x4のVoxelの塊
CSGからSDFを作る(ランタイム?もう一度調べる)
SDFはL1やL2ではなくてLmaxらしい
試行錯誤の後にメッシュやVolumeRenderingではなく点群による描画に行き着いたとのこと

肝としてはPointCloudデータの生成とその圧縮、クラスター単位のカリングとLOD、Compute?によるAtomic演算描画あたりだろうか