見出し画像

SpriteRenderer用のキラカードシェーダを作る

こんにちは、カキレモンです。

先日のunity1weekではガチャを引くゲームを作りました。その際にキラカード表現の実装について色々調べたので、noteにまとめていこうと思います。

さて、表題の通り基本的にはシェーダを使って何とかしていくわけですが、ネットでの実装法はなぜかメッシュ(MeshRenderer)を使って表示する前提のものがほとんどです。しかし、たかだかカード1枚の表示のためにメッシュを作るのはさすがに面倒くさいので、今回はSpriteRendererで簡単に表示できるシェーダを書いていきます。

参考(MeshRenderer用):

SpriteRenderer用の基本シェーダ

まずこちらのリポジトリなどを参考に、なるべく必要最小限っぽい部分だけを抜き出してSpriteRendererのSpriteを表示するだけのシェーダを書きます。今回はこれをベースにして機能を追加していきます。

方針

上に上げた動画の流れを参考にします。基本的にはShaderGraphをコードに書き起こすだけですが、一部のノードは少し工夫が必要そうです。もともと最後にマスクを掛ける工程がありますが簡単のため今回はカットします。

1. 接空間での視線方向ベクトルを求める(View Directionノード)
2. 視線方向に応じて光の色を決める(Sample Gradientノード)
3. テクスチャの色に光の色を足す

視線方向ベクトルの計算

こちらのサイトを参考にするとこのように書けそうです。

TANGENT_SPACE_ROTATION;
o.viewDir = normalize(mul(rotation, ObjSpaceViewDir(v.vertex)));

動画では適当な係数をかけたりオフセットを足したりしていますが、今回は簡単のためにそのまま使います。

Gradientの書き換え

動画で使っているGradientはShaderGraphでしか使えません。しかし最終的に虹色のグラデーションになればいいので、HSVのフォーマットで色相を動かしてグラデーションを掛けます。

HSVからRGBへの変換はこちらのサイトを参考にします。

ただしGLSLで書かれているのでHLSLで書き直します。

fixed3 hsv2rgb(fixed3 c)
{
    fixed4 K = fixed4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    fixed3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

これで、hsv2rgb(fixed3(t,1,1))のように書けばtが0~1で変化するとき虹色のグラデーションを得ることができます。

結果

これで得たグラデーションをテクスチャの色に適当に加算することでゲーミングな輝きを出すことができました。

できあがったコードはこちらです。

おわりに

ノイズ関数などで手を加えればもう少し実際のキラカードっぽくすることもできそうです。

さらに鏡面反射なども実装してやればもっと綺麗になるかもしれませんが、今回はこのくらいにします。

それでは、また。

この記事が気に入ったらサポートをしてみませんか?