cesium webgl2.0 shader various functions used

1. Functions related to angles

The following is a function related to angles, and we are all familiar with their usage.

Function Parameters Description
sin(x) radians sine function
cos(x) radians Cosine function
tan(x) radians tangent function
asin(x) radians arcsine function
acos(x) radians arccosine function
atan(x) radians arctangent function
radians(x) Angle Convert angle to radians
degrees(x) radians convert radians to angles

2. Mathematical functions

This type mainly operates on exponential logarithmic power functions.

Function Description
pow(x,y) x raised to the yth power. If x is less than 0, the result is undefined. Likewise, if x=0 and y<=0, the result is undefined.
exp(x) e to the power of x
log(x) Calculate the value of y such that x is equal to e raised to the power of y. If the value of x is less than 0, the result is undefined.
exp2(x) Calculate the x power of 2
log2(x) Calculate the value of y that satisfies x equal to 2 raised to the power of y. If the value of x is less than 0, the result is undefined.
sqrt(x) Calculate the square root of x. If x is less than 0, the result is undefined.
inversesqrt(x) Calculate the value of one of the square roots of x. If x is less than or equal to 0, the result is undefined.

3. Commonly used functions

Here are commonly used functions, which are very similar to the built-in functions in js and need to be remembered.

Function Description
abs(x) Return the absolute value of x
sign(x) If x>0, return 1.0; if x=0, return 0, if x<0, returns -1.0
floor(x) Returns the largest integer value less than or equal to x
ceil(x) Returns the smallest integer value greater than or equal to x
fract(x) Returns x -floor(x), that is, returns the decimal part of x
mod(x, y) Returns the modulus of x and y
min(x, y) Returns the smaller value of x and y.
max(x, y) Returns the larger value of x and y.
clamp(x, minVal, maxVal) Clamp the x value between minVal and maxVal, which means that minVal is returned when xmaxVal, return maxVal. When x is between minVal and maxVal, return x
mix(x, y, a) return Linear mixture of x and y, such as: x*(1?a) + y*a
step(edge, x) If x < edge, return 0.0, otherwise return 1.0
smoothstep(edge0, edge1, x) If x <= edge0, return 0.0; if x >= edge1 returns 1.0; if edge0 < x < edge1, performs a smooth Hermitian difference between 0 and 1. If edge0 >= edge1, the result is undefined.

5. Common forms of built-in function parameters

Common forms of built-in function parameter data types: float, vec2, vec3, vec4

6. Use built-in functions to implement various graphics

In the fragment shader (fragment.glsl), graphics with different effects are achieved through various built-in functions.
Declare the uv value and data accuracy before the main() function of fragment.glsl:

precision lowp float;
in vec2 v_st;

6.1 Use the modulo function mod() to achieve repeated gradient effects

precision lowp float;
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;
void main() {<!-- -->
// Multiply the y value of the texture coordinates by 10.0, and then take the remainder. The resulting value range is [0, 1] => Implement repeated rendering of the horizontal bar 10 times
  float strength = mod(v_st.y * 10.0, 1.0);
  out_FragColor = vec4(strength, strength, strength, 1.0);
}

6.2 Use step(edge, x) to achieve zebra stripe effect

1) In the step(edge,x) function, if x < edge, return 0.0, otherwise return 1.0.

precision lowp float;
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;
void main() {<!-- -->
// Multiply the y value of the texture coordinates by 10.0, and then take the remainder. The resulting value range is [0, 1] => Implement repeated rendering of the horizontal bar 10 times
  float strength = mod(v_st.y * 10.0, 1.0);
  // Similar to if(strength < 0.5) strength = 0.0; else strength = 1.0;
  strength = step(.5, strength);
  out_FragColor = vec4(strength, strength, strength, 1.0);
}


2) Change the boundary value in step to 0.8. When the strength is greater than 0.8, it returns 1, otherwise it returns 0, so the black width accounts for 80% and the white width accounts for 20%. code show as below

