Create a flag with shader + Mesh. Get the full code at the bottom of the article!

Results the preview

Method of use

  1. Create an empty node
  2. Add a user script componentmesh-texture-flag
  3. Add images
  4. Modify corresponding attributes

Realize the principle of

Generally speaking, it is to create a mesh model, and constantly modify the vertex coordinates through the vertex shader to achieve the effect of floating. Refer to the previous article for an introduction to mesh.

Determine vertex coordinates

To have multiple vertices in a vertex shader that can change positions, you need to split a shape into squares (triangles). The larger the number of partitions, the finer the effect, but the more performance costs are consumed. Below is an example of splitting into two rows and three columns.

The position information of each vertex is calculated from left to right from top to bottom according to the number of rows and nodes divided, node anchor points and node size. You can first calculate the position relative to the upper left corner, and then offset it according to the anchor point. The reference code is as follows.

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

Determine texture UV coordinates

The texture UV coordinate system is in the upper left corner, the U axis is to the right, the V axis is to the down, and the range is 0-1. And our coordinate system is based on the anchor point, x to the right, y to the up.

Figure out the proportion of position coordinates in the lower left corner according to the anchor point, and then flip v to figure out the corresponding UV coordinates. The reference code is as follows.

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;
Copy the code

Determine vertex index

Starting from the upper left corner of the grid, determine the vertex drawing method of the triangle. The following figure shows an index split into two rows and two columns.

Each cell has two triangles and the reference code is as follows.

// Computes the vertex index
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)); }};Copy the code

Vertex shader written

I’m using the sin function to modify the vertices.

A wave is a PI, so map the magnitude of the change in position to wave * PI. And you can figure out the Angle of the sine function by figuring out the width ratio.

The coordinates change over time with the built-in variable CC_time. You have to preview it in a non-editor because it’s not assigned by default.

The reference code is as follows.

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);
Copy the code

summary

Above for white jade ice free using Cocos Creator V2.2.2 developed “Waving the Flag!” Technology sharing. Have idea welcome message! If this article is helpful to you, please share it with your friends.


Full code original link