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

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

效果預覽

使用方法

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

實現原理

歸納來講就是建立 mesh 網格模型,經過頂點着色器對頂點座標不斷的修改,達到飄動的效果。關於 mesh 的介紹,能夠參考上一篇文章。git

肯定頂點座標

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

根據分割的行列數和節點大小,節點錨點,從左到右從上到下,算出每一個頂點的位置信息。能夠先算出相對左上角的位置,而後再根據錨點偏移,參考代碼以下。編輯器

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;

肯定頂點索引

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

每一個格子有兩個三角形,參考代碼以下。3d

// 計算頂點索引 
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函數對頂點進行修改。code

一個波浪就是一個 PI , 因此要把位置座標變化幅度映射到 wave * PI 。經過求出佔寬度比就能夠獲得 sin 函數的角度了。blog

經過內置變量 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 開發 "飄揚的旗幟!" 的技術分享。有想法歡迎留言!若是這篇對你有點幫助,歡迎分享給身邊的朋友。


完整代碼
原文連接

相關文章
相關標籤/搜索