E D R S I H C RSS
ID
Password
Join
우리가 아무 것도 세상에 가지고 온 것이 없음에 또 한 아무 것도 가지고 가지 못하리니 우리가 먹을 것과 입을 것이 있은 즉, 족한 줄로 알 것이다. - 성서

 * 원문링크 : [http]http://www.gamedev.net/opengl/volfog.html

Contents

1 Introduction
2 Particle based volumetrics
3 Ray sampled volumetric fog
4 Advanced stuff
4.1 Giving the fog substance - to let it interact with other objects
4.2 Using particles
4.3 Defining how fog would interact with an arbitrarily shaped object - using the vertices of the object would be used as points, and the objects edges as fog particle trajectories
5 The program basic description
5.1 keys
5.2 details
6 improvements

1 Introduction #

I've always enjoyed looking at clouds and fog in nature. I can watch the clouds rolling in from the Pacific Ocean and over the hills into the valley for hours. It's a beautiful mix of complexity, grace and beauty - which makes it one of those effects in real time 3d that everyone really wants, but is really hard to implement well. I've done lots of thinking and a little programming about creating decent 3d clouds, but have only recently decided to write an article on simple volumetric fog.

It is by no means simple of course. Until last year, fog in real-time games was more of an occlusion tool than a graphical effect. There were good 3d engines for rendering indoor scenes, because it could easily be split up to calculate what would be visible from any location (BSP trees in Doom, etc). However, in outdoor scenes, it's a little more complex, because in most instances, you can see a really long way. This didn't work well with the hardware of the time, so the far z clipping plane was brought in closer and a curtain of fog was dropped in front of the player. I believe Turok deserves the recognition of best demonstrating this. This sort of fog (which is currently all that is supported in hardware) is a mapping of the z value of a pixel to some function. While there is some variety in the function that can be used, it still doesn't look that great.

Volumetric fog, on the other hand is based on actual fog objects in the scene. They can be anywhere, and can produce much more realistic and cool visuals than depth-based fog. I'll describe 2 ways of doing this.

2 Particle based volumetrics #

My first idea for generating volumetric effects (fog, fire, smoke, clouds, etc) was to use particles. I thought this was a good approach because the particles could each be fed through a physics engine to create realistic movement and patterns. This is currently what is used most for fire and smoke as the animation produces a reasonably convincing effect. However there are some problems, which essentially boil down to how many particles are necessary to generate the desired effect. Fewer particles gives a more chunky look, but more particles means lots more calculations for physics, depth sorting, and blending.

One idea I have proposed is using procedural textured particles to achieve "sub-particle" detail. This has probably been researched before by someone, but I have not seen any specific articles. This can probably be used well in fire, smoke, and possibly clouds.

But for this article all we're interested in is ambient volumetric fog. By ambient I mean relatively uniform and still. And particles require too much calculation and don't give the right look.

3 Ray sampled volumetric fog #

The name pretty much explains it all. You cast a ray, determine if it intersects any fog volumes before hitting an opaque surface, and calculate the contributed color based on the color and density of the fog, as well as the distance the ray passed through the fog.

As you might expect, this method is used all the time in ray-tracing. Fog can be just another parameter for an object. You calculate the distance the ray is in the fog, and determine the contributed color. In ray-tracing, you can perform this calculation for every pixel - if you didn't, it wouldn't really be high-quality ray tracing! However, the time required to do this for every pixel just isn't acceptable for real-time games, so we break up the screen into segments. The segments can be completely uniform, or based on the polygonal data being rendered under it. This "fog-layer" is then blended over the scene to create the volumetric effect.

Epic's Unreal was the first game I know of to use this technique in a real-time 3D game. Here's some comments from Tim Sweeney about volumetric fog in Unreal:

Unreal uses fog maps, which are similar in concept to light maps. However, fog maps are blended onto polygons additively, after the texture and light map have been merged. The per-pixel equation is like this:

Pixel on screen = (Pixel from texture * Pixel from lightmap) + Pixel from fogmap.

Most people don't realize this neat trick, that a 2D texture pasted onto a 2D surface can produce what looks like a volumetric fog pattern filling 3D space. The trick is to recompute the fog map every frame, based on the viewer's location.

The actual volumetric fog computations (which generate pixels that fill the fogmap texture) is a line integral through 3D space, which integrates a spatial lighting function. Lots of raytracers (like persistence of vision) use this same math for non-realtime volumetric fog. The optimization that makes this possible in realtime is to use a low-density fogmap, which requires only a few thousand line integral calculations per frame -- as opposed to "one per pixel" as the raytracers do.

The Quake3 Arena engine also uses this method for volumetric texturing.

07/08/99 - I noticed an interesting OpenGL 1.2 [http]extension that is relevant to this article. It allows you to add another color fragment to the pipeline. That would reduce my program to one pass instead of two. There are also other extensions that add even more color fragments - good stuff. Let's get that driver model going MS!

07/25/99 - The reason for doing the fog in a second passis to prevent it from being affected by lighting. The lighting is calculated on the surface, so applying the fog to the surface color before lighting would result in incorrect shading.

4 Advanced stuff #

These comments are taken from an email exchange I had with Jon Tanner back in February.

4.1 Giving the fog substance - to let it interact with other objects #

In an ideal world, you could just pull math straight from fluid dynamics, get the right density and viscosity and other values and it would look amazing. Of course current computers are not capable of computing all that especially when you introduce arbitrary shaped objects interacting with the fog. But that's the basis from which all of the faster methods derive (the idea at least).

4.2 Using particles #

One way of adding a lot of realism is to break down each rendered particle into smaller particles as well. Though you won't do near as many computations for these sub-particles, it looks a lot better. The sub-particles would actually be texels on the particle, but you can see how you could apply some simplified fluid dynamics equations to a field of 2d elements based on external forces. Mostly it makes it look like you're rendering a much denser field of fog and hence looks more realisitc.

4.3 Defining how fog would interact with an arbitrarily shaped object - using the vertices of the object would be used as points, and the objects edges as fog particle trajectories #

Well, it's slightly more complicated than just the object's shape. It would actually end up begin a more rounded version of the object (imagine putting it in a wind tunnel). The fog would flow around the edges and swirl back at points. The trajectory idea is a good one, though it's actually more of a 3d vector field, but that's tough to do in realtime. You can represent the vector field with a set of set of functions, but it's always going to be some sort of curve no matter what the original object looks like.

5 The program basic description #

The program (download with source) is an implementation of the second method. It uses a simple scaled-cube based scene, and tesselates the scaled cubes to provide a high enough vertex density for the fog to look smooth. The cubes and the fog can be animated (position, size, & color).

5.1 keys #

This is a pretty basic, barely-interactive demo.

A - toggles animation F - toggles the fog S - toggles drawing the fog as a solid object

5.2 details #

The code is pretty well commented, so I'm not going to go over it too much. If youhave a question or comment, email me, and I'll put it up with an answer on this page.

Drawing the scene:
  • The scene is parsed in from the file and stored before the program begins. For each frame, the boxes are tesselated into an array of quads. It can optionally store color and normal information. It does not generate a display list of vertex array because the color values will not be the same for the fog pass.
  • Pass 1: the scene is drawn with GL lighting enabled, coloring the boxes based on their material color.
  • Pass 2: for each vertex, a function creates a ray casted from the eye to the vertex with fog boxes and calculates if it intersects any fog boxes.
  • If there is an intersection, it calculates the density of the fog box at each point (should be two points, entrance & exit, or entrance & vertex) and the distance between the two points. The density is an inverse square function based on distance from the center of the box (scaling it to a unit cube).
  • From the density and distance, it calculates the contributing color
  • The quad is blended over the old with it's new color

스크린샷:

fog01.jpg

6 improvements #

What can/should be improved:

  • Intelligent tesselation - only break up quads if there is a sufficient difference in calculated fog color contribution. You must start out with a reasonable tesselation level to avoid skipping over the middles of large polygons.
  • Less scene dependence - right now, it's dependent on the viewpoint staying on relatively the same area. Viewing the scene from the side can cause some serious problems. Also having the view in a fog volume will give strange results (this is pretty simple to fix).
  • Better density calculations - so it can be changed in the scene description.
  • Tesselating the surfaces to allow for strips and fans - since you're drawing them all twice, using one of these methods is very important.

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2010-10-28 12:42:54
Processing time 0.4907 sec