2
\$\begingroup\$

I have a 2d galaxy where each star is rendered a particle:

enter image description here

I'd like to approximate it with nebula, so that instead of seeing lots of tiny dots from afar, users will see lots smooth light in the area. Something like this:

enter image description here

I'm more interested in technology-agnostic solution which accurately resembles underlying particles. E.g. how would one approach this problem from math/physics standpoint?

But if you have hints how to do it in a specific technology - those are welcome too! I don't even know how to approach it. The final thing is implemented with WebGL.

\$\endgroup\$

5 Answers 5

2
+50
\$\begingroup\$

To get something decent I think would be pretty easy.

  1. Render your particles in the general pattern of nebula, make them very bright.
  2. Add perlin noise or similar.
  3. Add some very bright areas here and there to represent large stars.
  4. Apply bloom and hdr.
  5. Consider adding doing the same on a smaller scale and using it to occlude a few areas to represent darker areas.
  6. Save results in a texture (your nebula is not going to change over time right?)

I am sure you could take it a lot further than that but it would probably require experimentation. The nice thing with problems like this is you can process as much as you want because it's an offline problem really.

\$\endgroup\$
2
\$\begingroup\$

From a physics standpoint you would first need to choose which kind of nebula you want. Now, it looks like you actually want a galaxy, which is a different kind of object. From there we get three kinds of light:

When we look at a galaxy, the light we see comes from two sources. First, we see light from its billions of stars; since most galaxies are so far away, we don't see individual stars - just the combined diffuse light of all. Second, we see fluorescent light emitted by gas ionized by hot, luminous stars. These glowing gas clouds mark the sites of newly born stars - they often look like beads stringing the arms of spiral galaxies. The light from both stars and gas is dimmed to some extent by dust within the galaxy's interstellar medium.

http://skyserver.sdss.org/dr1/en/astro/galaxies/galaxies.asp

So, to get an "exact" physical solution, you would:

  1. Create an enormous amount of stars with varying levels of light emission using some reasonable distribution.
  2. And add a gas cloud which gives off a certain amount of light per unit volume - possibly connected to the stars in two ways (being "lit" by stars and being concentrated around stars)
  3. And then finally add a fog-like effect that dims and softens both kinds of light. It should be "volumetric" (not as some sort of layer above).

In practice this is probably not feasible.

If you're definitely using 2d, then I would just make the first 2 steps in a number of layers, and then dimming them out wrt to z. The gas could possibly be done using perlin noise as Lunquil suggest, but I think you should have a model that lets the stars and the gas cloud interact to make it look more natural.

Maybe using some caustics or some reaction-diffusion system.

https://en.wikipedia.org/wiki/Reaction%E2%80%93diffusion_system

\$\endgroup\$
1
\$\begingroup\$

I'm more interested in technology-agnostic solution which accurately resembles underlying particles. E.g. how would one approach this problem from math/physics standpoint?

The issue with the math/physics solution is that given the sheer scale of astronomical quantities it is wholly impractical to go the "fully accurate" route.

The reason that a nebula appears to be a solid glowing thing isn't that there are a bunch of stars and gasses very close together; it's that each individual glowing star and piece of gas is far enough away from us that we cannot resolve the individual pieces -- given their distance from us, they are so close together that the angle between adjacent points is small enough such that our eyes can literally not differentiate between different stars or heated gasses in the nebula (Look up the Rayleigh criterion if interested).

Furthermore, the propagation of light from a nebula, or more accurately from anything, follows what is known as the "inverse-square law:" the intensity of the light changes in inverse proportion to the square of the distance from the source. So, doubling the distance between you and a light source would quarter the intensity of light hitting you. Perhaps slightly less important for a computer game, but the result is that brighter parts of the nebula may not end up looking that much brighter than other parts (but of course, it depends on the actual brightness values involved).

And the actual frequencies of light which we can see are a product of black-body radiation. In simple words, the wavelengths of light emitted by a light source depend upon the temperature of said light source. And to make things even more complicated, the dopper effect, which applies to sound, light and other electromagnetic radiation, specifies that any relative movement between us and the observed light source can shift the frequency/color of light we observe towards either red (moving apart) or blue (moving closer), phenomenons called "redshift" and "blueshift" (Scientists are so creative at naming things!)

