iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 26
2
Modern Web

寫給工程師的 WebGL 學習心得系列 第 26

[WebGL - Day26] Displacement Filter (1/3) 原理

  • 分享至 

  • twitterImage
  •  

Displacement Filter 是一個常見的效果, PixiJS 裡也有這個濾鏡
但研究 Displacement Filter 並使用 WebGL 實作,仍然相當有趣


Displacement Filter 不是罕見的效果,在 The FWA 上看到這個網站時,
覺得處理得相當漂亮 - Mustafa Çelik
Mustafa Çelik

其中類似水波效果的是本篇要介紹的 Displacement Filter


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 texture

方便理解,先把 uv.xuv.y 圖像化:
xy 分開來看,0. 為黑、1.為白
uv.xy

由於接著的操作都與這張圖有關,
用黑白數值對應來思考較容易理解出輸出的結果

調整 uv 的值:

試著調整 uv.x 的值:
如果將 uv.x *.5,想像中可能會變成只有一半的畫面...

uv.x *= .5;

可是結果是:
uv 0.5
反而變成 兩倍寬 了!

因為 uv 圖變成如下:
最右邊的部分,從全白的 1. 變成 .5
對應就從原圖 最右邊變成中間的位置
uv 0.5


如果將 uv.x *2
原理類似, 在中間的時候就已經填滿成純白了
uv 2

所以輸出畫面的中間,已經是原本圖裡最右邊的位置了
uv 2

為什麼不是一直與旁邊延伸呢?
實際上右邊白色的部分已經 大於1
大於1 時的填法與素材填入的方式有關,在 Shadertoy預設重複
目前不會提到填法的部分

若使用 clamp() 這個方法,將 uv.x 的值限制在 0.1. 之間

uv.x *=2.;
uv.x = clamp(uv.x, 0., 1.);

uv 2
大於1. 的值會限制在 1.,而小於1. 的值會限制在 0.
就是直接往旁邊延伸的結果了

clamp 語法說明:clamp - OpenGL 4 Reference Pages

繼續調整 uv 值:

如果在 uv值 裡加上其他變化
例如在 uv.x 加上一個方形:
uv add

合出來的 uv.x:
uv add

套上圖片的結果:
uv add
好像有點類似範例希望的效果了

可是接近中間幾乎全白的部分,好像有點奇怪?
雖然看到的是白色,可是中間部分的值,實際上 大於1
所以才會是看起來 重複 的結果
uv add

驗證這個說法:
假設剛剛合出來的值是 tmpX,
再次使用 clamp() 這個方法,將 tmpX 的值限制在 0.1. 之間

float tmpX; // 剛剛合出來的圖
tmpX = clamp(tmpX, 0., 1.);

套上圖片,看來沒錯!
uv add


本篇使用數值 相加 的方法來說明,
同樣也可以將值做加減乘除 或其他運算
也許就會有意外但又不易那麼意外的效果了


上一篇
[WebGL - Day25] Metaball (2/2) - 在 Shadertoy 上實作與可應用效果
下一篇
[WebGL - Day27] Displacement Filter (2/3) 在 Shadertoy 上模擬與互動
系列文
寫給工程師的 WebGL 學習心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言