OptimizationsThere are a lot of optimizations you could make to this to make it run faster. To start with, a number of optimizations can be made to the SetColor() function. Caching variables and creating a few 1D lookup tables could speed up a number of the calculations. For instance, the phase function calculations could be replaced with a 1D lookup table, with one channel for Rayleigh and one for Mie. The same could be done for the attenuation calculation using three channels to avoid calling exp() 3 times. I'm sure there are others. It would also be a good idea to improve the hidden surface removal to avoid calling CGameEngine::SetColor() so many times. A dynamic level-of-detail implementation could also help minimize the number of calls to SetColor(). If that's not enough, you can use frame coherence to avoid re-calculating the colors for every vertex for every frame. You only need to update a vertex color when the camera or the light source moves far enough relative to that vertex to introduce a noticeable error in the color. Actually, if you keep the atmosphere from rotating with the planet (keep one side pointed at the light source), you only have to worry about the camera moving. Some of the work for this could be offloaded to the GPU. If nothing else, the conversion from the integral sums to the color values themselves could be done in a vertex shader. If you pushed the phase function calculation into a pixel shader, you would get much smoother gradients, which would look much better for the Mie scattering (which looks terrible with low tesselation). Last but not least, I hope that someone out there comes up with an even better way to do this. Although I'm proud of what I've accomplished given what I've been able to find online, I keep thinking there must be an even better way to do this, perhaps involving a 3-D buffer or multiple 2-D buffers. Other ThoughtsI am also working on real-time volumetric clouds, but I don't have them running real-time across a whole planet yet. Once I do that, it shouldn't be difficult to apply the atmospheric scattering to them to get those beautiful sunset colors. What will be difficult will be sampling the cloud shadow buffer in my atmospheric scattering loop, as that should give some cool shafts of light. It sounds a bit too close to ray-tracing though, and I'm not sure I'll be able to make it fast. Oh, and before you ask, the "ground" scattering looks way off when the camera is close to the ground because the vertices are so far apart in these brute-force spheres. The ground should look black (i.e. almost no light scattered in) directly beneath your feet because it's so close, but it won't if the nearest vertex is far away. With a dynamic LOD scheme like my planet renderer uses, it should look fine. About the Author Sean O'Neil has a CS degree from Georgia Tech with a specialization in computer graphics. His full-time job is in the telecom market, but he likes to spend a few hours a week playing around with graphics/game programming. His online articles managed to land him a part-time contract with Maxis for two years, but now he's back to doing it for the fun of it. If you have any questions, comments, or suggestions, you can contact him at s_p_oneil@hotmail.com or visit his home page at http://home.comcast.net/~s-p-oneil/. |
|