And that's not even getting into the formation & structure of your galaxy or nebula in the first place!

Replicating such accurate behavior in a computer program would be a rather daunting effort: the creation and simulation of many, many individual particles (stars), with a distribution of distances and temperatures, and then determine accordingly how a layer of gas around the stars would be heated and which frequencies of light it would emit at various spots. And that's all before you can even attempt to figure out how to draw it.

If you want to go that route, good luck. If at all possible I'd recommend doing the calculations and rendering offline and then just use a selection of pre-made images for your final game.

Still reading? Don't want to try to do this completely from a math/physics viewpoint? I don't blame you.

Anyways, my suggestion for how to do this in a somewhat reasonable way without too much pain:

  1. Start off by assigning each of your star-particles a color and brightness (probably via some distribution function)

  2. Add a bit of glow around each point according to its brightness and color. Individual stars would probably still be somewhat visible at this point, but the space between stars shouldn't be too much darker.

  3. If you want more uniformity of light, take the entire thing and blur it a bit more so that it, on average, looks about the same brightness. Ideally there would still be some bright spots, but not too many.

Optional -- Overlay some darker "clouds" to simulate masses of gas obscuring or blocking the light behind.

Essentially, take your point-lights and blur them together until it looks okay. It might not be perfect, but if done properly I don't think it would look too bad. (I'd try to make an example picture for you, but I'm not great at Photoshop)

\$\endgroup\$
1
\$\begingroup\$

This is probably the stupidest solution that you're going to see for all of the answers. But just here me out on this.

Have you thought about building a mesh out of the particle points, and interpolate vertex colors across them? This seems weird at first to think about... but this has actually worked when it comes to making resolution independent lens flares.

https://simonschreibt.de/gat/xrebirth-geometric-lensflares/

This also works great for keeping art looking nice too.

https://simonschreibt.de/gat/homeworld-2-backgrounds-tech/

What you would do is create some set of rules that would define the vertex color of the particles in relations to space before the simulation begins. As you do that, you'd build the mesh. Once it's done, you just scale it outwards.

To give a bit more volume to it, you can run sprite particles along the surface of certain portions of the mesh to give it that lit up dust effect.

\$\endgroup\$
0
\$\begingroup\$

I cannot agree with solutions proposing involving millions of particles, or just building up the result from a multitude of individual small pieces.

  • 1st off, it will be a hard work to place such tiny buildstones in huge 3d space in a sensible way (do YOU know the star distances, luminances, colors, densities? I don't :-)).
  • 2nd, the piececs lose their meaning along the downscaling anyway, as they end up in for example 500 by 500 pixels on the screen.
  • 3rd, there is no fixed rule for how the end result should look (the images you find will google are most likely improved in many ways anyway), and
  • 4th light equations are always surprising; in the end result you must clamp all color channels into 0...255 anyway, meaning the values smaller than 0.5 simply and harmfully fall off, although they had a relevance in the "physiclly correct" model.

This is artwork! If you only need to view the result in 2d, meaning no need to fly around the nebula, or enter into it, my approach would definitely be working with a shader and doing pixel processing from a handful of argument textures. One could indeed even have a handful of 3d objects as first guidance, if a view from different angles as needed (grab an isometric snapshot onto a rendersurface, work onwards from that). Reading textures and doing suitable custom maths on the color values (or numbers, if float32 argument textures) would be my approach to this challenge. Additive rendering on top of each other may be a way to go (eg. bouncing between 2 render surfaces a few times).

Would be about grabbing a good hires, middle res, low res and potentially a micro res texture, where the 2 last would be nicely tiling ones, and then just doing texture lookups and after calculation combining into a result that pleases the eye. The textures don't need to look like nebulas initially, they'd only be pixel and color/float32 value placeholders for the shader calculation.

Likely one could build a colorful nebula even from a picture of supermans pyjama and a tiling concrete texture, if using some creative pixel shader coding :-).

(Remember to use float32 surfaces always, so to not force intermediate calculation results into only 256 possible values per channel)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .