Game Development Community

Fog?

by Joshua Horns · in Torque 3D Professional · 08/23/2009 (12:57 pm) · 37 replies

Here's the full Post Effect in it's entirety.

Here are a couple videos
www.joshuahorns.com/FogReductionTest-1.wmv

www.joshuahorns.com/FogOverWaterTest-1.wmv

The shader:
//JoshuaHorns

#include "shadergen:/autogenConditioners.h"
#include "./postFx.hlsl"
#include "./../torque.hlsl"

uniform sampler2D prepassTex : register(S0);
uniform sampler2D backBuffer : register(S1);
uniform float4    fogColor;
uniform float3    fogData;
uniform float4    rtParams0;

float4 main( PFXVertToPix IN ) : COLOR
{   
   
   float FAR_PLANE = 1;
   float MAX_FOG_DISTANCE = .3;
   float depth = prepassUncondition( prepassTex, IN.uv0 ).w;
   if(depth >= FAR_PLANE)
   {
	  depth = depth * MAX_FOG_DISTANCE;
   }
  
   float scale = saturate(depth * fogData.x * 10000 / (1 - fogData.x));
        
   float4 bbColor = tex2D(backBuffer, IN.uv0);
   
   return  lerp(bbColor, fogColor, scale);
}

Here's the PostEffect
singleton ShaderData( FogPassShader2 )
{   
   DXVertexShaderFile 	= "shaders/common/postFx/postFxV.hlsl";
   DXPixelShaderFile 	= "shaders/common/postFx/fog2P.hlsl";
         
//   OGLVertexShaderFile  = "shaders/common/postFx/gl//postFxV.glsl";
//   OGLPixelShaderFile   = "shaders/common/postFx/gl/fogP.glsl";
            
   samplerNames[0] = "$prepassTex";
   samplerNames[0] = "$backBuffer";
   
   pixVersion = 2.0;
};

singleton GFXStateBlockData( FogPassStateBlock : PFX_DefaultStateBlock )
{   
   blendDefined = true;
   blendEnable = true; 
   blendSrc = GFXBlendSrcAlpha;
   blendDest = GFXBlendInvSrcAlpha;
};

singleton PostEffect( FogPostFx2 )
{   
   // Let the fog effect render during the 
   // reflection pass.
   allowReflectPass = true;
      
   renderTime = "PFXBeforeBin";
   renderBin = "ObjTranslucentBin";   
   requirements = "PrePassDepth";
   
   shader = FogPassShader2;
   stateBlock = FogPassStateBlock;
   texture[0] = "#prepass";
   texture[1] = "$backBuffer";
   
   renderPriority = 5;
   
   isEnabled = true;
};


************NOTE***************************
You MUST turn OFF the FogPostFx Post effect. (set isEnabled=false)
************NOTE***************************

File Placement:

The Post Effect goes in core/scripts/client/postFx/fog.cs
The shader goes in shaders/common/postFx


Usage:
Navigate to the LevelInfo object in the Scene Tree
Under Fog Density, Type in a value.
- Ideal Range (.01 - .0001)

This will scale the fog in or out.
.01 is fully fogged
.0001 is fully clear

Why these values? I had to map to the way water surfaces fogged. They became fully fogged around .01

Thanks to James for the nudge to go before the ObjTranslucentBin

Enjoy
Page «Previous 1 2
#1
08/23/2009 (1:59 pm)
Try adjusting fogbandheight. But it ain't gonna be a perfect solution on a hill that shape.

Also ... is that a 7.5 megabyte screenshot?
#2
08/23/2009 (2:06 pm)
Lol, well you see... I frapsed a screenshot and didn't bother to photoshop it to a jpeg.


There we go... jpeg.

I guess my point is that the fog isn't realistic. It should be a volume of fog, not just painted over geometry.
#3
08/23/2009 (5:16 pm)
On the Sky or ScatterSky there should be a "render ban height" field. That is the current way fog obscuring the sky works...
#4
08/23/2009 (6:11 pm)
Quote:There's nothing magical about the sky that should prevent it from being occluded by fog.
Well... actually there is something very magical about the skybox... its not regular geometry its a tiny box rendered around the camera.

To have fog in the skybox you have to define how close to the camera the stuff in your skybox images are. If they are really far away the fog is different from if its close. Its harder if you have stuff that is close to the camera and far from the camera in the same skybox... how do we know what bits are far and what bits are close.

So with that in mind we did add the hacky 'fogBandHeight' to SkyBox where you can define the texture space 0 to 1 height of the fake fog to render to the skybox. It works in some situations... it depends on your skybox images.

The best method is to render your skybox correctly in the first place. If you rendered it with the right fog density and color it would work 100% pixel perfect. You should also make your sky match your scene lighting while your at it.

A skybox needs to be custom designed to fit your scene if you want things to look right.
#5
08/23/2009 (6:49 pm)
Quote:Well... actually there is something very magical about the skybox... its not regular geometry its a tiny box rendered around the camera.

Well that's a fantastic implementation detail Tom. Personally, when you set a value which is supposed to describe the density of fog... it should probably describe the density of fog. Last time I checked, fog is a 3 dimensional phenomenon.

How about, and I'm just thinking out loud here, you have the fog settings describe fog and have some other setting like visible distance describe the "we'd like to consider obscuring the really far away geometry by painting a solid color over it".

By the way, that junk doesn't even work because I've run into situations where the edges of that solid color flicker with the crap it's supposed to be hiding behind it.

Quote:So with that in mind we did add the hacky 'fogBandHeight' to SkyBox where you can define the texture space 0 to 1 height of the fake fog to render to the skybox. It works in some situations... it depends on your skybox images.

OK...

Quote:You should also make your sky match your scene lighting while your at it.


I forgot that overcast skies were a prerequisite for fog. Oh wait, they aren't. In fact fog has nothing to do with the sky at all. I guess that's where the magic happens.





#6
08/23/2009 (7:07 pm)
So to be more constructive.

Would it be feasible to implement a post effect that blended the fog color with the scene based on fog density and distance?
#7
08/23/2009 (7:19 pm)
What distance? There is no distance from the camera in terms of the skybox.

This is why you listen to Tom, and/or research how fog has been done for the last 15 years of game development.

#8
08/23/2009 (7:21 pm)
@Pat

What is the depth value of the G-Buffer at an area covered by sky?

#9
08/23/2009 (7:26 pm)
Far plane, but it has no height above terrain. There is no reliable way to make a correspondence between world space, and the skybox. It may be "max fog density" as far as distance, but location is where the problem is. It's not an actual volume which is represented in world space...it's not the mission area, or the visible distance; it's the skybox.

Painting fog into the skybox is the way to do this, but fog volumes are a totally different problem. A fog volume covers a definable volume in world space. The skybox is a cube of size = 1 with textures on it.
#10
08/23/2009 (7:37 pm)
Why can't I define the max distance that contributes to the fog effect, sample the depth buffer and calculate the amount of fog color to blend to that pixel?

If the fog extends 100m down a ray and I hit something at 50m I do the calculation based on density and 50m. If I hit the far plane I do the calculation based on density and 100m.

Would that work?

Edit..
Quote:but location is where the problem is. It's not an actual volume which is represented in world space...it's not the mission area, or the visible distance; it's the skybox.

I'm only interested in the quad that gets rendered to the screen.
#11
08/23/2009 (8:29 pm)
I tried to explain it to you and even told you about the hack 'fogBandHeight', but you think you know better.

So you have the source... prove me wrong and i'll add it to the code.

I'm jumping out of this thread until i see your implementation of fog.

Good luck. :)

#12
08/23/2009 (10:42 pm)
Fair Enough. Here's my first pass at it. The constants need work (fog distance, max value; haven't quite nailed down what I want there) but the shader works with one exception that you will see toward the end.

The problem with this one is that it seems the waterblock surface is not factored into the depth of the scene. For that reason when you pass the edge of my terrain there is a sharp transition.

Think I need to draw a ray to intersect "sea level" but I'm really not sure at this point.

Sorry it's 18 megs.

www.joshuahorns.com/FogTest-1.wmv


I wasn't familiar with the YouTube method and I wasn't sure if it was an NDA violation so I didn't put it up there.

Here's the shader.

If I misjudged the tone of your earlier reply I apologize.

//-----------------------------------------------------------------------------
// Torque 3D
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#include "shadergen:/autogenConditioners.h"
#include "./postFx.hlsl"
#include "./../torque.hlsl"

