こんにちわ、オオバです。

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

この記事の内容

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

今回はオオバが尊敬するkeijiroさんのgithubリポジトリの中で比較的簡単そうな処理を勝手に選ばせて頂き勝手に写経。
写経する中で、これならイケそうというものを見つけて始めています。

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

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

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

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

シェーダーのソースコードから見ていきます。
VerticalScroll.shader · GitHub

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 - Win32 apps | Microsoft Docs

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

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

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

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

ここまでの大事ポイント

余談

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

  1. Propertiesで_MainTexの定義をしておく
  2. _MainTex という名前を変更できない

ただし上記の2点を守る必要があります。

C#側の処理

続いてC#側のソースを見ていきます。(短いです)

VerticalScroll.cs · GitHub

C#側はシンプルです。

m_mat.SetFloat("_ScrollValue", (float)Time.frameCount * m_speed);  

このように毎フレームスクロールする値を渡しているだけです。
その値を使ってShader側でスクロール処理をしています。

最後にソースの画像(src)を、出力(dest)のRenderTextureにコピーして画面を更新します。

Graphics.Blit(src, dest, m_mat);  

ちなみに最初にお見せした成果物は、Editorのインスペクタ上でm_speedの値を動的に変化させてスクロールスピードを早めたり向きを変えたりしています。

まとめ

今回非常に簡単な処理を大層な文章量でアウトプットしてみました。やっぱり自分で考えて、書いて動かすというプロセスを踏むことが一番身につくし覚えるなということを再認識しました(加えてブログにも備忘録書いたから忘れてもOKです)。

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

ウメハラ「BeasTV」17/1/19 - 一日ひとつだけ強くなる 慶應丸の内シティキャンパス講演 - YouTube

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

オススメ記事
2021秋 Asset Refreshセール
100以上のアセットがなんと50%OFF!!オオバもいくつか買いました!
期間 : 10月2日午後3時59分まで
検証環境