太郎Work

Unityとかで困ったこと等を残しておきます

GenerateHLSL完全に理解した

GenerateHLSLとは?

RenderPipelineのコードを見ているとあちこちで見かけるAttributeで、名前からして自動生成?
便利そうなので調べてみたのですが一切記事が出ず、公式リファレンスもほぼ説明がないのでまとめました
Unityは2021.3.14を使用しています

docs.unity3d.com

続きを読む

Unity2021.2のOverlay機能を使う

Overlay機能

Unity2021.2からSceneView上の要素はOverlayというものに置き換わり、自由に配置を動かせるようになりました。
ParticleSystemを選択したときのウィンドウも↓こんな感じになっていて左上をドラッグすることで自由に動かすことができます

f:id:tarowork:20220318174303p:plain:w300
ParticleSystemOverlay

自分でも追加したくなったのでやってみたのですがめちゃくちゃ簡単だったのでメモ

続きを読む

フレア処理を高速化した話

この記事はQualiArts Advent Calendar 202020日目の記事になります。
昨日は 無料のDataformでBigQueryにおけるデータ加工のDXを改善して幸せになろう - Qiita でした

はじめに


現在開発中のプロジェクトではUniversalRenderPipeliene(以下URP)を使用しているためレンズフレアを使用することができません

f:id:tarowork:20201215184412p:plain
Lens Flareは対応していない...

LensFlareどころかHaloも使用できないため画面にフレアを描画する手段がURPには用意されていません。


他にもかなり機能制限があるので比較を見たい方はこちら
docs.unity3d.com


そこでアセットストアでLensFlareを探すと何個か引っかかるのですが意外と存在しない…
https://assetstore.unity.com/?q=Lens%20Flare&orderBy=0

この中で一番細かく設定できそうだったProFlareを導入したのですが、大量のフレアを出すとCPU,GPU共に負荷が高く、実機でボトルネックとなってしまったのでSRP用に描画部分を作り直すことにしました
このアセット自体は非常に高品質なレンズフレアを作成できるためちょっと使う分であればオススメです

assetstore.unity.com

続きを読む

ShaderGraphのPBRMasterNodeを拡張してみた

UniversalRPには標準でPBRMasterNodeがありますが、Fogの処理を変えたかったりほんの少し処理変えたかったりしたかったので自作のMasterNodeを作ってみました
速攻で仕様変わっていたらすみません...
Unity2019.4+ShaderGraph7.5.0+UniversalRP7.5.0

8/24追記
ShaderGraph9.x.xでは仕様が全く違うためここで作ったものは動きません...

  • はじめに
  • 最低限必要なファイルを複製する
  • Culling設定をMaterial側に持たせる
    • PBRMasterNodeからTwo Sidedを削除
    • SubShaderにCull設定を追加
    • ShaderPropertiesにCull設定を追加
  • Fogを自前のものに置き換える
    • fogのmulti_compileを更新
    • hlsl複製
    • シェーダ改修
  • Cutoffの数値でAlphaTest処理を分岐させる
    • ShaderGraphのAlphaTest仕様
    • 従来の処理に合わせて_ALPHATEST_ONマクロを定義する
  • おわり

はじめに

ShaderGraphのクラスはprivateになっているため、何かしらの方法でアクセスできるようにする必要があります

  • Graphicsリポジトリをフォークしてその中に直接スクリプトを追加する
  • AssemblyInfo.csに記載されている名前でasmdefを作成する

2個めはかなり無理矢理な手法になってしまうので直接スクリプトを追加する方針にしました

github.com
↑このリポジトリはクソデカなので落とすときは気をつけてください

最低限必要なファイルを複製する

My~とか適当な名前をつけて以下のファイルを複製します

PBRMasterGUI.cs
生成されたシェーダコードに使用されるMaterialEditor

f:id:tarowork:20200818165435p:plain
拡張しなければデフォルトのGUIで描画される

PBRMasterNode.cs
MasterNode実体 Slotの追加や設定で使用するシリアライズパラメータもここでもたせる

f:id:tarowork:20200818165403p:plain
Graphの終点に配置するコード生成を行うノード

