はじめに
こんにちは!
2023年10月4日から31日までの1か月間、CA Tech JOBのインターンシップ生として株式会社ColorfulPaletteで就業させていただきました。
北田正利(@Masari_Ditgames)です。(HAL大阪4年制3年 就職活動直前に執筆)
普段は、大阪でHAL大阪(専門学校)に在籍しており、Unity(C#)・DirectX(C++)でゲーム開発を学びながら、子供向けプログラミング教室や出身高校で、Unityでのゲーム開発の授業を行っております。
この記事では、私が1か月間グラフィックスエンジニアとして現場で学んだことや、感じたことをご紹介させていただきます。
インターンシップでの目標
今回、一つの大きい目標を立てておりました。
「自分自身がゲームエンジニアとして働く姿を明確にする」
これまでの開発では、個人での開発やユーザーよりもコンテスト受けをよくするためのチーム開発が中心でしたので、どうしても現場を想像しながらの開発に偏っており、今回初めての開発現場でハードルが高いといわれているグラフィックスエンジニアの業務を実体験し、私自身がこれから目指すエンジニアの将来像をしっかりと持っておきたいと考えておりました。
タスク
- URPで画面を歪ませるポストプロセスの実装
- Unityエディター上でのみ、揺れ骨がおかしくなるバグの修正
- タイムラインでの停止でTrailRendererが止まらないバグの修正
この中でも「URPで画面を歪ませるポストプロセスの実装」タスクに関することに絞ってお話しできればと思います。
ポストプロセス
レンダリング結果の画像を画面に出力する前に、フィルターとエフェクトを適用する処理です。
- ブラー
- 被写界深度
- アンビエントオクルージョン(環境遮蔽)
などがよく使われます。
RendererFeature
URPの機能の一つで、Unityがオブジェクトを画面に出力するまでの工程の中に描画パスを自由に差し込みやすくする機能です。描画パス中のどのタイミングで処理を差し込むのかをRenderPassEventで指定でき、透明オブジェ クトの描画前に処理させることなどができるため、シェーダーだけでは実装が難しい処理やより効率的な描画プロセス、自前のポストプロセスを実装することに活用されます。プロジェクトごとに独自の描画パスを実装できるため、個々のプロジェクトに特化した描画プロセスを構築することが容易になります。
はじめてのURP Renderer Feature
専門学校では、「DirectX」を使ったオリジナルのレンダーパイプラインの制作を中心に学んでいたので、今回初めてUnityのレンダーパイプラインを触ることになり、少し心構えをしておりました。しかし、基本的にレンダーパイプラインの流れは一緒ですので、DirectXでの知識が非常に役に立ったと感じました。
波で画面を歪ませるシェーダー(スクリーンディストーション)
業務では、元々実装されていた「ディストーション(歪み)」処理を改良して、歪みの表現パターンを増やせるように 汎用性を持たせつつ、元々実装されているディストーションと同等のパフォーマンスを目指しました。
実機テスト 負荷検証
波の作成と実装まではスムーズに進みましたが、負荷検証の結果が厳しいものとなったので、最適化させることに一層力を入れました。
実装初期段階の計測結果 (改良前)
この段階では、2次関数をループして波を表現する関数で波の歪みを表現しておりました。実装と汎用性を優先していると、この処理だけに5ms近くまで負荷が高くなってしまいました。
完成時の計測結果 (改良後)
完成して実装する時点での計測結果は「 1.3ms 」で、処理負荷を7割ほど軽減することに成功しました。
軽量化
スクリーンディストーションの負荷を軽減するために行った最適化で実装したことや学んだことを紹介します。
CPUで計算させる
「CPUは高度な計算が得意」「GPUは単純な計算が得意」といった性質を理解した上で、させたい処理がどちらに適しているかで、処理を分けることが非常に大切だと学びました。
今回のケースでは、途中まで波の回転をシェーダーで処理させていましたが、移動・回転・スケールのアフィン変換行列には三角関数を使った計算が含まれるためCPUでアフィン変換行列を作成し、その結果をGPUへ送ることで、GPUでは行列の合成計算だけで処理できるように置き換えることができました。
ピクセルシェーダーで計算すると、各ピクセルごとに計算することになるため、この方法では一度の計算で済むということも大きな利点です。
割り算を減らす
除算は加算や乗算と比べて計算コストが何倍も大きいため、逆数を使って予め計算を行い、GPU側では定数として扱うなど、他の演算に置き換えることで負荷が軽減されることがあります。
さらに、定数で除算する計算は変数で除算する計算よりも処理が軽減されることもありますので、除算する場合は定数で除算することを心がけることで処理負担が軽減される可能性があります。
saturate関数やsign関数をうまく使えばいろんな使い方ができる
saturate(x) ・・・ xの値を0~1にクランプしてくれます。
sign(x) ・・・ xが0未満の場合は-1、0の場合は0、0より大きい場合は1を返してくれます。
この二つの関数は計算コストが高くないため、活用して符号の抽出や、シェーダーの負荷原因である条件分岐などの処理をこの二つの関数で代用することができます。
コンパイル結果(アセンブリ)で計算を確認
シェーダーをコンパイルした結果をアセンブリとして確認すると、想像以上に計算が行われていたり、実はそこまで負荷がなかったりなど、シェーダーで記述しているとわからない処理を詳細に調べられるため、高負荷な処理がわからない場合の分析手段の一つとして持っておくことが大事だと思います。
フレームデバッガー
特定のフレームを止めて、そのフレームのそれぞれのドローコールが表示されるデバッグ機能です。
実行時の結果を確認できるため、グラフィック上の不具合などはどの時点のドローコールで起こっているかを調べると、効率的に不具合を発見することができます。
フレームデバッガーはCPUからGPUに送る定数バッファの情報も確認することができるため、CPUで計算された変数が想定通りに渡されているかの確認も行えます。
私も業務では、実行の際にどのタイミングで差し込んだパスが呼ばれているのかを確認したり、作成したシェーダーへ送られた定数バッファの内容を確認したりしておりました。
タスク以外の話
インターンシップではタスク以外で学んだことがあるので、ご紹介させていただきます。
クライアントエンジニアの勉強会
ColorfulPaletteでは、週に一回クライアントエンジニアだけの勉強会が行われており、参加させていただきました。
勉強会では、新しく開発した機能から得られた技術や、個人的に興味のある技術などの幅広い技術的な知識を共有されておりました。実際にゲームやライブで使われている最新技術の開発秘話をお聞きすることができ、とても貴重な体験ができました。
社員さんとのランチ
ランチでは、エンジニアの方だけでなく、タスクではなかなか関わることが少ないようなデザイナーさんから、プランナー、譜面制作、人事、コアテクやアプリボットの社員さんまで、様々な分野の方々とランチに行かせていただきました。サイバーエージェントの社員さんは付近のランチ事情に非常に詳しく、「渋谷のおいしいお店リスト」ができるほどでした。社員さんそれぞれのタスクのこと、技術的な質問、私自身がサイバーエージェントへの入社を志望する理由、ゲーム開発での悩みについても親身になって聞いてくださり、ランチを通して学ぶことが非常に多かった と今でも感じております。普段話せないようなことも、ランチでは話しやすく緊張も忘れるほど、とても有意義な時間を過ごせました。
カフェタイム
ColorfulPaletteでは、カフェタイムという社員同士で館内にあるカフェでゆっくり相談できる機会を作ることができます。私も、就業期間中に2回ほどカフェタイムをメンターさんと3Dエンジニアのマネージャーさんのお二方に実施していただきました。インターンシップと同時並行で就職活動も行っておりましたので、私自身の夢や本当にやりた いことなどの悩みを抱えておりました。そんな悩みをお二方は本当に親身になって話を聞いてくださり、不安が一気になくなっていった思い出が残っております。
クラブ活動 ・ ホビー
私も驚いたのですが、実はColorfulPaletteにはクラブ活動もあるんです!私もバイクとカフェが趣味なので、「ホビーバイク」と「カフェ部」に1か月だけ入部させていただきました。この活動では業務やタスクに関係なく、好きなこ とや趣味が一緒の人同士で集まって趣味を楽しんだり、お話や情報共有をされておりました。社員さんの普段の業務では見えなかった一面が趣味や好きなことを通して見れたり、普段交流が少ない役職同士の交流もあり、私の中で、就業中の大きな楽しみの一つとなっておりました。
最後に
CA Tech JOBで1か月間、実際の業務に触れ、学生では得られないような知識や経験を得ることができました。このCA Tech JOBを通して、自分自身が目指しているエンジニアとはどういった職業で、どんなことが求められているのかを肌で体感できたからこそ、自分自身がエンジニアとして働く姿を想像できるようになりました。あと1年半学生生活を送りますが、グラフィックスエンジニアに求められる知見の広さを得るために日々邁進していきます。
1か月間本当にお世話になりました。ありがとうございました。