用 shader effect 實現雨滴落水效果!Cocos Creator 3D

最近逛論壇時,看到一位大佬在分享各種 shader 特效。基於其中的水波 shader ,白玉無冰寫了一個玩水效果!

先一起看看效果~

用 shader effect 實現雨滴落水效果!Cocos Creator 3D

點擊任意位置,會在該位置生成一個水紋,就像是雨水落在水窪中一樣~

如何使用 effect 文件?新建一個 material ,Effect 屬性選擇 water , 接著將紋理圖片拖到相應參數。

用 shader effect 實現雨滴落水效果!Cocos Creator 3D

最後為你的模型節點選擇材料。

用 shader effect 實現雨滴落水效果!Cocos Creator 3D

水紋片元著色器實現原理:通過計算與點擊點的距離和方向,用 sin 函數模擬水紋效果。通過計算點擊時間戳和當前時間與距離,判斷是否添加水紋效果。再將多個點擊點疊加起來,得到 texture 最終 uv 。 主要代碼如下。

<code>for(int i = 0; i < 10; i++){
vec2 uvDir = normalize(v_uv - center[i].xy);
float dis = distance(v_uv, center[i].xy);
float dis_time = center[i].z - cc_time.x + dis * 3.0;

if ( center[i].z > 0.0 && dis_time < 0.0 && dis_time > -0.1 ){
uv += sin_A * uvDir * sin(sin_W * cc_time.x - dis * sin_D);
}
}
o *= texture(mainTexture, uv);
/<code>

如何獲取點擊點?這裡需要用到射線檢測,如果對射線檢測不瞭解的話,可以參考

通過射線檢測,會返回一個距離參數,再結合射線的起點和方向,可以計算出點擊點的座標。參考代碼如下。

<code>this._temp_v3.set(this._ray.o);
this._temp_v3 = this._temp_v3.add(this._ray.d.clone().multiplyScalar(item.distance));
/<code>

這個座標是世界座標,還需要計算出在模型中的相對位置,數值範圍是 0~1。可以通過模型的最小、最大位置,計算出這個值。並將當前的渲染時間戳一併賦值。

<code>const minPosition = item.node.worldPosition.clone().add(this.model_plane.mesh.struct.minPosition);
const maxPosition = item.node.worldPosition.clone().add(this.model_plane.mesh.struct.maxPosition);
this._temp_v4.set((this._temp_v3.x - minPosition.x) / (maxPosition.x - minPosition.x), (this._temp_v3.z - minPosition.z) / (maxPosition.z - minPosition.z), director.root.cumulativeTime, 0)/<code>

如何傳值給 shader 中的 uniform 變量?可以通過 material 直接設置。

<code>this.model_plane.material.setProperty(`center${this._count++ % 10}`, this._temp_v4);/<code>

當然還有一個效率更高的方法,直接使用 pass 的接口。

<code>const pass = this.model_plane.material.passes[0];
pass.setUniform(pass.getHandle(`center${this._count++ % 10}`), this._temp_v4);/<code>

既然用到了 shader ,順便講一下存儲限定字吧。attribute 只能出現在頂點著色器中,一般用來表示逐頂點信息。uniform 變量是一個全局變量,頂點著色器和片元著色器共用。varying 變量的任務是從頂點著色器向片元著色器傳輸數據。

用 shader effect 實現雨滴落水效果!Cocos Creator 3D

以上為白玉無冰使用 Cocos Creator 3D 實現"玩水效果"的技術分享。完整代碼在公中號[白玉無冰]中。如果你有想法,歡迎留言分享!



分享到:


相關文章: