なんとかするから、なんとかなる

エンジニア関係のことを書きます

Unite2017 参加しました その10

ゲームの見た目も盛ったら変わる!!!!ヤバい!!ポストプロセス!!入門!!!!!!!!!

www.slideshare.net

ポストプロセッシングとは

レンダリング後の画像に対して、見た目を豪華に、綺麗にすることができる。

Post Processing Stack

ポストプロセッシングをするための、アセット

おすすめ設定

  • ColorSetting = linear
  • Rendering Path = defferd
  • HDR = ON

弱点

  • AnimatorでAnimationをつけることができない  ⇨ スクリプト経由でアニメーションはつけられるが、アセットに対して破壊的変更をするため、オススメできない
  • シェーダバリアントを大量に生成してしまう。各機能の組み合わせに最適化されたシェーダが作成されてしまう。ビルドがやたらと長くなる。

Anti Aliasing

FXAA

軽量なアンチエイリアス、便利だけど品質低い

特徴

境界線を見つけ出して、そこにぼやっとつける。

TAA

こっちの方が高品質なアンチエイリアス

特徴

ピクセルに対して、サンプルする点をサブピクセル精度でランダムに変更する。 ジラジラ感を消すことができる。

引数について
  • Jitterを変更することで、処理速度が変わる
  • stationaryは周囲の影響を受けるピクセル数を変更する

Anviant Oculution

エッジ強調を行なって、映像のホリをくっきりさせる。くぼみが際立つ

Screen Space Reflection

  • レンダリングの後に、3D情報を元に、反射すべきものを判断して、反射させる。
  • そもそも画面にないものは反射しないので、見切れている場合は、ぼかすなどでごまかす。
  • 処理が重い
  • Defferd Shading限定

Width Modifier

見えないものは基本的に詰まっているという前提であるが、このパラメーターで見えない部分の詰まっている距離を抑えることができる。

Depth of Field

フォーカスを合わせる。近くにピントを合わせたり、遠くにピントを合わせる。 すごいこだわりを感じる機能

Motion Blur

シャッター速度が遅い時にできる、ブレをだす。

Eye Adaption

  • 画面の明るさを自動で制御することができる。
  • 急に明るいところに出た時などの目の慣れを表現できる
  • ComputeShader必須
  • AutoExposureなどの露光を変更することも可能

Bloom

発光、光っている感じを出すことができる。

Color Grading

明るさと色調の設定をすることができる。 トーマッピングで、白飛び黒潰れをなんとかできる。

Clomatic Avalation

レンズの歪みを再現することができる。

Grain

フィルムのザラザラ感をつける。拡大した時にザラザラして見える。

Vignette

カメラの周辺に黒枠をつけることができる。

Dithering

グラデーションのシマシマを消すことができる。

Unite2017 参加しました その9

WebGL:ゲームプラットフォームとしてのWebと現在と未来

www.slideshare.net

WebGLの動機

ブラウザのプラグインを無くしたい

Web Assembly(.wasm)

  • ブラウザ向けのバイナリフォーマット
  • W3Cのコミュニティグループで議論されている
  • WebAssembly Explorerでコードを書いてコンパイル結果を見ることができる

対応状況

  • FireFox ChromeはMVP(Minimum Viable Product 最低限の実装はサポート)
  • Edge, safariは開発中

WASM MVP とは

  • 最低限必要な要件が定義されている内容
  • WASMモジュールの構造などに対応する、などなど

WASMの特徴

  • 早い Nativeと比較して130〜150%くらいの実行時間で動くことができる。

    asm.jsとWASMの違い

  • WASMの方が早い。WASMは構文解析の時間が無いので早い。
  • asm.jsはブラウザごとにコンパイル方法が異なる。(ベンダー依存)

WebGL

今のところ2世代

普及率

WebGLはほとんど100%。WebGL2は50%ないくらい。

WebGL出力の注意点

WebGLでは以下のように出力される

C# ⇨ (MONO) ⇨ IL ⇨ (il2cpp) ⇨ C++ ⇨ (Clang) ⇨ LLVM IL ⇨  WASM + JS

  • 結構重たい処理はJSに投げた方がスレッドが異なるので楽。
  • 2種類のGCが存在するので注意。プロファイルする際は両方を使う

    • JSVM内のUnity用メモリはUnityのGCが使用される
    • JSVM内はJSVM用のGCが走る
  • ファイルシステムはメモリ上に仮想的に作っているので、ファイルが多すぎるとメモリを圧迫することになる。

    • IndexedDBもその裏ではメモリ上に展開している。

Webのこれから

  • Shared Array Buffer: 共有メモリ(スレッドの実現)
  • 音声処理の別スレッド化
  • payment
  • キャッシュ処理

Unite2017 参加しました その8

Unityライティング最新情報

www.slideshare.net

光表現について

  • GI Global illumination 間接光
  • Baked GI 事前に計算しておくGI
  • procomputed RealTime GI リアルタイムで間接光をつくる

UnityではStaticな動かない物体に対しては、前もって間接光を計算しておく。

LightProve

空間にライトを検知するものを置いて、間接光の影響を計算しやすくするための仕組み

  • 1モデル1つのproveからしか影響を受けられなかった。
  • 上記が改善され、モデルが複数のproveを受けられるようになった

リアルタイムな間接光について

リアルタイムな間接光はクラスタ単位で計算される。

クラスタの大小は変更可能。

影の表現

光を遮り、影を作るためにはメッシュやポリゴンは必要となる。

メッシュやポリゴンが増えると、負荷が上がるため辛い。

動的な影と静的な影について

それぞれの影を混ぜるMixed Lighting

Mixed Lighting

  • unity5.6以前では、うまくMixedすることができず、影の上に影が映ってしまうことがあった。 また、光沢の表現(スペキュラ)がお粗末だったらしい。
  • MixedLightingは大きく4種類
    • Subtractive
    • Baked Indirect
    • Shadow Mask
    • Distance Shadow Mask

Subtractive

  • 5.6以前のmixedに近い機能
  • 影を全てTextureに焼きこんでしまう(static)
  • 動的なオブジェクトに対しては計算をする。
  • 動的な場合は影の色を変更することができるので、影の上に影が描画されてしまうことを避けられる。
  • 影の上に影以外のmixedデメリットを引き継いでいる。光沢の表現は難しい

Baked Indirect

  • 間接光のみを事前に計算しておくが、影は全てリアルタイム表現しましょう。という発想。
  • 静的なオブジェクトに対しても影を描画するため辛いという欠点がある。処理時間がかかりすぎる

Shadow Mask

  • 静的な影は前もって計算、動的な影はその場で計算。
  • ライトは動的に描画することができるので光沢も表現することができる。
  • 間接光はテクスチャに焼き込む
ShadowMaskではクッキーがつかえる
  • マスクとして影を用意しているので、色や輝度を変更することは可能
  • ただし、間接光はすでにTexutreに焼かれているため注意が必要。
Baked Shadow Angle
  • 使用することはあるが動的な影と静的な影の差が見えてしまう。

Distance Shadow Mask

  • Dynamic とShadowMaskの混合
  • 距離が近い部分はDynamic,遠い部分はShadow Mask
  • すなわち、近くてよく見えるところは頑張って描画するが、遠いところは低解像度でもOKとする

Unity2017.1から

QualitySettingsからShadowMaskとDistanceShadowMaskは切り替えが可能となる。

ローレベルのユーザはShadowMask、ハイエンドユーザはDistance Shadow Maskを利用する。

その他

  • 影を落とすためだけのオブジェクトをおく方法もある。
  • 影を落とすためだけに、低解像度のメッシュを置いても良い。
  • 高解像度のポリゴンによる陰を低解像度オブジェクトで影を遮ることで作る。すなわち影を作るのはそこまでハイポリゴンは不要である。

ライトのBaked 設定

ライトの設定は大変なので、その改善方法を紹介

LightExplorer

シーン内のライト及びEmissiveの一覧を表示してくれる便利さん

Progressive LightMapper

  • シーンが見えているライトを優先的にBakedしていくので、プレビューが早い
  • 大まかに計算後、詳細に計算するのでやっぱりプレビューが早い
  • リアルタイムGIはできない。
  • ライトを焼いてから、proveを焼くので、proveに大きく依存するシーンではプレビューには時間がかかる

Unite2017 参加しました その7

最適化をする前に覚えておきたい技術

www.slideshare.net

最適化への手順

プロファイリング

処理ごとにかかった時間、メモリの使用状況を把握する。

まずは、Unityのprofiler 詳しく知りたければ、Nativeのprofiler(Xcodeとか)を使う

[window] - [プロファイラー]

対処する

メモリの使用量が多い

  • 単純な使用量か、メモリリーク
  • C#(MonoMemory)が原因か、Unityが原因か

