テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】GDC 2019のセッション動画が公開

GDCで行われたUnityのセッション動画の幾つかが公開されました。

Keynote

Keynoteです。

www.youtube.com

2時間見るのが面倒くさいという場合は、下の記事が凄い分かりやすいです。

www.famitsu.com

またGDCの映像の裏で雑談放送もやってました。

www.youtube.com

セッション一覧

www.youtube.com

動画が間違ってる奴や、今後増えそうな感じなのでとりあえず一覧ページのみ

【Unity】Unityのリアルタイムレイトレーシング用ビルドが公開

f:id:tsubaki_t1:20190406230819p:plain

UnityでRTXを試せるビルドが公開されました。

デモ

下のデモでは、リアルタイムレイトレースと実際の車を交互に表示しています。殆ど見分けが付きません。

動かせるオブジェクトで間接光や反射といった表現が出来るのは面白いですね

www.youtube.com

カスタムエディター

現状、パッケージとしてではなくUnityエディターのカスタムビルド…しかもUnityエディターを丸ごとGithubに配置するという漢らしい雑さっぷりです。

https://github.com/Unity-Technologies/Unity-Experimental-DXRgithub.com

マニュアルはこちら

https://github.com/Unity-Technologies/Unity-Experimental-DXR/blob/master/documentation/The%20Experimental%20DXR%20project%20manual.pdfgithub.com

質問や議論はコチラ

Unity - Unity Experimental HDRP DXR - Unity Forum

試したかった

色々と試した結果、我が家のGeForce GTX 950Mでは無理だった事を思い出しました。( ˘ω˘)スヤァ…

当然ですが、RTXが可能なグラボが必要です。

そろそろ新しいのに買い替えたい所はありますが、以前にコレがあったので正直何処のメーカーの何を買えば良いのか分からんっていう。

tsubakit1.hateblo.jp

静音性が高くてコンパクト…は無理ですよねぇ

関連

以前のUniteでの講演は結構面白い

www.youtube.com

【Unity】Visual Effect Graph(VFX Graph)をLWRPで使用する

f:id:tsubaki_t1:20190403232154j:plain

Visual Effect GraphがLWRPに対応したので、その設定方法と、対応方法についてです。

Visual Effect Graph

Visual Effect Graphはノードベースのエフェクト生成ツールです。

パーティクルの後継機という扱いですが、機能が非常に柔軟で単純なエフェクト以外にもマップ的な表現など、様々な応用が効く感じです。動きについては、下の動画がテンション上がります。

www.youtube.com

www.youtube.com

Visual Effect GraphがLWRPに対応

Visual Effect Graphは以前はHDRPのみ対応でしたが、ver 5.8.0 より LWRPにも対応しました 。これでVRやモバイルなどHDRPではしんどい環境でも動作することが期待出来ます。

なお前提としてVisual Effect GraphはCompute Shaderを使用するので、Compute Shaderに対応していない環境では動作しません またAndroidの、特にOpenGLES3系だとComputeShaderが非常に不安定という話をよく聞きます(Vulkanだと割と動くという話も)。使用する場合、ターゲット端末上で動作するのかはちゃんと確認するのが良さそうです。*1

f:id:tsubaki_t1:20190403220649j:plain

ちなみにVisual Effect Graphは、各粒子(パーティクル)の生成タイミングや位置をCompute Shaderで、実際の描画は通常のShaderで行うシステムです。このシステムの面白い所はパーティクルの座標の動きを生成するCompute Shaderをノードから生成出来るという点にあります。

この「粒子の動き」は別のパイプラインでも同じ物が使えるため、描画の部分さえ差し替えてやれば他のパイプラインでも使える事が予想出来ます。つまりLWRPでVisual Effect Graphを使用するには 最終的な描画用シェーダーのテンプレートをLWRPの物に差し替えれば良いという訳です。

(描画部分はoutputノードと一致する感じです)

f:id:tsubaki_t1:20190403223736j:plain

f:id:tsubaki_t1:20190403230726j:plain

LWRP対応の手順

Visual Effect Graphは、描画機能を差し替えるのを割と簡単に実現出来るようになっています(現在は)。なので描画に使用するテンプレートを差し替えてやります。

LWRP用のテンプレートフォルダは、 Packages/visual effect graph/Shaders/RenderPipeline/LWRP にあります。

なので Project Settings > VFXRender Pipeline Settings Path を、 Packages/com.unity.visualeffectgraph/Shaders/RenderPipeline/LWRP に変更してやります。

f:id:tsubaki_t1:20190403231401j:plain

f:id:tsubaki_t1:20190403231424j:plain

あとはVisual Effect Graphのエディターを開き、Compleボタンを押します。

これでLWRP対応のシェーダーが生成されて、LWRPでもVisual Effect Graphが使用出来ます。

