用 shader + mesh 立個 flag 吧! 文章底部獲取完整代碼!node
mesh-texture-flag
歸納來講就是建立 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座標系在左上角,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 開發 "飄揚的旗幟!" 的技術分享。有想法歡迎留言!若是這篇對你有點幫助,歡迎分享給身邊的朋友。