I’ve been experimenting with the Sprite system for creating a dynamic stardome. While there are some huge advantages to using a stardome (you can fly between the stars, individual star visuals), there is a problem between how the sprite is rendered, and how a real star would be rendered.
In a game engine, if you move away from the sprite, rendering size can fall to smaller than 1 pixel, then it becomes invisible. This seems independent of Camera.maxZ
- in reality, you can easily see a star when you are thousands of times too far away to see its disk - basically it is HDR.
So, for a realistic star system (or any highly luminous object) using sprites you would want the following behavior.
The sprite changes size as you recede from it.
At the point where the sprite takes up 1 pixel, you want to have a function that (a) retains 1 pixel rendering, but (2) makes that pixel slowly dimmer, but retain 1 pixel rendering size, based on a sort of HDR luminosity.
Is there any way to accomplish this with the current Sprite system, e.g. in the pipeline.
As an alternative, one could draw a single point, and makes its visibility dependent on a distance function.
Not that I know of. You would need the projected coordinates of the quad to know if it is one pixel or less in screen space, but the projection is done in the vertex shader and the projected coordinates are not available on the CPU side.
You could of course do the projection yourself and act upon the result, but it’s not something that the sprite / sprite manager is currently doing.
Yes, that’s my conclusion. Have to write a custom shader?
Basically, this means that at great distances, a sprite will be “twinkly” when you move the camera - that single pixel flips on and off. I tried building 3D stars with the Hyg database (10,000 or so) and when you pull away far enough, they twinkle as a group in an unpleasant way.
No, I don’t think a custom shader will do it because you get the vertices one at a time in the vertex shader, you don’t have the full vertex list available.
I think you will have to project “by hand” each of your star each frame, and if the quad of the sprite is below one pixel you could disable the sprite and display “something else” in it place.
You could also speed up a bit those things by pre-computing the distance at which each sprite will be 1 pixel or less in the screen and only testing each frame the current distance of the sprite with this pre-computed distance to know when to do a specific display.
I’ll experiment with that idea!
The SpriteManager turns out to really perform well. I put 119k sprites and updated color alpha and size, full speed run with a VR-capable desktop!