preface

The previous section realized the addition of building wireframes, model exterior walls and road floor materials. This section prepares you for the rise line effect with a simple shader.

Train of thought

Briefly, the idea is to filter by obtaining the height Z of the model vertex coordinates, set the height to the color of the rising line in a certain interval, and the color of the other heights is normal. Keep rising to make the rising line keep rising, and reset it when it reaches a certain height.

The composition of ShaderMaterial

To achieve the main pass through Three custom material (ShaderMaterial) to achieve, first of all to achieve a simple ShaderMaterial to see the composition of this material.

  const shader = new THREE.ShaderMaterial({
      // Pass the value from the program into the shader
        uniforms: {},// Vertex shader
         vertexShader: 'void main() {gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `.// Fragment shader
         fragmentShader: 'void main() {gl_FragColor = vec4(1.0); } `});Copy the code
  1. Vertex shader (vertexShader Vertex shaders are used to process vertex data. In this example, the main code of the vertex shader is:
 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
Copy the code

Let’s talk about what each variable means

  • Position: model point position data.

  • ModelViewMatrix: the view matrix, is equal to the camera. MatrixWorldInverse * object in matrixWorld, model matrix and camera matrix matrix (view) is the product of the.

  • ProjectionMatrix: projectionMatrix, equal to camera. ProjectionMatrix

  • Gl_Position: the projected position of the model point position on the screen after matrix transformation. The relationship between this value and position is shown below.

After the above matrix changes, the model is projected to the clipped coordinate system and then, through a series of calculations, displayed on the screen.

  1. Fragment shader (fragmentShader The fragment shader is the color of the slice. The vertex shader in this example is as follows:
 gl_FragColor = vec4(1.0.1.0.1.0.1.0);
Copy the code

Gl_FragColor is the color of each fragment, which is uniformly set to white VEC4 (1.0, 1.0, 1.0, 1.0). Then assign this material to the model

Geometry is the geometry attribute of the model, and shader is the material defined above
  const city = new THREE.Mesh(object.geometry, shader);
// Add the reconstructed model object to the scene
  scene.add(city);
Copy the code

Here’s what it looks like:

All building models show white.

Rise line effect achieved

  1. This effect requires four values: the height to which the line risesheight, the color of the rising lineuFlowColor, the color of the architectural modeluCityColor, the height value z of the model point (which is present in the vertex shader and needs to be passed from the vertex shader to the fragment shader), and then pass these values throughuniformsPass it into the shader. The shader code is as follows:
   const shader = new THREE.ShaderMaterial({
        uniforms: {
          height: this.height,
         uFlowColor: {
            value: new THREE.Color("#5588aa"),},uCityColor: {
            value: new THREE.Color("#FFFFDC"),}},vertexShader: ` varying vec3 vPosition; void main() { vPosition = position; Gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `.fragmentShader: ` varying vec3 vPosition; uniform float height; uniform float uStartTime; uniform vec3 uSize; uniform vec3 uFlow; uniform vec3 uFlowColor; uniform vec3 uCityColor; Void main() {// Model base color vec3 distColor=uCityColor; Float topY = vposition. z +5.0; float topY = vposition. z +5.0; float topY = vposition. z +5.0; float topY = vposition. z +5.0; If (height > vposition. z && height < topY) {// distColor = uFlowColor; } gl_FragColor = vec4(distColor, 0.6); } `.transparent: true});Copy the code

Render adds the following code

      this.height.value += 0.03;
      if(this.height.value>100)
      {
        this.height.value=0.0
      }
Copy the code

Let’s start with the code in Render, which executes on every render, incrementing height with each frame and resetting it when height is greater than 100.

Next was the definition of shader material. Here, we imported the required height of the rising line, the color of the rising line, uFlowColor, and uCityColor of the architectural model in imaginative. In vertexShader, the fragmentShader point positions required by the fragmentShader are vPosition. The two shaders share the same point position directly with the variable VARYING, so that the variables needed to raise the effect are complete.

In the fragment shader, first define the model’s base color distColor, then define the position of the flow color float topY = vposition. z +5.0; Vposition. z is the z value of the current point plus a width that is the part of the model that needs to be colored. The next step is to filter the point height between vposition. z-height and vposition. z+0.5-height. Set the color of this section to the uFlowColor of the rising section. The display effect is shown as follows:

Project address: github.com/lixiaochjaj…