読者です 読者をやめる 読者になる 読者になる

渋谷ほととぎす通信

完全趣味でやってるUnityメモ。説明できないところを説明できるようにするための個人ブログ。昨日の自分より少しでも大きく慣れるように。。。 ※所属団体とは一切関係がありません

無限スクロールイメージエフェクト


f:id:esakun:20170328225939p:plain

環境

  • Unity5.5.2p2

以前にもGLSL Sandboxを移植してイメージエフェクトを書いて遊んでいたのですが、あまり深く理解せず、とりあえず触っていただけでしたので、今年はじっくりと理解しながら書いていく年にしていきたいと今は思っています。

今回は私が尊敬するkeijiroさんのgithubリポジトリの中で比較的簡単そうな処理を勝手に選ばせて頂き勝手に写経。
写経する中で、これならイケそうというものを見つけて始めています。
※ハードルを下げて継続させることが大事とウメハラも言ってました

お題「画面をスクロールさせるイメージエフェクト」

f:id:esakun:20170328214102g:plain
◆今回の成果物です

今回は↑のようなイメージエフェクトを作ってみます。

ではシェーダから見ていきます。

fracで小数点だけ残してUV座標を操作する

frac関数を使うのがポイントで、0〜1の範囲でUV座標をオフセットすることでピクセル位置をずらし、スクロールしているように見せることが出来ます。

該当箇所の処理を見ていきます。

float v = i.uv.y;

今回のスクロールは縦方向のみなので、↑のようにUV座標の縦方向にあたるuvのy要素に注目します。
UV座標のVにあたるため変数名はvです。


v = frac(v + _ScrollValue);

変数vに_ScrollValueを加算しfrac関数で処理します。frac関数引数の小数点部分のみを残す関数です。
よって変数vには0~0.99999….の値が入ります。

◇参考 : frac (DirectX HLSL)


return tex2D(_MainTex, float2(u, v));

tex2D関数はUV座標におけるピクセルの色(RGBA)を取得する関数です。 tex2Dの第2引数にUV座標を代入するわけですが、ここに先程加算したv要素を含んだUV値を代入しています。

こうすることで縦方向のみ画像全体がオフセットされて移動していきます。

オフセットしていくということは、どんどん上下どちらかに移動し続けていく気がしますが、
先程のfrac関数で1以上の値にはならないため、繰り返しスクロールすることになります。 ※frac関数を外せば画像は繰り返さずに移動し続けます

余談

イメージエフェクトは_MainTex変数にカメラが写したソースのRenderTextureが代入されます。
※これ最初気づきませんでした;;

  1. Propertiesで_MainTexの定義をしておく
  2. _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です)。

日をあまり置かず、コンスタントにそしてハードルを上げ過ぎずにアウトプットしていければと思います。

www.youtube.com

ちなみに冒頭のウメハラの件はコチラです。
長いですけど私にとってはとても刺激的な動画でした。

あわせてどうぞ

www.shibuya24.info

www.shibuya24.info

www.shibuya24.info