precision lowp float;
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;
void main() {<!-- -->
  // Multiply the y value of the texture coordinates by 10.0, and then take the remainder. The resulting value range is [0, 1] => Implement repeated rendering of the horizontal bar 10 times
  float strength = mod(v_st.y * 10.0, 1.0);
  // Similar to if(strength < 0.5) strength = 0.0; else strength = 1.0;
  strength = step(.8, strength);

  out_FragColor = vec4(strength, strength, strength, 1.0);
}


3) In the same way, when the x value of vUv is taken, vertical stripes are generated.

precision lowp float;
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;
void main() {<!-- -->
  // Multiply the x value of the texture coordinates by 10.0, and then take the remainder. The resulting value range is [0, 1] => Implement repeated rendering of the horizontal bar 10 times
  float strength = mod(v_st.x * 10.0, 1.0);
  // Similar to if(strength < 0.5) strength = 0.0; else strength = 1.0;
  strength = step(.8, strength);

  out_FragColor = vec4(strength, strength, strength, 1.0);
}


4) Add horizontal and vertical stripes

precision lowp float;
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;
void main() {<!-- -->
 // Multiply the x value of the texture coordinates by 10.0, and then take the remainder. The resulting value range is [0, 1] => Implement repeated rendering of the horizontal bar 10 times
 float strength = mod(v_st.x * 10.0, 1.0);
 // Similar to if(strength < 0.5) strength = 0.0; else strength = 1.0;
 strength = step(.8, strength);
 strength + = step(0.8, mod(v_st.y * 10.0, 1.0));

 out_FragColor = vec4(strength, strength, strength, 1.0);
}


5) Stripes are multiplied (intersection position is 1, rest is 0)

precision lowp float;
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;
void main() {<!-- -->
 // Multiply the x value of the texture coordinates by 10.0, and then take the remainder. The resulting value range is [0, 1] => Implement repeated rendering of the horizontal bar 10 times
 float strength = mod(v_st.x * 10.0, 1.0);
 // Similar to if(strength < 0.5) strength = 0.0; else strength = 1.0;
 strength = step(.8, strength);
 strength *= step(0.8, mod(v_st.y * 10.0, 1.0));

 out_FragColor = vec4(strength, strength, strength, 1.0);
}


6) Stripe subtraction

precision lowp float;
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;
void main() {<!-- -->
 // Multiply the x value of the texture coordinates by 10.0, and then take the remainder. The resulting value range is [0, 1] => Implement repeated rendering of the horizontal bar 10 times
 float strength = mod(v_st.x * 10.0, 1.0);
 // Similar to if(strength < 0.5) strength = 0.0; else strength = 1.0;
 strength = step(.8, strength);
 strength -= step(0.8, mod(v_st.y * 10.0, 1.0));

 out_FragColor = vec4(strength, strength, strength, 1.0);
}


7) Block graphics

precision lowp float;
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;
void main() {<!-- -->
 // Multiply the x value of the texture coordinates by 10.0, and then take the remainder. The resulting value range is [0, 1] => Implement repeated rendering of the horizontal bar 10 times
 float strength = mod(v_st.x * 10.0, 1.0);
 // Similar to if(strength < 0.5) strength = 0.0; else strength = 1.0;
 strength = step(.2, strength);
 strength *= step(.2, mod(v_st.y * 10.0, 1.0));

 out_FragColor = vec4(strength, strength, strength, 1.0);
}


8) Colorful T letter

precision lowp float;
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;

void main() {<!-- -->
  // Render the intersection based on x
  float barX = step(.4, mod(v_st.x * 10.0 - .2, 1.)) * step(.8, mod(v_st.y * 10.0, 1.));
  // Get intersection based on y rendering
  float barY = step(.4, mod(v_st.y * 10.0, 1.)) * step(.8, mod(v_st.x * 10.0, 1.));
  float strength = barX + barY;
  out_FragColor = vec4(v_st, 1.0, strength);
}

6.3 Use absolute value abs() to achieve gradient from the middle to both sides

//The value range is [-.5,.5]
  float strength = abs(v_st.x - 0.5);
  out_FragColor = vec4(strength, strength, strength, 1.0);

6.4 Use the minimum value min() to achieve gradient

float strength = min(abs(v_st.x - 0.5), abs(v_st.y - 0.5));
 out_FragColor = vec4(strength, strength, strength, 1.0);

6.5 Use the maximum value max() to achieve gradient effect

float strength = max(abs(v_st.x - 0.5), abs(v_st.y - 0.5));
out_FragColor = vec4(strength, strength, strength, 1.0);

6.6 Use step(), max(), abs() to realize small squares

 float strength = step(.1, max(abs(v_st.x - .5), abs(v_st.y - .5)));
out_FragColor = vec4(strength, strength, strength, 1.0);


On the contrary, if the middle square is white and the outer frame is black, then:

 float strength = step(.1, max(abs(v_st.y - .5), abs(v_st.x - .5)));
 out_FragColor = vec4(strength, strength, strength, 1.0);

6.7 Use the downward rounding function floor() to achieve stripe gradient

1) Implement vertical stripes (horizontal gradient)

float strength = floor(v_st.x * 10.) / 10.;
out_FragColor = vec4(strength, strength, strength, 1.0);


2) Implement horizontal stripes (vertical gradient)

float strength = floor(v_st.y * 10.) / 10.;
out_FragColor = vec4(strength, strength, strength, 1.0);


3) Use stripes to multiply to achieve a gradient grid

float strength = floor(v_st.x * 10.) / 10. * floor(v_st.y * 10.) / 10.;
  out_FragColor = vec4(strength, strength, strength, 1.0);

6.8 Use the upward rounding function ceil() to implement gradient grid

float strength = ceil(v_st.x * 10.) / 10. * ceil(v_st.y * 10.) / 10.;
  out_FragColor = vec4(strength, strength, strength, 1.0);

6.9 Use the random function radom() to achieve random effects

Although the random function is not provided by the built-in function, random-like effects can be achieved through algorithms:
Declare the random function before the main() function:

// Random function
float random(vec2 st) {<!-- -->
  return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
}

1) Random effects

float strength = random(v_st);
  out_FragColor = vec4(strength, strength, strength, 1.0);


2) Random grid effect

float strength = ceil(v_st.y * 10.) / 10. * ceil(v_st.x * 10.) / 10.;
  strength = random(vec2(strength, strength));
  out_FragColor = vec4(strength, strength, strength, 1.0);

6.10 Use length to return the vector length (calculate the length along the radius)

float strength = length(v_st);
  out_FragColor = vec4(strength, strength, strength, 1.0);

6.11 Use the distance function to calculate the distance between two vectors

1) Calculate the distance between the uv vector and the (0.5, 0.5) center point

float strength = 1. - distance(v_st, vec2(0.5, 0.5));
  out_FragColor = vec4(strength, strength, strength, 1.0);


2) Use phase division to achieve light spot effect

float strength = .5 / distance(v_st, vec2(0.5, 0.5)) - 1.;
  out_FragColor = vec4(strength, strength, strength, 1.0);


3) Achieve the cross star effect

float strength = .15 / distance(vec2(v_st.x, (v_st.y - .5) * 5. + .5), vec2(.5, .5)) - 1.;
  strength + = .15 / distance(vec2(v_st.y, (v_st.x - .5) * 5. + .5), vec2(.5, .5)) - 1.;
  out_FragColor = vec4(strength, strength, strength, strength);

6.12 Use the rotation function rotate() to achieve the rotating dart effect

//Rotation function
//(uv, degree of rotation, center of rotation)
vec2 rotate(vec2 uv, float rotation, vec2 mid) {<!-- -->
  return vec2(cos(rotation) * (uv.x - mid.x) + sin(rotation) * (uv.y - mid.y) + mid.x, cos(rotation) * (uv.y - mid.y ) - sin(rotation) * (uv.x - mid.x) + mid.y);
}
vec2 rotateUv = rotate(v_st, -czm_frameNumber * 5.0, vec2(0.5));
  float strength = 0.15 / distance(vec2(rotateUv.x, (rotateUv.y - 0.5) * 5.0 + 0.5), vec2(0.5, 0.5)) - 1.0;
  strength + = 0.15 / distance(vec2(rotateUv.y, (rotateUv.x - 0.5) * 5.0 + 0.5), vec2(0.5, 0.5)) - 1.0;
  out_FragColor = vec4(strength, strength, strength, strength);