渋谷ほととぎす通信

新しいこと、枯れたこと問わず大庭が興味を持ったものを調査、生活の効率を求める完全趣味の技術ブログ。基礎を大事にしています。

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


f:id:esakun:20170328225939p:plain

環境

  • Unity5.5.2p2

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

あわせて読みたい
・GLSLのサンプルが数多く投稿されているGLSL SandboxのコードをUnityに移植する方法を紹介しています
GLSL SandboxをUnityに移植する方法その1 - 渋谷ほととぎす通信
・そもそもシェーダとは何だろう?ということを自分の言葉で解釈し説明してみました
「シェーダ」とは何なのか、を自分の言葉でまとめてみる - 渋谷ほととぎす通信

とりあえず写経、写経、写経ゥ!!

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

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

f:id:esakun:20170328214102g:plain

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

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

シェーダのソースコードから見ていきます。

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

関数名 説明
frac 引数の小数点部分のみを残す関数


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が代入されます。
※これ最初気づきませんでした;;

  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

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

あわせてどうぞ