PBRSettingsView.cs

f:id:tarowork:20200818165130p:plain
MasterNodeの右上のアイコンをクリックしたときのウィンドウ


PBRSubShader.cs
SubShader生成時の文字列生成ロジック(includeファイルとか)


これだけであとは型を置き換えればMasterNodeが完成します
ここからは機能を追加してみます

続きを読む

Timeline関連メモ

何かあったら追記していきます

Timelineでカスタムトラックを作成したときにcurves編集ボタンを出す条件
f:id:tarowork:20200722180312p:plain

AnimatedParameterUtility.cs内に実装があった
IPlayableBehaviour を実装したクラスのフィールドを必ず持つ必要がある

static FieldInfo[] GetScriptPlayableFields_Internal(IPlayableAsset asset)
{
    return asset.GetType()
        .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
        .Where(
            f => typeof(IPlayableBehaviour).IsAssignableFrom(f.FieldType) &&                                        // The field is an IPlayableBehaviour
            (f.IsPublic || f.GetCustomAttributes(typeof(SerializeField), false).Any()) &&       // The field is either public or marked with [SerializeField]
            !f.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any() &&                 // The field is not marked with [NotKeyable]
            !f.GetCustomAttributes(typeof(HideInInspector), false).Any() &&                     // The field is not marked with [HideInInspector]
            !f.FieldType.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any())         // The field is not of a type marked with [NotKeyable]
        .ToArray();
}

EnterPlayMode時にNativeArrayのエラーが発生する

Unity2019.3.1f1の時点です

再生までの時間が早くなるEnterPlayModeを使用すると
NativeArrayアクセス時に↓このエラーが発生します

InvalidOperationException: The NativeArray has been deallocated, it is not allowed to access it

ExecuteAlwaysを指定しているためOnEnableでnew、OnDisableでDisposeしているのですが、どうも適切に開放、確保ができていないようです。

f:id:tarowork:20200226111055p:plain

ReloadSceneにチェックを付ければエラーは発生しなくなりました

UnityTimelineのTrackをスクリプトから入れ替える

現在Timeline関連の実装をしているのですが、Trackの順序をスクリプトから入れ替えたくなったのでメモ
多分こんなことしたい人いないと思うので需要ゼロです

入れ替えたい理由はPlayableOutputの接続順をプログラム的に変えたかったためです

本来はWindow内でTrackを掴むことで順番を入れ替えられます

f:id:tarowork:20200219134548p:plain
Timeline Window

このTrackを保持しているのはPlayableDirectorに指定しているTimelineAssetですが、このTimelineAssetにはMoveが用意されていません

docs.unity3d.com

悲しいことにCreateTrackとDeleteTrackしかなく、TimelineWindowの実装を追っていくと内部でMove的なメソッドは存在していますが呼び出しやすい感じにはなっていません…

そこでTrackを入れ替えたときのTimelineAssetの差分を見てみると `List m_Tracks` 中身を変更しているだけでした
f:id:tarowork:20200219144759p:plain

なので無理やりSerializedPropertyから書き換えることで入れ替えがうまくいきました。

var so = new SerializedObject(timelineAsset);
var tracks = so.FindProperty("m_Tracks");
tracks.MoveArrayElement(src, dst);
so.ApplyModifiedProperties();
so.Dispose();

これだけだとTimelineWindowの描画が更新されないのでReflectionでTimelineAssetを再読み込みするメソッドを呼び出します
第4引数のboolをtrueにしておくことで実質Reload状態にすることが出来ました

var timelineWindowType =
    typeof(UnityEditor.Timeline.TimelineEditor).Assembly.GetType("UnityEditor.Timeline.TimelineWindow");
var window = EditorWindow.GetWindow(timelineWindowType);
var method = timelineWindowType.GetMethod("SetCurrentTimeline",
    BindingFlags.Instance | BindingFlags.NonPublic,
    null,
    new[] {typeof(TimelineAsset), typeof(PlayableDirector), typeof(TimelineClip), typeof(bool)},
    null);

method?.Invoke(window, new[] {timelineAsset, _director, (object) null, true});
<||