#SonarFx
ソナーのような表現ができるフリーのアセットです。
下記のgif動画で赤い波が中心から湧き出る表現がそれです。
(キューブが湧き出てるのはパーティクルで、この記事では解説しません。)
このアセットがどうやってこのエフェクトを表現しているのか解説します。
SonarFx
#使い方
下記のブログで使い方が説明がされてるので省きます。
テラシュールブログ
#仕組み
Cameara.SetReplacementShader(shader, null)
で画面範囲内に映るモデルのシェーダーを、
ソナーの中心点から一定距離が時間変化で赤くなるサーフェースシェーダーに差し替えることで、ソナー表現をしています。
#shader部分
処理の肝になるシェーダーの解説です。
下記シェーダーで、時間変化で一定距離のモデルの表面のEmittionが変化するのを表現しています。
void surf(Input IN, inout SurfaceOutput o)
{
#ifdef SONAR_DIRECTIONAL
float w = dot(IN.worldPos, _SonarWaveVector);
#else
float w = length(IN.worldPos - _SonarWaveVector);
#endif
// Moving wave.
w -= _Time.y * _SonarWaveParams.w;
// Get modulo (w % params.z / params.z)
w /= _SonarWaveParams.z;
w = w - floor(w);
// Make the gradient steeper.
float p = _SonarWaveParams.y;
w = (pow(w, p) + pow(1 - w, p * 4)) * 0.5;
// Amplify.
w *= _SonarWaveParams.x;
// Apply to the surface.
o.Albedo = _SonarBaseColor;
o.Emission = _SonarWaveColor * w + _SonarAddColor;
}
float w = length(IN.worldPos - _SonarWaveVector)
上記はソナーの中心からモデルのメッシュまでの距離になります。
w -= _Time.y * _SonarWaveParams.w;
w /= _SonarWaveParams.z;
w = w - floor(w);
wの少数部分のみを抽出して横軸時間のノコギリ波を作っています。
http://moge32.blogspot.jp/2013/11/gen-waveform.html
// Make the gradient steeper.
float p = _SonarWaveParams.y;
w = (pow(w, p) + pow(1 - w, p * 4)) * 0.5;
ノコギリ波にボカしを加えています。
ちなみに_SonarWaveParamsはSonarFx.cs側からシェーダーに渡されるパラメータになります。
var param = new Vector4(_waveAmplitude, _waveExponent, _waveInterval, _waveSpeed);
Shader.SetGlobalVector(waveParamsID, param);
// Apply to the surface.
o.Albedo = _SonarBaseColor;
o.Emission = _SonarWaveColor * w + _SonarAddColor;
最後にEmissionに波の効果を反映して終了です。
かなりシンプルな手法でこれだけのエフェクトを実現しているのが驚きです。