Displacement Filter 是一個常見的效果, PixiJS 裡也有這個濾鏡
但研究 Displacement Filter 並使用 WebGL 實作,仍然相當有趣
Displacement Filter 不是罕見的效果,在 The FWA 上看到這個網站時,
覺得處理得相當漂亮 - Mustafa Çelik
其中類似水波效果的是本篇要介紹的 Displacement Filter
先前在 Shadertoy 裡,使用圖片或影片時會用到一段程式碼:
vec2 uv = fragCoord/iResolution.xy;
vec3 col = texture(iChannel0, uv).rgb;
Shadertoy 裡 uv 算出來的值是左下到右上 (0, 0)
到 (1, 1)
,texture()
語法將 iChannel0 素材 對應的 uv
值,運算給 col
方便理解,先把 uv.x
與 uv.y
圖像化:
將 x 與 y 分開來看,0.
為黑、1.
為白
由於接著的操作都與這張圖有關,
用黑白數值對應來思考較容易理解出輸出的結果
試著調整 uv.x 的值:
如果將 uv.x *.5
,想像中可能會變成只有一半的畫面...
uv.x *= .5;
可是結果是:
反而變成 兩倍寬 了!
因為 uv 圖變成如下:
最右邊的部分,從全白的 1.
變成 .5
,
對應就從原圖 最右邊
變成中間
的位置
如果將 uv.x *2
:
原理類似, 在中間的時候就已經填滿成純白了
所以輸出畫面的中間
,已經是原本圖裡最右邊
的位置了
為什麼不是一直與旁邊延伸呢?
實際上右邊白色的部分已經 大於1
,大於1
時的填法與素材填入的方式有關,在 Shadertoy 裡預設
是重複
目前不會提到填法的部分
若使用 clamp()
這個方法,將 uv.x
的值限制在 0.
與 1.
之間
uv.x *=2.;
uv.x = clamp(uv.x, 0., 1.);
大於1.
的值會限制在 1.
,而小於1.
的值會限制在 0.
就是直接往旁邊延伸的結果了
clamp 語法說明:clamp - OpenGL 4 Reference Pages
如果在 uv值 裡加上其他變化
例如在 uv.x
加上一個方形:
合出來的 uv.x:
套上圖片的結果:
好像有點類似範例希望的效果了
可是接近中間幾乎全白的部分,好像有點奇怪?
雖然看到的是白色,可是中間部分的值,實際上 大於1
所以才會是看起來 重複 的結果
驗證這個說法:
假設剛剛合出來的值是 tmpX,
再次使用 clamp()
這個方法,將 tmpX 的值限制在 0.
與 1.
之間
float tmpX; // 剛剛合出來的圖
tmpX = clamp(tmpX, 0., 1.);
套上圖片,看來沒錯!
本篇使用數值 相加 的方法來說明,
同樣也可以將值做加減乘除
或其他運算
也許就會有意外但又不易那麼意外的效果了