three.js BufferGeometry blob code update error

Viewed 245

I currently learning three js and I was following this tutorial however noticed that the code is invalid for the current version of threejs and you can see the main change below. Going by this document I've updated the bit of code to:

  var k = 1;
     
  const positions = sphere.geometry.attributes.position.array;
  for (var i = 0; i < positions.length - 2; i++) {
    const v = new THREE.Vector3(
      positions[i], 
      positions[i + 1], 
      positions[i + 2]
    ).normalize()
    .multiplyScalar(
      1 + 0.3 * noise.perlin3(
      positions[i] * k + time,
      positions[i + 1] * k,
      positions[i + 2] * k));
      positions[i] = v.x;
      positions[i + 1] = v.y;
      positions[i + 2] = v.z;
  }
  
 sphere.geometry.attributes.position.needsUpdate = true;

However as you can see from the snippet the vertex displacement is not smooth and does not resemble the tutorial. What I'm missing here?

var renderer = new THREE.WebGLRenderer({ canvas : document.getElementById('canvas'), antialias:true});
// default bg canvas color //
renderer.setClearColor(0x7b7b7b);
//  use device aspect ratio //
renderer.setPixelRatio(window.devicePixelRatio);
// set size of canvas within window //
renderer.setSize(window.innerWidth, window.innerHeight);




var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 5;


var sphere_geometry = new THREE.SphereGeometry(1, 128, 128);
const material = new THREE.MeshPhongMaterial({
    color: 0x0000FF,
    shininess: 1000,
  })

var sphere = new THREE.Mesh(sphere_geometry, material);
scene.add(sphere);
const ambientLight = new THREE.AmbientLight(0x798296)
scene.add(ambientLight)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
    directionalLight.position.set(5, 10, 7)
scene.add(directionalLight);
sphere.geometry.attributes.position.needsUpdate = true;

var update = function() {

  // change '0.003' for more aggressive animation
  var time = performance.now() * 0.003;
  //console.log(time)

  //go through vertices here and reposition them
  
  // change 'k' value for more spikes
  var k = 1;
     
  const positions = sphere.geometry.attributes.position.array;
  for (var i = 0; i < positions.length - 2; i++) {
    const v = new THREE.Vector3(
      positions[i], 
      positions[i + 1], 
      positions[i + 2]
    ).normalize()
    .multiplyScalar(
      1 + 0.3 * noise.perlin3(positions[i] * k + time,                 positions[i + 1] * k,
      positions[i + 2] * k));
      positions[i] = v.x;
      positions[i + 1] = v.y;
      positions[i + 2] = v.z;
  }
  
 sphere.geometry.attributes.position.needsUpdate = true;
}

function animate() {
  sphere.rotation.x += 0.01;
  sphere.rotation.y += 0.01;

  update();
  /* render scene and camera */
  renderer.render(scene,camera);
  requestAnimationFrame(animate);
}


requestAnimationFrame(animate);
html, body {
  margin:0;
  overflow:hidden
}
<script src="https://fariskassim.com/stage/rebel9/teaf/blob/v4/js/perlin.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<canvas id="canvas"></canvas>

1 Answers

This is how you can deform a sphere with noise, using BufferGeometry:

enter image description here

var renderer = new THREE.WebGLRenderer({ canvas : document.getElementById('canvas'), antialias:true});
// default bg canvas color //
renderer.setClearColor(0x7b7b7b);
//  use device aspect ratio //
renderer.setPixelRatio(window.devicePixelRatio);
// set size of canvas within window //
renderer.setSize(window.innerWidth, window.innerHeight);




var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 5;


var sphere_geometry = new THREE.SphereGeometry(1, 128, 128);
const material = new THREE.MeshPhongMaterial({
    color: 0x0000FF,
    shininess: 1000,
  })

var sphere = new THREE.Mesh(sphere_geometry, material);
scene.add(sphere);
const ambientLight = new THREE.AmbientLight(0x798296)
scene.add(ambientLight)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
    directionalLight.position.set(5, 10, 7)
scene.add(directionalLight);
sphere.geometry.attributes.position.needsUpdate = true;

var update = function() {

  // change '0.003' for more aggressive animation
  var time = performance.now() * 0.003;
  //console.log(time)

  //go through vertices here and reposition them
  
  // change 'k' value for more spikes
  var k = 1;
  var v3 = new THREE.Vector3();   
  const positions = sphere.geometry.attributes.position;
  for (var i = 0; i < positions.count; i++) {
    v3.fromBufferAttribute(positions, i).setLength(k);
    let n = noise.perlin3(v3.x, v3.y, v3.z);
    v3.setLength(1 + 0.3 * n);
    positions.setXYZ(i, v3.x, v3.y, v3.z);
  }
  positions.needsUpdate = true;
  sphere.geometry.computeVertexNormals(); // don't forget to call this
}

function animate() {
  sphere.rotation.x += 0.01;
  sphere.rotation.y += 0.01;

  update();
  /* render scene and camera */
  renderer.render(scene,camera);
  requestAnimationFrame(animate);
}


requestAnimationFrame(animate);
html, body {
  margin:0;
  overflow:hidden
}
<script src="https://fariskassim.com/stage/rebel9/teaf/blob/v4/js/perlin.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<canvas id="canvas"></canvas>

Related