My current project involves creating a points cloud with moving points that are confined within a sphere of a specified radius, X.
Initially, I was able to achieve this without using shaders, but now I am experimenting with shaders to enhance the effect.
What I have implemented so far is as follows:
const uniforms = {
u_time: { value: 0 },
u_radius: { value: 1500 },
};
const vShader = `
uniform float u_time;
uniform int u_radius;
attribute vec3 velocity;
varying vec3 v_position;
void main() {
v_position = position;
vec3 vel = velocity * u_time;
if(length(position) > float(u_radius)) {
vel = vel * -1.0;
}
gl_Position = projectionMatrix * modelViewMatrix * vec4(position + vel, 1.0);
gl_PointSize = 10.0;
}`;
const fShader = `
varying vec3 v_position;
void main() {
vec3 color = vec3(1.0);
gl_FragColor = vec4(color, 0.7);
}`;
My approach involves comparing the length of each vertex's current position to the sphere radius. If the position falls outside the sphere, the velocity vector is negated to keep it within the sphere.
Unfortunately, my current implementation does not yield the desired result, as the particles spread out over time.
As a beginner in three.js and GLSL, I suspect I must be overlooking something obvious.
EDIT:
The gif showcases the effect I have achieved so far using Points, an array of positions, and an array of velocities (initially randomized during initialization).
(The particles move randomly but stay within the sphere, although this may not be clear in the gif due to compression.)
Upon each tick, I iterate over the particles array, updating their positions based on velocity vectors. If a particle's position exceeds the sphere radius, I reverse the velocity vector and update the corresponding indices in the velocities array. Finally, I mark the Points geometry position attribute for update.