f:id:tsubaki_t1:20190403231602p:plain

f:id:tsubaki_t1:20190403234205g:plain
LWRP対応のセットアップ手順

おまけ:Legacy Render Pipelineの対応

LWRPとHDRPの違いは概ね「描画用のシェーダー」…なら、実は通常のれんだーパイプラインでも使えるんじゃね? という発想ですが、実は使えます。

Render Pipeline Settings Path を、 Packages/com.unity.visualeffectgraph/Shaders/RenderPipeline/Legacyとすれば、VFX-Graph ver 5.10現状では使用する事が出来ました。

f:id:tsubaki_t1:20190403231824j:plain

ただし、これは正式対応という訳ではなく「以前にレガシーパイプラインで作ってたから、公開した方が良いと思って公開した。メンテはしない」という立ち位置で、バージョンが上がると使えなくなる可能性がある項目でもあります。Mesh等に対応したい場合は、他のパイプラインのテンプレートを参考に、自分でテンプレートを記述する必要がありそうです。

https://t.co/JNgk1Q1s4P

とは言え、現状Scriptable Render Pipeline系に全面的に移行出来ないというケースもあるので、結構ありがたいと思う自分が居ます。

感想

GPUパーティクル楽しいですね。量を増やしてもCPUが増えない辺り。

関連

blogs.unity3d.com

*1:みんなiPhoneになぁ~れ☆

【Unity】AddressableAssetSystemのAssetReferenceで、一覧表示するアセットを任意の型に制限したい

AddressableでのAssetReferenceで、任意のアセットを指定する方法についてです。

参照するアセットを絞り込んでおきたい

Addressableでアセットの遅延ロードを行いたい時、AssetReferenceでアセットを指定するというアイディアがあります。ただし、この時に登録しているアセットの数が膨大だと非常に面倒な事になります。

特にキャラクター名等、非常によく使うアドレスはテクスチャやオーディオ、その他諸々で複数登録されている事もありえるので、これを一覧から正しく選択しろというのはヒューマンエラーの元です。

f:id:tsubaki_t1:20190402231321j:plain
登録してる中から一つを探し出すのは面倒くさい

これに対応する理にかなったAPIとして [AssetReferenceTypeRestriction( type )]というAttributeがありましたが、何故かコレをver 0.6.6で廃止してくださいやがりましたので、他のアプローチを紹介します。

AssetReferenceTを使用する

解決法としては、AssetReferenceT<T>を継承したクラスを定義します。ジェネリックを使用したクラスはシリアライズ出来ないので、一々AssetReferenceT<T>を継承したクラスを定義する必要があります。

例えば下のような、ゲーム内でHPパラメーターを共有するScriptableObject:GameDataクラスがあったとして…

[CreateAssetMenu]
public class GameData : ScriptableObject
{
    [SerializeField] private int originalHP;
    public int HP { get; set; }

    private void OnEnable() => HP = originalHP; // 起動時にHPを初期化
    public bool IsDead() => HP < 0; // HPが0以下だったら死亡判定
    public void Damage(int value) => HP -= value; // ダメージを受けたらHPを減らす
}

f:id:tsubaki_t1:20190402232044j:plain
GameDataインスタンスはアセットとして複数のPrefabやSceneで共有可能にしてある状態

GameDataのみを使用可能なAssetReferenceTを用意します。

[System.Serializable] // Serializable属性が必ず必要
public class AssetReferenceGameData : AssetReferenceT<GameData> { }

あとは AssetReferenceの代わりにAssetReferenceGameData をAddressableの呼び出し元コードに設定します。

f:id:tsubaki_t1:20190402232525j:plain
指定したアセットしか表示されない

public class PlayerSpawn : MonoBehaviour
{
    // AssetReferenceではなくAssetReferenceGameData
    [SerializeField] AssetReferenceGameData gameData; 

    private void Awake()
    {
        enabled = false;
        gameData.LoadAsset().Completed += (data) =>  enabled = true;
    }

    private void OnDestroy()
    {
        gameData.ReleaseAsset();
    }

    private void Update()
    {
        // 取得済みのアセットを使用するが、こちらはキャストが必要
        ((GameData)gameData.Asset).Damage(1); 
    }
}

補足

ちなみにAssetReferenceTで指定出来る型は、UnityEngine.Objectのみみたいです。正確にはUnityEngine.Objectのアセットのみっぽく、Componentは指定出来ませんでした。ここにInterfaceが指定出来れば、色々な面で非常に楽になるんですが… ふっきゅんきゅんきゅん!

ついでにAssetReferenceLabelRestriction属性も廃止になり、ラベルを取得するAssetReferenceUILabelRestrictionクラスになりました。こちらは悪くないです。