レイトレ日記 2022/06/16

今日は,シーン読み込みを実装することに。
毎回どうしようか悩んで,結局間に合わず同じものを使いまわすという過ちを繰り返してきたので,今回はちゃんとやることにした。

理想的にはバイナリ読み込んで,バイナリキャストして,そのまま使える形になるやつが欲しい!
…と思ったら既にありました。

FlatBuffers!!
https://github.com/google/flatbuffers

これよ。これ!欲しかったやつ。
早速試すと,かなり簡単にバイナリフォーマットを定義できる。
最初はstructとtableの違いが判らなかったが,プリミティブ型じゃないものを配列に取る場合はtableにしないとエラーになるので,自前定義のやつを配列で使いたい場合はtableにすればいいみたい。

結構便利なので,メッシュやらテクスチャやらの定義も書きまくる。

struct Vector2
{
    x:float;
    y:float;
}

struct Vector3
{
    x:float;
    y:float;
    z:float;
}

struct Vector4
{
    x:float;
    y:float;
    z:float;
    w:float;
}

struct Matrix3x4
{
    row0:Vector4;
    row1:Vector4;
    row2:Vector4;
}

struct ResVertex
{
    Position:Vector3;
    Normal:Vector3;
    Tangent:Vector3;
    TexCoord:Vector2;
}

table SubResource
{
    Width:uint;
    Height:uint;
    MipIndex:uint;
    Pitch:uint;
    SlicePitch:uint;
    Pixels:[byte];
}

table ResTexture
{
    Dimension:uint;
    Width:uint;
    Height:uint;
    Depth:uint;
    Format:uint;
    MipLevels:uint;
    SurfaceCount:uint;
    Option:uint;
    Resources:[SubResource];
}

struct ResMaterial
{
    BaseColor:uint;
    Normal:uint;
    Orm:uint;
    Emissive:uint;
}

table ResMesh
{
    MateiralId:uint;
    VertexCount:uint;
    IndexCount:uint;
    Vertices:[ResVertex];
    Indices:[uint];
}

struct ResInstance
{
    MeshIndex:uint;
    Transform:Matrix3x4;
}

table ResScene
{
    MeshCount:uint;
    InstanceCount:uint;
    TextureCount:uint;
    MaterialCount:uint;
    IblTexture:ResTexture;
    Meshes:[ResMesh];
    Instances:[ResInstance];
    Textures:[ResTexture];
    Materials:[ResMaterial];
}

root_type ResScene;

お作法的には,スネークケースで書かないと警告が出る。…が,そんな他人のルールなんて知ったこっちゃない。仕事じゃないんで。
自分さえよければいい。それが趣味プログラムの醍醐味!

ランタイム側はファイルを読み込んで,バイナリを

auto resScene = GetResScene(m_pBinary);

と引数で渡してやれば,データにアクセスできるようになる。すごく簡単!
ランタイムの読み込み側は実装したので,あとはシーンエディットと書き出しさえ実装すれば,パストレの実装に集中できそう。
シーンエディタ作るのめんどいなぁ。どうしよ?

残り75日!

レイトレ日記 2022/06/12

今日は,目標だった交差判定するところまでを実装した。

DXRでレイとヒットしたところが,赤くなる。
あとは,使うかわからんが,デノイズ処理用にアルベドと法線のデータも毎フレーム作成するようにした,デバッグビューで表示できるようにもしておいた。

あとは,マテリアルのデータや頂点データ等がちゃんとレイヒット時に取れるようになれば,パストレが組めそう。
で,そのためにはシーンデータの管理周りを整備しなくちゃなということで,実装に着手。シェーダ側は既に実装済み。

色々と進めると,作ったModelMgrクラスが根本的にダメなことがわかったので修正した。
HLSL側にでっかいVertexBufferとIndexBufferを渡して使う仕組みだったんだが,UINT32_MAX以上の数扱えないことに今更気が付いたという感じ。
結局,VertexBufferとIndexBufferは各メッシュごとに小分けに作ることにした。
HLSLはDynamicResourceで直接ResourceDescriptorHeapから頂点バッファとインデックスバッファを参照するように変更。
このために,DescriptorIndexを渡す必要があるので,