C#が大きいぞ

  • C#スクリプトで使用しているメモリ。(GCされる)
  • C#が確保したメモリは解放されてもC#専用領域として残ってしまう。(reserved) (Editor拡張でもメモリは取られるので、実機で確認する。)

とりあえず スクリプトを修正する

Unityメモリが大きいぞ

  • TextutureやMeshなどが原因で、リークの可能性もある。
  • ProfilerからAsset毎にメモリ内の容量をチェックできる。その他に公式ツールも存在する。

不必要なアセットなどを削除するようにする

ロードが長い問題

何が長いのか、初期化処理か、ロード時間か、きちんと原因を調べる profilerでロード時間をフレーム毎に見てみる。

[スクリプト].awakeが長い場合は、初期化が辛いことになっている。

  • プロフィリングの時はDebugLogは止めるようにする。DebugLogは割と重い。

texture.awakeが重い

無駄なものを読み込んでいないか、やたらとリッチなTextureは存在しないかを確認する。

AssetBundleを使っている場合は、予期せず重複して読み込んでいることがあるので、注意。

一瞬ゲームが固まる問題

  • GCが走った場合に起こる現象。
  • profilerでCGが起きていないかを確認する。

対策

  • C#スクリプトでのメモリの消費を抑える。
  • 文字列の置換や検索、足し算は気をつける。

フレームレートが低い問題

FPSのフレーム間で終わらない処理をしてしまったのが原因(30FPSよりも下がると、人の体感で遅く感じてしまう)

  • ゲームロジックによる負荷か、描画処理による負荷か
  • profilerでrenderingをみることでわかる。

どうする

  • 描画ならデザイナーさんとの交渉
  • ゲームロジックなら、C#のスクリプトかUnity側の処理か。GameObejctが3000を超え始めたらC#のスクリプトの問題
  • BehaviourUpdateをprofilerを見ることでわかる。
  • phisicsなんとかで物理が重いのかがわかる。
  • insepectorのTimemanagerでフレーム数をきちんと下げると良い。
  • UIが重い場合、頂点の計算に時間がかかる
  • 何かの変更があれば、すべての頂点を計算し直すため
描画の負荷で考える
  • 無駄な描画をしている場合が割と多いので気をつける
  • Objectの描画処理はFrameDebuggerで確認することができる。
ちなみに
  • 頂点数もprofilerから確認することができる。
  • 透明描画や、半透明を塗るのも結構大変。ImageEffectなどもかなり時間がかかる
Shaderはどうですか?
  • ピクセル毎に細かく計算するため、気をつける。
  • 特に、地面や空は画面の中でかなりの面積をようするため軽めのShaderにすると良い。

Shaderについては各プラットフォームのprofilerで見た方がいい。

描画負荷を深掘りしたい場合

  • iOSならXcode
  • Androidなら各GPUメーカーによって問い合わせ、Tegra, SnapDragonなどのによって変わるので注意

Unite2017 参加しました その6

C#ジョブシステムによるモバイルゲームのパフォーマンス向上テクニック

www.slideshare.net

はじめに

  • これからの方向性を示した内容。まだまだ変わる可能性がある。

Jobs101

  • マルチコアのハードにきちんと対応するためにJob化がされる。
  • ただしマルチコアに対応するために並列処理をきちんと意識する必要がある。
  • Unity2017.2 以降で対応予定

2017以降の新機能

  • C++とC#間ではmarshalingなしでアクセスできるNativeArrayの型ができる
  • jobに最適化された新たなコンパイラができる

    • jobSystemではGCが働かないunmanagedなので、developperがきちんとDisposeする必要がある。
    • これにより、マルチスレッドにより特化したコーディングが可能となる。
  • MONOのコンパイル処理が変わる

    • ILから中間言語を出して、最適化そしてLLVM送りさらに最適化、そしてメモリに書き込む。

現在のマルチスレッドに対する制限

  • Jobをまだ止めることができない。
  • スレッドセーフではない

job化のbest practice

  • DataOrientedDesign(DOD)
  • マルチスレッドに対応していなくもDODを適応すべき
  • Objectをまとめて同じスクリプトを適応するよりも、Arrayにつめてマネージャーへ

DODへの方法

Step1(従来のMonoBehavior追加する方法)

MonoBehaviorに対して関数を追加して使う

Step2

オブジェクトのすべてのtransformをArrayで管理する。

Step3

IComponentDataを利用して、各Objectの情報を格納する

Step4

データの整合性をとれるようにする。

Unite2017 参加しました その5

