地味にやるほかに道はない。

こんにちわ、Pocolです。
また、120fps対応しろと言われたら大変なので、どうやったっけ?
…というメモ書きを残しておこうと思います。

今回いう所の120FPS対応というのは、超強つよのPCではなく,いわゆる推奨スペックで120FPSを達成するやつで,他の会社みたいにぬるいやつじゃないのでご注意ください。
パフォーマンスバジェットですが,きついのはGPU側に大体なると思います。CPU側は有識者がいればなんとかなるし,CPU側はなんだかんで見れる人は多いはず。
GPU側はグラフィックスプログラマーの中でも,ちゃんと精通している人しかガチな最適化が出来ないということになりやすいです。で,最適化を頑張っても何ともならないなら、仕様的に削るに持っていくほかありません。

GPUパフォーマンスバジェットですが、ざっくりモデル描画で2ms程度に抑えないと,体感的に負け確定です。
1フレームを6.9ms~7.3ms程度に抑えるのが理想です。最低でもには7.9msぐらいに収まっていた方が安心できます。
そして、どうやって120fpsに持っていくか?ですが,ほぼ敵はモデル描画とアップスケールになるはずです。多分この二つが間違いなくボトルネックになります。
モデル描画の方は、とにかく書かないようするのと,シェーダの切り替えコストをできるだけ減らすようにします。シェーダハッシュ順とかでソートしてあげると,切り替えコストがかなり減ります。
続いて,アップスケールですが、こいつが重い。とくにかく重い。4kへのアップスケールとかやるとそら重い。…なので,できるだけアップスケールは最後に持ってくるようにして,そこまでのパスをまず縮小スケールで描くようにして,パフォーマンスをあらかじめ稼いでおきます。で、アップスケール自体が重いのは,これはもう命令を最適化するほかないです。できるだけ,16bit-floatを使った命令演算にするなどして,レジスタプレッシャーなどを減らします。16bitで行けるところは、できるだけ16bitにします。もちろんテクスチャデータ型などもです。AMDやNVIDIAであれば,16bit用のハードウェア専用命令があるので,こいつらを駆使してください。このあたりの最適化はシェーダに相当強いエンジニアと一緒に最適化していくと良いです。手元に実装時の資料無いのでうる覚えですが,アップスケールパスを 1.5ms程度に抑えないと,つらかったような気がします。当初は2.5msぐらいかかっていたかと。
 
 モデル描画で 2ms, アップスケールで,1.5ms,おそらくライティングコストはそんなに変わらないので,1ms程度はかかるとすると,これで4.5ms程度です。残りの3msで,できる限りの処理に回します。
当然,非同期コンピュート使って処理時間を隠蔽できる箇所は,できるだけ非同期コンピュートを使うように駆使しまくります。

 あとは,GPUプロファイラ使って,ハードウェアカウンターとにらめっこしながら,ボトルネックを解消していきます。
推奨スペックでの120fps対応は生半可な気持ちではできないので,強くアピールしたいものだけに労力を集中して,諦められるところは諦めて大胆な最適化をします。例えば,賑やかしのオブジェクトなどはゲーム体験に全く関わらないとし,全部表示しないようにするなどです。ここはアーティストの強い協力がないと達成できないので,二人三脚で乗り切る強い絆を事前に構築しておく必要があります。一緒に乗り越えるという形で作業を進めていけるように環境を整えましょう。

 特定条件に応じたプログラムの最適化みたいなのは、かえってエンバグを起こしやすいので,最後にやるのはお勧めしません。出来るだけ、汎用的に効くものを優先した方が結果的に楽になります。

 結構120fps対応はでかいところ真っ先につぶして,あとのちまちまして塵積となるやつを潰すという地味な戦いになるので,意外と持久戦になります。60fpsまでは,やることやればちゃんと速くなりますが,そこからネタが尽き,「どうにもならねー!!!」っていう苦悩との戦いになります。結局地味に積み重ねる他に手段はないです。

 とにかく毎日プロファイルを取って、無駄なところを省いたり無くしていく。これに尽きます。

昨今は見た目よりも最適化が重視される時代です。どんなに見た目が良くても,どんなにキャラが魅力的でも,カクカクのクソ重い動作はユーザーに強い不快感を与えます。
最適化はプログラマーが頑張ればなんとかなるものでもありません。全員の協力が必要です。最適化に関して,理解あるチーム作りをできるように心がけましょう。
ゲームは総合芸術です。この総合芸術の中には最適化も含まれます。ゲームの総合力を上げて,魅力的なゲームをユーザーに届けましょう。
そして,そうすればきっと低評価もつかず,ユーザーの心も鷲掴みにできるはずです。

