Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Unity+スマホで3Dゲーム開発最適化するための考え方
Search
Cygames
January 14, 2016
Programming
15
24k
Unity+スマホで3Dゲーム開発最適化するための考え方
2015/11/15 Cygames Tech Fes
Cygames
January 14, 2016
Tweet
Share
More Decks by Cygames
See All by Cygames
『GRANBLUE FANTASY Relink』キャラクターの魅力を支えるリグ・シミュレーション制作事例
cygames
0
350
『GRANBLUE FANTASY: Relink』最高の「没入感」を実現するカットシーン制作手法とそれを支える技術
cygames
1
280
『GRANBLUE FANTASY Relink』ソフトウェアラスタライザによる実践的なオクルージョンカリング
cygames
0
300
高品質なフォトグラメトリデータを取得するためのハードウェア&ソフトウェア開発
cygames
0
910
AIを活用した柔軟かつ効率的な社内リソース検索への取り組み
cygames
0
800
『GRANBLUE FANTASY: Relink』開発からリリースまでを支えたCI/CDの取り組み
cygames
0
210
『GRANBLUE FANTASY: Relink』専任エンジニアチームで回す大規模開発QAサイクル
cygames
0
220
『GRANBLUE FANTASY: Relink』クオリティと物量の両立に挑戦したフェイシャルアニメーション事例 ~カットシーンからランタイムまで~
cygames
0
220
『GRANBLUE FANTASY: Relink』キャラクターの個性にlinkした効果音表現
cygames
0
110
Other Decks in Programming
See All in Programming
CSC305 Lecture 13
javiergs
PRO
0
130
Vaporモードを大規模サービスに最速導入して学びを共有する
kazukishimamoto
4
4.3k
『ドメイン駆動設計をはじめよう』のモデリングアプローチ
masuda220
PRO
8
440
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
150
Server Driven Compose With Firebase
skydoves
0
400
LLM生成文章の精度評価自動化とプロンプトチューニングの効率化について
layerx
PRO
2
140
約9000個の自動テストの 時間を50分->10分に短縮 Flakyテストを1%以下に抑えた話
hatsu38
24
11k
PagerDuty を軸にした On-Call 構築と運用課題の解決 / PagerDuty Japan Community Meetup 4
horimislime
1
110
[PyCon Korea 2024 Keynote] 커뮤니티와 파이썬, 그리고 우리
beomi
0
110
Outline View in SwiftUI
1024jp
1
170
Amazon Neptuneで始めてみるグラフDB-OpenSearchによるグラフの全文検索-
satoshi256kbyte
4
330
Hotwire or React? ~Reactの録画機能をHotwireに置き換えて得られた知見~ / hotwire_or_react
harunatsujita
9
4.1k
Featured
See All Featured
A designer walks into a library…
pauljervisheath
202
24k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Designing for Performance
lara
604
68k
The Invisible Side of Design
smashingmag
297
50k
Building Adaptive Systems
keathley
38
2.2k
Gamification - CAS2011
davidbonilla
80
5k
[RailsConf 2023] Rails as a piece of cake
palkan
51
4.9k
The Pragmatic Product Professional
lauravandoore
31
6.3k
Intergalactic Javascript Robots from Outer Space
tanoku
268
27k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
800
GitHub's CSS Performance
jonrohan
1030
460k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
22k
Transcript
Unity+スマホで3Dゲーム開発/最適化 するための考え方 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE 株式会社Cygames エンジニア
金井 大
自己紹介 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 金井 大
• 技術研究チーム所属のエンジニアです • VR、ゲームエンジン、グラフィックスとかの研究 開発してます
アジェンダ $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • Unity +
スマホで3Dゲーム開発/最適化する ための考え方を、以下で紹介します – 開発の指針 – 構成およびスペックの一例 – 開発と最適化のためのTIPS – 指針と手法の答え合わせ
開発の指針 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
大事なこと $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 端末の性能を把握する •
コンテンツの要素を把握する – 適切な単位で区切り – コストを把握し – そのコストを最適化する • 要素を選択できるようにする
UNITY HARDWARE STATISTICS $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE •
出典:http://hwstats.unity3d.com/mobile/ • unity mobile stat で検索
詳細 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • Mali 400
MP: 20.0% • Adreno 305: 12.5% • PowerVR SGX543: 10.9% • Apple A7: 8.5% • Adreno 330: 5.9% • Adreno 306: 5.4% • Apple A8: 4.7% • PowerVR SGX544: 4.1% • Adreno 320: 2.8% • Vivante GC1000: 2.3% • Videocore IV: 2.2% • Mali 450 MP: 2.1% • Mali T760: 2.1% • PowerVR SGX540: 1.6% • PowerVR SGX531: 1.5% • Adreno 203: 1.4% • PowerVR SGX535: 1.3% • Adreno 200: 1.2% • PowerVR SGX554: 1.0% • Adreno 225: 0.9% • Adreno 405: 0.8% • Mali T628: 0.7% • Apple A8X: 0.6% • PowerVR G62xx: 0.5% • Mali T624: 0.5% • Tegra 2: 0.5% • Intel HD BayTrail: 0.4% • Adreno 220: 0.4% • Vivante GC2000: 0.4% • BlueStacks ES2.0 Emu: 0.3% • Tegra 3: 0.3% • Mali 300: 0.3% • Mali T720: 0.3% • Mali T622: 0.2% • Adreno 205: 0.2% • PowerVR G64xx: 0.2% • Adreno 420: 0.2% • Adreno 430: 0.1% • Immersion.16: 0.1% • Adreno 418: 0.1% • Vivante GC7000: 0.1% • Vivante GC800: 0.1% • Something strange: 0.1% • Adreno 304: 0.0% • PowerVR SGX530: 0.0% • Vivante GC4000: 0.0% • Android ES Emulator (GeForce): 0.0% • Tegra 4: 0.0% • Mali T604: 0.0% • Android ES Emulator (Radeon): 0.0%
3DMARK $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 出典:http://www.futuremark.com/hardware/mobile/ •
3DMARK mobile results で検索
3DMARK $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 拡大
どうしてこうなった $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • キャリア •
チップセット • CPU – コア数 – クロック • GPU • メモリ
PCゲームのグラフィックス設定 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 出典: http://doope.jp/media/15q1/img2826_01.j
pg
$POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • どこまでユーザーに選択させるか?
スマホでの現実解は? $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • ある程度は大まかに制御したい –
エフェクト ON/OFF – 効果音 ON/OFF – FPS – スペックの抽象化
$POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 「スペックの抽象化」ってなんやねん
例えばシェーダーを例に $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • Vertex shader
– カラーアニメーション – UVアニメーション – アウトラインメッシュの法線方向への拡大 – セルルック • Fragment shader – イメージエフェクト – スキンシェーダー – ノーマルマップ – セルルック
アプリケーションでの抽象化 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • Vertex shader
– カラーアニメーション – UVアニメーション – アウトラインメッシュ – セルルック • Fragment shader – イメージエフェクト – スキンシェーダー – ノーマルマップ – セルルック 低スペック 高スペック 使わない
端末に落とし込む $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • Vertex shader
– カラーアニメーション – UVアニメーション – アウトラインメッシュ – セルルック • Fragment shader – イメージエフェクト – スキンシェーダー – ノーマルマップ – セルルック 低スペック 高スペック 使わない iPhone5s iPhone6 iPhone6s Galaxy S5 Galaxy S6
大事なこと $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 端末の性能を把握する •
コンテンツの要素を把握する – 適切な単位で区切り – コストを把握し – そのコストを最適化する • 要素を選択できるようにする
構成およびスペックの一例 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
目標 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 60fpsをキープしたい •
キャラクターを5体表示 • 絵力 – フェイシャル – モーションキャプチャー – 他と差別された強い絵力が欲しい! • タイトなスケジュールに負けない
より現実的なゴール $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 低スペック端末では –
幅広く動作するようクオリティぎりぎりまでスペック を落としつつ60fpsをキープ • 高スペック端末では – 高性能端末で高品質な画面を提供しつつ60fpsを キープ
キャラクター $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • スペック –
テクスチャ • ETC1(αチャンネルなし)/PVR • Mipmapなし(データサイズ縮小のため – ウェイト • 基本は2ボーン – 3ボーンをPlayerSettingで2にするとメッシュが崩れることがあ る
キャラクター $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • フェイシャル –
ボーン制御 – Animatorで眼球、リップの動きを用意し、外部から 制御 – 眼球の追従先をプログラム制御 • アウトライン – アウトラインメッシュ – 頂点カラーでの調整 – リムライト、セルルックは…? • 造形が良ければアウトラインでも
キャラクター $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • クロス –
独自実装 – それなりに重いので、まずはC#でチューン • 計算部分のみなら22行程 – マルチスレッド化できるようにデータ局所化 – あとはネイティブプラグイン化すれば…
背景 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • テクスチャ –
基本はETC1(αチャンネルなし)/PVR – Mipmapあり – UVアニメーション用に3MB程度を確保 • 画面キャプチャ – ImageEffectで作成した中間バッファを流用 – 1フレーム遅れた絵になるが低コスト
その他 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • ライティング –
基本的にはライティングしない – アンビエント – 板を1軸回転してカメラに向けてボリュームライトっぽく • シャドウ – リアルタイムシャドウは断念 – 板ポリの安いやつ。Diffuseに焼く。 • ないと立体感なくなります • パーティクル – 一定数まとまったメッシュを用意 – パーティクルとして降らせる – Vertex shaderで動きをつける
Image Effect $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • ImageEffect
– DOF(被写界深度 – Bloom – カラーコレクトはオミット • Unityのシェーダーをベースに – 1カメラで実現できるようカスタマイズ – ついでに高速化
Directシーン $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • キャラクターや背景の任意組み合わせを確認でき る専用シーン
• デザイナー/プランナーの作業、確認が主用途 • 各種アセットのデータ形式に対応 – 通常アセット – アセットバンドル(サーバー上 – アセットバンドル(ローカルPCにつくったやつ • 端末でも動作可能 – アプリ本体を経由しないので、単体テストやコスト計測 にも使える
開発と最適化のTIPS $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
計測 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
Unity Profiler $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
Statistics $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
FrameDebugger $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • DrawCallを確認可能 –
Unity5から こ の へ ん が 描 画 リ ク エ ス ト
GPU Profiler $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 描画系の追跡はUnity
Profilerでは限界がある – オーバーヘッド – GPUのプロファイルに難アリ • チップセットと対になったGPU Profilerを使う – iOS -> instruments / OpenGL ES Frame Debugger – Adreno -> Adreno Profiler – Tegra -> PerfHUD ES • 端末や要素の性能を把握できる
例:Adreno Profiler $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
Adreno Profiler $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • プロファイルした情報を保存することが可能
– チューニング前後の比較に • 頂点データ/テクスチャの保存 • シェーダーの可視化と変更 • Etc…
Adreno Profiler $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • FrameDebuggerと同じくDrawCallが目視で
きる
Adreno Profiler $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • フレームバッファ、テクスチャのキャプチャ
• シェーダー修正
Adreno Profiler $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • FPSやGPU使用率などをグラフ化
描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • おおざっぱに以下のように考える –
vertex負荷 = (描画リクエストされた頂点数) x (vertex shaderの命令数) – fragment負荷 = (描画されたピクセル数) x (fragment shaderの命令数) – 厳密にはパイプライン次第だと思う • 各ベンダー/各世代のチップ考慮するのは大変なので
描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 出典: http://climserv.ipsl.polytechnique.fr/documentation/idl_he
lp/images/shader_detail.gif
描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 例:球(4000頂点)を(1/1)と(1/4)で描画し た時の比較
– vertex負荷は同じ – fragment負荷は約1/16になる
描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • vertex負荷の制御はデリケート –
描画対象となる頂点数を減らしたい – 何らかで頂点数を削れば良いのだが… • データ削減するとシルエット崩れや作業コストが懸念 • カリング精度を上げるにはCPU/GPU負荷が懸念 • fragment負荷は比較的制御しやすい – 描画面積とシェーダーで制御できる – カメラワークには注意
描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • vertexは最初から低めに抑さえる –
特に低スペック端末を考えると低めにせざるを得 ない – 最低限のLODデータを用意する • fragment負荷を制御できる手段を用意する – ImageEffectをOn/Offする – 画面解像度を制御する – Meshのfragmentシェーダーを軽量版に切り替える
描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
描画順の制御 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
描画順の制御 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 前提として「描画順」と「ZTest」を理解する –
ZTestが有効な場合、隠れたfragmentは描画されない • 1がZ値的に手前にある時、1を描いてから2を描 くと、一部は描画されない 2 1
描画順の制御 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 極端にすると。 •
1を描画してから2を描くと、2は殆ど描画されな い 2 1
隠れているのがポイント $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • アウトラインメッシュの描画が無駄になるので •
こういう順番にしたい
描画順の制御 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 不透明は(基本的には)手前から描く –
隠れた個所はfragmentシェーダーが走らない – 基本的にUnity側が手前からソートしてくれてる
描画順の制御 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • なんだけど –
原点位置を基準にソーティングする – 意図した結果になるとは限らない – こういう時は床を最後にしたいが原点基準だと。。。
描画順の制御 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • Unityで描画順を制御する手段 –
Camera.depth – MeshRenderer.sortingLayerName – MeshRenderer.sortingOrder – Material.renderQueue
描画順の制御 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 優先としては以下になる Camera.depth
sortingLayerName =“default” sortingOrder =0 renderQueue=2000 renderQueue=2010 renderQueue=3000 sortingOrder =100 renderQueue=2000 renderQueue=2010 renderQueue=3000 sortingLayerName =“after” sortingOrder =10 renderQueue=2000 renderQueue=2010 renderQueue=3000 sortingOrder =200 renderQueue=2000 renderQueue=2010 renderQueue=3000
Camera.depth $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • CameraはCullingMask設定が必要になるなど、 色々面倒
– ImageEffect使用時は注意! • Camera.clearFlags=Depthだとclearが劇重 • GPU20%程度の消費することも
MeshRenderer.sortingLayerName $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • sortingLayerNameは以下で追加可能 –
Layers -> Sorting Layers • 記載の順番に処理される
MeshRenderer.sortingOrder $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 同じsortingLayerNameでの描画順 •
sortingLayerNameと合わせて運用を考える
Material.renderQueue $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • マテリアル単位で描画順を制御する •
Material.renderQueueはシェーダーからも設定可能 – Tags {"Queue"="Geometry-1" "RenderType"="Opaque"} • Queueは文字列に見えるけど実際は数値 – Background = 1000 – Geometry = 2000 – AlphaTest = 2450 – Transparent = 3000 – Overlay = 4000 • なので、前述の例は「1999」になる
こんな事も $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 「髪の毛より手前にある眉」
髪の毛より手前にある眉 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 髪の毛に隠れてしまう眉毛を何とかして手前 に出したい
– ZTest / ZWriteをOffにして対処 – ZTestしないので、「必ず」最前面に眉が描かれる (髪の上に描かれる) – ZWriteしないので、他のオブジェクトにZ値干渉し ない
髪の毛より手前にある眉 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 弊害として、他キャラの眉毛が貫通してくる可 能性がある
– 描画順を制御して奥から描く • キャラA頭 • キャラA眉 • キャラB頭 • キャラB眉 • …
髪の毛より手前にある眉 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 問題はいくつか残る –
頭と眉の形状によっては、自キャラの眉が貫通して くる • カメラワークでの回避 – 無駄な描画が発生する • 我慢する
SetPassとDrawCall $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
DrawCall $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • まずDrawCall –
GPUへ描画リクエストする、ということ – 固有のマテリアルを描画リクエストすると 1DrawCall消費する – Unity5からStatisticsより消失しました
$POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 「固有のマテリアルを描画リクエストするとDrawCall 消費する」ってなんやねん •
「固有のマテリアル」ってなんやねん
DrawCall $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 固有のマテリアルとは –
UnityEngine.Materialのメンバがユニークであるこ と – 例えば • Colorが異なる • Textureが異なる • Shaderが異なる • Etc… – 他と異なるメンバがあれば、それは固有である
DrawCall $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • BOX全体にマテリアルA →
DrawCall=1 • BOX各面にマテリアルABC → DrawCall=3 A A B C
DrawCall $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • (BOX全体にマテリアルA)x2 →
DrawCall=2 • (BOX各面にマテリアルABC)x2 → DrawCall=6 A A B C A A B C
DrawCallとバッチ処理 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 同じマテリアルだったら最適化できそう •
そこでバッチ処理 • 同じマテリアルをもつドローコールを統合する
DrawCallとバッチ処理 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • (BOX全体にマテリアルA)x2 →
DrawCall=1 A A
DrawCallとバッチ処理 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • (BOX各面にマテリアルABC)x2 →DrawCall
数は描画順に依存する(後述) A B C A B C
DrawCallとバッチ処理 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • バッチ処理は2種類ある •
StaticBatch – 移動しない同一マテリアルを持つメッシュをマーキングし、 事前にバッチ用のデータをしこむ – 統合の効果が高いが、移動したりマテリアル操作するメッ シュには適応できない • DynamicBatch – 前後のドローコールが同一マテリアルをもつ場合、ランタイ ム時に統合する – ランタイムに行うのでCPUコストがそこそこある – StaticBatchより効果が低い(頂点数等の制限数がある) • http://docs.unity3d.com/ja/current/Manual/DrawCallBatchin g.html
DynamicBatch $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • DynamicBatchの注意点 –
前後のドローコールが同一マテリアルを持たないと統 合しない – 描画順によっては統合できない! – 例えば描画順が以下だと統合されない • BOX(マテリアルA • BOX(マテリアルB • BOX(マテリアルC • BOX(マテリアルA • BOX(マテリアルB • BOX(マテリアルC • DrawCall=6になる
DynamicBatch $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 描画順が以下であれば統合される –
BOX(マテリアルA – BOX(マテリアルA – BOX(マテリアルB – BOX(マテリアルB – BOX(マテリアルC – BOX(マテリアルC – DrawCall=3になる • 描画順は前述のsortingOrderで制御可能
DrawCall $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • DrawCallを減らすのであれば、描画時に固有 マテリアルが連続するよう、ルールを決めてお
く – Batch処理を利用する – sortingOrder等で描画順を制御する – そもそも固有マテリアルを減らす • テクスチャを共有化する • シェーダーを共有化する • 変更するパラメーターを限定する • Etc…
SetPass $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • SetPassとは –
よりパフォーマンスの指針となる数値 – DrawCall時に前回使用したマテリアルから変更が あった場合、1SetPass消費する
SetPassとDrawCall $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 【Unity】Unity Performance
Casual Talk 「ド ローコール伝説の終わり」 レポート – http://qiita.com/baba_s/items/5260807ced7fc3c02ca 6
SetPassとDrawCall $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • (BOX全体にマテリアルA)x2 →
SetPass=1 • バッチに依存せず、SetPassは1になる A A
SetPassとDrawCall $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • (BOX各面にマテリアルABC)x2 →
SetPassは描 画順に依存する • SetPassを減らすにはDrawCallと同じく描画順を 意識する • DrawCallと同じノウハウが利用できる A B C A B C
Depth Texture $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
Depth Texture $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • ImageEffectの被写界深度はZ値を参照してボカ
シ処理を行う • Z値を参照するには、DepthTextureが必要 – Camera.depthTextureMode = DepthTextureMode.Depth; • 注意点 – DepthTextureはRenderTargetへ描画を行うことで 生成されてる – DepthTextureへポリゴンを描いている、ということ – 単純に描画頂点数が二倍になる
Depth Texture $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • DepthTextureへの描画時に利用されるシェー
ダーは? – シェーダー中のTagsを参照してます • http://docs.unity3d.com/ja/current/Manual/SL- ShaderReplacement.html – UnityにLightModeというタグが用意されており、以 下タグを持つSubShaderに置き換わる • Tags{ "LightMode" = "ShadowCaster" } – Unity4 -> 5で変更された箇所なので注意
Depth Texture $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • ShadowCasterシェーダーを実装する理由
– アウトライン+DOF時に必要となる事がある – キャラクターはアウトライン分微妙にサイズが大き くなる • ので、DepthBufferに書き込む大きさを調整する – やらないとアウトラインがボケてしまう
Multi threaded Rendering $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
Multi threaded Rendering $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE •
CPUがGPUを待つケースが減り、FPSの上昇が 期待できる • (空いてるCPUコア数が少ないと意味はない)
Multi threaded Rendering $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE •
なのですが。。。 – UnityのMultiThreaded Renderingに関する資料は 少ない – マルチスレッド関係は不具合出やすい個所なので 注意しましょう。 • Multithreaded + DynamicBatchでハングする事例あり • Unity5.0.2p3で発生
指針と手法の答え合わせ $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE
大事なこと $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 端末の性能を把握する •
コンテンツの要素を把握する – 適切な単位で区切り – コストを把握し – そのコストを最適化する • 要素を選択できるようにする
端末の性能を把握する $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 実際に計測すること •
Profiler – Unity Profiler – Frame Debugger – GPU Profiler • 各種サイト – 3DMARK – Unity Hardware Statistics
要素を適切な単位で区切る $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • ゲーム的かつ技術的な視点で区切る –
キャラクタ/背景/エフェクト – 頂点数/テクスチャ/ボーン数 – シェーダー – ImageEffect – CPU/GPU
コストを把握 $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 実際に計測すること •
Profiler – Unity Profiler – Drame Debugger – GPU Profiler • CPU/GPUどちらがネックなのか • GPUネックならこれが参考になります • Computer Graphics Gems JP 2015 • http://www.borndigital.co.jp/book/5498.html# • 2.5.4 パイプラインのボトルネック解析
コストを最適化する $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 定期的に監視すること –
できるだけ早いタイミングから – 想定された端末でのチェック – 機能が入ると知らない間にコスト上がる • 配分を決めること • FPS/SetPassといった性能指針を
要素を選択する $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • What if
– ◦◦したらどうなるだろう • キャラクタを増やすor減らす • ImageEffectをOn/Offする • シェーダーを切り替える • 選択を容易にする機能を実装する • ゲームと独立した場所があるとベスト
おしまいです $POGJEFOUJBM $PQZSJHIU $ZHBNFT *OD "MM3JHIUT3FTFSWFE • 時間があればDEMO