前回に続き、DrawCall削減で、ParticleのGPU Instancing関連を調査
#ParticleSystem
##Billboard
通常Particleを表示させると下記のようになる
DynamicBatchingが効いてちゃんと効率化されてます
ParticleSystemのRenderingを見てみましょう。
RenderModeがBillboardですね。BillboardではGPU Instancingは使えないが
DynamicBatchingでいいようにしてくれます
##mesh
GPU Instancingを使うにはmeshにします
meshにすると、メッシュをパーティクルとして飛ばせます
デフォルトで Default-ParticleSystemというメッシュが付いています
そしてそのシェーダーはGPU Instancing対応しています
GPU Instancing無し
DynamicBatchingは効いてるが、GPU Instancingはありません
GPU Instancingあり
GPU Instancing効いてます
#自作のマテリアルをつける
Shader "Instancing2"
{
SubShader
{
Tags { "RenderType" = "Opaque" "DisableBatching" = "True"}
Pass
{
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#pragma instancing_options procedural:vertInstancingSetup
#include "UnityCG.cginc"
#include "UnityStandardParticleInstancing.cginc"
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 color : TEXCOORD1;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
UNITY_SETUP_INSTANCE_ID(v);
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = i.color;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}
前回とほぼ同じだが、
#pragma instancing_options procedural:vertInstancingSetup
がないとちゃんと動かなかった。基本的にGPU Instancingを行う時は上記オプションをつけたほうがよさそうだ
また、Colorプロパティーに関するものは今回無いので削除した
ちゃんと効く
#グラデーションをする
ParticleのパラメータでStartColorをグラデーションにしてみる
色が変わる=マテリアルが変わるので、普通に行うと色の数だけマテリアルが生成されると思うが
##Default-ParticleSystem
グラデーションでパーティクルが表示されたが
DrawCallは GPU Instancingの有無にかかわらず単色の時と変わらない
何故だろうか?
##自作メッシュ
メッシュを自作に変更する
GPU Instancing無しだとちゃんと表示されるが
有りにすると全部白いパーティクルになった
何かがおかしい
答えは、Instancingの仕組みにある
頂点属性や、プロパティーは INSTANCE_IDにより配列から値を取り出す
Positionは実は UnityObjectToClipPos の内部で計算されている
が、Colorはそのままなのでダメ
Colorの変換には vertInstancingColor という関数が用意されている
頂点シェーダーの Color代入部分を下記に変更
o.color = v.color;
vertInstancingColor(o.color);
これで、パーティクルも GPU Instancingが正常に行われた
もちろん、前回の方法で、ShadowCasterもGPU Instancing化された
#今回できなかったやつ
本当はこのあたりもちゃんと調査したかったけど
案件が炎上したので、火消しに戻るため参照で
##パーティクルのカスタムデータ
頂点属性をカスタマイズすることが出来ます
##コンピュートシェーダでインスタンシングデータ作成
コンピュートシェーダでデータ作る
##パーティクルのインスタンス事にプロパティ変更
マテリアル変数を UNITY_INSTANCING_BUFFER_START でブロック化し
インスタンス事に変数を与える方法は以前行ったが
これもパーティクルで行えるはずである