はじめに
シェーダーを利用して、エネルギーが集まるような表現を作る方法を紹介します。
サンプルプロジェクト(GitHub)
本記事で紹介するエフェクト・モデル・シェーダー・テクスチャはすべてサンプルプロジェクトに含まれています。
STYLY-Unity-Examples – TwistEffect
作り方 解説
今回は3Dモデルの作成にHoudiniを使用します。
Houdiniの導入や基本的な使い方については以下の記事をご覧ください。
準備 : SideFX Labsのインストール(Houdini)
今回はHoudiniのLabs Disc Generatorノードを使用するのですが、初期のHoudiniにはこれはインストールされていません。
SideFX LabsをHoudiniへインストールする必要があります。
まずはHoudiniの画面上部のSideFX Labsシェルフの Update Toolsetをクリックします。
Update ボタンをクリックするとSideFX LabsがHoudiniへインストールされます。
インストールが完了すると以下のようなダイアログが表示されます。
Houdiniを再起動するとSideFX Labsのツール一式が利用可能になっています。
手順01 : 円盤メッシュの作成(Houdini)
円盤メッシュの作成
HoudiniのLabs Disc Generatorノードで円盤メッシュを作成し、ROP Geometryノードでobjファイルとして出力します。
Labs Disc GeneratorはUV展開済みの円盤メッシュを一撃で作成してくれる、便利なノードです。
円盤メッシュのobj出力
ROP Geometry ノードにはobjファイルの出力先のパスを指定します。
objファイルの出力先にはUnityプロジェクトのAssets/以下を指定しましょう。
Save to Diskをマウスクリックすることでobjファイルが出力されます。
作成したobjファイルはUnity上でSceneビューへドラッグアンドドロップし、Scene上へ出しておきます。
手順02 : 基本となるシェーダーの作成
次にエフェクト用シェーダーを作成します。
まずはProjectウィンドウ上の右クリックメニューからCreate/Shaderを選択し、シェーダーを作成します。
シェーダー名はTwistEffectShaderとします。
作成したシェーダーを開き、以下のシェーダーコードを貼り付けます。
Shader "STYLY/Examples/TwistEffectShader"
{
Properties
{
_MainTex ("Main Texture", 2D) = "white" {} // main color texture
_MaskTex ("Mask Texture", 2D) = "white" {} // mask texture
_Color ("Color", Color) = (1, 1, 1, 1)
_Twist ("UV Twist", Float) = 0.0 // uv twist
_ScrollSpeedX ("Scroll Speed X", Float) = 0.0 // uv scroll speed x
_ScrollSpeedY ("Scroll Speed Y", Float) = 0.0 // uv scroll speed y
_Power("Power", float) = 1.0
_SmoothstepEdge1("Smoothstep Edge 1", float) = 0.0
_SmoothstepEdge2("Smoothstep Edge 2", float) = 1.0
}
SubShader
{
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
LOD 100 //
ZWrite Off
Blend SrcAlpha One
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv_main : TEXCOORD0;
float2 uv_mask : TEXCOORD1;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
sampler2D _MaskTex;
float4 _MainTex_ST;
float4 _MaskTex_ST;
fixed4 _Color;
half _ScrollSpeedX;
half _ScrollSpeedY;
half _Twist;
half _Power;
fixed _SmoothstepEdge1;
fixed _SmoothstepEdge2;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv_main = TRANSFORM_TEX(v.uv, _MainTex);
o.uv_mask = TRANSFORM_TEX(v.uv, _MaskTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
float2 uv = i.uv_main;
fixed4 col = tex2D(_MainTex, uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
手順03 : マテリアルの作成
作成したシェーダーを右クリックし、マテリアルを作成します。
作成したマテリアルは円盤メッシュを適用します。
手順04 : 円盤メッシュにテクスチャを張り付ける
以下のテクスチャ(noise01)を円盤メッシュに貼り付けます。
上記のテクスチャ(noise01)を先ほどのマテリアル上にアタッチします。
円盤メッシュの表示は以下のようになります。
手順02 : テクスチャUVスクロールする
次に時間経過でUVをずらし、以下のような動きを作ります。
シェーダーをfragの中身を以下のように変更します。
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
float2 uv = i.uv_main + float2(_Time.y * _ScrollSpeedX, _Time.y * _ScrollSpeedY);
fixed4 col = tex2D(_MainTex, uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col * _Color;
}
_Time.yは時間、_ScrollSpeedXと_ScrollSpeedYは今回定義したスクロールの速さのパラメータです。
マテリアルのパラメータの Scroll Speed Y を 0.5に設定してみます。
結果は以下のようになります。
テクスチャUVのY成分が毎秒0.5ずつ増加し、テクスチャは下方向へズレていきます。
手順03 : テクスチャにマスクをかける
ここで、テクスチャに対して以下のようなアルファマスクを乗算したいと思います。
シェーダーのfrag関数を以下のように書き換えます。
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
float2 uv = i.uv_main + float2(_Time.y * _ScrollSpeedX, _Time.y * _ScrollSpeedY);
fixed4 col = tex2D(_MainTex, uv);
fixed4 mask = tex2D(_MaskTex, i.uv_mask);
col = col * mask;
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col * _Color;
}
テクスチャカラーのcolにマスクカラーmaskを乗算しています。
次に、マテリアルにマスクテクスチャをアタッチします。
結果は以下のようになります。
手順04 : UVをひねる
次にUVをyに比例して横にずらす、という処理を加えます。
具体的にはUVのx成分にy成分を加算します。
シェーダーのfrag関数を以下のように書き換えます。
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
float2 uv = i.uv_main + float2(_Twist * i.uv_main.y, 0.0);
fixed4 col = tex2D(_MainTex, uv + float2(_Time.y * _ScrollSpeedX, _Time.y * _ScrollSpeedY));
fixed4 mask = tex2D(_MaskTex, i.uv_mask);
col = col * mask;
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col * _Color;
}
UVのY成分が1増加すると、UVのX成分は_Twist増加します。
マテリアルのパラメータTwistを-0.7に設定してみます。
結果は以下のようになります。
手順05 : pow関数で強弱をつける
ここで、テクスチャカラーにpowを適用して色の強弱を強めてみます。
シェーダーのfrag関数を以下のように書き換えます。
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
float2 uv = i.uv_main + float2(_Twist * i.uv_main.y, 0.0);
fixed4 col = tex2D(_MainTex, uv + float2(_Time.y * _ScrollSpeedX, _Time.y * _ScrollSpeedY));
fixed4 mask = tex2D(_MaskTex, i.uv_mask);
col = pow(col, _Power) * mask;
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col * _Color;
}
マテリアルのパラメータPowerを3に設定してみます。
結果は以下のようになります。
色の強弱がつき、エフェクトのディテールが増えたのではないでしょうか。
手順06 : smoothstep関数で強弱をつける
シェーダーのsmoothstep関数を使うと色にコントラストをつけることができます。
Photoshopのトーンカーブのような効果を与えることができます。
シェーダーのfrag関数を以下のように書き換えます。
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
float2 uv = i.uv_main + float2(_Twist * i.uv_main.y, 0.0);
fixed4 col = tex2D(_MainTex, uv + float2(_Time.y * _ScrollSpeedX, _Time.y * _ScrollSpeedY));
fixed4 mask = tex2D(_MaskTex, i.uv_mask);
col = pow(col, _Power) * mask;
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
col.a = smoothstep(_SmoothstepEdge1, _SmoothstepEdge2, col.a);
return col * _Color;
}
マテリアルのパラメータSmoothstep Edge 1, Smoothstep Edge 2 は以下のように設定してみます。
結果は以下のようになります。
以上でエフェクト用シェーダーの完成です。
パラメータの設定例
エフェクトのパラメータを変えることで様々な表現を作ることができます。
設定例1
Powerの値をマイナスに設定すると、エフェクトが発光するような感じになります。
設定例2
マスクを変えることでも、エフェクトの形状を変えることができます。
UnityからSTYLYにプレハブをアップロードする方法
シェーダーを適用したオブジェクトを、UnityからSTYLYにアップロードします。
UnityからSTYLYにアップロードする方法は以下のマニュアル記事をご参照ください。