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 Entdecke mehr on 28 de setembro de 2016 - 11:15 am

    Das verspreche ich ihnen.

  2. #2 by katana on 28 de setembro de 2016 - 11:42 am

    Exp茅dition rapide , article exactement comme d茅crit

  3. #3 by handmade katana on 28 de setembro de 2016 - 11:42 am

    Article exactement comme d脙 漏 crit … Envoi rapide et soign茅 . R茅p茅tera entreprise

  4. #4 by недвижими имоти бургас агенции on 28 de setembro de 2016 - 11:48 am

    After study a few of the blog posts on your website now, and I truly like your way of blogging. I bookmarked it to my bookmark website list and will be checking back soon. Pls check out my web site as well and let me know what you think.

  5. #5 by продажба на едностайни апартаменти софия on 28 de setembro de 2016 - 11:55 am

    There is noticeably a bundle to know about this. I assume you made certain nice points in features also.

  6. #6 by cold steel katana on 28 de setembro de 2016 - 12:39 pm

    Excellent shoe, thanks !

  7. #7 by Tommie Deadmond on 28 de setembro de 2016 - 1:24 pm

    Over and more than once more I like to think about this problems. As a matter of fact it wasn’t even a month ago that I thought about this really thing. To be honest, what will be the answer though?

  8. #8 by shock review on 28 de setembro de 2016 - 1:26 pm

    I possess the game and when I tried it on my computer, it was every broken up and crappy. I’m just thinking of buying a new pc anyway. Does anyone know of a computer in which the game is effective?.

  9. #9 by mspy premium on 28 de setembro de 2016 - 2:26 pm

    Now i am interested in style and I would like to start a blog but I have no idea where to begin or how to get people interested in my blog. Any concepts welcome..

  10. #10 by apply singapore pr on 28 de setembro de 2016 - 4:52 pm

    Nice. Thank you for your post!

  11. #11 by Naginata on 28 de setembro de 2016 - 5:09 pm

    Thanks! Great Product and shipping

  12. #12 by SAKABATO on 28 de setembro de 2016 - 5:09 pm

    Great transaction. Super fast shipping and great packing. Thanks!

  13. #13 by cool swords on 28 de setembro de 2016 - 5:23 pm

    Great transaction. Exp茅dition rapide superbe et grand emballage . Merci !

  14. #14 by katanas for sale on 28 de setembro de 2016 - 6:33 pm

    LOVE IT!!!!!!!!!

  15. #15 by Kelley on 28 de setembro de 2016 - 7:31 pm

  16. #16 by Wynajem Podnośników Teleskopowych Warszawa on 28 de setembro de 2016 - 9:24 pm

    I have recently started a site, the info you offer on this website has helped me greatly. Thank you for all of your time & work. “A physicist is an atom’s way of knowing about atoms.” by George Wald.

  17. #17 by budget on 28 de setembro de 2016 - 10:28 pm

    Every when inside a though we pick blogs that we study. Listed beneath would be the newest web-sites that we choose

  18. #18 by Click This Link on 29 de setembro de 2016 - 2:39 am

    tricare marriage counselor jacksonville fl

  19. #19 by Pressure Seal Gate Valve on 29 de setembro de 2016 - 4:25 am

    check below, are some absolutely unrelated web sites to ours, even so, they’re most trustworthy sources that we use

  20. #20 by wakizhasi on 29 de setembro de 2016 - 5:23 am

    Item as described. Timely shipping.

  21. #21 by recipes on 29 de setembro de 2016 - 8:44 am

    we came across a cool website that you may well enjoy. Take a search in the event you want

  22. #22 by Japanese Swords on 29 de setembro de 2016 - 9:17 am

    Chaussure telle que décrite . Opération facile , expédition rapide ! A + !

  23. #23 by pr application on 29 de setembro de 2016 - 10:12 am

    Nice post. Thank you.

  24. #24 by samurai katana on 29 de setembro de 2016 - 11:29 am

    Perfect description, fast shipping!!!!!

  25. #25 by sword cane on 29 de setembro de 2016 - 11:29 am

    love this shoe its huge very fast shipping

1 87 88 89
(não será publicado)