シェーダープログラミング入門!カスタムシェーダー、作るで!

www.slideshare.net

rendering pipeline

どのようにして、Unityがレンダリングを実行するか

shaderを書くための言語

  • CG(C for Graphics) Sessionで使われてた言語はこれ。 C言語に似た言語

  • Shader Lab

CG(C for Graphics)の見方

v2f

v2fではvertexをCG(C for Graphics)で使えるようにするための構造体

Properties

Propertiesを利用することで、UnityのInspectorから値を指定することができる。 詳しくは参考URLのサンプルプログラムShader4

Shaderのタイプは大きく分け3つ

それぞれ表現方法によってどれを使うかは異なる。 基本的な使い方は、subshader の中にそれぞれに対応する関数を作ってあげる。

  • Vertex Sharders
  • Fragment Shaders
  • Surface Shaders

Vertex Shaders

Vertex Shadersでは頂点を入力に対して、頂点を位置を変更して出力する。 Shaderで動きをつけたいときに使える。

flaot vert(appdata_base v)

頂点座標に対して処理を実行する

  • 引数 appdata_base 頂点(vertex), 法線(normal), UV情報(texcorrd)が含まれている。 より詳細な情報(UV2)などは、appdata_fullという構造体に含まれている。

v.vertexに対して、倍率を指定すると拡大/縮小して表示することがができる。 時間などの係数をかけることで、簡単なモーションを表現することもできる。

Fragment Shaders

Pixcel 1つ1つに対して、色やAlpha値を変更するときに使える。 色彩の表現を付け加えるときに便利。

half4 frag(v2f i)

この関数のなかで各ピクセルに対して処理を実行することができる。

Sessionでは、この関数で以下を返すことで、Shaderが適応されたオブジェクト赤色になっていた。

return half4(1,0,0,1)

Surface Shaders

Pixel 1つ1つに対する処理というよりは、面に対して何かしらの表現を付け加えるときに便利。

void surf(Input IN, inout SurfaceOutput o)

事前にテクスチャをして置き、SurfaceOutputのalbedoを指定することでテクスチャを貼り付けることができる。

o.Albedo = tex2D(_MainTexture, IN.uv_MainTexture).rgb;

tex2Dの第二引数IN.uv_MainTextureでuv座標を指定しているため、第二引数を動的に変化させることでTexutureがオブジェクトの表面を流れるような表現をすることができる。

Emmission Texture

MainTextureが全体に対するベースとなるTexutureで、EmmissionTextureその上に張ることができる。Texutureを重ねて表現するときに便利

  • 参考 その他テクスチャの張り方

    事前にテクスチャを指定しておき、vert関数でuv座標を指定、fragでその色情報を取り出すことで、テクスチャの貼り付けができる。

参考資料

github.com

デモでかなりわかりやすく各Shaderを紹介していたので、動画が待ち望まれる!

Unite2017 参加しました その4

バグを殲滅!Unityにおける実践テスト手法

www.slideshare.net

Unity のテストツール

Unity 標準テスト環境あり

  • Unity5.6 play mode
  • Untiy5.5以前 edit mode

単体テスト

NUnit

  • C#向けのテストツール
  • Unityの古めのバージョンから支えていたが、Unity5.6からNUnit3系となったっぽい

TIPS

  • MonoBehaiviorのオブジェクトはTearDownでnew する
  • GUIで指定する各Objectは引数の差し替えで追加する。
  • なので、依存関係がやばいとテストが大変

単体テスト環境の欠点

  • MonoBehaiviorのライフサイクルはテストできない
    • もしテストをするなら、MVPのPresenterのような形でライフサイクルときちんと切り出さなければならない?
  • SingletonやStaticなものは、テストを再実行してもメモリ上に残る。(明示的にイニシャライザをしてあげる)
  • Unity5.6未満だと、テストで作成されたgameObjectはテスト後でも残るので、明示的にデストラクタを呼ぶ必要がある。

結合テスト

方法

  • キャラクタなどをnewして、Positionなどを整えることで結合テストが可能となる。
  • Object間の関係をテストするのに使える。接触した場合の動作など。
  • PlayModeであれば、ライフサイクルのテストも可能

MonobehaviourTest

  • Unity5.6から使えるようになったテスト
  • ライフサイクルをスタブする場合に便利かもしれない
  • いくつかバグがすでに見つかっているので注意

その他 テストツール詳解

  • UnityTestTools
  • Integration Test Framework
  • Unity UI Test Automation