I'm learning to use the THREE.js library by creating a particle sphere inside my React App. Referencing this project, I've managed to get somewhat of a start, but am at a bit of a dead-end.
For some reason, despite the fact that all my code is essentially the same - except for some deprecated methods being swapped out - THREE will render a weird straight line every time.
After looking at the documentation for a few hours and trying to learn the individual methods of this component, I'm still scratching my head.
This is what I have (a live version can be viewed here ):
let camera;
let renderer;
let scene;
const vector3D = new THREE.Vector3();
// Get constraints of the canvas.
const getConstraints = () => {
const canvas = document.getElementById("canvas");
const { width, height } = canvas.getBoundingClientRect();
// Get attribute-set width and height - defaulting to computed constraints.
return [canvas.width ?? width, canvas.height ?? height];
};
// Retrieve a random point in the sphere for a particle to be set at.
const getRandomPointInSphere = radius => {
const x = THREE.MathUtils.randFloat(-1, 1);
const y = THREE.MathUtils.randFloat(-1, 1);
const z = THREE.MathUtils.randFloat(-1, 1);
const normaliseRatio = 1 / Math.sqrt(x * x + y * y + z * z);
vector3D.x = x * normaliseRatio * radius;
vector3D.y = y * normaliseRatio * radius;
vector3D.z = z * normaliseRatio * radius;
return vector3D;
};
// Initialisation methods.
const initScene = () => {
const [canvasWidth, canvasHeight] = getConstraints();
// Renderer initialisation.
renderer = new THREE.WebGLRenderer({
canvas: document.getElementById("canvas"),
antialias: true, alpha: true,
});
renderer.setSize(canvasWidth, canvasHeight);
renderer.setPixelRatio(window.devicePixelRatio);
// Scene initialisation.
scene = new THREE.Scene();
// Camera initialisation.
camera = new THREE.PerspectiveCamera(45, canvasWidth, canvasHeight, 1, 1000);
camera.position.set(100, 0, 100);
};
const initPoints = () => {
const geometry = new THREE.BufferGeometry();
const positions = [];
const particleSize = 0.2;
const particleColor = 0x1826e0; // Dark blue
const particleCount = 50000 / (particleSize * 10);
for(let i = 0; i < particleCount; i++){
let vertex = getRandomPointInSphere(50);
positions.push(vertex.x, vertex.y, vertex.z);
}
geometry.setAttribute("position", new THREE.Float32BufferAttribute(positions, 3));
const material = new THREE.PointsMaterial({ size: particleSize, color: particleColor });
const particles = new THREE.Points(geometry, material);
scene.add(particles);
};
initScene();
initPoints();
renderer.render(scene, camera);
I'm very new to THREE (and canvases in general), so all help is appreciated.
First of all, the line with camera instantiation has to be like this: camera = new THREE.PerspectiveCamera(45, canvasWidth / canvasHeight, 1, 1000);
, there is the slash instead of comma.
And then, camera has to look at the scene's center, thus camera.lookAt(scene.position);
Snippet with fixed code:
body{ overflow: hidden; margin: 0; } canvas{ border: 1px solid red; }
<canvas id="canvas" width="400" height="400" /> <script type="module"> import * as THREE from "https://cdn.skypack.dev/three@0.136.0"; // THREE variables let camera; let renderer; let scene; let v3 = new THREE.Vector3(); // Get constraints of the canvas. const getConstraints = () => { const canvas = document.getElementById("canvas"); const { width, height } = canvas.getBoundingClientRect(); // Get attribute-set width and height - defaulting to computed constraints. return [canvas.width?? width, canvas.height?? height]; }; // Retrieve a random point in the sphere for a particle to be set at. const getRandomPointInSphere = radius => { v3.randomDirection(); const normaliseRatio = 1 / Math.hypot(v3.x, v3.y, v3.z); v3.setLength(radius * normaliseRatio); return v3; }; // Initialisation methods. const initScene = () => { const [canvasWidth, canvasHeight] = getConstraints(); // Renderer initialisation. renderer = new THREE.WebGLRenderer({ canvas: document.getElementById("canvas"), antialias: true, alpha: true, }); renderer.setSize(canvasWidth, canvasHeight); renderer.setPixelRatio(window.devicePixelRatio); // Scene initialisation. scene = new THREE.Scene(); // Camera initialisation. camera = new THREE.PerspectiveCamera(45, canvasWidth / canvasHeight, 1, 1000); camera.position.set(100, 0, 100); camera.lookAt(scene.position); }; const initPoints = () => { const geometry = new THREE.BufferGeometry(); const positions = []; const particleSize = 0.2; const particleColor = 0x1826e0; // Dark blue const particleCount = 50000 / (particleSize * 10); for(let i = 0; i < particleCount; i++){ let vertex = getRandomPointInSphere(50); positions.push(vertex.x, vertex.y, vertex.z); } geometry.setAttribute("position", new THREE.Float32BufferAttribute(positions, 3)); const material = new THREE.PointsMaterial({ size: particleSize, color: particleColor }); const particles = new THREE.Points(geometry, material); scene.add(particles); }; initScene(); initPoints(); renderer.render(scene, camera); </script>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.