Code Snippet : Fog Shader


In this code snippet we are going to show some simple ways to create a fog like effect in 3D games.
The fog effect is a post process (operates on a full screen quad) that recieves the framebuffer texture (the one with the game rendered content) and a depth texture as main parameters.
The depth texture (used normally in deferred shading) contains the post projected Z/W coordinate of all objects (the Z buffer content actually =P).


To generate it, you can use the following shader in all objects of your scene (prefer rendering it to a single 32 bits texture for better precision)

float4x4 WVP;

struct VertexToPixel
{
	half4 Position		: POSITION;
	half2 ScreenPos			: TEXCOORD0;
};
struct PixelToFrame
{
	half4 Color 			: COLOR0;
};

VertexToPixel MyVertexShader(half4 inPos: POSITION0)
{
	VertexToPixel Output = (VertexToPixel)0;
	Output.Position = mul(inPos, WVP);
	Output.ScreenPos = Output.Position .zw;
	return Output;	

}

PixelToFrame MyPixelShader(VertexToPixel PSIn) : COLOR0
{
	PixelToFrame Output = (PixelToFrame)0;
	Output.Color = PSIn.ScreenPos.x/PSIn.ScreenPos.y;
	return Output;
}

technique Depth
{
	pass Pass0
    {
    	VertexShader = compile vs_2_0 MyVertexShader();
        PixelShader  = compile ps_2_0 MyPixelShader();
    }
}

It just output the z/w of each rendered “pixel”. The post process shader that creates the fog effect is:

float2 halfPixel;
float dz;
float4x4 InvertViewProjection;
float3 cameraPosition;
float far;
float near;
float3 fcolor = {0.5, 0.5, 0.5};

texture cena;
sampler cenaSampler = sampler_state
{
   Texture = ;
   AddressU  = Clamp;
   AddressV  = Clamp;
};

texture depth;
sampler depthSampler = sampler_state
{
   Texture = ;
   MinFilter = POINT;
   MagFilter = POINT;
   MipFilter = POINT;
   AddressU  = Clamp;
   AddressV  = Clamp;
};
struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
};
VertexShaderOutput VShader( float4 Pos: POSITION, float2 Tex : TEXCOORD)
{
	VertexShaderOutput output;
	Pos.x =  Pos.x - 2*halfPixel.x;
	Pos.y =  Pos.y + 2*halfPixel.y;
    output.Position = float4(Pos);
    output.TexCoord = Tex;
    return output;
}

float4 Pshader(VertexShaderOutput input) : COLOR
{
    float depthVal = tex2D(depthSampler,input.TexCoord).r;
    float3 cen = tex2D(cenaSampler ,input.TexCoord );

    //compute screen-space position
    float4 position;
    position.x = input.TexCoord.x * 2.0f - 1.0f;
    position.y = -(input.TexCoord.x * 2.0f - 1.0f);
    position.z = depthVal;
    position.w = 1.0f;
    //transform to world space
    position = mul(position, InvertViewProjection);
    position /= position.w;

	float d = length(position - cameraPosition);
	float l = saturate((d-near)/(far-near));
    return float4(lerp(cen,fcolor, l),1);
}

float4 PixelShaderExponencial(VertexShaderOutput input) : COLOR
{
    float depthVal = tex2D(depthSampler,input.TexCoord).r;
    float3 cen = tex2D(cenaSampler ,input.TexCoord );

    //compute screen-space position
    float4 position;
    position.x = input.TexCoord.x * 2.0f - 1.0f;
    position.y = -(input.TexCoord.y * 2.0f - 1.0f);
    position.z = depthVal;
    position.w = 1.0f;
    //transform to world space
    position = mul(position, InvertViewProjection);
    position /= position.w;

	float d = length(position - cameraPosition);
	float l = exp(-d * dz);
	l = saturate(1 - l);

    return float4(lerp(cen,fcolor, l),1);
}

float4 PixelShaderExponencialSquared(VertexShaderOutput input) : COLOR
{
    float depthVal = tex2D(depthSampler,input.TexCoord).r;
    float3 cen = tex2D(cenaSampler ,input.TexCoord );

    //compute screen-space position
    float4 position;
    position.x = input.TexCoord.x * 2.0f - 1.0f;
    position.y = -(input.TexCoord.y * 2.0f - 1.0f);
    position.z = depthVal;
    position.w = 1.0f;
    //transform to world space
    position = mul(position, InvertViewProjection);
    position /= position.w;

	float d = length(position - cameraPosition);
	float l = exp( - pow( d * dz , 2 ) );
	l = saturate(1 - l);

    return float4(lerp(cen,fcolor, l),1);
}

