飄揚的旗幟!shader 編程實戰!Cocos Creator!


用 shader + mesh 立個 flag 吧! 文章底部獲取完整代碼!

效果預覽

使用方法

  1. 創建一個空節點
  2. 添加用戶腳本組件 mesh-texture-flag
  3. 添加圖片
  4. 修改對應屬性

實現原理

概括來說就是創建 mesh 網格模型,通過頂點着色器對頂點坐標不斷的修改,達到飄動的效果。關於 mesh 的介紹,可以參考上一篇文章。

確定頂點坐標

為了讓頂點着色器里有多個頂點可以改變位置,需要把一個形狀分割成多個方形(三角形)。分割數量越大,效果越精細,但需要消耗更多的性能消耗。下圖是分割成兩行三列的例子。

根據分割的行列數和節點大小,節點錨點,從左到右從上到下,算出每個頂點的位置信息。可以先算出相對左上角的位置,然后再根據錨點偏移,參考代碼如下。

const x = (_col - this._col * this.node.anchorX) * _width / this._col;
const y = (_row - this._row * this.node.anchorY) * _height / this._row;

確定紋理uv坐標

紋理uv坐標系在左上角,u軸是向右,v軸是向下,范圍是 0-1。而我們的坐標系是根據錨點確定的,x軸向右,y軸向上。

根據錨點求出位置坐標在左下角的占比,然后再翻轉一下v就可以求出對應的uv坐標了。參考代碼如下。

const u = (pt.x + this.texture.width * this.node.anchorX + this.offset.x) / this.texture.width;
const v = 1.0 - (pt.y + this.texture.height * this.node.anchorY + this.offset.y) / this.texture.height;

確定頂點索引

從網格左上角的格子開始,依次確定三角形頂點畫法。下圖是分割成兩行兩列的索引。

每個格子有兩個三角形,參考代碼如下。

// 計算頂點索引 
let ids = [];
let getIndexByRowCol = (_row, _col) => {
    return _row * (this._col + 1) + _col;
}
for (let _row = 0; _row < this._row; _row++) {
    for (let _col = 0; _col < this._col; _col++) {
        ids.push(getIndexByRowCol(_row, _col), getIndexByRowCol(_row, _col + 1), getIndexByRowCol(_row + 1, _col));
        ids.push(getIndexByRowCol(_row + 1, _col), getIndexByRowCol(_row + 1, _col + 1), getIndexByRowCol(_row, _col + 1));
    }
};

頂點着色器編寫

使用的是sin函數對頂點進行修改。

一個波浪就是一個 PI , 所以要把位置坐標變化幅度映射到 wave * PI 。通過求出占寬度比就可以得到 sin 函數的角度了。

通過內置變量 cc_time 可以使坐標隨着時間變化。不過得在非編輯器下才能預覽到,因為默認是不會賦值的。

參考代碼如下。

float angleSpanH = wave * 3.14159265;
float pz = amplitude * sin(cc_time.x * speed - (a_position.x - startPos.x + a_position.y - startPos.y) / textureWidth * angleSpanH);
vec4 position = vec4(a_position.x, a_position.y + pz, a_position.z, 1);

小結

以上為白玉無冰使用 Cocos Creator v2.2.2 開發 "飄揚的旗幟!" 的技術分享。有想法歡迎留言!如果這篇對你有點幫助,歡迎分享給身邊的朋友。


完整代碼
原文鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM