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

📄 fluidrendering.fx

📁 游戏编程精粹6的光盘源代码
💻 FX
字号:
//=============================================================================
// fluidrendering.fx by Frank Luna (C) 2004 All Rights Reserved.
//=============================================================================


//*****************************************************************************
// Globals

uniform extern float4x4 gWorld;
uniform extern float4x4 gWorldInv;
uniform extern float4x4 gWVP;
uniform extern float3   gEyePosW;
uniform extern texture  gDispMap;
uniform extern texture  gRefractMap;
uniform extern texture  gReflectMap;
uniform extern texture  gNormMap0;
uniform extern texture  gNormMap1;
uniform extern float4   gTexOffsets;

static float3 gSpecMtrl     = {0.5f, 0.5f, 0.5f};
static float  gSpecPower    = 256.0f;
static float  gTransparency = 1.0f;

static float3 gAmbientLight = {0.4f, 0.4f, 0.4f};
static float3 gDiffuseLight = {1.0f, 1.0f, 1.0f};
static float3 gSpecLight    = {1.0f, 1.0f, 1.0f};
static float3 gLightVecW    = {0.0f, 0.4472f, -0.8944f};

//*****************************************************************************
// Texture Samplers

sampler gDispSmplr = sampler_state
{
    Texture   = <gDispMap>;
    MinFilter = POINT; 
    MagFilter = POINT;
    MipFilter = NONE;
    AddressU  = CLAMP;
    AddressV  = CLAMP;
};

sampler gRefractSmplr = sampler_state
{
    Texture   = <gRefractMap>;
    MinFilter = LINEAR; 
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU  = CLAMP;
    AddressV  = CLAMP;
};

sampler gReflectSmplr = sampler_state
{
    Texture   = <gReflectMap>;
    MinFilter = LINEAR; 
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU  = CLAMP;
    AddressV  = CLAMP;
};

sampler gNorm0Smplr = sampler_state
{
    Texture   = <gNormMap0>;
    MinFilter = LINEAR; 
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU  = WRAP;
    AddressV  = WRAP;
};

sampler gNorm1Smplr = sampler_state
{
    Texture   = <gNormMap1>;
    MinFilter = LINEAR; 
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU  = WRAP;
    AddressV  = WRAP;
};

//*****************************************************************************
// Vertex Shader

struct OutVS
{
    float4 posH     : POSITION0;
    float3 lightVecT: TEXCOORD0;
    float3 viewVecT : TEXCOORD1;
    float2 nmap0UV  : TEXCOORD2;
    float2 nmap1UV  : TEXCOORD3;
    float2 projUV   : TEXCOORD4;
    float  refractWt: TEXCOORD5;
};

OutVS GPUFluidRenderingVS(float3 posL : POSITION0, float2 uv : TEXCOORD0)
{
	OutVS outVS = (OutVS)0;
	
	// Sample heightmap for displacement.
	float4 data = tex2Dlod(gDispSmplr, float4(uv, 0.0f, 0.0f));
 
	posL.y = data.r;
	outVS.posH = mul(float4(posL, 1.0f), gWVP);
	
	// Build tangents and normal vectors.
	float3 xtan  = normalize(float3(1.0f, data.g, 0.0f));
	float3 ztan  = normalize(float3(0.0f, data.b, 1.0f));
	float3 normalL = normalize(cross(ztan, xtan));
	
	// Orthonormal basis.
	float3x3 tanBasis;
	tanBasis[0] = xtan;
	tanBasis[1] = normalL;
	tanBasis[2] = ztan;
	
	// Transforms from local space to tangent space.
	float3x3 tanBasisInv = transpose(tanBasis);
		
	// Get everything in local space.
	float3 lightVecL = mul(gLightVecW, (float3x3)gWorldInv);
	float3 eyePosL   = mul(float4(gEyePosW, 1.0f), gWorldInv).xyz;
	float3 viewVecL  = normalize(eyePosL - posL);

	// Refract based on view angle.
	float refractWt = pow(max(dot(viewVecL, normalL), 0.0f), 1.0f);
	
	// Refract based on height of camera from water plane.
	float3 posW = mul(float4(posL, 1.0f), gWorld);
	outVS.refractWt = max(0.0f, refractWt - 0.020f*abs(posW.y-gEyePosW.y));
	
	// Transform to tangent space.
	outVS.lightVecT = mul(lightVecL, tanBasisInv);
	outVS.viewVecT  = mul(viewVecL, tanBasisInv);
	
	// Scroll normal maps and scale for tiling.
	outVS.nmap0UV = (uv*2.0f) + gTexOffsets.xy;
	outVS.nmap1UV = (uv*2.0f) + gTexOffsets.zw;
	
	// Projection texture coordinates.
	outVS.projUV  = outVS.posH.xy / outVS.posH.w;

	// Transform to [0, 1].
	outVS.projUV.x = ((outVS.projUV.x * 0.49f) + 0.5f);
	outVS.projUV.y = ((outVS.projUV.y * -0.49f) + 0.5f);
	
    return outVS;
}

float4 GPUFluidRenderingPS(float3 lightVecT : TEXCOORD0,
                           float3 viewVecT : TEXCOORD1,
                           float2 nmap0UV : TEXCOORD2, 
                           float2 nmap1UV : TEXCOORD3, 
                           float2 projUV  : TEXCOORD4,
                           float refractWt : TEXCOORD5) : COLOR
{
	// Interpolated normals can become unnormal, so normalize them.
	lightVecT = normalize(lightVecT);
	viewVecT  = normalize(viewVecT);
	
 	// Swap z,y coords since normal map "up" is along z-axis.
	float3 n1 = tex2D(gNorm0Smplr, nmap0UV).xzy;
	float3 n2 = tex2D(gNorm1Smplr, nmap1UV).xzy;
	
	// Expand from [0, 1] compressed interval to true [-1, 1] interval.
    n1 = (n1 - 0.5f) * 2.0f;
    n2 = (n2 - 0.5f) * 2.0f;
	float3 normT  = normalize(0.5f*(n1+n2));
	
	// Sample texture maps.
	float4 c0 = tex2D(gReflectSmplr, projUV + (normT.xz*0.05f));
	float4 c2 = tex2D(gRefractSmplr, projUV + (normT.xz*0.05f));
	float3 color = (1.0f-refractWt)* c0 + (refractWt) * c2;
 
	// Do lighting.
	float3 ambient = color*gAmbientLight;
	float3 diffuse = max(dot(lightVecT, normT), 0.0f)*color*gDiffuseLight;
	
	float3 r = reflect(-lightVecT, normT);
	float  s = pow(max(dot(r, viewVecT), 0.0f), gSpecPower);
	float3 spec = s*gSpecMtrl*gSpecLight;
	
	return float4(ambient + diffuse + spec, gTransparency);
}

technique GPUFluidRenderingTech
{
    pass P0
    {
        vertexShader = compile vs_3_0 GPUFluidRenderingVS();
        pixelShader  = compile ps_3_0 GPUFluidRenderingPS();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -