Vulkan+glslでレイマーチング04 & 雑談
ちょっと間が空きましたが、Vulkan + glsldでレイマーチングやってみたの続きです。
前回↓
今回やったこと
・ 鏡面反射の実装
・ オブジェクトスペースの回転
・ ユニフォームバッファ追加
前回に比べて見た目はだいぶ変わりました。内部実装も変わりました。結構Vulkanの勉強になりましたね。
コードは↓です
鏡面反射の実装
中央のオブジェクトと床が鏡面反射してます。これは、レイがオブジェクトにあたったとき、鏡面素材であれば、法線とレイの反射ベクトルを計算してレイの方向を変更することにより実装されています。
簡単にじっそうできるかなーと思ってたましたが、ノイズがでたり画面の一部が真っ黒になっちゃったりして案外手こずりました…
鏡面反射の実装については↓が詳しいです
オブジェクトスペースの回転
オブジェクトスペースの回転を追加しました。中央で回転してるやつですね。
ただ、チェック模様がワールドスペース座標を基準に色付けしているため、オブジェクトスペースで回転させるとチェック模様がぶれて見えるという問題がありました。
苦肉の策として、オブジェクトをすべてワールド座標の原点に置くことで解決しました。(それってオブジェクトスペースと言わないのでは…)
回転については↓が詳しいです
ユニフォームバッファ追加
今回最も時間をかけた部分です。ユニフォームバッファを追加することにより、オブジェクトの大きさや回転量などをシェーダー全体で共通化することができ、シェーダーコードが整理されます
…が、ユニフォームバッファを追加するのが結構厄介でした…。というのも、C++側からシェーダーへデータを渡す場合、Vulkanだとディスクリプタという機能(概念?)を利用するのですが、このディスクリプタがとても複雑で、ユニフォームバッファを追加するというごく単純なこともかなり苦戦してしまいました。
結局、たくさん参考文献を読んで、ディスクリプタについて自分なりのまとめを作りました↓
その文章量の多さから、ディスクリプタの複雑さを感じていただければ幸いです。
できなかったこと
オブジェクトの反復をやってみたかったのですが、なぜかうまく行かなかったので諦めました
屈折表現・ソフトシャドウなども検討していましたが、時間がなくてできませんでした。
まぁ、あくまでVulkanの勉強なので、レイマーチング特有の実装には時間をかけないことにしました。
今後の展開
イメージサンプリング・ファイルインポートなどをやろうかなと思います。この辺ができてないとまともな表現ができませんからね。
レイマーチングはイメージやファイル操作をしなくてもそれなりの画面が作れるというのは強みですね。
本当に実用レベルのレンダラを作ろうとしたら、最適化やコード設計についても考えなくてはなりませんが、今は考えないようにします。
とにかく、絶対必要な機能(イメージサンプリング・ファイルインポート)の実装ができるようになることを目指します。