環境
- Unity5.5.2p2
以前にもGLSL Sandboxを移植してイメージエフェクトを書いて遊んでいたのですが、あまり深く理解せず、とりあえず触っていただけでしたので、今年はじっくりと理解しながら書いていく年にしていきたいと今は思っています。
GLSL SandboxをUnityに移植する方法その1 - 渋谷ほととぎす通信
・そもそもシェーダとは何だろう?ということを自分の言葉で解釈し説明してみました
「シェーダ」とは何なのか、を自分の言葉でまとめてみる - 渋谷ほととぎす通信
とりあえず写経、写経、写経ゥ!!
今回は私が尊敬するkeijiroさんのgithubリポジトリの中で比較的簡単そうな処理を勝手に選ばせて頂き勝手に写経。
写経する中で、これならイケそうというものを見つけて始めています。
※ハードルを下げて継続させることが大事とウメハラも言ってました
今回のお題「画面をスクロールさせるイメージエフェクト」
このようなイメージエフェクトを作ってみます。
fracで小数点だけ残してUV座標を操作する
シェーダのソースコードから見ていきます。
frac関数を使うのがポイントで、0〜1の範囲でUV座標をオフセットすることでピクセル位置をずらし、スクロールしているように見せることが出来ます。
関数名 | 説明 |
---|---|
frac | 引数の小数点部分のみを残す関数 |
float hoge = 100.4578; float result = frac(hoge); // resultの値は0.4578になります
該当箇所の処理を見ていきます。
float v = i.uv.y;
今回のスクロールは縦方向のみなので、↑のようにUV座標の縦方向にあたるuvのy要素
に注目します。
UV座標のVにあたるため変数名はv
としていますです。
v = frac(v + _ScrollValue);
変数vに_ScrollValueを加算しfrac関数
で処理します。
frac関数
は引数の小数点部分のみを残す関数です。
よって変数vには0~0.99999....の値が入ります。
◇参考 : frac - Windows applications | Microsoft Docs
return tex2D(_MainTex, float2(u, v));
tex2D
関数はUV座標におけるピクセルの色(RGBA)を取得する関数です。
tex2D
の第2引数にUV座標を代入するわけですが、ここに先程加算したv要素を含んだUV値を代入しています。
こうすることで縦方向のみ画像全体がオフセットされて移動していきます。
オフセットしていくということは、どんどん上下どちらかに移動し続けていく気がしますが、
先程のfrac関数
で1以上の値にはならないため、繰り返しスクロールすることになります。
※frac関数を外せば画像は繰り返さずに移動し続けます
ここまでの大事ポイント
- frac関数を使用する
余談
イメージエフェクトは_MainTex
変数にカメラが写したソースのRenderTextureが代入されます。
※これ最初気づきませんでした;;
- Propertiesで_MainTexの定義をしておく
_MainTex
という名前を変更できない
ただし上記の2点を守る必要があります。
C#側の処理
続いてC#側のソースを見ていきます。(短いです)
C#側はシンプルです。
m_mat.SetFloat("_ScrollValue", (float)Time.frameCount * m_speed);
このように毎フレームスクロールする値を渡しているだけです。 その値を使ってShader側でスクロール処理をしています。
最後にソースの画像(src)を、出力(dest)のRenderTextureにコピーして画面を更新します。
Graphics.Blit(src, dest, m_mat);
ちなみに最初にお見せした成果物は、Editorのインスペクタ上でm_speed
の値を動的に変化させてスクロールスピードを早めたり向きを変えたりしています。
まとめ
今回非常に簡単な処理を大層な文章量でアウトプットしてみました。やっぱり自分で考えて、書いて動かすというプロセスを踏むことが一番身につくし覚えるなということを再認識しました(加えてブログにも備忘録書いたから忘れてもOKです)。
日をあまり置かず、コンスタントにそしてハードルを上げ過ぎずにアウトプットしていければと思います。
ちなみに冒頭のウメハラの件はコチラです。
長いですけど私にとってはとても刺激的な動画でした。