前篇講了 Shdertoy 上的 Displacement Filter 實作,
今天終於要把程式碼通通組合起來了!
在 PixiJS 上讓物件 跟著滑鼠座標移動 的方式,可參考我先前的文章:
[PixiJS - Day-10] Ticker 與 動態製作
JavaScript:
app.ticker.add(function(delta) {
// 目前滑鼠的 x 座標
var mouseX = app.renderer.plugins.interaction.mouse.global.x;
// 跟隨座標的演算法
bunny.x += (mouseX - bunny.x) * 0.0625;
});
其中的 0.0625
是 1/16 的意思,
就以前學習時的說法,乘比除快,2的次方倍比非次方倍快
就一直沿用著
在滑鼠移動時會感覺有條線跟著,或著選擇 Debug模式 會看到紅線
就是產生 uv 變化 效果的 中心點
Fragment Shader:
uniform float uX;
uniform float uX2;
uniform float uX3;
在 JavaScript 跟隨滑鼠座標時,也另外產生兩個值進 Shader:
uX:跟著滑鼠 座標x 移動的線 (紅線)
uX2:跟著滑鼠 座標x 移動的線,但跟隨速度較 uX 慢
(黃線)
uX3:滑鼠座標 uX 與 uX2,會在 uX2 的 另一邊
(黃線)
Debug 時的黃球:使用 PixiJS 繪圖API 生成 (JavaScript),
座標與 Shader 產生的黃線位置相同
實際畫出漸層線的值
Fragment Shader:
uniform float uD;
實作上相當重要的變數,
計算 uX 與 uX2 的相對位置 (紅線與黃線的距離
),
決定畫出來的模糊程度 (距離越遠效果越 明顯
)
雖然也可以在 Shader 裡算出 uD 的值,
但 uD 值在 JavaScript 也有作用,因此在從 JavaScript 帶入
( JavaScript 用這個值決定是否 換頁 )
雖非必要,當作練習與額外挑戰
JavaScript:
透過 dat.GUI 的選擇,將模式資訊帶進 Shader 裡:
gui.add( effectController, 'Mode', [ 'NORMAL', 'DEBUG', 'AUTO_DEMO' ] ).onChange( modeChange );
//
function modeChange(){
switch(effectController.Mode){
case 'NORMAL':
// ...
break;
case 'DEBUG':
// ...
break;
case 'AUTO_DEMO':
// ...
break;
}
}
Fragment Shader:
uniform bool uDebugMode;
只在下層顯示 debug 效果
if(uv.y > 0.5 ){
// ...
}
在 PixiJS 裡,下方是 uv.y>.5
,
這時輸出的畫面再畫上半透明的黑色
接著再畫上 uv變化 的值:
maskDebug = mask;
//...
if(uDebugMode == true){
color = texture2D(uSampler, uv2);
color = mix(color, vec4(maskDebug), 0.5);
}else{
color = texture2D(uSampler, uv2);
}
mask 是原本用來做 uv變化 的值,
在 debug 模式時,再畫上一次,
這次 不做輸出的遮罩 ,直接在輸出畫面上再畫上 uv變化 的值 (因次會看見白色漸層)
就完成土法煉鋼的 PixiJS Displacement Filter 互動 了!