I was visiting a forum recently and saw a big man sharing various shader effects. Based on one of the water wave shader, Bai Yu no Ice wrote a playing water effect! Get the full code at the bottom of the article! You can also try the water!

Let’s take a look at the effect

Clicking on any location will create a water pattern in that location, just like rain falling in a puddle

How do I use the effect file? Create a New Material, select Water for Effect, and drag the texture image to the appropriate parameter.

Finally, select materials for your model nodes.

Water chip shader implementation principle: by calculating the distance and direction of the click point, using the sin function to simulate the water effect. Determine whether to add water ripple effect by calculating click timestamp and current time and distance. Add the points together to get the texture final UV. The main code is as follows.

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; float dis_time = center[I]. 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);Copy the code

How do I get clicks? Here you need to use X-ray detection, if you do not know about X-ray detection, you can refer to the use of raycast X-ray detection! Cocos Creator in 3 d!

With the X-ray detection, a distance parameter is returned, which, combined with the origin and direction of the ray, can be used to calculate the coordinates of the click point. The reference code is as follows.

this._temp_v3.set(this._ray.o);
this._temp_v3 = this._temp_v3.add(this._ray.d.clone().multiplyScalar(item.distance));
Copy the code

This coordinate is the world coordinate, and we need to calculate the relative position in the model, and the value range is 0 to 1. This value can be calculated from the minimum and maximum positions of the model. Assign the current render timestamp as well.

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

How to pass values to uniform variables in shader? You can set it directly through material.

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

A more efficient approach is to use the Pass interface directly.

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

Now that WE’re using shader, let’s talk about storing qualifiers. Attributes can only appear in vertex shaders and are generally used to represent per-vertex information. Uniform variable is a global variable shared by vertex shaders and slice shaders. The job of the VARYING variable is to transfer data from the vertex shader to the chip shader.

The above is the sharing of baiyu ice-free technology using Cocos Creator 3D to achieve “playing with water effect”. If you have any ideas, please share them in the comments!



Try the link to the full code refer to the article Resources