若對 3D 尚未有美好的想像,請參閱前面兩篇文章:
庭園階段呈現的預覽(目前成果)
偷偷附上 demo site
前幾天在寫模型載入實驗的時候,發現網頁的 3D render 其實是枯山水造景。很細碎的思索裡面,庭院提供一個很棒的場所。網頁也是很棒的場所。
在闔上眼睛之前的幾分鐘裡面,突然想到自己從小的一個夢想就是在家裡的庭院能夠有個枯山水庭園,每天可以掃落葉、爬梳砂石。那不如直接在 web 上面直接做個庭園如何?還能夠玩玩。
起床後,我思考庭園的架構。一定得從平面開始。
THREE.PlaneBufferGeometry
絕對派得上用場。
載入了基本的場景之後,剛開始我嘗試想要直接去寫 vertex shader 去動態的改動整個平面上面的點。這件事情可以說是相當簡單。假如不知道 vertex shader 的作用的人可以回去參考§d3§ 打坐練神功!Three.js 黑魔法的咒語 WebGL!GPU 的平行宇宙!媽啊。
// plane.vert
...
float sin1 = sin((position.x + position.y) * 0.2 + time * 0.5);
float sin2 = sin((position.x - position.y) * 0.4 + time * 2.0);
float sin3 = sin((position.x + position.y) * -0.6 + time);
vec3 updatePosition = vec3(position.x, position.y, position.z + sin1 * 50.0 + sin2 * 10.0 + sin3 * 8.0);
gl_Position = projectionMatrix * modelViewMatrix * vec4(updatePosition, 1.0);
如此一來,就可以產生像是這樣隨著時間不斷波動的平面,像是海浪一樣平靜的。
實驗到了這一步,我可以確定的事情是:改動平面上的點是完全可行的。但是剛剛那樣是濕濕的水平面,而非想像中的枯山水的形象。當然啦,我後面可能會想要把那個波動放到我的禪院裡面!想到就興奮。
竹帚刮擦所生的波紋有很多種形式,其一常見的是繞石浪紋。石頭象徵的是山、是島、是大地,而砂石則是海洋與白浪。
我們可以用一個很簡單的數學來表達這個意象,就是在平面上面決定一個圓心 ,而平面上面任何一點跟圓心的距離平方是:
使用距離當作三角函數的 phase 就可以創造出圓形的波浪效果。
float r = pow(pow(position.x, 2.0) + pow(position.y, 2.0), 0.5);
float z = position.z;
if (r < 350.0) {
z += 50.0 * cos(r * 0.1);
}
vec3 transformed = vec3(position.x, position.y, z);
雖然形狀看起來邏輯是對了,但是因為用的是 wireframe(就是用框線去呈現立體感的 render 手法),所以完全都還沒考慮到陰影的狀況。
加上基本材質(material)與燈源(light)之後,就突然發現一個大問題。
整個陰影的效果都是爛掉的。因為想要呈現完整的陰影的話,在 vertex shader 改動完之後,必須得要連每個點的 vertex normal都一起算完透過varying
送進去 fragment shader。但是那樣的數學模型就太過複雜了,完全沒有辦法輕鬆地去調動 vertex 創造地景。
我,嘗試了各種方法:
沒有找到任何一個實用的、效率的解法。
但是我突然看到一絲轉機。而產生了下面的金屬山水。
請繼續思考、繼續幻想、繼續追求吧!明天繼續靜坐掃地。
欲知詳情,請待下回分曉。
關於作者
Vibert Thio
致力於將對於技術的深度研究轉化為新型態藝術創作的能量,並思考技術的拓展/侷限與其對於藝術論述/呈現的影響。專長為數位藝術創作、音像程式設計、互動設計,喜愛即時運算的臨場感與不可預測。