www.pudn.com > SnowAccumulation.zip > Snow.fx, change:2007-08-14,size:8792b
//--------------------------------------------------------------------------------------
// File: BasicVTF.fx
//
// The effect file for the BasicVTF sample.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
#define FPTYPE half
#define FPTYPE2 half2
#define FPTYPE3 half3
#define FPTYPE4 half4
float4 g_MaterialDiffuseColor; // Material's diffuse color
float3 g_LightDir; // Light's direction in world space
float4 g_LightDiffuse; // Light's diffuse color
float4 g_LightAmbient; // Light's ambient color
float4x4 g_mWorld; // World matrix for object
float4x4 g_mWorldIT;
float4x4 g_mWorldView;
float4x4 g_mViewProj;
float4x4 g_mProjection;
float4x4 g_mWorldViewProjection; // World * View * Projection matrix
float4x4 g_mViewInverse;
float3 g_upObjectSpace;
float4 g_SnowColor;
float SceneWidth;
float SceneHeight;
float OffsetAmount = 0;
float SampleDistance = 0;
float BaseSnowPct = 0.4;
float SpecExpon = 120.0;
float Ks = 0.26;
float Bumpy = 1.0;
float Kd = 0.9;
float SnowBias = 0.02;
float4x4 g_mExposureWorldViewOrthoProj;
float normalDistortionAmount = 0.1;
float dotNormalDistortionAmount = 0.2;
//--------------------------------------------------------------------------------------
// Textures & samplers
//--------------------------------------------------------------------------------------
texture g_pTerrainTexture; // Color texture for mesh
texture g_ExposureDepthMapTexture; // Color texture for mesh
texture g_Noise3D;
sampler MeshTextureSampler =
sampler_state
{
Texture = <g_pTerrainTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
sampler ExposureDepthMapSampler =
sampler_state
{
Texture = <g_ExposureDepthMapTexture>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = POINT;
MAGFILTER = POINT;
};
sampler ExposureDepthMapSamplerPixel =
sampler_state
{
Texture = <g_ExposureDepthMapTexture>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
sampler NoiseSampler =
sampler_state
{
Texture = <g_Noise3D>;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
// Rather than stick everything in this file, pulled some util functions out into other files.
#define EXPOSURESAMPLER_VERTEX ExposureDepthMapSampler
#define EXPOSURESAMPLER_PIXEL ExposureDepthMapSamplerPixel
#define NOISESAMPLER NoiseSampler
#define NOISEOCTAVES 3.0
#include "SnowShaderUtils.fxh"
//--------------------------------------------------------------------------------------
// Vertex shader output structure
//--------------------------------------------------------------------------------------
struct VS_OUTPUT
{
float4 Position : POSITION; // vertex position
float2 TextureUV : TEXCOORD0; // vertex texture coords
float3 Normal : TEXCOORD1; // vertex normal
float3 OrthoUVnDepth : TEXCOORD2;
float3 ToView : TEXCOORD3;
};
VS_OUTPUT RenderSceneVS_NoSnow( float4 vPos : POSITION,
float3 vNormal : NORMAL,
float2 vTexCoord0 : TEXCOORD0)
{
VS_OUTPUT Output;
float3 vNormalWorldSpace;
vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorldIT)); // normal (world space)
// Transform the position from world space to homogeneous projection space
Output.Position = mul(vPos, g_mWorldViewProjection);
Output.Normal = 0.5*vNormalWorldSpace+float3(0.5,0.5,0.5);
// Just copy the texture coordinate through
Output.TextureUV = vTexCoord0;
Output.OrthoUVnDepth=float3(0,0,0);
float4 wsP = mul(vPos,g_mWorld);
Output.ToView = (0.5*normalize(g_mViewInverse[3].xyz - wsP))+0.5.xxx; // obj coords
return Output;
}
VS_OUTPUT RenderSceneVS_SM20( float4 vPos : POSITION,
float3 vNormal : NORMAL,
float2 vTexCoord0 : TEXCOORD0)
{
VS_OUTPUT Output;
float3 vNormalWorldSpace;
Output = RenderSceneVS_NoSnow(vPos,vNormal,vTexCoord0);
// $ Vertex texture is used to pull out the exposure of the point
float4 orthoPos = mul(vPos,g_mExposureWorldViewOrthoProj);
orthoPos.y *= -1; // UV coords have an inverted Y axis
float2 uv = 0.5*orthoPos.xy + float2(0.5,0.5);
Output.OrthoUVnDepth = float3(uv,orthoPos.z);
return Output;
}
VS_OUTPUT RenderSceneVS_SM30( float4 vPos : POSITION,
float3 vNormal : NORMAL,
float2 vTexCoord0 : TEXCOORD0)
{
VS_OUTPUT Output;
float3 vNormalWorldSpace;
// $ Vertex texture is used to pull out the exposure of the point
float4 orthoPos = mul(vPos,g_mExposureWorldViewOrthoProj);
orthoPos.y *= -1; // UV coords have an inverted Y axis
float2 uv = 0.5*orthoPos.xy + float2(0.5,0.5);
Output.OrthoUVnDepth = float3(uv,orthoPos.z);
float XSD = SampleDistance/SceneWidth;
float YSD = SampleDistance/SceneHeight;
float exposure = 0;
// current position
exposure += exposureAtVertex(uv,orthoPos.z);
// A box around us. Capped to 3 more, since only 4 VTF per VS...
exposure += exposureAtVertex(uv+float2(XSD,YSD),orthoPos.z);
exposure += exposureAtVertex(uv+float2(-XSD,YSD),orthoPos.z);
exposure += exposureAtVertex(uv+float2(0,-YSD),orthoPos.z);
exposure /= 4;
// $ Note these two operations are independant of depth, so mask load lag.
// Transform the normal from object space to world space
vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorldIT)); // normal (world space)
float normalDotUp = saturate(dot(vNormalWorldSpace,float3(0,1,0)));
// exposure = exposure*pow(normalDotUp,10);
exposure = exposure*normalDotUp;
// $ Offset the vertex a little if it is accumulating snow
float4 wsP = mul(vPos,g_mWorld);
float4 wsP2 = float4(wsP.xyz + OffsetAmount*exposure*vNormalWorldSpace,vPos.w);
// Transform the position from world space to homogeneous projection space
Output.Position = mul(wsP2, g_mViewProj);
Output.Normal = 0.5*vNormalWorldSpace+float3(0.5,0.5,0.5);
// Just copy the texture coordinate through
Output.TextureUV = vTexCoord0;
Output.ToView = (0.5*normalize(g_mViewInverse[3].xyz - wsP))+0.5.xxx; // obj coords
return Output;
}
float4 RenderScenePS_NoSnow( VS_OUTPUT In ) : COLOR
{
FPTYPE3 vNormalWorldSpace = (2*In.Normal)-FPTYPE3(1,1,1);
FPTYPE3 Vn = normalize(2*In.ToView-1);
FPTYPE3 Hn = normalize(Vn + g_LightDir);
FPTYPE hdn = dot(Hn,vNormalWorldSpace);
FPTYPE ldn = dot(g_LightDir,vNormalWorldSpace);
FPTYPE4 litVec = lit(ldn,hdn,SpecExpon);
FPTYPE3 diffContrib = litVec.y * g_LightDiffuse;
FPTYPE3 specContrib = ((litVec.y * litVec.z * Ks) * g_LightDiffuse);
// choose a color based on exposure
FPTYPE3 diffuseColor = tex2D(MeshTextureSampler, In.TextureUV);
FPTYPE diffuseSpec = saturate(g_LightAmbient+Kd)*diffContrib+Ks*specContrib;
return float4(diffuseColor.xyz*(diffuseSpec),1);
}
float4 RenderScenePS( VS_OUTPUT In) : COLOR
{
return SnowPixel(In.TextureUV,In.Normal,In.OrthoUVnDepth,In.ToView,true,true,true);
}
//--------------------------------------------------------------------------------------
// Renders scene to render target
//--------------------------------------------------------------------------------------
technique RenderScene_SM20
{
pass P0
{
VertexShader = compile vs_2_0 RenderSceneVS_SM20();
PixelShader = compile ps_2_a RenderScenePS();
}
}
technique RenderScene_SM30
{
pass P0
{
VertexShader = compile vs_3_0 RenderSceneVS_SM30();
PixelShader = compile ps_3_0 RenderScenePS();
}
}
technique RenderScene_NoSnow
{
pass P0
{
VertexShader = compile vs_3_0 RenderSceneVS_NoSnow();
PixelShader = compile ps_3_0 RenderScenePS_NoSnow();
Cullmode=none;
}
}