22

I wanted the classic warp-speed starfield but every naive attempt spawned 20k separate Mesh objects and my fans took off. The trick was forcing the model to reach for InstancedMesh (or a single Points cloud) and to budget the draw calls up front.

The other thing that broke early versions: stars would pop out of existence at the near plane. Telling it to recycle a star's z back to the far plane instead of allocating a new one kept the geometry buffer static and the GC quiet.

Anyone found a clean way to add a subtle chromatic streak per star without a second render pass?

THE PROMPT
Build a single self-contained three.js scene (importmap from unpkg, no build step) of a hyperspace starfield. Hard constraints:
- Exactly ONE draw object: a `Points` cloud of {COUNT} stars (default 8000), never per-star Meshes.
- Store position/velocity in flat Float32Array attributes; recycle stars by resetting z to the far plane when they pass the camera, never allocate in the animation loop.
- Camera fixed at origin looking down -z; stars stream toward it. Speed controlled by a single `warp` uniform (0..1) I can lerp.
- Give near stars a longer point size than far stars using `gl_PointSize = size * (1.0 / -mvPosition.z)` in a custom ShaderMaterial.
- Respect devicePixelRatio but cap at 2 so it stays 60fps on integrated GPUs.
- No orbit controls, no lights (Points don't need them), no textures.
Before writing code, state your per-frame CPU budget and confirm zero allocations happen inside `requestAnimationFrame`.
the recycle-z instead of reallocate note is the whole ballgame for GC. wish more starfield tutorials led with that.coffee_compiler 1 month ago
add a comment

2 Answers

14

The 1.0 / -mvPosition.z sizing is right but it blows up hard near the camera and you get dinner-plate stars. Clamp it. I also moved the streak you asked about into the same shader: stretch the point along its velocity in the vertex stage by offsetting gl_Position, no second pass needed.

THE PROMPT
In the vertex shader clamp size: `gl_PointSize = clamp(size / -mvPosition.z, 1.0, 24.0);`. For streaks, pass a per-star velocity attribute and offset the clip-space position by `velocity.xy * streakLen * warp` so fast stars smear toward center.
7

Nice, but if you ever want colored stars, don't set vertexColors on a Points cloud and then also multiply in the fragment shader, they double up and everything goes white. Pick one. I feed a vColor varying and drop the material color entirely.

Your Answer