明日からCEDEC!

こんばんみん。Pocolです。

いよいよ明日からCEDECですね。
今年は前日入りしています。
所属会社も変わったこともあり,レポート提出しないといけないので,レポート提出用に明日からこちらにメモを残していこうかなと思います。

ちなみ、みなさんご存じかと思いますが…
CEDECの受講パスですが,バーコードに不備があり交換の必要があるそうです。
詳しくは下記の公式ページをご参照ください。
パス交換のお願いとお詫びのご連絡

新しい名刺が欲しい方は会場でお声がけください!
明日からの3日間楽しみです!
それでは、また。


レイトレ合宿の季節ですね!

こんばんわ、Pocolです。
レイトレ合宿の季節になりましたね。

そういえば,去年のレイトレ合宿については何も書いていないような気がしたので,書いておきます。
昨年の結果は下記ページから確認できます。
https://sites.google.com/view/rtcamp9

私の去年のテーマは「GGXで描画する!」というものでした。
完全な鏡面反射では面白みがないので,すこしグロッシーな反射を描画したい。…と思いレンダラーを書いてみました。

ソースコードは下記にあります。
ponzu


実装としては,DirectX RayTracingを用いています。
デノイザーはクロスバイラテラルフィルタを使う単純なものです。
アセットはKenny Blaster Kitを拝借しています。

プログラム作成はかなりトライアルアンドエラーを繰り返すので,昨年からシェーダリロードに対応するようにしました。
今年はもうひとつ進めてblinkを用いたC++側のホットリロード対応しようかなって思います。

PNG出力はやっぱりfpngが圧倒的に速いので,昨年も用いました。恐らく今年も用いると思います。
https://github.com/richgel999/fpng

シーンデータはFlatBuffersを利用しており,デシリアライズの時間が短くなるようにしています。
https://github.com/google/flatbuffers

さて,今年開催されるレイトレ合宿10ですが,ルールや実行環境は下記の通りだそうです。
https://github.com/shocker-0x15/rtcamp10_setup/blob/main/exec_env_spec.md
今年は,256秒で描画しないといけないそうです。出来るだけ無駄なくプログラムを組まないといけないですね。
今年の参加エントリーはもう締め切られているため,レイトレ合宿への参加に興味がある人は,日頃からレイトレのプログラム画像をX(旧Twitter)などにあげると良いかもしれません。

Wave組み込み命令を使ったテクニック

今週の,Graphics Programming Weekly Issue 347 – July 7th, 2024で,Wave組み込み命令を使ったテクニックの記事が記載されていました。
非常に参考になるので,目を通しておいた方が良いかと思います。
Compute shader wave intrinsics tricks

ライティングに関係するものはSIGGRAPH 2017 Advances in Real-time Rendering Courseの”Improved Culling for Tiled and Clustered Rendering”に記載されています。
ゲーム開発者であれば,とあるプラットフォームSDKのサンプルプログラムにも記述があるので見てみると良いかと思います。

コースティクスシェーダ

ShaderToyにいい実装があったので,自分なりにパラメータ調整したやつ。

// Based on: https://www.shadertoy.com/view/3d3yRj
// See also: KdotJPG's https://www.shadertoy.com/view/wlc3zr

float water_caustics(vec3 pos, float thickness) {
    vec4 n = snoise( pos );

    pos -= thickness*n.xyz;
    n = snoise( pos );

    pos -= thickness*n.xyz;
    n = snoise( pos );

    pos -= thickness*n.xyz;
    n = snoise( pos );
    return n.w;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 p = (-iResolution.xy + 2.0*fragCoord) / iResolution.y;

    // camera matrix
    vec3 ww = normalize(-vec3(0., 1., 0.8));
    vec3 uu = normalize(cross(ww, vec3(0., 1., 0.)));
    vec3 vv = normalize(cross(uu,ww));

    vec3 rd = p.x*uu + p.y*vv + 1.5*ww;	// view ray
    vec3 pos = -ww + rd*(ww.y/rd.y);	// raytrace plane
    
    pos.y = iTime*0.25;	// animate noise slice
    pos *= 3.;		// tiling frequency

    float w = mix(water_caustics(pos, 0.085), water_caustics(pos + 1.0, 0.085), 0.5);

    // noise [-1..+1] -> color
    float intensity = exp(w*2.5 - 1.);
    fragColor = vec4(vec3(intensity), 1.);
}

