- 1 はじめに
- 2 サンプル
- 3 使用するテクスチャ
- 4 テクスチャの二値化
- 5 しきい値の時間変化
- 6 テクスチャ二値化シェーダー作成
- 7 エフェクトの作成
- 8 UnityからSTYLYにプレハブをアップロードする方法
はじめに
UnityのシェーダーとParticleSystemを組み合わせて以下のような炎エフェクトを作成する方法を解説します。
サンプル
STYLY GALLERYからサンプル空間を体験できます。
記事で紹介しているUnityプロジェクトのダウンロードはこちらからできます。
ダウンロードしたzipファイルを解凍し、「STYLY_Examples」→「ShurikenShader_Fire」フォルダ内のUnityプロジェクトが今回作成する炎シェーダーの完成形です。
使用するテクスチャ
今回は、以下のようなグレースケールテクスチャを使用します。
テクスチャの二値化
テクスチャカラーがしきい値を下回る部分は黒く、しきい値を上回る部分は白くするようなテクスチャ二値化を行います。
テクスチャをしきい値(Threshold)で二値化するようなシェーダーコードは以下のようになります。
color = step(Threshold, color)
しきい値の時間変化
今回作成する炎エフェクトでは、時間経過でしきい値を変化させて粒子の形状を変化させます。
テクスチャ二値化シェーダー作成
ParticleSystemから二値化のしきい値のコントロールを行えるシェーダーの作成方法を解説します。
frag関数
ParticleSystemのCustom Vertex Streamsという仕組みを利用することで、シェーダーへ値を渡せます。
今回はParticleSystemから流れてくる数値を i.texcoord2.x で取得し、これをテクスチャ二値化のしきい値として利用するようなシェーダーを作成します。
fixed4 frag(v2f i) : SV_Target
{
fixed4 texColor = i.color * tex2D(_MainTex, i.texcoord);
fixed4 col = i.color * step(i.texcoord2.x, texColor.r);
...
シェーダー全体
シェーダーコード(.shader)の全体は以下のようになります。Shader "Custom/Particles/Alpha Crunch - Alpha Blended" {
Properties{
_MainTex("Grayscale Texture", 2D) = "white" {}
}
Category{
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" }
Blend SrcAlpha OneMinusSrcAlpha // Alpha Blended
ColorMask RGB
Cull Off Lighting Off ZWrite Off
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile_particles
#pragma multi_compile_fog
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed4 _TintColor;
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float4 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float2 texcoord2 : TEXCOORD1;
UNITY_FOG_COORDS(1)
UNITY_VERTEX_OUTPUT_STEREO
};
float4 _MainTex_ST;
v2f vert(appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
o.texcoord2.xy = v.texcoord.zw; // Copy TEXCOORD0.zw
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 texColor = i.color * tex2D(_MainTex, i.texcoord);
fixed4 col = i.color * step(i.texcoord2.x, texColor.r);
col.rgb *= col.a;
UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(0,0,0,0)); // fog towards black due to our blend mode
return col;
}
ENDCG
}
}
}
}
エフェクトの作成
作成したシェーダーを利用して、エフェクトを作成する方法を解説します。
ParticleSystemの作成
マテリアルの設定
上記のシェーダーからマテリアルを作成し、Rendererモジュールに登録します。
結果
ParticleSystemへマテリアルを設定すると、以下のように白い四角の粒子が飛ぶようになります。
Custom Dataの設定
Custom Dataを利用して、二値化のしきい値として使うためのFloat値を定義します。
ここで定義したFloat値は後にシェーダー側へ渡されます。
Custom Dataを有効にする
Vectorデータの設定
Disableと表示されている部分をクリックし、Vectorを選択します。
Float値が4つ出てきますが、今回はFloat値を1つだけ使うのでNumber of Components を1に設定します。
結果
Custom DataのCustom1にFloat値が1つある状態になりました。
パラメータの名前を変える
パラメータ名がXだと分かりづらいので、Xの部分をクリックしてThreshold(しきい値)という名前を入れておきます。
Custom Vertex Streams の設定
次に、Custom Dataをシェーダーへ渡すための設定を行います。
Custom Vertex Streamsを有効にする
Rendererモジュールの中にあるCustom Vertex StreamsのチェックをONにします
チェックをONにすると、ストリームのリストが出現します。
ParticleSystemからシェーダーへ渡したいデータはここで定義します。
データをストリームへ登録
リストの右下にある、+ボタンをクリックします。
今回はCustomDataのCustom1のX成分を登録したいので、 Custom -> Custom1.xを選択します。
Custom1.xがCustom Vertex Streamsへ追加され、TEXCOORD0.z経由でシェーダーへ値が流れるようになりました。 シェーダーからTEXCOORD0.zの値を参照したい場合、i.texcoord2.xを参照します。
以上で、Custom Vertex Streamsの設定は完了になります。
しきい値を変えたときのパーティクルの変化
Custom DataのThresholdの値を変更すると、パーティクルの見た目も変化します。
ここのThresholdはシェーダー内で以下のような二値化計算のしきい値として利用されています。 (実際はThresholdはi.texcoord2.xとしてシェーダーへ渡されています。)
fixed4 col = i.color * step(Threshold, texColor.r);
しきい値を時間変化させる
次に、このThresholdを時間で変化させるようにしてみます。
Thresholdの右側にある三角のアイコンをクリックします。
Curveを選択します。
Curveに設定すると、時間変化でパーティクルの形状が以下のように変化します。
炎エフェクトの作成
今回作成したシェーダーを利用して、以下のような炎エフェクトを作成する方法を解説します。
オレンジ色の炎エフェクト + 黄色の炎エフェクトという二つの要素から構成されています。
1つめのエフェクトを作成
炎の外側の部分を作成していきます。
Particle System作成
Particle Systemを作成し、名前をFire_Redとします。
基本モジュール
Start Lifetime, Start Size, Start Rotationをランダムに値に設定し、粒子にばらつきを持たせます。
Emissionモジュール
Emissionモジュールでは、粒子の発生数を設定します。
Shapeモジュール
Shapeモジュールでは、粒子の発生位置を設定します。
今回は発生位置に小さなばらつきを持たせるため、Radiusに小さな値を設定しています。
Velocity over Lifetimeモジュール
Velocity over Lifetimeモジュールでは、時間経過での粒子スピードの変化を設定します。
XYZ成分はそれぞれ以下のように設定しています。
粒子は最初にガス燃焼の加熱によって加速しながら上昇し、そのあとは空気冷却によって減速するようなイメージでスピードを設定しています。
空気の乱気流をイメージして、XY方向のスピードにもばらつきを持たせています。
Size over Lifetimeモジュール
最初はわずかに膨張し、そのあと少しずつ収縮していくようなイメージでサイズ変化を設定します。
Rotation over Lifetimeモジュール
粒子にランダムな回転の動きを持たせることで、エフェクトの動きをより複雑にします。
Custom Dataモジュール
エフェクトの後半で、粒子の形状がじわじわと粒子が削れていくようなイメージで Thresholdのカーブを設定します。
Rendererモジュール
オレンジ色の炎は黄色い炎より後ろに表示したいので、Sorting Fudgeの値を増やしておきます。
一つ目の要素が完成
オレンジ色の炎エフェクト(Fire_Red)が完成しました。
2番目のエフェクトを作成
炎の内部の部分のエフェクトを作成していきます。
Particle System作成
最初に作成した Fire_Redを複製し、Fire_Yellowという名前にします。
基本モジュールの設定
エフェクトのバラつきを意識しつつ、最初のエフェクトより短いLifetimeを設定します。
Emissionモジュール
Shapeモジュール
Velocity Over Livetimeモジュール
Size over Lifetime モジュール
Rotation over Lifetimeモジュール
Custom Dataモジュール
Rendererモジュール
今回の黄色い炎は、オレンジの炎の手前に表示したいのでSorting Fudgeを0に設定します。
2番目のエフェクトが完成
以下のような黄色い炎エフェクト(Fire_Yeloow)が完成しました。
Fire_RedとFire_Yellowを合わせる
空のParticleSystemを作成し、その中へFire_RedとFire_Yellowを入れることで
エフェクトが同時に再生されるようになります。
空のParticleSystem作成
ParticleSystemを作成し、名前をFX_Fireとします。
FX_Fireではパーティクルを発生させたくないのでモジュールをすべてOFFにします。
FX_Fireの中にエフェクト二つを入れる
FX_Fireの中に。 Fire_RedとFire_Yellowを入れるとFire_RedとFire_Yellowが同時に再生されるようになります。
結果
以下のようなエフェクトになり、炎エフェクトの完成です。
UnityからSTYLYにプレハブをアップロードする方法
作成した炎エフェクトをSTYLYにアップロードする手順を解説します。
Unityで作成した炎エフェクトをSTYLYにアップロードする手順は以下の通りです。
- FX_Fireをprojectウィンドウに移動してプレハブ化する
- UNITY PLUGIN FOR STYLYをインポート
- プレハブを右クリックして「Upload prefab or scene to STYLY」をクリック
- アップロード完了
詳細なアップロード方法は以下のマニュアル記事で解説しているので、よくわからないという方はこちらの記事をご参照ください。
お疲れ様でした。以上でシェーダーを利用した炎エフェクトの作り方解説は終わりです。