technique FogShader
{
	pass P0
	{
		VertexShader = compile vs_3_0 VShader();
		PixelShader = compile ps_3_0 Pshader();
	}
}

technique FogExponencialSquaredShader
{
	pass P0
	{
		VertexShader = compile vs_3_0 VShader();
		PixelShader = compile ps_3_0 PixelShaderExponencialSquared();
	}
}

technique FogExponencialShader
{
	pass P0
	{
		VertexShader = compile vs_3_0 VShader();
		PixelShader = compile ps_3_0 PixelShaderExponencial();
	}
}

The idea is very simple and naive, we just blend the scene color with the fog color using the scene distance (from depth texture) as a control parameter.
All the parameter used in the shaders are self explanatory (camera position, near plane, far plane …..). The only strange one is the dz (density) that we normally set to 0.001f.
The halfpixel is a directx 9c stuff (correction needed because of the directx rasterizer algorithm, in directx > 9c, this is not needed) and can be calculated in the following way (in XNA):

 Vector2 halfPixel = new Vector2()
            {
                X = 0.5f / (float)game.GraphicsDevice.PresentationParameters.BackBufferWidth,
                Y = 0.5f / (float)game.GraphicsDevice.PresentationParameters.BackBufferHeight
            };
           

We showed three ways of doing this (normal, exponencial and exponencial squared), you can choose each of then according with you quality/speed trade off.

, , ,

  1. #1 by Ariel Backstrom on 27 de agosto de 2016 - 5:37 am

    buy facebook cheap

  2. #2 by Milford Humphrey on 27 de agosto de 2016 - 5:39 am

    check out this page

  3. #3 by samurai in japanese on 27 de agosto de 2016 - 7:17 am

    Fast shipping, great product!!

  4. #4 by SATTA MATKA RESULT on 27 de agosto de 2016 - 9:06 am

    Every once in a though we select blogs that we read. Listed below are the most current sites that we pick out

  5. #5 by japanese katana swords on 27 de agosto de 2016 - 3:22 pm

    Grand vendeur . Expédition rapide. Des prix raisonnables

  6. #6 by lustig Post on 27 de agosto de 2016 - 3:28 pm

    Sie bearbeite sie kräftig und feuchte muschis umschloss sie mit den Lippen.

  7. #7 by iklan baris gratis on 27 de agosto de 2016 - 4:36 pm

    Well I truly liked studying it. This subject provided by you is very useful for accurate planning.

  8. #8 by ciagniki massey ferguson on 27 de agosto de 2016 - 5:40 pm

    Thank you for sharing excellent informations. Your website is so cool. I’m impressed by the details that you have on this web site. It reveals how nicely you perceive this subject. Bookmarked this web page, will come back for extra articles. You, my pal, ROCK! I found just the info I already searched all over the place and just could not come across. What a great web-site.

  9. #9 by Constance Tropea on 27 de agosto de 2016 - 7:56 pm

    Hello. magnificent job. I did not imagine this. This is a excellent story. Thanks!

  10. #10 by Gun Control on 28 de agosto de 2016 - 7:10 am

    This website is amazing. I will tell about it to my friends and anybody that could be interested in this subject. Great work guys!

  11. #11 by Marinda Pleiss on 28 de agosto de 2016 - 10:22 am

    I am curious to find out what blog platform you have been utilizing? I’m having some small security issues with my latest blog and I’d like to find something more risk-free. Do you have any suggestions? lords mobile free gems

  12. #12 by podziekowania dla gosci na komunii on 28 de agosto de 2016 - 1:50 pm

    Real nice design and good content , nothing at all else we want : D.

  13. #13 by Optiline at bdomains.com on 28 de agosto de 2016 - 4:47 pm

    very good put up, i actually love this web site, keep on it

  14. #14 by bdomains optiline.lv on 28 de agosto de 2016 - 5:29 pm

    I like what you guys are up too. Such clever work and reporting! Carry on the excellent works guys I have incorporated you guys to my blogroll. I think it’ll improve the value of my site :).

  15. #15 by http://www.torontosrealestateagent.ca on 28 de agosto de 2016 - 5:36 pm

    756027 585205Right after examine a couple of with the weblog posts inside your site now, and I truly like your manner of blogging. I bookmarked it to my bookmark site list and may well be checking back soon. Pls take a appear at my site as effectively and let me know what you believe. 111569

  16. #16 by der vollständige Bericht on 28 de agosto de 2016 - 9:41 pm

    85 e manchmal auch 85 f je nachdem wie der BH aus fällt.

  17. #17 by r4 3ds on 29 de agosto de 2016 - 4:01 am

    Enjoyed every bit of your article.Much thanks again. Awesome.

1 70 71 72
(não será publicado)