ちなみに元にしたコードは,https://www.shadertoy.com/view/ssfBDfにあります。

バジェット&パフォーマンス メモ

開発の為に各社のパフォーマンスバジェット数などのメモを残しておきます。
基本はPS5世代のオープンワールド関連で,メモは随時更新します。
また、ここに載っていないものでご存じのものがあれば、ぜひコメント等にて紹介して頂けると幸いです。

Cyberpunk 2077

・GDC 2023, “Building Night City: The Technology of Cyberpunk 2077”.
エンティティは15 millionなので,15 * 100万 = 1500万エンティティ。
ワールドセクターは256m単位。



Spider-Man 2

GDC 2024, “Applied Mesh Analysis: Automating Distant City LODs in Marvel’s Spider-Man 2”.

Hogwarts Legacy

GDC 2024, “Open World Rendering Techniques in ‘Hogwarts Legacy'”.
TODO : 後で追記。

Alan Wake2

GDC 2024, “Large Scale GPU-Based Skinning for Vegetation in Alan Wake”.





Call of Duty:MW2



God of War Ragnarok

GDC 2023, “Rendering “God of War: Ragnarok””.



Horizon Forbidden West

GDC 2023, “Space-Efficient Packaging For Horizon Forbidden West”.

GDC 2022, “Adventures with Deferred Texturing in Horizon Forbidden West”.

Ghost of Tsushima

GDC 2021, “Zen of Streaming: Building and Loading Ghost of Tsushima”.


Final Fantasy 16

CEDEC 2023, “Final Fantasy XVI:大規模ゲーム開発に向けて開発環境の取り組み”.

Skull and Bones

CEDEC 2023, “Skull and Bones カメラ依存のテクスチャストリーミング実例紹介”.


Tom Clancy’s The Division

GDC 2016, “Global Illumination in Tom Clancy’s The Division”.


眼球のコースティクスのリファレンス

忘れないようにメモ。
眼球のコースティクスのリファレンス動画がX(旧Twitter)に上がっていました(5年前)。

高解像度バージョンの動画などはスレッドにリンクがあり,https://t.co/bc9HF4uWO5からダウンロードできるようです。

接線空間データの圧縮について

知識というのは更新しないダメですね。
法線データのOctahedral Encodingをよく用いています。

※図は[Cigolle 2014]より引用。

ここで,Octahedron を45度回転させて,符号をビットを別に持てば,表現する面積領域が増えるから精度が倍に上がるのと,OctWrap()の演算も無くなるので,デコードも高速できるそうです。

これが,John White 3Dというブログの,”Signed Octahedron Normal Encoding”という記事にのっていました。これをみて「ほぇぇ~」と感心しました。頭いい!
ただ、符号ビットを別に持つの何かやだなーと思っていたのですが,R10G10B10A2なら10bit分が残っているので,この32bitでNormal, Tangent, Bitangentを表現しちゃいたいところです。

以前に書いたかもしれませんが,SIGGRAPH 2020のDOOMで使っている,接線空間表現を使おうかなと思っていました。

※図は[Geffroy 2020]より引用。

しかし、今日もっといいやつを見つけました。
Jeremy Ongさんの”Tangent Spaces and Diamond Encoding”というブログ記事。この中でも上記のDOOMの方式が紹介されていますが,もっといいのがダイヤモンドエンコーディングというやつ。

※図は[Ong 2023]より引用

ここでも,Octahedronの考えを利用しています。ちなみにサンプルコードは下記の様です。

※コードは[Ong 2023]より引用

ダイヤモンドエンコードで得られた接線を表すデータを残りの10bit部分に入れてしまえば,うまくR10G10B10A2に収めることができます。

ちなみに,Octahedron Encodingですが,Z+の半球が約束されているのであれば符号ビットもいらないので,下記のHemi-Octで実現できるそうです。

※コードは[Cigolle 2014]より引用

…ということで接線空間データの圧縮についてでした。

参考文献

  • [Cigolle 2014] Zina H. Cigolle, Sam Donow, Daniel Envangelakos, Michael Mara, Morgan McGuire, Quirin Meyer, “A Survey of Efficient Representations for Independent Unit Vectors”, Journal of Computer Graphics Techniques Vol.3, No.2, 2014.
  • [JohnWhite3D 2017] John White 3D, “Signed Octahedron Normal Encoding”, https://johnwhite3d.blogspot.com/2017/10/signed-octahedron-normal-encoding.html, 2017.
  • [Geffroy 2020] Jean Geffroy, Axel Gneiting, Yixin Wang, “Rendering The Hellscape of DOOM Eternal”, SIGGRAPH 2020 Advances in Real-Time Rendering course.
  • [Ong 2023] Jeremy Ong, “Tangent Spaces and Diamond Encoding”, https://www.jeremyong.com/graphics/2023/01/09/tangent-spaces-and-diamond-encoding/, 2023.

Game Boy 研修(2)

今日は,エミュレーターの実装の進め方について紹介します。

基本的には…
MJHDというのブログ記事の「Rustでゲームボーイエミュレータを自作した話」に沿った手順で実装するのが良いと思います。
また,どのよう実装するかイメージがつかめない方は「脱・初級者のための自作GBエミュレーター開発」というスライドを参考にするものよいかもしれません。

Step.1 ROMをデコードする
Step.2 CPU処理を実装する
Step.3 PPU処理を実装する
Step.4 デバッガを実装する
Step.5 CPUテストROMを通す
Step.6 機能追加・改善を考え,実装する。

ROMをデコードする

まずは,ゲームボーイのソフト。つまりカートリッジデータが読み込みできなければ話になりません。
…なので,まずはカードリッジデータを読み込めるようにしましょう。カードリッジデータが読み込めれば,ゲームで使用する命令列などが読み取れるようになるはずです。
カートリッジのデータフォーマットなどについては,Pan Docs にまとまっているようなので,どういうデータ構造になっているのか?についてはドキュメントを読みましょう。
どんなプログラマーもドキュメントが読み解けるようにならなければいけません。特に,コンソールプラットフォームなどは秘密事項の塊で,インターネットに情報が出ることはめったになく,公式ドキュメントを見なければ何も出来ないということが多々あります。
そのため,ドキュメントを見ながら実装力をつける訓練の最初の一歩としてやってみましょう。

CPU処理を実装する

続いて,絵を出す前にCPU処理をエミュレートした方が良いでしょう。
ロード命令やジャンプ命令・加算・減算・ビット演算など基本的な命令を実現できるようになりましょう。
また,基本的な命令の実装を通じて,低レベルで何が行われるのか?を知ることが研修の目的の一つでもあります。

PPU処理を実装する

グラフィックスプログラマーを目指すものであれば,絵が出せなければいけません。また,やっぱりゲームは絵が出てこそ!というところもあるので,絵を出しましょう。
また、PPU(Picture Processing Unit)で何が行われているかを知りましょう。これを知るためには,PPU処理を実装するのが一番です。
PPU処理の実装が出来れば,一番処理にGame Boyプログラムで作った「Hello World」の文字列表示プログラムが動かせるようになるはずです。

デバッガを実装する

PPU処理まで実装出来たら,あとはひたすら精度・品質を上げていくだけです。
そのためには,デバッガの実装は必須でしょう。
また,デバッガを実装するためにどのようなことをしなければないのか,普段我々がVisual Studio何気なくつかっているブレークポイントなどの機能はどのようにしておこなわれているのか?などデバッガの仕組みを身をもって体験してください。

CPUテストROMを通す

