iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 21
0

source code

0. 今日工事

  • 棋盤
  • 小溪
  • 潛動

1. 棋盤

今天不玩網路技術,玩的是算數跟實驗!Modern Web 就是這麼棒!

1.1 條紋

先看看這一行簡單的東西,產生的是後面一個單一方向的條紋樣式。uv代表的是現在運算的點的位置向量。原因是利用 x 當作三角函數的相位,就會沿著與 x 軸平行的方向震盪。而pow的作用是修飾條紋起伏的狀態。

heightmapValue.x = pow(sin(uv.x * 200.0), 0.5) * 10.0;

https://ithelp.ithome.com.tw/upload/images/20180110/201078287vzqyVai3r.png

1.2 Grid

不複雜,就是四捨五入取進位。uGridUnit代表的是每側有幾個方塊(因為傳進來是 float 將進行floor)。而mod就是取其所在單位是在奇數還是偶數格。

float unit = 1.0 / floor(uGridUnit);

// gridX, gridY 若為 0,即代表偶數格。為 1,則是奇數格。
float gridX = mod(uv.x / unit, 2.0);
float gridY = mod(uv.y / unit, 2.0);

if ((gridX < 1.0 && gridY < 1.0) || (gridX >= 1.0 && gridY >= 1.0)) {
  heightmapValue.x = pow(sin(uv.y * 200.0), 0.5) * 10.0 * uBackgroundWaveScale;
}

https://ithelp.ithome.com.tw/upload/images/20180110/20107828xOnJfDvtz4.png

2. 小溪

既然能夠產生平行的波紋,我就想到庭園中常見的波浪形的波紋。今天運動的時候突然想到,好像只要把 y 丟到三角函數當做 phase,把這個數字加上 x 之後再當作 phase,就可以達到這樣的效果。原因是 y 的效應會造成等高線隨著 y 軸上下震盪,也就讓最後的 output 成波紋狀。

float angle = uv.x * 200.0;
float wave = sin(uv.y * 10.0) * 8.0;
float sum = angle + wave;
// heightmapValue.x 即為高度
heightmapValue.x = pow(sin(sum), 0.5) * 10.0 * uBackgroundWaveScale;

https://ithelp.ithome.com.tw/upload/images/20180110/20107828UmWR1jigP1.png

2.1 旋轉矩陣

對於線性代數有了解的傢伙,就會知道 uv 丟進一個二維的旋轉矩陣就可以輕易的把小溪給轉個方向!所以我也做了每次重新產生新方向的功能。設定預設角度需要如下:

mat2 uWaveTransform = mat2(0.8, 0.6, -0.6, 0.8);
vec2 uvNew = uWaveTransform * uv;
//而後面原本是用 uv 的改成使用 uvNew 就可以產生旋轉效果了!

https://ithelp.ithome.com.tw/upload/images/20180110/20107828jkgMbzUFxB.png

2.2 數字實驗室

反正 phase 跟 rate 丟來丟去到最後自己也已經不知道為什麼圖形會長怎樣了,所以後面就開始亂試效果,看看怎麼樣比較好看!

float angle = uv.x * uv.y * 200.0;
float wave = sin(uvNew.y * 10.0 + sin(uvNew.x * 10.0) * 0.8) * 8.0;

https://ithelp.ithome.com.tw/upload/images/20180110/20107828z2vM0w3iS7.png

float angle = uv.x * uv.y * 200.0;
float wave = sin(uvNew.y * 10.0 + sin(uvNew.x * 10.0) * 0.8) * 8.0;

https://ithelp.ithome.com.tw/upload/images/20180110/20107828AtHXQpZFYn.png

float angle = uv.x * uv.y * 200.0;
float wave = sin(uvNew.y * 10.0 + sin(uv.y * 10.0) * 2.0) * 8.0;

https://ithelp.ithome.com.tw/upload/images/20180110/20107828VUU6jNSkd1.png

3. 潛動


每次動畫的過程中,我會利用uniforms將一個 tweening 好的數字丟到 shader 裡面(我會在之後討論模型動態的時候講解 tweening,這裡可以想像就是一個會自動從 0 經過一段時間逐漸跑到 1 的變數),並當作整體地板 scale 的常數去控制 pattern 的出現與否。這個就是一個乘法,相當簡單。

若市仔細觀察上面的 gif,會發現距離石頭那個位置的越遠的地方會越先塌陷、並且越慢回升。相反的,石頭位置的地平面最慢塌陷、最快回升。達到這樣的效果,我是利用跟中心的距離d,當作 tweening 參數uMasterScale的指數。高次方使得上面的時間關係得以發生。

// uCircularWave[2].xy 代表的是石頭的位置
float d = length(uv - uCircularWave[2].xy);

// uMasterScale 會在一段時間裡面從 0 逐漸變化到 1,或是 1 到 0
heightmapValue.x *= pow(uMasterScale, (d + 0.02) * 15.0);

7. 請愛CYBER の audio / VISUAL

石頭很可愛,可是石頭哪來的?可以多顆一點嗎?

附上 source code

關於作者

Vibert Thio

致力於將對於技術的深度研究轉化為新型態藝術創作的能量,並思考技術的拓展/侷限與其對於藝術論述/呈現的影響。專長為數位藝術創作、音像程式設計、互動設計,喜愛即時運算的臨場感與不可預測。


上一篇
§d20§ webの 禪師!運氣弄四海!Texture 與 Material 的好用之處!
下一篇
§d22§ webの 禪師!運氣挪心山!動力之枯朽山水!
系列文
aesthEtic,CYBERの audio / VISUAL,網頁中的聲音與影像研究30

尚未有邦友留言

立即登入留言