Galaxy Generation - How to render extremely far away objects

Hi everyone, I’m working on a Godot 4.7 project to generate a galaxy that can be explored using a 3D camera in freecam. Right now, my concept generates stars with their own properties, such as luminosity, radius, and temperature, and generates 3D Sphere Meshes, the stars, at random points in the scene (I do plan to look into procedural generation while I scratch away at this question).

What I’m struggling to understand is how I can create hundreds (or thousands) of distant objects and have them be visible to the player, both technically and practically, in Godot.

Right now, my main approach is to swap from a 3D Mesh to a Sprite3D that always faces the player, and factors in the star properties to create the glow (or hide it completely), but there are a few issues with my execution;

  • The Sprite3D and Mesh are children of a master “Star” node. I suspect once I implement procedural generation, I could separate the two far more easily.
  • Far enough away, the camera’s Far property kicks in, and the object disappears.
  • I’m pretty certain that as this scales, it’ll become a performance hog.

I’m hoping to gather some more resources and guides to gather a better picture of how I could complete this. Thank you in advance!

Maybe this guide could help with alternative approach to make stars Godot 4 shaders - a list of video tutorials - #60 by FencerDevLog

Anything close to realistic will need a lot of faking and optimization. One part would include solutions like the shader as @artemisia suggested. You have to be more explicit what you want to achieve.

There are two main restrictions by math precision.

With single precision floats in vanilla Godot, is used for positions, UVs, physics etc. When you are more than 10km away from the world origin the precision starts to get visible. At 10km the smallest value is around 1mm. At distances of 20-30km the problem starts to get annoying, juggling objects, distorted textures (if in world coords) etc.
There are two solutions for that problem.
Stay with the Camera at the world origin and move the content of the world around the camera.
Or, compile your own Godot with double precision.
Read more about it here:

The other precision problem is the depth buffer of the camera. That’s where far and near plane are restricting what is visible. That’s to sort the pixel in distance to the camera. And that has a limit, too, how to store the minimal distance between two pixel of the buffer. It’s not linear, steps closer to the camera are smaller than steps at the far plane. Default in Godot it’s 0.05m and 4km. They are soft limits, you can type bigger values than the limits of the slider. But at some point you’ll get z-fighting, shadow problems etc.

With your solution you have to stay with the galaxy in these limits. For everything else you have to fake it, with scaling of Objects, massive reduce distances or project with a shader on the sky. At huge distances you have no parallax on distant objects on movement.
In reality you can see the stars only because they are sooo bright.
At only a fraction of real distances you can’t render the objects on screen, they are way smaller than a pixel.
It all depends what you want to show at a singe star, how close do you want to approach a star.

Let’s say you make a star 0.02m in Godot, to be visible rel. large on screen with near plane of 0.05m before clipped.
At 4km (the far plane) the star would be too small to be visible on 1080p resolution. At 4km a pixel at far plane is around 3.5m. So the star would be no longer visible way earlier.

To bring some realistic values. If the Sun would be 0.02m the next star would be ca. 600km away. Way above every of the precision limits. The Sun would be 3,600,000km from the world origin, if the world origin is the black hole at the center of the milky way galaxy. The galaxy would be 13,600,000km with the Sun 0.02m.

The Space is so huge and so empty.

Project positions to a smaller sphere centered around the player/camera. You can then use multi mesh instance to draw the actual objects/sprites.