Starlight
by tiffany
Starlight for Godot 4.3
(Planet rendered using Atmosphere Shader v0.4)
Starlight is a Godot addon that renders 100 000 stars in realtime, with
low performance cost. It's an alternative to using a skybox, and
also may be relevant to anyone making a space game.
Check out the demo in your web browser: https://tiffnix.com/starlight-demo
Article describing how this works: https://tiffnix.com/star-rendering
Features
- Stars are rendered positionally in 3D, allowing you to fly around and
see stars go by. - Exact position, luminosity, and temperature of each star can be
configured by you. - Physically based light model: Using a Point Spread Function
(PSF), rather than a texture that grows or shrinks with
distance/brightness. - Based on MultiMeshInstance3D for performance.
- Uses a trick to avoid being clipped by the far plane, to let stars be
very far away. - Works with Forward+, Mobile, and Compatibility renderers.
- Comes with a random star generator based on main sequence stars (classes M through O).
Usage Guide
To get started, insert Stars.tscn
into your scene. By default, nothing
will be visible. You can attach the script StarGenerator.gd
to
randomly generate stars. The default will be 10 000.
StarGenerator
This script procedurally generates stars in a ball centered on the
origin. It has these properties:
size
: Stars are spawned inside of a sphere of this radius.star_count
: The number of stars to create.rng_seed
: The random seed to use when generating stars. Incrementing
this will give you a different sky.generate_at_origin
: If checked, one extra G-type star will be
generated exactly at0, 0, 0
. This can be useful for representing
the Sun in your scene.
For further customization of the star generator, I recommend editing the
script directly.
StarManager / Stars.tscn
There is only 1 script property exported, which is which shader to use.
The default points to Star.gdshader
. You can fork the shader easily by
changing this.
The script also forwards the shader parameters which you can edit
directly.
If you want to load your own star catalog, or use a custom random star
generator, you will need to call set_star_list()
with an array of Star
.
The Star constructor takes 3 arguments:
position
: 3D position in model space units.luminosity
: Luminosity in solar luminosity. Approximately 1.0 for Sol.temperature
: Effective temperature in Kelvin. Approximately 5778 for Sol.
Star.gdshader
The following visual properties are exposed:
emission_energy
- Multiplier for how bright stars should be.
Generally this is some extremely large number like500000000
-
you'll need to add or remove zeros until it looks right.color_gamma
- How strongly colors should show through. A value of 1
should be close to real life, while a very high value of 5-10
resembles what you see in false-color images from telescopes. A value
of 3 or 4 is a good balance.billboard_size_deg
- This controls how much of the screen the PSF
texture takes up, in degrees. For the default JWST PSF I recommend a
value of around 45.meters_per_lightyear
- This is a scaling setting, you'll need to set
it depending on how far away you want your stars to be.luminosity_cap
- This is the maximum brightness a star can have. The
main usage of this is to prevent the PSF texture from being blown out
and showing as a white square. This mainly happens when very close to
stars.texture_emission
- This is the actual PSF texture. The default one
is the PSF from the James Webb Space Telescope, because it looks cool.
There are a few others in thepsf-textures
folder which can be used
instead.texture_emission_tint
- A tint value applied to the PSF texture. The
provided PSF textures need a tint value to look correct, there is a
table in psf-textures/README.md.clamp_output
- Clamps the output from 0 to 1 when enabled. Can be
useful depending on how your HDR is setup.
In order to have good performance, the PSF texture needs to be cropped
depending on how bright the star is on screen. The majority of stars
only appear as a couple of pixels in size, as opposed to covering almost
the entire screen for a star you're very close to. This cropping
behavior directly affects how much overdraw there is, which can
massively impact performance. You will need to adjust these properties
if you change the PSF texture from the default JWST one. To control this
behavior, the shader has these properties:
min_size_ratio
- This is the minimum size that a star can render at.
This corresponds to the innermost bright spot of the PSF texture, and
is usually a very small value like 0.003.max_luminosity
- This is the point at which the cropping stops and
the full PSF texture is used. To set this value, try to find the point
at which the PSF texture is fully visible, specifically things like
diffraction spikes reach the edge of the texture. Then adjust
max_luminosity until it's just below that point.scaling_gamma
- Diffraction spikes usually fall in brightness
according to distance^2 from the center of the texture, which means a
value of ~0.5 is ideal. You may need to use other values depending on
your PSF texture. For a perfect airy disk in particular, the falloff
is faster than quadratic.debug_show_rects
- This can be useful while tweaking any of these
values. It helps visualize whether any stars are being over-cropped,
or if there is too much overdraw in your scene.
Be careful when tweaking these values. You may want to reduce the star
count to something more manageable like 1000 or 10,000 while doing this.
Setting scaling_gamma
to 0 by accident, for example, can crash Godot,
your graphics drivers, or even your entire PC.
The shader also requires knowledge of the camera FOV to work correctly.
StarManager tries to automatically find the Camera3D of the current
viewport, but in some cases this auto-detection may be wrong, and you
will need to edit StarManager.gd for your needs. It also does not
display correctly in the editor due to it using different FOV settings
from the scene.
Credit
Code is released under MIT license.
The default PSF texture, jwst.png
, is based on FITS data obtained
from here. Code for cropping, downscaling, and packing into PNG
is located in docs/jwst2png.py
.
The alternative PSF textures hst.png
, hex_aperture.png
, and
airy_disk.png
were created using Poppy based on examples in the
documentation. Code is located in docs/poppy_psfs.ipynb
.
Download
Support
If you need help or have questions about this plugin, please contact the author.
Contact Author