⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 water.fx

📁 这也是一个游戏编程基础入门的事例!它是通过鼠标的移动改变照相机的仰角
💻 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 + -