こんにちは。ポケラボクリエイティブ部です。
クリエイティブ部の若手メンバーがスキルアップに励む姿をお送りしているCreative Blogですが、今回はクリエイティブ部のシステムサポートチームのシニアエンジニアがShaderGraphの習得に励む姿をお送りします。
システムサポートチームとは、クリエイティブ部が制作したキャラクターデータの実装サポートや、制作支援ツールの開発・運営保守などを行っているクリエイティブ部所属のエンジニアのチームです。
「Creative Blog #4 ShaderGraphでマスク処理」「Creative Blog #7 ShaderGraphで光る武器を作る」に続く、ShaderGraphの第三弾!今回はどんなShaderを作るのか!?
ShaderGraphに関しては下記のサイトをご参照ください。
https://blogs.unity3d.com/jp/2018/02/27/introduction-to-shader-graph-build-your-shaders-with-a-visual-editor/
今回はShaderGraphで下記の3点の画面効果を作ります。
・グレースケール(画面の白黒化)
・セピア調
・ブラウン管テレビのような横歪みノイズ
今回は画面効果なので、RenderTextureを使います。
シーンの構成はこのような感じです。
RenderTextureを作成し、MainCameraにRenderTextureを設定します。
RawImageを作ってRenderTextureを設定して画面いっぱいに引き伸ばします。
RawImageのMaterialに今回作るシェーダを設定します。
まずはグレースケールから作っていきますが、色々調べるとグレースケールとセピア調は深く紐づいているようで、セピア調を作るにはグレースケールが必要らしいです。
俄然、グレースケールを作っていきます!
グレースケールは、RGBを下記のように処理すると表現できます。
float gray = dot(color.rgb, fixed3(0.299, 0.587, 0.114));
なので、それをShaderGraphに置き換えます。
シェーダグラフ編集ウィンドウの中身はこのようになります。
※セピア調の処理も入ってますがご了承ください。
一番のポイントは、RGBの値に数値を掛け合わせている所。
先ほど書いたロジックをShaderGraphで再現するとこのようになります。
・RGBのそれぞれの値に数値をかける(Rには0.299、Gには0.587、Bには0.114)
・まずRとGをAddで繋ぐ
・上記で繋いだRGとBをAddで繋ぐ
ロジックでは1行で済みましたが、ShaderGraphでは5つのノードを使って再現します。
あとは色味(グレースケールの強さ)を調整したいので、調整用のプロパティ「GrayscaleTuning」を作成し、Multiplyで繋ぎ、Unlit MasterのColorに繋ぎます。
これでグレースケールの完成です。
結果がこちらになります。
続いてセピア調。
セピア調はグレースケールした後に色を掛け合わせるだけになります。
シェーダグラフ編集ウィンドウの中身はこのようになります。(先程と同一)
グレースケールの後、プロパティ「AddColor」で設定したセピア調の色をMultiplyで繋げているだけです。
これだけです!!!
結果がこちらになります。
グレースケールとセピア調は比較的簡単でした。
RBGにあの値を掛け合わせるとグレースケールになるんですね!
最後に横歪みノイズを説明します。
このサイトを参考にしつつ作業します。
http://u0u1.net/CZyV
まず、横歪みノイズの要件定義は下記の通りです。
・ブラウン管テレビなどで見られる画面の歪みを表現
・波打ったように画面が歪む
・歪みの度合いによって画面が一部暗くなる
シェーダグラフ編集ウィンドウの中身はこのようになります。
ちょっと複雑なので、まずは大まかな処理を説明します。
処理は大きく分けると下記の4つになります。
1. UVを使って横線を作る
2. 歪みの上限を設定し横線と繋げる
3. 歪みの強さを決め、上限処理済みの横線と繋げて歪みを作成
4. 歪みの強さから暗さを算出し、横線と繋げて暗くなる範囲を確定
まずUVを使って横線を作ります。
・UVノードをSplitノードに繋ぐ
・SimpleNoiseノードを作成し、SimpleNoiseノードのUVに、SplitノードのGに繋ぐ
#ちなみにRだと縦線
・Sliderノードを作成し、SimpleNoiseノードのScaleに繋ぐ
#Sliderノードの値が大きいほど横線の数が増える
#このSliderノードはプロパティ化して調整が出来るようにする
続いて歪み処理です。
・RemapノードのInにSimpleNoiseノードのOutを繋ぐ
・RemapノードのOut Min Maxが上限と下限の設定
・Inspecotorで調整したかったのでSliderノードを作成しプロパティ化(これが歪みの強さ)
・Out Min Maxに値を入れる為、Vector2ノードを作成し、XとYにSliderノードを繋ぐ
#Vector2ノードのXは下限なので、Negateノードを通して繋ぐ
#Negateノードを使う事で1つのプロパティで上限と下限が設定可能
続いて上限設定と横線を繋ぎます。
・RemapノードとMultiplyノードを繋ぎ、MultiplyノードのBに歪みの強さを繋ぐ(※詳細は後述)
・次に、AddノードのAに結果を繋ぎ、Bには横線の作成で使ったSplitノードのRを繋ぐ
・CombineノードのRにAddノードのOutを繋ぎ、GにSplitノードのGを繋ぐ
#元のUVに歪み情報を合算することで歪み処理が完成
・CombineノードのRGを、Sample Texture 2DノードのUVに繋げて完成
これで横歪みノイズの処理が出来ました。
歪みの強さを作成し処理を繋げます。
・SimpleNoiseノードのUVにSliderノードを繋ぐ
#Sliderノードはプロパティ化(WavePower)
#SimpleNoiseノードのScaleを調整(今回は 2 を固定値として設定)
・Powerノードを作成し、SimpleNoiseノードのOutを繋ぐ
・Powerノードを、Remapノードが繋がっているMultiplyノードのBに繋げる
これでプロパティのWavePowerが 0 以上だと画面が歪むようになります。
値が大きいほど歪みの強さが増します。
最後に、歪みの強さに応じて横線が少しだけ暗くなるようにします。
・Remapノードを作成し、Powerノードを繋げる
・RemapノードのOut Min Maxを調整(Minが0、Maxが0.4)
#Maxの値が大きいほど暗さが強まる
・このままだと逆に白くなるので、Negateノードを繋げ、次にMultiplyノードに繋げる
・MultiplyノードのAには、横線を作成しているSimpleNoiseノードを繋げる
・MultiplyノードのOutを、Sample Texture 2DノードのRGBAとAddノードで繋げる
これで横線の部分が少し暗くなりました。
結果はこのようになります。
歪み無し。
歪み弱。(WavePowerが0.2)
歪み強。(WavePowerが0.5)
難しかったです!当初の想定よりも作りが複雑でした…。
WavePowerをプログラムで往復させ、往復させる速度も一部ランダムにすることで意図した表現ができると思います。
今後もめげずにShaderGraphで色々な表現を実現できるように学習を進めたいと思います。
いかがでしたでしょうか?
昨今のソーシャルゲームは表現まわりのリッチ化が進み、どんどん見た目が豪華になり、表現の幅も広がっているのでShaderを使った表現の追求は課題だと感じています。
クリエイティブ部では表現力の向上のために、これからも積極的にShaderの学習と、Shaderを活用した表現の研究に力を入れていきます。
次回もご期待ください!