Moving retrowave grid

Hi, community!

There’s an approach of how to make a moving grid, using THREE.GridHelper() with THREE.ShaderMaterial() (r94).

var division = 20;
var limit = 100;
var grid = new THREE.GridHelper(limit * 2, division, "blue", "blue");

var moveable = [];
for (let i = 0; i <= division; i++) {
  moveable.push(1, 1, 0, 0); // move horizontal lines only (1 - point is moveable)
}
grid.geometry.addAttribute(
  "moveable",
  new THREE.BufferAttribute(new Uint8Array(moveable), 1)
);
grid.material = new THREE.ShaderMaterial({
  uniforms: {
    time: {
      value: 0
    },
    limits: {
      value: new THREE.Vector2(-limit, limit)
    },
    speed: {
      value: 5
    }
  },
  vertexShader: `
    uniform float time;
    uniform vec2 limits;
    uniform float speed;
    
    attribute float moveable;
    
    varying vec3 vColor;
  
    void main() {
      vColor = color;
      float limLen = limits.y - limits.x;
      vec3 pos = position;
      if (floor(moveable + 0.5) > 0.5){ // if a point has "moveable" attribute = 1 
        float dist = speed * time;
        float currPos = mod((pos.z + dist) - limits.x, limLen) + limits.x;
        pos.z = currPos;
      } 
      gl_Position = projectionMatrix * modelViewMatrix * vec4(pos,1.0);
    }
  `,
  fragmentShader: `
    varying vec3 vColor;
  
    void main() {
      gl_FragColor = vec4(vColor, 1.);
    }
  `,
  vertexColors: THREE.VertexColors
});

scene.add(grid);

and in the animation loop:

  time += clock.getDelta();
  grid.material.uniforms.time.value = time;

Reference to SO

4 Likes

Are there any documentation on this at all such as THREE.GridHelper

@Google_User
Ehm :slight_smile:
THREE.GridHelper() and its source code.
Feel free to explore the documentation and examples on Three.js :wink:

vertexShader: `
uniform float time;
uniform vec2 limits;
uniform float speed;

attribute float moveable;

varying vec3 vColor;

void main() {
  vColor = color;
  float limLen = limits.y - limits.x;
  vec3 pos = position;
  if (floor(moveable + 0.5) > 0.5){ // if a point has "moveable" attribute = 1 
    float dist = speed * time;
    float currPos = mod((pos.z + dist) - limits.x, limLen) + limits.x;
    pos.z = currPos;
  } 
  gl_Position = projectionMatrix * modelViewMatrix * vec4(pos,1.0);
}

, fragmentShader:
varying vec3 vColor;

void main() {
  gl_FragColor = vec4(vColor, 1.);
}

`,

Could you explain to me what you are doing there? Thanks!

As the lines move towards the camera, we change their z-values.
We have limits on z-axis, from -50 to 50, so we’ll put them into the limits uniform (x = min, y = max).
In the vertex shader: if a point is moveable (moveable attribute equals to 1), then we’ll calculate a distance, that the point passes (uniform speed * uniform time), add point’s current position, get its modulo with subtraction between max and min limits, and add the min limit :slight_smile:
That’s all :beers:

You know, when I was writing that post, I came up with yet another thought about another approach.
This one: How to achieve this material effect [gif image]? - #18 by prisoner849

A few day back I saw the similar approach being used to develop dynamic 3d Terrain.
May be this could help as well.
The first half of the video explains the grid creation and the motion.

Although, it does not use three.js, but one can get to know the approach easily.

1 Like

@Atul_Mourya
Interesting :+1:
The approach with Perlin noise he uses in this video, I used it here with Three.js

Looks really impressive :+1::+1: