Sign in to follow this  
LudoDesign

HLSL Fog Shader

Recommended Posts

LudoDesign    100
Hello,

I am looking to make a fog shader in a game like Zelda. However, I would like the fog center on the player (and not on the camera) to mask the limit of the terrain. Player is defined by 2 coordinates X and Y (PlayerX and PlayerY). :blink:
I apply the following FX file but it does not seems to work the whole scene is bright white.

[code]float4x4 view_proj_matrix;
float PlayerX;
float PlayerY;
float StartRangeFog;
float EndRangeFog;
float radius;

struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 Txr1: TEXCOORD0;
float1 Fog: FOG;
};

VS_OUTPUT vs_main( float4 inPos: POSITION, float2 Txr1: TEXCOORD0)
{
VS_OUTPUT Out;
float4 Pos = mul(view_proj_matrix, inPos);
Out.Pos = Pos;
Out.Txr1 = Txr1;
radius=sqrt(pow(inPos.x-PlayerX,2)+pow(inPos.y-PlayerY,2));
Out.Fog = clamp((radius-StartRangeFog)/(EndRangeFog-StartRangeFog),0,1);
return Out;
}

technique Simplest
{
pass P0
{
VertexShader = compile vs_1_1 vs_main();
//PixelShader = compile ps_2_0 Texture();
}
}[/code]


Do you know what is wrong ?
I am kind of new at HLSL shaders. Many thanks in advance for your help ! :D

Share this post


Link to post
Share on other sites
Juliean    7077
Your calculations seems wrong to me. Where did you get these formulas from? Try that:

[url="http://msdn.microsoft.com/en-us/library/bb173401%28v=vs.85%29.aspx"]http://msdn.microsoft.com/en-us/library/bb173401%28v=vs.85%29.aspx[/url]

My fog-shader, based on these calculations, looks like this:

[code] float3 vCameraDir = CameraPos - VertexPosition;

float4 Color float4(lerp(color,float4(0.5, 0.5, 0.5f, 1.0f),saturate((length(vCameraDir)-10.0f)/(100.0f-10.0f))), 1.0f);[/code]

Share this post


Link to post
Share on other sites
Hodgman    51334
Firstly - if you write "[font="Courier New"]Out.Fog = 0;[/font]" at the end, does the shader work (but with no fog visible)?

I don't think this is related to your problem, but [font="Courier New"]radius[/font] should be a local variable inside [font="Courier New"]vs_main[/font], not a global variable.

Are you using this effect file on just the world/environment?

How large are the values of StartRangeFog/EndRangeFog compared to the range of values in your vertex positions?
Likewise, what kind of values do PlayerX/PlayerY have compared to the vertex positions?

[hr]Some HLSL tips:
Instead of:
[font="Courier New"]radius=sqrt(pow(inPos.x-PlayerX,2)+pow(inPos.y-PlayerY,2));[/font]
You can write:
[font="Courier New"]radius=distance(inPos.xy, float2(PlayerX,PlayerY));[/font]
Or ideally:
[font="Courier New"]float2 PlayerXY;[/font]
[font="Courier New"]...[/font]
[font="Courier New"]radius=distance(inPos.xy, PlayerXY);[/font]

Also, with your fog calculation you can use saturate instead of clamp, and the subtraction operation (end-start) should be done on the CPU and the result put into your shader:
[font="Courier New"]float StartRangeFog;[/font]
[font="Courier New"]float RangeFog;//this is (end - start)[/font]
[font="Courier New"]...[/font]
[font="Courier New"]Out.Fog = saturate((radius-StartRangeFog) / RangeFog);[/font]

Share this post


Link to post
Share on other sites
LudoDesign    100
Many thanks for your help ! :lol:

The solution was this one :

[code]float4x4 matWorldViewProj;
float4x4 matWorld;
float4x4 matWorldIT;
float4 AmbientColor;
float4 PlayerPos;
float AmbientIntensity = 0.6;
float StartFog = 112;
float4 ColorFog = {0.96,0.96,0.96,1};
float3 LightDirection = {1,1,1};

struct VS_INPUT

{
float4 Position : POSITION;
float3 Normal : NORMAL;
};



struct VS_OUTPUT

{
float4 Position: POSITION;
float3 Light : TEXCOORD0;
float3 Normal : TEXCOORD1;
float Fog: FOG;
};

VS_OUTPUT vs_main(VS_INPUT In)
{
VS_OUTPUT Out;
Out.Position = mul(In.Position, matWorldViewProj);
Out.Light = normalize(LightDirection);
Out.Normal = normalize(mul(matWorld,In.Normal));
float4 PlayerPosWorld = mul(PlayerPos, matWorld);

float DistFog = distance(In.Position.xy, PlayerPosWorld.xy);
Out.Fog = saturate(exp((StartFog-DistFog)*0.33));
return Out;
}

struct PS_OUTPUT
{
float4 Color : COLOR;
};

PS_OUTPUT ps_main(VS_OUTPUT In) : COLOR
{
PS_OUTPUT Out;
float4 ColorBase = saturate(AmbientIntensity * AmbientColor+dot(In.Light,In.Normal));
Out.Color = lerp(ColorFog, ColorBase, In.Fog);
return Out;
}

technique Simplest
{
pass P0
{
VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main();
}
}[/code]

However, it works for the fog but result in terms of material is ugly. I am still working to implement Phong/Bump effect.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this