Rendering an atmosphere

Started by
5 comments, last by Stainless 9 years, 4 months ago

Hi all,

I have a question. I'm working on a space engine at the moment, and I have successfully created geodesic grid sphere's for planets and have all the appropriate physics for space ships (using a physics engine). So far I have a very rough draft/clone of Kerbal Space Program (but years behind their progress, not intending to compete with their product. But rather as a hobbyist just playing around with graphics API/physics APIs and trying to bind them together.)

Now that I have the basics down, I've realized that my planet graphics are really bad and I want to improve it. The first thing I want to do is create an atmosphere.

I have a technique down and I just want to bump it off you guys, as I have no real idea how to implement it. I am guessing I'd do it in HLSL.

So what I'm thinking is to create another geodesic grid sphere around the planet's surface with a larger radius. But rather than just make it a blue color, which of course won't give a good gradient or depth to the atmosphere, to do something else with it:

What I'm thinking of doing is make this atmosphere surface 2 sided and also transparent. Then calculate the amount of distance between the start of the atmosphere and either the planet itself or the backside of this new atmosphere sphere. The more distance or pixels between the start and the backside, the more atmosphere is present and color the pixel according (blue for earth).

Now the question is this: How do I implement that in a shader? I assume I may have to render like a shadow map, and write the depth of the start of the atmosphere and compare that to the object behind it, much like you do with shadow mapping. Would this be the best approach? Before I waste days trying to implement this, can you guys maybe point me in a better direction if you may have one?

Thanks.

Advertisement

If your planet sphere vertices have normals, you can just render a larger version and dot the normal with the normalized (eye -> worldposition) vector to determine how much the rendered geometry is "facing" the camera. Stuff that's directly facing the camera will be invisible, stuff that's directly perpendicular (the edges of the atmosphere as seen from the viewer) will be the most visible.

Essentially, the dot product will give you a number between 0 and 1 (well, -1 and 1, but negative stuff is facing away and won't be rendered if culling is enabled). Then you can map that 0 to 1 range to whatever "alpha" you need... you'll probably want an exponential function in there, since the atmosphere would only tend to be truly visible at values close to 0.

I use something similar to render the atmosphere here:

[attachment=25041:TN.jpg]

My approach for rendering the atmosphere is to take the mesh (in my case, it's a subdivided cube warped into a sphere shape), calculate the silhouette by comparing adjacent faces and findings edges where one face points toward the camera and one point faces away, then I extrude out geometry for the atmosphere.

Clipboard11.png

It's a lot of work to be doing on the CPU, but it means I'm filling a lot less pixels when I draw the atmosphere, and the technique also works with the oddly shaped planets I have in my game:

Clipboard04.png

I think phil_t's approach is more elegant though.

Along with the above, try looking at Celestia. It's open source so you can look at how they do it.

If you are looking for higher-fidelity atmosphere rendering, you might want to start with Sean O'Neil's method, and then take a look at Eric Bruneton's method. Those two are pretty much the gold standard of rendering realistic atmospheric scattering.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Thanks for the comments guys. There was a few approaches here I didn't think of. Phil's approach would probably work great for my scenario, but I'm thinking it might not work well if I was landing on the planet itself? I want to try to create a hybrid engine where I can fly around in space and then also land on the planet. So sort of like a flight sim + planet orbiting. But I'm sure I could get it to work if I played around with it.

I like Sean O'Neil's and Eric Bruneston's methods (which look great, but I have a feeling I could make an entire career out of rendering an atmosphere if I wanted to after seeing those sites)... I'm going to see if I can absorb what they are doing. Some of their diagrams looked similar to what I wanted to do (I'd probably simplify it though).

I did a little tutorial on planets a while back that included atmospheres

http://stainlessbeer.weebly.com/planets-1-mercators.html

The HLSL for the atmosphere shader is here

http://stainlessbeer.weebly.com/planets-9-atmospheric-scattering.html

Not how I would do it these days, but maybe it will give you some ideas.

This topic is closed to new replies.

Advertisement