シェーダー勉強内容(2022年6月)
はじめに
2022年6月に勉強した内容です。
過去の記事はこちら
Unity
6月から始まった新プロジェクトのためのURP対応の2DシェーダーであるSkadiShaderを開発していました。
大まかな必要な機能は2週間ぐらいで実装できました。
URPの既存のシェーダーであるSprite-Lit-DefaultからLight2Dに対応している部分を調べて写経し、その後必要な機能を付け足していきました。
写経しているときに困ったのがUSE_SHAPE_LIGHT_TYPEキーワードについての情報があまりないということでした。
調べてもヒットしなかったのでプロファイラーとにらめっこしながら自分で調べることになりました。
詳しいことはこちらにまとめてあります。
Light2Dに対応するシェーダーを書くのならTYPE_0~TYPE_3まで全部追加していいと思います。
写経で完成したのがこちら
その後はアウトラインが必要になったので追加
アウトラインはアウトラインのみ書かれたテクスチャを用意し、それをメインテクスチャと合成することで作成しています。
計算で作ると1ピクセルの大きさが微妙にずれるのでそれを防ぐために今回はアウトラインは別テクスチャで指定するように実装しました。
また、Unityが用意したLight2Dに対応させるメソッドが内部でアルファをdiscardしていたため1Passで作ろうとするとアウトラインの部分が描画されませんでした。
なのでアウトラインは別でPassを作りました。
ここでdiscardしていました。
また、アウトラインを使わない場合は余分な処理を減らすために頂点シェーダーでポリゴンを小さくし、計算する量を減らしています。
v2f vert (appdata v)
{
// SKADI_EPS = 0.00001
if(!_UseOutline) v.positionOS *= SKADI_EPS;
}
Emissionも必要なので追加しました。
光り方を
直線
サイン波
のこぎり波
三角波
矩形波
から選べるようにしました。
float FlickerWave(int flickerMode, float flickerSpeed)
{
float speed = _Time.y*flickerSpeed*2.;
float wave = 0.;
if(flickerMode == 0) wave = 1.;
if(flickerMode == 1) wave = (sin(speed*SKADI_PI)+1.)*.5;
if(flickerMode == 2) wave = frac(speed*.5+.5);
if(flickerMode == 3) wave = abs(2.*frac(speed*.5-.25)-1.);
if(flickerMode == 4) wave = step(.5, frac(speed*.5+.5));
return wave;
}
シンセサイザーのオシレーターで波を設定できるのでそれをヒントにしました。
今後
今のプロジェクトでシェーダーに追加しなくてはならない機能が出てきたら追加します。
それまではVRC用のシェーダーをちょくちょく開発します。