Why are all particles positioned in the center on x axis in THREE.JS



I’m new to THREE.JS and I’m trying to figure out how to make particle system and I can’t get it to work properly. As title says all of the particles are positioned in the center on X axis, it seems that Y and Z are ok.

Picture of the result: https://i.stack.imgur.com/xUuAn.png What I want to achieve: https://i.stack.imgur.com/vA0tL.jpg

Code:

    const scene = new THREE.Scene();

    const camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth - 10 / window.innerHeight,
      1,
      1000
    );

    camera.position.z = 300;

    const ambientLight = new THREE.AmbientLight(
      0xFFFFFF
    );

    const particleBufferGeometry = new THREE.BufferGeometry();
    const positionArray = [];

    for (let i = 0; i < 10000; i++) {
      positionArray.push((Math.random() * 2 - 1) * 200);
      positionArray.push((Math.random() * 2 - 1) * 200);
      positionArray.push((Math.random() * 2 - 1) * 200);
    }

    particleBufferGeometry.setAttribute("position", new THREE.Float32BufferAttribute(positionArray, 3));

    const particlePointsMaterial = new THREE.PointsMaterial({
      size: 0.1
    });

    const particlePoints = new THREE.Points(particleBufferGeometry, particlePointsMaterial);

    const renderer = new THREE.WebGLRenderer({
      antialias: true,
      alpha: true,
      canvas: canvasRef.current!
    });

    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setClearColor(0xFFFFFF, 0);
    renderer.setSize(
      window.innerWidth - 10,
      window.innerHeight
    );

    scene.add(ambientLight, particlePoints);
    
    renderer.render(scene, camera);

Answer

The error occurs when you initialize your camera. Your aspect ratio is

window.innerWidth - 10 / window.innerHeight

Example: 1920 - 10 / 1080 = 1919.99 (wrong aspect ratio)

but due to the order of operations, it’s calculating the division first so 10 / height happens before the subtraction. Just make sure you use parentheses correctly and the problem will be solved:

(window.innerWidth - 10) / window.innerHeight

Example: (1920 - 10) / 1080 = 1.76 (Correct aspect ratio)

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
    45,
    (window.innerWidth - 10) / window.innerHeight,
    1,
    1000
);
camera.position.z = 300;

const particleBufferGeometry = new THREE.BufferGeometry();
const positionArray = [];

for (let i = 0; i < 10000; i++) {
    positionArray.push((Math.random() * 2 - 1) * 200);
    positionArray.push((Math.random() * 2 - 1) * 200);
    positionArray.push((Math.random() * 2 - 1) * 200);
}

particleBufferGeometry.setAttribute("position", new THREE.Float32BufferAttribute(positionArray, 3));

const particlePointsMaterial = new THREE.PointsMaterial({
    size: 0.1
});

const particlePoints = new THREE.Points(particleBufferGeometry, particlePointsMaterial);

const canvasRef = document.querySelector("#canvas");

const renderer = new THREE.WebGLRenderer({
    antialias: true,
    canvas: canvasRef
});

renderer.setSize(window.innerWidth - 10, window.innerHeight);

scene.add(particlePoints);

function animate() {
  particlePoints.rotation.y += 0.01;
  renderer.render(scene, camera);

  requestAnimationFrame(animate);
}

animate();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r126/three.min.js"></script>

<canvas id="canvas"></canvas>


Source: stackoverflow