I Metaball definition
Metaball technology is a technology developed by Blinn in 1982, which is suitable for building deformable surfaces. This technology uses metaball to establish an energy field, and then establishes a 3D model through the equipotential surface in the scalar domain to represent the software or implicit surface. Simply put, it means arranging some Metaballs in space. Each metaball has an energy field, which is usually expressed by potential function. There are countless points in the space. At one point, its energy is the superposition of its potential by each metaball. Then find out the points with the same potential energy at all points in space, and get a surface composed of these points.
II Understanding of Metaball
metaball can be understood as the isosurface of 3D space. Generally speaking, it is a method defined in 3D space: input coordinates as (x,y,z) and output as a float number. The output depends on the threshold. 1 is returned above the threshold and 0 is returned below the threshold In this way, the 3D space is divided into two parts, one is solid and the other is hollow. When two parts of a continuous surface meet, we call it an isosurface. This isosurface will look different from other parts, that is, what we need to deal with is the location of the metasphere connection
3, 2D Metaball core algorithm
For the potential energy calculation formula of A point in space, first, only two Metaballs are set in the scene, A and B. the ball center of A is (x1,y1,z1), the energy is E1, B is the ball center is (x1,y2,z2), and the energy is E2. The potential functions for calculating the potential energy of space point (x ', y', Z ') are:
E'(x', y', z') = E² / (x-x')² + (y-y')² + (z-z')²
In this way, for each spatial point, if the coordinates are (x ', y', z '), its potential energy can be expressed by the following formula:
E'(x', y', z') = E² / (x1-x')² + (y1-y')² + (z1-z')² + E² / (x2-x')² + (y2-y')² + (z2-z')²
Calculation example:
There are 20 Metaballs in the scene. How to draw the metaball fusion effect
1. Calculate the potential energy of space points
As mentioned earlier, the potential energy of a certain point is the superposition of its potential by each Metaball, so we can calculate it in the slice Shader as follows:
//Calculate the potential energy of each point according to 20 metaspheres float v = 0.0; for ( int i = 0; i < 20; i++ ) { vec4 mb = u_metaballs[i]; float dx = st.x - mb.x; float dy = st.y - mb.y; float r = mb.z; //radius v += r * r / (dx * dx + dy * dy); //Stack the potentials of 20 Metaball s according to the formula given above }
u_metaballs is a uniform variable that stores the position and radius information of the small ball, which is passed in by javascript.
Note: because it is a 2D metasphere, there is no coordinate in the Z direction of space, that is, dz=0
2. Draw according to the threshold
vec4 color = vec4(1.0); float rangeMax = 5.2; //Highest threshold float rangeMin = 4.7; //Minimum threshold if (v > rangeMax) { color = vec4(0.0, 0.0, 0.0, 1.0); //If the potential energy is greater than rangMax, it is black } else if (v > rangeMin) { color = vec4(0.0, 0.0, 0.0, smoothstep(1.0, 0.0, (rangeMax - v) / (rangeMax - rangeMin))); //If the potential energy is between the size threshold, the smooth transparency is set } else { //If the potential energy is less than rangeMin, it is transparent color = vec4(1.0, 1.0, 1.0, 0.0); }
Here, smoothstep implements the processing of the fusion part, and introduces the built-in function of GLSL smoothstep function
genType smoothstep (genType edge0,genType edge1,genType x)
If x < = edge0, return 0.0; If x > = edge1, return 1.0;
If edge0 < x < edge1, smooth Hermite interpolation between 0 and 1 is performed.
If edge0 > = edge1, the result is undefined.
The following figure compares the values returned by smoothstep and linstep in chronological order:
IV Let the ball move
The coordinates of Metaball can be changed dynamically. Here, the dx,dy calculation is directly changed to:
float dx = st.x + cos(u_time + mb.w) * mb.x; //u_ The time and w attributes change to make the ball move float dy = st.y + sin(u_time + mb.w) * mb.y;
Then the coordinates of MB will be based on u_time changes all the time, with a cycle of 2 Π/ mb.w. The amplitude is 2
Where u_time passed in by javascript, u_time keeps accumulating
V Extended transformation
From some of the above formulas
Change u_ X and Y in Metaballs can change the initial position of Metaballs
Change u_ z in Metaballs can change the radius of Metaballs, that is, the size of Metaballs
Change u_ w in Metaballs can change the period of metaball position transformation
We can also add cos (u_time + MB. W) * MB X is multiplied by a factor that changes the amplitude of the change
More smooth and interesting actions can be created through gsap actions
For example:
//x. When the range of Y position becomes wider, and z increases, that is, the radius of the ball increases, and w value increases, the period becomes shorter this.balls.forEach(ball => { TweenLite.killTweensOf(ball); TweenLite.to(ball, 3, { delay: Utils.random(0, 0.5), x: Utils.random(-0.5, 0.5), y: Utils.random(-0.5, 0.5), z: Utils.random(0.04, 0.3), w: ball.x + Utils.random(4, 15), ease: Power2.easeInOut, //'power2.inOut', }); });