Hi,
here is the full code. I try to add a function so that the heigh of the fog changes slightly, but i think if it´s too much you will see that it is a faked "volumetric" fog.
Interactive fog is just behind my knowledge, perhaps further.
Code:
material stone_tga
{
// Define your bitmaps as skins
skin1 = alphamap;
skin2 = effectmap;
effect
"
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Define your needed values
float4x4 matWorldViewProj; //
float4x4 matWorldView; //
float4x4 matWorld; // entity position/direction
float4 vecFog; // fog parameters
float4 vecViewPos; //
float4 vecTime; //
// Define your textures
texture entSkin1; // level texture
texture entSkin2; // shadow texture
texture mtlSkin1; // alpha texture
texture mtlSkin2; // effect texture
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Texture settings
sampler sBase = sampler_state // level texture
{
Texture = <entSkin1>; // Give your texture here
MipFilter = Linear; // None | Point | Linear | Anisotropic | PyramidalQuad | GaussianQuad
MinFilter = Linear;
MagFilter = Linear;
AddressU = Wrap; // Wrap | Mirror | Clamp | Border | MirrorOnce
AddressV = Wrap;
AddressW = Wrap;
BorderColor = {255, 0, 0, 0}; // Color for AddressUVW with Border
};
sampler sShadow = sampler_state // shadow texture
{
Texture = <entSkin2>;
MipFilter = Linear;
MinFilter = Linear;
MagFilter = Linear;
AddressU = Wrap;
AddressV = Wrap;
};
sampler sAlpha = sampler_state // alpha texture
{
Texture = <mtlSkin1>;
MipFilter = Linear;
MinFilter = Linear;
MagFilter = Linear;
AddressU = Wrap;
AddressV = Wrap;
};
sampler sGrass = sampler_state // grass texture
{
Texture = <mtlSkin2>;
MipFilter = Linear;
MinFilter = Linear;
MagFilter = Linear;
AddressU = Wrap;
AddressV = Wrap;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Input and output structs
//
// Possible input values for vertexshader
//
// POSITION[n] position
// BLENDWEIGHT[n] blend weights
// BLENDINDICES[n] blend indices
// NORMAL[n] normal vector
// PSIZE[n] point size
// COLOR[n] diffuse and specular color
// TEXCOORD[n] texture coordinates
// TANGENT[n] tangent
// BINORMAL[n] binormal
// TESSFACTOR[n] tessellation factor
//
// Possible output values for vertexshader
//
// POSITION Position
// PSIZE Point size
// FOG Vertex fog
// COLOR[n] Color (example: COLOR0)
// TEXCOORD[n] Texture coordinates (example: TEXCOORD0)
//
//
// Possible input values for pixelshader
//
// COLOR[n] diffuse and specular color
// TEXCOORD[n] texture coordinates
//
// Possible output values for pixelshader
//
// COLOR[n] diffuse and specular color
// TEXCOORD[n] texture coordinates
// DEPTH[n] Depth (example: DEPTH0)
//
// Define the input of your vertexshader
struct VS_IN
{
float4 Pos : POSITION;
float2 Shadow : TEXCOORD0;
float2 Base : TEXCOORD1;
float2 Alpha : TEXCOORD2;
float2 Grass : TEXCOORD3;
};
// Define the output of your vertexshader
struct VS_OUT
{
float4 Pos : POSITION;
float2 Shadow : TEXCOORD0; // Shadow is binded to TEXCOORD0, so it get transported to the pixelshader
float2 Base : TEXCOORD1;
float2 Alpha : TEXCOORD2;
float2 Grass : TEXCOORD3;
float Fog : FOG;
};
// Define the input for your pixelshader
struct PS_IN
{
float2 Shadow : TEXCOORD0; // The ouput of the vertexshader is given through TEXCOORD0
float2 Base : TEXCOORD1;
float2 Alpha : TEXCOORD2;
float2 Grass : TEXCOORD3;
};
// Define the output for your pixelshader
struct PS_OUT
{
float4 Color : COLOR; // We only give a color value back
};
//////////////////////////////////////////////////////////////////////////////////////////////////////
// functions
float4 sfInvert( float4 value )
{
return 1 - value;
}
float4 sfNegate( float4 value )
{
return - value;
}
float4 sfSepia( float4 value )
{
float4 vGrey = float4( 0.3, 0.59, 0.11, 0 );
float4 vSepia = float4( 0.9, 0.70, 0.30, 1 );
return dot( value, vGrey) * vSepia;
}
float4 sfGrey( float4 value )
{
float4 vBW = float4( 0.3, 0.59, 0.11, 0 );
return dot( value, vBW);
}
float4 sfBlackWhite( float4 value, float level) // PS 1.4
{
float4 vBW = float4( 0.3, 0.59, 0.11, 0 );
value = dot( value, vBW );
value = 1 - step( value, level );
return value;
}
float4 sfPosterize( float4 value, float level ) // PS 1.4
{
if ( value.r < level ) value.r = 0; else value.r *= 1.0f;
if ( value.g < level ) value.g = 0; else value.g *= 1.0f;
if ( value.b < level ) value.b = 0; else value.b *= 1.0f;
return value;
}
float AddFog(float3 Pos)
{
float value;
float3 P = mul( Pos, matWorld );
value = 1 - ( distance( P, vecViewPos ) - vecFog.x ) * vecFog.z;
return value;
}
float _AddSoilFog(float3 Pos)
{
float value;
float3 P = mul( Pos, matWorld );
value = 1 - ( distance( P, vecViewPos ) - vecFog.x ) * vecFog.z;
//value = value + ( P.y / 60 ) * (1 - ( distance( P, vecViewPos ) - vecFog.x ) * vecFog.z) / 16;
value = value + ( P.y / 60 );
return value;
}
float AddSoilFog(float3 Pos)
{
float value;
float low;
float high;
float3 P = mul( Pos, matWorld );
high = 1 - ( distance( P, vecViewPos ) - vecFog.x ) * vecFog.z;
low = ( P.y / 30 ); // min. low fog
value = lerp( high, low, 0.2); // mixing high and low fog
return value;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
// vertexshader
VS_OUT vs( VS_IN In )
{
VS_OUT Out = ( VS_OUT ) 0; // Declare your output
Out.Pos = mul( In.Pos, matWorldViewProj ); // Transform the ouput to the view
Out.Shadow = In.Shadow; // Get the shadow texture for the current position
Out.Base = In.Base; // Get the level texture for the current position
Out.Alpha = In.Base; // Cause alpha/grass texture have no current positions (they ar not applied to level geo)
Out.Grass = In.Base; // we use the positions of the level texture
Out.Alpha.y = In.Base.y - 0.5; // Shift the alpha to the bottom
Out.Fog = AddSoilFog( In.Pos );
return Out;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
// pixelshader
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
float4 shadow;
float4 alpha;
float4 grass;
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
shadow = tex2D( sShadow, In.Shadow.xy ); // ..
alpha = tex2D( sAlpha, In.Alpha.xy ); // ..
grass = tex2D( sGrass, In.Grass.xy ); // ..
color = lerp( color, grass, alpha); // Interpolates between color and grass via alpha
color = color * shadow; // and apply the shadow
Out.Color = color; // Write the output
return Out; // and give it back
// For more functions like tex2D or lerp take a look at
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/highlevellanguageshaders/intrinsicfunctions/intrinsicfunctions.asp
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
technique test
{
// Define your passes
pass p0
{
// Compile your shaders
VertexShader = compile vs_1_0 vs();
PixelShader = compile ps_1_0 ps();
}
}
";
}