uniform sampler2D prepassTex : register(S0);
uniform sampler2D backBuffer : register(S1);
uniform float3    eyePosWorld;
uniform float4    fogColor;
uniform float3    fogData;
uniform float4    rtParams0;

float4 main( PFXVertToPix IN ) : COLOR
{   
   
   float FAR_PLANE = 1;
   float MAX_FOG_DISTANCE = .3;
   float MAX_FOG_DENSITY = .97;
   float depth = prepassUncondition( prepassTex, IN.uv0 ).w;
   float scale;
     
   if(depth >= FAR_PLANE)
   {
	  depth = depth * MAX_FOG_DISTANCE;
   }
 
   scale = saturate(depth/(1-MAX_FOG_DENSITY));
  
      
   float4 bbColor = tex2D(backBuffer, IN.uv0);
   float r = lerp(bbColor.r, fogColor.r, scale);
   float g = lerp(bbColor.g, fogColor.g, scale);
   float b = lerp(bbColor.b, fogColor.b, scale);
   
   return float4(r,g,b,1);  
}
#13
08/23/2009 (11:12 pm)
What you are describing is already how the fog posteffect works. The only difference is you are counting the sky ( pixels > 0.999 depth ) as full fog instead of no fog.

Translucent objects (like water) have to render their own fog, which they currently do. So if you change the equation for fog calculation in the posteffect then you should also change it in the water shaders.
#14
08/23/2009 (11:21 pm)
@James

I was going on the assumption that it was believed to be necessary to write the fog on the skybox via that variable described in some other posts above. My personal preference is for the type of fog effect you see in the movie (sky fogged out). I could be the only one but I didn't think it looked realistic the other way.

The brute force method for solving the waterblock issue could be to create terrain that stretches well beyond the mission area. This avoid the sharp transition between the waterblock on top of the terrain and the waterblock with no terrain below it (the problem you see at the end of the movie).

I don't mind how the fog works below water, I just wanted a different way to visualize the fog effect than the one you see in the first pic.
#15
08/23/2009 (11:29 pm)
Right, it breaks down in believability with very high fog density.

The problem is with a lower fog density you will end up with the reverse case. The terrain will look unfogged and the sky will still be completely fogged (because its infinitely far away).

I'm not sure I really follow what problem you have with the fogging on water (from above water). Is it that it has no depth if no terrain under it so it gets fully fogged over?

So long as your fog posteffect renders before water it should not be a problem. That is how it currently works.
#16
08/23/2009 (11:38 pm)
Here's a shot with max fog density at 0.

www.joshuahorns.com/unfogged.jpg
I tried rendering fog before water. It makes it so the fog does not overlay the water or vegetation.

The problem is (at the end of the movie) when I show the sharp boundary between water and fog. If I go past the end of the terrain and look straight down, instead of seeing water I see a gray abyss. I think the problem is it's taking the depth but seeing the far plane instead of the surface of the water. When it does this and calculates fog it gives me max fog.
#17
08/23/2009 (11:53 pm)
The current way it works is, fog happens after opaque objects and before transparent objects. It is up to transparent objects to self-fog.

If you want the fogging of transparent objects to match the new equation you have in your posteffect you need to change the water shader and probably also the fog "feature" that transparent objects use for shadergen materials.

This isn't really a trivial change, and the alternative to try rendering water and other transparent objects into depth is even harder.

If its going to be completely foggy and you'll never see the sky then you don't really even need a skybox right? Just set the canvas clear color to be your fog color, crank up the density, and problem solved right?
#18
08/24/2009 (12:03 am)
I think though I can vary fog by setting a single uniform in script to get the amount of fog I want. If I have to keep track of more than one thing at a time bad things happen.

I tried the skybox bandheight thing and it worked perfectly... I tried it before I wrote the shader. The way you guys wrote it works, it isn't intuitive (to me). I'm sure there's a good reason why things fog themselves, though that sounds slightly perverted, but I haven't learned that yet.


Thanks for the clarification.
#19
08/24/2009 (12:12 am)
Another random idea, you could hack an "overcast" field into SkyBox that grays it out gradually ( from 0 to 1 ).

Yeah translucent objects really do have to self-fog, they also have to self-light. Its a big problem with translucent objects in a deferred engine.
#20
08/24/2009 (6:57 am)
Hot damn, your first pass at it is looking pretty good, Josh! The fog drawn in front of the skybox looks slick. Nice video!
Page «Previous 1 2