Playing with Real-Time Shadowsについてのメモ

新年明けましておめでとうございます。
本年もProject ASURAをよろしくお願い致します。

昨年から、ちょっと分け合って各社さんとお話しする機会があって,その中でシャドウについて困っているという話題になりまして。
改めて、シャドウ関連を調べなおしているのですが,13年前にわからなかったことが,GPTさんのおかげでようやく分かるようになってきたので、
今日は今後の実装用にメモを残しておこうと思います。
資料は、下記になります。Real-Time Shadowsのページからダウンロードできます。
[Kasyan 2013] Nikolas Kasyan, “Playing with Real-Time Shadows”, SIGGRAPH 2013.

(さらに…)

リングコマンド!

こんばんわ、Pocolです。

ImGui使っていると、なんかみんな同じ見た目になってしまって面白くないなーと思いました。
そこで,聖剣伝説風のリングメニューを作ってみました。

ソースコードはGitHubにあげています。
https://github.com/ProjectAsura/ImRing

使い方はいたって簡単です。
メニュー項目は第1引数にラベル名,第2引数にImTextureID型のアイコン画像を指定してください。
実装例は次のように追加します。

ImRingItem menus[] = {
    {"Menu1", MenuIcon1},
    {"Menu2", MenuIcon2},
    {"Menu3", ImTexureID_Invalid},
};

アイコン画像がない場合は,ラベル名の1文字目をアイコン代わりに描画します。
アニメーション更新のため,毎フレームImGuiRingMenu::Update()と,ImGuiRingMenu::Draw()を呼び出してください.

// アニメーションを更新.
menu.Update(deltaSeconds);

// 描画処理.
if (menu.Draw(selectedItemIndex, menus, _countof(menus)))
{
    // ここで,選択された項目に応じた処理を行う.
    ...
}

キーを操作を変更したい場合は,ImGuiRingMenu::ConfigのKeyMenuStartやKeyXXXという値を使用したキーのImGuiKey列挙体の値に変更してください。

…というわけで、自作したリングメニューの紹介でした。

あとで読むリスト

こんばんわ、Pocolです。
仕事が忙しすぎて、全然最近論文が読めていないです。
年末・年始の時間を使って、今年の論文を見ておきたいなーと思ったので,メモを随時追加しておくことにします。

SIGGRAPH 2025

・Spherical Lighting with Spherical Harmonics Hessian
  岩崎先生と土橋先生のやつ。
・Bernstein Bounds for Caustics
  コースティクスが気になったので…。
・WishGI: Lightweight Static Global Illumination Baking vis Spherical Harmonics Fitting
  メモリ削減がかなりできるらしい。
・Segment Based Light Transport Simulation
  蜂須賀先生が共同著者にいるやつ。頂点ベースではなくセグメントベースで光輸送を計算する新しいレンダリング手法っぽい。
・Histogram Stratification for Spatio-Temporal Reservoir Sampling
  画像をみる感じだと良さげ。

Eurographics 2025

・Fast Sphere Tracing of Procedural Volumetric Noise for Very Large and Detailed Scenes
  スフィアトレーシングの高速化の話っぽいので,雲とかのレンダリングの高速化に使えるかも。
・Physically Based Real-Time Rendering of Eclipses
  日食の物理ベースレンダリングで、画像がかっこいい。大気の話も含んでいるかもしれないので、あとで確認。
・Dynamic Voxel-Based Global Illumination
  あまり良くはなさそうだが、アイデアがもらえるかもしれないので見る。

I3D 2025

・Aokana:A GPU-Driven Voxel Rendering Framework for Open World games
  メモリ使用量が従来の1/9で,レンダリング速度が最大4.8倍速くなるらしいので、要チェック。

レイトレ合宿11 参加レポート

こんにちわ、Pocolです!
毎年恒例のレイトレ合宿に参加してきました。
ついに第1回合宿から連続で作品提出しているのは,ykozwさんと私だけになってしまったので,どんなにへぼくても何とか来年も作品提出できるように頑張ろうと思いました。

本戦

今年は最多の22作品+1エクスビジョンという結果になりました。

さて、今年の私の提出作品ですが,下記のような作品を作りました。


ソースコードは下記にて公開しています。
https://github.com/ProjectAsura/ponzu/tree/rtcamp_2025

実装概要ですが,下記のような感じです。

今年はブリキのおもちゃ感をテーマにレンダリングしてみました。
まぁ、実装の方は大したことやっていないのですが,RISを導入してみました。
気持ち収束が早くなったかな?という感じがしていますが、ちゃんと比較していないので気のせいかもしれません。

昨年までは乱数生成にPCGを使っていたのですが,今年はAndanteさんのブログで紹介されているIbuki Hashに変更してみました。サクッと差し替えできるのでお勧めです。

あと、去年まではお手製デノイザーを使っていたのですが、このデノイザー内でクロスバイラテラルフィルタを使用していたのですが,この関係で最終出力結果がボケボケな絵になってしまうということが分かったので,今年は思い切ってクロスバイラテラルフィルタを一切使わないという割り切った実装にしてみました。そのおかげでスペキュラーがいい感じの見た目になるようになりました。

アセット作成にはAsset Forgeを使用しました。


Kenneyさんのサイトで配布しているキットバッシュとAsset Forgeを使って,レベルを作りました。
Asset Forgeを初めて使う状態でしたが,操作が簡単なので2時間ぐらいでレベルを作成しました。何とか間に合ってよかったです。お手軽にシーンが作成できるようになったので、来年も使おうかなとおもっています。おススメです。
 ちなみにAsset Forgeは下記から購入できます。日本円で約3000円ちょっとでそんなにお高くないので,自分で配置シーンツールとか作るのがかったるい人には良いと思います。
https://kenney.nl/tools/asset-forge

セミナー


今年も、非常に盛りだくさんの内容でした。
また、皆さんのセミナー資料がアップされたら、順次取り上げていこうと思います。

今年度は本当に時間がなかったので、比較的に誰にも分かる内容かつ知らない人には役立つ内容ということで,DXR 1.2の機能紹介をちらっとやりました。
以下に資料を上げているので,興味ある人は見てやってください!

…ということで本業で忙しい状態でしたが、今年も何とか参加できて良かったです。
このあと、参加者の方から続々とレポートが上がってくると思われるので,そちらも楽しみです。
みなさん、レイを飛ばしましょう!では。

恒例のBBQ会!

こんにちわ。Pocolです。
今年もCEDEC恒例のグラフィックスプログラマーで集まってやるBBQ会(グリル会)を開催するそうです!
昨年参加された方は今年もご参加ください!

詳細については幹事のnikqさんのツイートをご参照ください。

2025/07/07更新
※チケットは完売しました。

果報は寝て待て!

こんばんわ、Pocolです。

昨年に引き続き,グラフィックスプログラマーやTAさんなどでBBQ会を開催するようです。
昨年参加された方は是非奮ってご参加ください。
詳細は,近日中に主催者よりご案内あるそうなので,お待ちください。

そんなわけで,皆で肉喰いましょう!
今年も楽しみだ…。

それではまた!

Steam Deckでのデバッグ

こんにちわ。Pocolです。

Steam Deckでのデバッグ方法について,ググってもあんまりいい情報が出てこなかったので,ここにメモしておこうと思います。

前提

  • Steamの公式ドキュメントを見ておきましょう。
  • Microsoft Child Process Debugging Power Tool をインストールしておきましょう。設定も忘れずに
  • デバッグDLLはSteam Deck実機上に含まれないので,あらかじめ転送するフォルダにデバッグ用のDLLを含めるようにしましょう
  • 開発PCとSteam Deckは同一LAN上になるように接続しておきましょう。
  • Windowsで開発しているものであれば,Proton – Experimentalにするのを忘れないように。

Visual Studioを使ったデバッグ

リモートデバッグを使用して,デバッグを行います。
まず,SteamOS Devkit OSを立ち上げて,実行ファイルやアセットなどを1つのフォルダ下にまとめておきます。
次にUploadを実行する前に下記の設定を行っています。

  • Steam Playにチェック入れる(This title requires Steam Playの項目)
  • Steam Play debugにチェックを入れる(Start Visual Studio C++ debugger service on launchの項目)
  • Wait for attachにチェックを入れる(Wait for a debug client to attach)

チェックを入れてから,Uploadボタンを押して実行ファイルとアセットファイルなどを実機に転送します。
DISMISSにならずにちゃんとアップロードできていたら,Steam Deck実機上からゲームを起動します。
ゲームはSteam Deckのホーム画面から「ライブラリでもっと見る」を選択し,「非STEAM」の項目に居る場合があるので,R1ボタンで切り替えて,デバッグしたいアプリを選択してください。

ゲームが起動したらアタッチ待ちに入るので,Steam Deck上で,Steamアイコンが表示された状態でグルグル回っている画面で止まった状態になります。
この状態で,開発用PC側からアタッチをかけます。
Visual Studioを立ち上げて,リモートデバッグを選択します(「デバッグ」>「プロセスにアタッチ」)。

「リモート認証なしーWindows」を選択して,検索ボタンを押します。
ウィンドウが立ち上がるので,その中からsteamdeckを選択します。
選択するとプロセス一覧が表示されるようになるはずなので,steam.exeを選択します。
前述したChild Process Debugging Power Toolがインストールされて入れば,ゲームにアタッチできるようになります。
アタッチ後は通常のVisual Studioのデバッグと同様に進めていけばよいです。

RenderDocを使ったデバッグ

SteamOS Devkit Client を立ち上げ,Devkitsボタンを押して,下から3番目あたりにある 「RenderDoc captures enabled」にチェックを入れておきます。
チェックを入れたSteam Deck上でデバッグしたいゲームを起動します。
ちゃんと設定がされていれば,画面左上にRenderDocのオーバーレイが表示されるようになっているはずなので,これを確認します。

続いて,開発PCからRenderDocを立ち上げ、メニューから File > Attach to Running Instanceを選択します。
Remote Host Managerというウィンドウが立ち上がるので,Steam DeckのIPアドレスを打ち込み,Addします。
Referesh Allを押して,更新をかけます。ゲームが立ち上がっていれば,win64_preloaderというようなプロセスがあるので,これを選択して Connect to App ボタンを押します。
コネクションが確立されたら,RenderDoc上から,Capture Frame(s) Immediately ボタンを押して,フレームキャプチャーを実行します。
キャプチャーが成功すれば,Captures collected にフレーム画面が表示されるようになります。このデータを一度開発PC上に保存しておきます。
保存の仕方はフレーム画像を右クリックしてポップアップメニューからSave を選択すればファイルダイアログが立ち上がるので,好みの場所に保存しておいてください。

次にフレームデバッグの準備をします。Steam Deck上で,RenderDocのremoteserverを起動する必要があります。
SteamOS Devkit Clientに戻り,Devkitsボタンを押して切り替え,Remote Shell ボタンを押し,ターミナルを起動します。
ターミナルが起動したら renderdoccmd remoteserver -d を打ち込み,RenderDocリモートサーバーを起動させます。
成功すれば,
Spawning a replay host listening on *…
Detaching.
というようなメッセージが表示されるはずです。
次に開発PC側のRenderDocの接続設定を変更します。
RenderDocウィンドウの左下にReplay Contextがあるので,これを接続しているSteam Deckに変更してください。
接続できれば,ステータスバーが Remote server ready というように表示が変わるはずです。

ここまで来たら,あとはいつも通りです。
キャプチャーしたフレームを選択すると,ドローコールなどが見えるようになるので,通常通りにグラフィックスデバッグを進めていきます。

おわりに

かなり設定が面倒ですが,これでデバッグが進められるようになるはずです。
デバッグDLLがなかったり,依存DLLが無いとサイレントでゲームが落ちるようなので,まずはちゃんと起動する状態にするのと,RenderDocのフレームキャプチャーしても落ちない状態に持っていくのが,難所だったりするので頑張ってください。

またカスタムビルド

どうしてもエディタとしてVisual Studioを使いたいPocolです。

一番簡単なカスタムビルドのメモです。
.vcxprojをテキストエディタで開いて,一番下のほうに次ような感じでコマンドを挿入します。

  </ImportGroup>
  <Target Name="Build">
      <Exec Command="call build.bat" />
  </Target>
  <Target Name="Clean">
      <Exec Command="call clean.bat" />
  </Target>
</Project>

ちなみにExecタスクのドキュメントは下記ですので,細かい設定を追加した場合は下記を参考にしてください.
MSBuildリファレンス > タスクリファレンス > Execタスク
https://learn.microsoft.com/ja-jp/visualstudio/msbuild/exec-task?view=vs-2022

Visual Studio上からリビルドを実行した場合は,Clean —> Build の順番で呼び出しされます。
もしリビルド自体をカスタマイズしたいなら

  <Target Name="Rebuild">
    <Exec Command="call rebuild.bat" />
  </Target>

とやってあれば,自前にリビルドコマンドに変更できます。

実行時のコマンドのカスタマイズは,通常のVCと同じようにプロパティから変更すれば良いと思うので,それでやればよいかと思います。
…というわけでカスタムビルドのメモ書きでした。

どっかで

クリックしてtede-msbuild-2.0.pdfにアクセス

とか

あたりを参考にもうちょいちゃんとしたものを今後改造してみたいと思います。