[UE4]徐々に石化するシェーダーを作る+5色マスクとかおまけ


前書き

  • この記事には筆者の性癖が含まれます。予めご了承ください。
  • 当記事の中ではこういう概念をマスクと呼称しますが思いっきりfloat値です。
  • 実装の垂れ流しなのでバッドプラクティスかもしれないです。

目次

  • 徐々に変化する関数マスク
  • 5色マスク
  • おまけ:実装したUE4シェーダー

徐々に変化する関数マスク

様々なシチュエーションに対応するために今回複数の関数を用意しました。
1. 全体がフェード
2. まだら模様(ドラゴンズド○マ リスペクト)
3. 下から上がってくるやつ
4. その逆

  1. 全体がフェードするやつはこんな感じです

  2. まだら模様はこんな感じです(意外と絵が微妙だったので修正したい)

3.下から上がってくるやつ(意外とry

ノードと計算式は以下です。
斑に関してはやっぱりUVでやったほうが良いのでは・・・?と思ったりしなくはないです

mask.hlsl
//mask_gen
float outf=0.0f;
float s_mlt=4.0f;
switch(floor(num)){
case 0: outf=in_alpha;break;
//sin波5つを1~0にしてからpowをかけ0~-1にする
case 1:outf=pow((sin(5*s_mlt*local_.x+6)+sin(7*s_mlt*local_.y+1)+sin(13*s_mlt*local_.z+13)
+sin(11*s_mlt*atan2(local_.z,local_.x)*length(float2(local_.z,local_.x))+3)
+sin(17*s_mlt*atan2(local_.z,local_.y)*length(float2(local_.z,local_.y))+23))/10+0.5,3)
+in_alpha*2-1;break;
//localzとの組み合わせでせり上がるとこ+うねうね
case 2:outf=pow(in_alpha*1.02+(1-local_.z)+sin((atan2(local_.y,local_.x))*90)/50,20);break;
case 3:outf=pow(in_alpha*1.02+local_.z+sin((atan2(local_.y,local_.x))*90)/50,20);break;
}
return outf;

5色マスク

カスタマイズゲー用に5箇所の塗り分けが可能なマスク
RGBA1枚で実装できる(多分)最大色数

挙動

色A,B,C,D,Eがあるとき、
- (0,0,0,0)→色A100%
- (1,0,0,0)→色B100%
- (0,0.5,0,0)→色A50%,色C50%
- (0.7,0.3,0,0)→色B70%,色C30%
- (7,3,0,0)→色B70%,色C30%

計算式

重A=clamp(1-(R+G+B+A),1,0);
重(B,C,D,E)=(R,G,B,A)/clamp(R+G+B+A,999,1);
出力色=色A*重A+色B*重B+...

おまけ:実装したUE4シェーダー

https://qiita.com/vak/items/ced4811350b438104f7d の内容を含みます

4層構造になっております
A層:シェーダーの要件ごとにベース色、パラメーターを準備(この組をマテリアルと呼ぶ)(今回の場合は5色マスクがベース色に)
B層:状態異常番号とベースカラーを受け取り状態異常時のマテリアルを出力
C層:A層とB層を当記事のマスクでマテリアル合成
D層:C層で合成されたマテリアルから色を出力

パラメーターはベース色、アンビエント反映度、スフィアマップ、キューブマップ反映度の4点

問題点

UE4のマテリアル関数機能ではサンプラーを出力できない
そのためスフィアマップの計算はモデルに適用するマテリアルであるA層で行う必要がある

上記をまとめたものが以下になります

実装サンプル

https://twitter.com/vak_DJregion/status/1195453585904943104
steamでプレイできるのでよろしくね(ダイマ2)