📄 water.fx
字号:
//水波的实现
//2009.3.20
//neo
//采用法线贴图与环境贴图
struct Mtrl
{
float4 ambient;
float4 diffuse;
float4 specular;
float specPower;
};
struct DirLight
{
float4 ambient;
float4 diffuse;
float4 specular;
float3 direction;
};
texture g_texEnv;
texture g_texNormal1;
texture g_texNormal2;
Mtrl g_mtrl;
DirLight g_light;
float4x4 g_world;
float4x4 g_invWorld;
float4x4 g_WVP;
float3 g_eyePosW;
float2 g_waveOffset1;
float2 g_waveOffset2;
float g_texScale;
sampler EnvMap = sampler_state
{
Texture = <g_texEnv>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
sampler Normal1 = sampler_state
{
Texture = <g_texNormal1>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
sampler Normal2 = sampler_state
{
Texture = <g_texNormal2>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
struct VSOut
{
float4 posH: POSITION0;
float2 tex0: TEXCOORD0; //法线1
float2 tex1: TEXCOORD1; //法线2
float3 lightDirT: TEXCOORD2; //light direction in tangent space
float3 toEyeT:TEXCOORD3; //vector to eye in tangent space
float3 toEyeW: TEXCOORD4; //用于环境贴图
//float3 normalW: TEXCOORD5;
};
static float3 T = float3(1.0f,0.0f,0.0f);
static float3 B = float3(0.0f,0.0f,-1.0f);
static float3 N = float3(0.0f,1.0f,0.0f);
VSOut VS(float3 posL:POSITION0,float2 tex0:TEXCOORD0)
{
VSOut V = (VSOut)0;
V.posH = mul(float4(posL,1.0f),g_WVP);
float3x3 TBN;
TBN[0] = T;
TBN[1] = B;
TBN[2] = N;
float3x3 toTangentSpace = transpose(TBN);
//计算toEyeT
float3 eyePosL = mul(float4(g_eyePosW,1.0f),g_invWorld).xyz;
float3 toEyeL = normalize(eyePosL - posL);
V.toEyeT = mul(toEyeL,toTangentSpace);
//lightDirT
float3 dirL = mul(float4(g_light.direction,0.0f),g_invWorld).xyz;
V.lightDirT = mul(dirL,toTangentSpace);
//计算纹理坐标
float2 tex = tex0 * g_texScale;
V.tex0 = tex0 + g_waveOffset1;
V.tex1 = tex0 + g_waveOffset2;
float3 posW = mul(float4(posL,1.0f),g_world);
//V.normalW = mul(float4(0.0f,1.0f,0.0f,0.0f),g_world).xyz;
V.toEyeW = g_eyePosW - posW;
return V;
}
float4 PS(float2 tex0: TEXCOORD0,float2 tex1: TEXCOORD1,
float3 lightDirT: TEXCOORD2,float3 toEyeT: TEXCOORD3,
float3 toEyeW: TEXCOORD4): COLOR
{
//从法线贴图中获取法线
float3 normalT1 = tex2D(Normal1,tex0).xyz;
float3 normalT2 = tex2D(Normal2,tex1).xyz;
//transform to [-1,1]
normalT1 = normalT1 * 2.0f - 1.0f;
normalT2 = normalT2 * 2.0f - 1.0f;
//平均法向量
float3 averNormalT = normalize(0.5f*(normalT1 + normalT2));
//计算环境反射
float3 normalW = float3(0,1.0f,0.0f); //假设水面始终与地平面平行
toEyeW = normalize(toEyeW);
float3 rEnv = reflect(-toEyeW,normalW) + 0.4f*averNormalT;
float3 reflectColor = texCUBE(EnvMap,rEnv).rgb;
//混合反射分量与物体材质
float blendFactor = 0.5f;
float3 ambientMtrl = blendFactor*reflectColor + (1-blendFactor)*g_mtrl.ambient;
float3 diffuseMtrl = blendFactor*reflectColor + (1-blendFactor)*g_mtrl.diffuse;
//环境光
float3 ambient = g_light.ambient.rgb * ambientMtrl;
//漫射光
lightDirT = normalize(lightDirT);
float d = max(dot(-lightDirT,averNormalT),0);
float3 diffuse = d * (g_light.diffuse.rgb * diffuseMtrl);
//镜面光
toEyeT = normalize(toEyeT);
float3 r = reflect(lightDirT,averNormalT); //反射向量
float s = pow(abs(max(dot(r,toEyeT),0)),g_mtrl.specPower);
if(d<= 0.0f)
s = 0.0f;
float3 specular = s * (g_light.specular * g_mtrl.specular).rgb;
float3 finalColor = ambient + diffuse + specular;
return float4(finalColor,g_mtrl.diffuse.a);
}
technique Tech
{
pass P0
{
vertexShader = compile vs_2_0 VS();
pixelShader = compile ps_2_0 PS();
AlphaBlendEnable = True;
SrcBlend = SrcAlpha ;
DestBlend = InvSrcAlpha;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -