Shader: Randomize point positions from origins


I´m writing a shadermaterial for the use with Threejs´s THREE.Points.
I now want to set points at each origin xyz vector/position - which works fine so far.
Now I want to add (over the time) a random value to each xyz vector in the shader, so that the points update there position (per point) due to the new random values.

So do I do it via attributes, or via uniforms, or… how do the cool kids do that today?

My ShaderMaterial looks like this by now:

    var uniforms = {

      texture:    { value: this.library.get("dot") },
      posScale: { value: 0.05 },
      customSize: { value: 0.5 },
      time: { type:"f", value:0.1 }


    var shaderMaterial = new THREE.ShaderMaterial( {

      uniforms:       uniforms,
      vertexShader:   `
          attribute float size;
          uniform float time;
          uniform float posScale;
          uniform float customSize;
          varying vec3 vColor;

          void main() {

            vColor = color;

            vec3 nposition = position * posScale;
            vec4 mvPosition = modelViewMatrix * vec4( nposition, 1.0 );

            gl_PointSize = size * ( 800.0 / -mvPosition.z ) * customSize;
            gl_Position = projectionMatrix * mvPosition;
      fragmentShader:  `
          uniform sampler2D texture;
          varying vec3 vColor;

          void main() {

            gl_FragColor   = vec4( vColor, 1.0 );
            gl_FragColor   = gl_FragColor * texture2D( texture, gl_PointCoord );

      depthTest:      false,
      transparent:    true,
      vertexColors:   true,
      blending: THREE.AdditiveBlending,


Why not try randomness at shader level :slight_smile:

Doing this just with uniforms is not possible since their values are equal for all vertices. You can do this in the shader like mentioned by @prisoner849 but you will have more control if you provide random values with an additional attribute. Updating attributes per frame is okay but set BufferAttribute.dynamic to true in order to indicate that the data in the buffer will often change. This will allow WebGL to handle your attributes more efficiently.

BTW: Generating random or noise values in the shader can be expensive. In general, I prefer to sample a noise or random map if possible.

1 Like