最後の仕上げです。
実機で動作保証がされているCPUテストと呼ばれるROMを実行し,自作のエミュレーターで正常動作すること確認してください。
テストのROMは以下にあります。
https://gbdev.gg8.se/files/roms/blargg-gb-tests/
正常動作しない場合は,エミュレーターの実装に問題があるということです。
特に会社等では,テスト駆動開発を実施している会社もあるのと思うので,ここでテストの重要さ,製品の品質保証など,クオリティーを上げる大事さを学んでください。

機能追加・改善を考え,実装する

言われた仕様,あるいはお題に通りに作れば最低ラインは超えたことになります。少なくとも一般的な会社では言われたこと通りものを作ることが出来れば,きちんと給料は支払われるはずです。
ここから先は,「他とどう差別化するか?」という話です。同じ機能でも見た目をカッコよくできるのであれば,付加価値はあがるでしょう?また,他社や他人には出来ない機能追加をするのもよいかもしれません。あるいは,思い切って機能を削ることによる分かりやすさの改善・動作安定性なども差別化が図れるでしょう。
余力がある人は,自分なりのカラーを出せるように改造・改変してみてください。
特に昨今はKFCの事例のように何も考えない会社が作るとUX(User Experience:ユーザー体験またはユーザー体感)が激悪化しやすいです。また,どことはいいませんが解約手続きの面倒さなど,もう二度と使うもんか!と思うような酷いものあったりします。ユーザーにとって何か使いやすいのか?何が嬉しいのか?については我々は常に思考を巡らせる必要があります。特に日本の大手会社(例えば電機メーカーなど)などはこうした考えが非常に弱く,そのせいで海外メーカーにシェアを取られるというひどい状況に陥っています。携帯電話のUXの酷さなどはそのもっともたる例のひとつになるかもしれません。
我々はグローバルに戦っていく必要があります。そのためは,常にユーザーないし,使う側の立場にとって良いものを提供する必要があると思います。
そこで,余力がある人は作ったアプリに対して,ユーザーにとって有益であるような機能追加・機能改善を実行してみてください。
恐らく基本となる考え方は「自分だったら嬉しいか・喜ぶか」がベースになるのではないかと思います。そこから,平均と比べて自分がどのぐらいズレがあるのかを推測して補正していくと良いでしょう。

Screen Space Reflection関連の資料

実装用メモです。

SSRを実装すると,エッジ部分どうすんのよ?っていう問題が付きまとうのですが,下記の資料で解決方法の1つが示されています。
[Genin 2017] Remi Genin, “Screen Space Planer Reflections in Ghost Recon Wildlands”, https://remi-genin.github.io/posts/screen-space-planar-reflections-in-ghost-recon-wildlands/

SSRの実装自体は下記記事が参考になります。

また,ナイーブな実装だと,下に伸びるようなアーティファクトが発生することがあります。この問題への対策の一つとして,深度の厚みを考慮することによってある程度回避する方法が述べられています(Notes On Screen Space HIZ Tracing)。

また、上記のブログでは,深度によるアーティファクトの問題が指摘されていますが,GDC 2016のTHE RENDERING OF INSIDEの中で紹介されている隣接セルの深度を補間するのが良いでアイデアではないかと触れられています。

最適化については,“Screen Space Reflections in The Surge”の中で触れられているInterleave化を試すのが良いかもしれません。SSAOなどでは実際に実装してみた経験があり,かなり処理負荷削減できました。ただ、この手法はHi-Zには相性が悪いかもしれません。

色々と試して思うのは,HYBRID SCREEN-SPACE REFLECTIONSにあるように,近い点をSSRで解決してしまって,遠い箇所についてはレイトレしてしまった方が,良いかもしれないと思っていますが,実際にHi-Z使うよりもいい結果とパフォーマンスが得られるかどうかまでは試していないので,どこかで試してみるのはありかもしれないです。

また深度の厚みに関しては,”Screen Space Reflection Techniques”という文献の中で,Min-Max Hi-Zという手法が紹介されており,これを使うとパフォーマンスやアーティファクトの問題が解決できるかもしれないです。こちらもまだ試せていないです。