struct Instance
{
    uint32_t VertexBufferId;
    uint32_t IndexBufferId;
    uint32_t MaterialId;
};

という構造体を作って,これをバッファ化することに。このバッファにはInstanceID()を使ってアクセスする。
無理やりInstanceIdにマテリアルIDとジオメトリIDをパッキングする方法をやめたので,マテリアル数も少し多く扱えるようになった。
DynamicResource様様ですね。大分実装が楽になった。
結構めんどっちい実装なので,アドベントカレンダーのときに,ざっくりどんなつくりは説明しようかなって思っています。

残り79日!

レイトレ日記 2022/06/07

おとといは、会社の提出物関係で残業してしまったので,作業できず。
昨日は,マテリアルエディタのバグを修正した。

結局,定数バッファが設定されていなかったというしょぼバグ。
設計して,そのあとずっと実装を忘れていたんだろうな…。

あとはスキニング用の処理も中途半端な状態になっていて,ボーン行列が設定されない関係で計算がおかしくなっていたので,いったんスキニング処理をしないようにして対処。
時間が出来た時の楽しみとしてスキニング処理周りは残しておくことにする。
これで,スタティックメッシュについては問題なくマテリアルも表示できるようになったので,今夜はエクスポーターを書いて,いよいよレイトレ用のメッシュバイナリとマテリアルバイナリを作ることにする。
週末からはようやくレイトレできそうな予感。

残り84日!

レイトレ日記 2022/06/05

昨日はレイトレするためのメッシュとマテリアルを設定するためにマテリアルエディタの実装を進めていた。
まだ、何かバグってはいるもののジオメトリがそれっぽく読み込めるようになった。

一応だけども,日本語と英語の言語切り替えも対応しておいた。以前に実装した奴よりもシンプルな実装に出来て満足。

土日の目標だった,FBXとGLTFの読み込みは辛うじて達成。
マテリアル設定があやしいのとFBXの表示面がおかしい気がするので,今日対応出来たら対応しておく。
マテリアル定義はシェーダファイルから自動で作成されるように実装しているので,シェーダ書けば簡単に定義を追加することが可能。
シェーダ自体もホットリロードが利くように実装しているので,ガシガシ実装を進められる。

今日は,自前形式のメッシュとマテリアル形式に出力して,明日・明後日あたりから,DXRでレイトレするところまで進めたいなぁ…。

残り86日!

昨日は,ykozwさんが,レイトレアドベントカレンダーで「魔方陣、ガロア体、QMC」についての記事を公開してくれたようです。結構記事が長くてビビったのと,わかりやすく書かれていて,自分みたいな素人でも分かるのがいいですね。今回実装としてR2をサンプラーとして使おうかと思っていたので,こうした善し悪しが書かれている記事は大変有益で,本当に助かります。
こういう有益な記事が増えると,もっと国内で増えてくれると嬉しいですね。

レイトレ日記 2022/05/31

昨日は,とりあえずざっくりシェーダを書くところまで。
ルートシグニチャなどのレイアウト周りを決定した,Dynamic Resourceを使うことにしたので,ローカルルートシグニチャ要らずでスッキリした。
で,コンパイルしたが何かシェーダ周りで引っ掛かりまくる。
調べてみたら,何かWindows SDKのインストールが中途半端な状態になっていて,dxcompiler.dllとdxil.dllが同じディレクトリに存在しない状態になっていて,おかしなバイナリを吐き出す状態になっていた。
最新のWindows SDKをVisual Studio Installerから入れることで解決。
最新のWindows SDKを使ってもDynamic Resource周りでビルドエラーがでるので,Agility SDKを導入。
これで,ビルドが通ってアプリが立ち上がるところまで確認できた。

今日からは,マテリアルエディタ周りの実装に入って,DXR使ってメッシュを表示するためにメッシュのバイナリとマテリアルのバイナリを出力して,交差判定するところぐらいまで実装を奨めたい。
マテリアルエディタのメッシュローディングにassimp使っていたんだけども,メンテがめんどいのとFBXが正しく読み込めないとかの問題があることがわかったので,assimpは廃止しよう。
代りにtinygltfとFBX SDKとあと自前のOBJローダーを使って3ファイルだけサポートするように変更してしまおう。
ライトとかの設定もできるようにしたいところだなぁ…。

残り91日