//--------------------------------------------------------------------------- // Flight Simulator X - Shader Effect Files // Copyright (c) 2006, Microsoft Corporation //--------------------------------------------------------------------------- #include <Common.fxh> #include <MaterialDecl.fxh> #include <D3D9Texture.fxh> #include <FuncLibrary.fxh> #define vLightDir vSunVectorWorld // Potential textures texture Water_BaseTexture : MATERIAL_BASE_TEXTURE; texture Water_EnvTexture : MATERIAL_ENVIRONMENT_TEXTURE; texture Water_BumpTexture : MATERIAL_BUMP_TEXTURE; // Global variables float3 vCamEyePoint : VIEWPOSITION; float fTimeScale : WATER_BUMP_TIME_SCALE; float fBumpScale : WATER_BUMP_SCALE; float fBumpUVScale : WATER_BUMP_UV_SCALE; float fBumpU : WATER_BUMP_DISTANCE_SCALE; float fBumpV : WATER_BUMP_LIGHT_SCALE; float fFresnelFactorMin : WATER_FRESNEL_FACTOR_MIN; float fFresnelFactorMax : WATER_FRESNEL_FACTOR_MAX; float fSpecularPower : SPECULAR_POWER; float fSpecularBoost : SPECULAR_BOOST; float fSpecularBlend : SPECULAR_BLEND; float fBumpRotation : WATER_BUMP_ROTATION; float fBumpTimeX1 : WATER_BUMP_TIME_X1; float fBumpTimeY1 : WATER_BUMP_TIME_Y1; float fBumpTimeX2 : WATER_BUMP_TIME_X2; float fBumpTimeY2 : WATER_BUMP_TIME_Y2; float fBumpTimeScale2 : WATER_BUMP_TIME_SCALE_2; // Samples used by this shader sampler Water_BaseSampler = sampler_state { Texture = (Water_BaseTexture); AddressU = Clamp; // terrain textures must be clamped AddressV = Clamp; MinFilter = (State_MinFilter); MagFilter = (State_MagFilter); MipFilter = (State_MipFilter); MipMapLodBias = (State_MipMapLodBias); }; sampler Water_BumpSampler = sampler_state { Texture = (Water_BumpTexture); AddressU = Wrap; AddressV = Wrap; AddressW = Wrap; MinFilter = D3DTEXF_LINEAR; MagFilter = D3DTEXF_LINEAR; MipFilter = D3DTEXF_LINEAR; MipMapLodBias = (State_MipMapLodBias); }; sampler Water_EnvMapSampler = sampler_state { Texture = (Water_EnvTexture); AddressU = Clamp; AddressV = Clamp; MinFilter = (State_MinFilter); MagFilter = (State_MagFilter); MipFilter = (State_MipFilter); MipMapLodBias = (State_MipMapLodBias); }; struct VSWATER20_INPUT { float4 vPos : POSITION; float4 vColor : COLOR0; float3 vNormal : NORMAL; float2 vTex : TEXCOORD0; }; struct VSWATER20_OUTPUT { float4 vPos : POSITION; float fFog : FOG; half4 vColor : COLOR0; float4 TexBump : TEXCOORD0; float4 TexEnvMap : TEXCOORD1; float4 TexBase : TEXCOORD2; float4 MiscData : TEXCOORD3; float3 vNormalWS : TEXCOORD4; float3 vPosWS : TEXCOORD5; float3 vEyePosWS : TEXCOORD6; float4 TexScreen : TEXCOORD7; }; #define fresnMin 0.1 #define fresnMax 0.7 half fresnel2( half3 vEyeDir, half3 vSurfaceNorm ) { half frdot = min( 1 - dot(vEyeDir, vSurfaceNorm), 1 ); return lerp( fresnMin, fresnMax, frdot * frdot ); } VSWATER20_OUTPUT Water20VS(const VSWATER20_INPUT v,const bool b30Shader) { VSWATER20_OUTPUT o = (VSWATER20_OUTPUT)0; // Transform to clip space o.vPos = mul(v.vPos, mFullProj); // Compute fog o.fFog = ComputeFog(o.vPos.w, FOG_END, FOG_RECIP, FOG_SELECT_VERTEX, FOG_SELECT_TABLE); // Transform to world space float3 vWorldPos = mul(v.vPos, mWorld); // Compute eye vector float3 vEye = normalize(vCamEyePoint - vWorldPos); // Scale normal based bump based on dist //float fNormalScale = max(1.0,length(vEye)-fBumpDistScale); // Scale bumpmap texture coordinates by detail coordinates //float2 bmp = fmod(v.vPos.xz * (fBumpUVScale * 0.0001f),1024.0f); float2 bmp = fmod((vWorldPos.xz + float2(fBumpU, fBumpV) - mWorld[3].xz) * (fBumpUVScale * 0.0001f),256.0f); float2 sc = float2(sin(fBumpRotation),cos(fBumpRotation)); if (b30Shader) { o.TexBump.xy = bmp + (fSimTime * fBumpTimeScale2)*float2(fBumpTimeX1,fBumpTimeY1); o.TexBump.zw = (bmp*fBumpScale) + ((fSimTime * fBumpTimeScale2)*float2(fBumpTimeX2,fBumpTimeY2))/2.0f; o.TexBump.zw = float2(o.TexBump.z * sc.y - o.TexBump.w * sc.x, o.TexBump.z * sc.x + o.TexBump.w * sc.y); } else { o.TexBump.xy = bmp + (fSimTime * fTimeScale)*float2(0.4,-0.4); o.TexBump.zw = (bmp*fBumpScale) + ((fSimTime * fTimeScale)*float2(-1.0,1.0))/2.0f; o.TexBump.zw = float2(o.TexBump.z * sc.y - o.TexBump.w * sc.x, o.TexBump.z * sc.x + o.TexBump.w * sc.y); } // Send out interpolated normal for lighting o.vNormalWS = normalize(TransformVectorToSpace(v.vNormal, mWorld)); // Send out eye pos o.vPosWS = vWorldPos; o.vEyePosWS = vCamEyePoint; // Output vertex color straight to PS // The alpha component is used to represent the relative // depth of the water, used in computing water translucenty // The color component is simply the color scaled by the // diffuse sun lighting component o.vColor.a = v.vColor.a; o.vColor.rgb = 0.5/*( 1 - fresnel2(vSunVectorWorld_Sun.xyz, o.vNormalWS.xyz) ) * 0.5*/; // Environment mapping is determined from the screen-space coordinates // of our geometry. This implies that we need to divide them by W, and then // offset/scale into a 0-1 range. Because of interpolation issues due to front // clipped geometry, the info is pre-processed and passed to the PS where the 1/W // is applied. We also apply the normal to the data to emulate reflections caused // by the animating geometry o.TexEnvMap.xyz = o.vPos.xyz+o.vPos.www; // o.TexEnvMap.xyz = o.vPos.xyz+o.vPos.www*(1.0+0.25*o.vNormalWS.xzy/fNormalScale); o.TexEnvMap.w = 2.0*o.vPos.w; o.TexScreen.xyz = float3(1,-1,1)*o.vPos.xyz+o.vPos.www; o.TexScreen.w = 2.0*o.vPos.w; // Diffuse texture coordinates o.TexBase.xy = v.vTex; // Compute per-poly fresnel o.MiscData.x = 1.0 - lerp(fFresnelFactorMin, fFresnelFactorMax, pow(smoothstep(0,1,saturate(-normalize(vWorldPos).y)),0.5)); o.MiscData.y = 0; o.MiscData.z = 0; o.MiscData.w = 0; return o; } float4 Water20PS(VSWATER20_OUTPUT Input, const bool b30Shader) : COLOR { float4 Bump; float2 BumpEnv; float4 Color; float2 specularFactor; // Renomalize the input vectors and determine the // eye vector for lighting and reflection float3 vEyeDirWS; vEyeDirWS = normalize(Input.vEyePosWS - Input.vPosWS); // Sample the base color and bumpmaps // Since this is essentially a texbem style operation, we // manually apply the matrix to the bumpmap values, we then // scale our envmap texcoords by 1/W before factoring in the // bumpmap float3 vSurfaceNorm; if (b30Shader) { Bump = tex2Dbias(Water_BumpSampler, float4(Input.TexBump.xy,0,-2.0f)) + tex2Dbias(Water_BumpSampler, float4(Input.TexBump.zw,0,-3.0f)); Bump = normalize(Bump-1.0f); vSurfaceNorm = Bump.xzy; BumpEnv = (Input.TexEnvMap.xy/Input.TexEnvMap.w)+ (0.2f*Bump.xy); } else { Bump = tex2Dbias(Water_BumpSampler, float4(Input.TexBump.xy,0,-2.0f)) + tex2Dbias(Water_BumpSampler, float4(Input.TexBump.zw,0,-3.0f)); Bump = normalize(Bump-1.0f); vSurfaceNorm = Bump.xzy; BumpEnv = (Input.TexEnvMap.xy/Input.TexEnvMap.w)+ (0.2f*Bump.xy); } // Compute the diffuse lighting component of the water. float3 vHN; float3 vHN2; vHN = normalize(vEyeDirWS.xyz + vSunVectorWorld_Sun.xyz); vHN2 = normalize(vEyeDirWS.xyz + vSunVectorWorld_Moon.xyz); specularFactor = fSpecularBlend*(pow(fSpecularBoost*saturate(float2(dot(vSurfaceNorm, vHN),fSunMoonInterpolant * dot(vSurfaceNorm, vHN2))), fSpecularPower)); // Sample the water textures and determine the final color float4 baseColor = tex2D(Water_BaseSampler, Input.TexBase); float4 envColor = tex2Dbias(Water_EnvMapSampler, float4(BumpEnv.xy,0,1 * (Input.TexScreen.z/Input.TexScreen.w))); float4 terrainColor = baseColor; float fAlpha = baseColor.a; float4 fLand = { baseColor.a, baseColor.a, baseColor.a, baseColor.a }; half fr = fresnel2( vEyeDirWS.xyz, vSurfaceNorm.xyz); Color = half4( lerp( baseColor.rgb * Input.vColor.rgb, envColor.rgb, fr ), 1); // return Color; return float4(lerp(Color.xyz + (vSunDirectional * specularFactor.x) + (0.3 * (specularFactor.y + saturate(dot(vSunVectorWorld_Moon,vSurfaceNorm)))).xxx, terrainColor.xyz, fLand),fAlpha); } // ------- 3.0 ---------- float4 Water30PS(VSWATER20_OUTPUT Input) : COLOR { return Water20PS(Input,true); } // ------- 2.0 ---------- float4 Water20PS(VSWATER20_OUTPUT Input) : COLOR { return Water20PS(Input,false); } // ------ VS ------ VSWATER20_OUTPUT Water20VS(VSWATER20_INPUT Input) { return Water20VS(Input,false); }
//--------------------------------------------------------------------------- // Flight Simulator X - Shader Effect Files // Copyright (c) 2006, Microsoft Corporation //--------------------------------------------------------------------------- #include <Common.fxh> #include <MaterialDecl.fxh> #include <D3D9Texture.fxh> #include <FuncLibrary.fxh> #define vLightDir vSunVectorWorld // Potential textures texture Water_BaseTexture : MATERIAL_BASE_TEXTURE; texture Water_EnvTexture : MATERIAL_ENVIRONMENT_TEXTURE; texture Water_BumpTexture : MATERIAL_BUMP_TEXTURE; // Global variables float3 vCamEyePoint : VIEWPOSITION; float fTimeScale : WATER_BUMP_TIME_SCALE; float fBumpScale : WATER_BUMP_SCALE; float fBumpUVScale : WATER_BUMP_UV_SCALE; float fBumpU : WATER_BUMP_DISTANCE_SCALE; float fBumpV : WATER_BUMP_LIGHT_SCALE; float fFresnelFactorMin : WATER_FRESNEL_FACTOR_MIN; float fFresnelFactorMax : WATER_FRESNEL_FACTOR_MAX; float fSpecularPower : SPECULAR_POWER; float fSpecularBoost : SPECULAR_BOOST; float fSpecularBlend : SPECULAR_BLEND; float fBumpRotation : WATER_BUMP_ROTATION; float fBumpTimeX1 : WATER_BUMP_TIME_X1; float fBumpTimeY1 : WATER_BUMP_TIME_Y1; float fBumpTimeX2 : WATER_BUMP_TIME_X2; float fBumpTimeY2 : WATER_BUMP_TIME_Y2; float fBumpTimeScale2 : WATER_BUMP_TIME_SCALE_2; // Samples used by this shader sampler Water_BaseSampler = sampler_state { Texture = (Water_BaseTexture); AddressU = Clamp; // terrain textures must be clamped AddressV = Clamp; MinFilter = (State_MinFilter); MagFilter = (State_MagFilter); MipFilter = (State_MipFilter); MipMapLodBias = (State_MipMapLodBias); }; sampler Water_BumpSampler = sampler_state { Texture = (Water_BumpTexture); AddressU = Wrap; AddressV = Wrap; AddressW = Wrap; MinFilter = D3DTEXF_LINEAR; MagFilter = D3DTEXF_LINEAR; MipFilter = D3DTEXF_LINEAR; MipMapLodBias = (State_MipMapLodBias); }; sampler Water_EnvMapSampler = sampler_state { Texture = (Water_EnvTexture); AddressU = Clamp; AddressV = Clamp; MinFilter = (State_MinFilter); MagFilter = (State_MagFilter); MipFilter = (State_MipFilter); MipMapLodBias = (State_MipMapLodBias); }; struct VSWATER20_INPUT { float4 vPos : POSITION; float4 vColor : COLOR0; float3 vNormal : NORMAL; float2 vTex : TEXCOORD0; }; struct VSWATER20_OUTPUT { float4 vPos : POSITION; float fFog : FOG; half4 vColor : COLOR0; float4 TexBump : TEXCOORD0; float4 TexEnvMap : TEXCOORD1; float4 TexBase : TEXCOORD2; float4 MiscData : TEXCOORD3; float3 vNormalWS : TEXCOORD4; float3 vPosWS : TEXCOORD5; float3 vEyePosWS : TEXCOORD6; float4 TexScreen : TEXCOORD7; }; #define fresnMin 0.05 #define fresnMax 0.5 half fresnel2( half3 vEyeDir, half3 vSurfaceNorm ) { half frdot = min( 1 - dot(vEyeDir, vSurfaceNorm), 1 ); return lerp( fresnMin, fresnMax, frdot * frdot ); } VSWATER20_OUTPUT Water20VS(const VSWATER20_INPUT v,const bool b30Shader) { VSWATER20_OUTPUT o = (VSWATER20_OUTPUT)0; // Transform to clip space o.vPos = mul(v.vPos, mFullProj); // Compute fog o.fFog = ComputeFog(o.vPos.w, FOG_END, FOG_RECIP, FOG_SELECT_VERTEX, FOG_SELECT_TABLE); // Transform to world space float3 vWorldPos = mul(v.vPos, mWorld); // Compute eye vector float3 vEye = normalize(vCamEyePoint - vWorldPos); // Scale normal based bump based on dist //float fNormalScale = max(1.0,length(vEye)-fBumpDistScale); // Scale bumpmap texture coordinates by detail coordinates //float2 bmp = fmod(v.vPos.xz * (fBumpUVScale * 0.0001f),1024.0f); float2 bmp = fmod((vWorldPos.xz + float2(fBumpU, fBumpV) - mWorld[3].xz) * (fBumpUVScale * 0.0001f),256.0f); float2 sc = float2(sin(fBumpRotation),cos(fBumpRotation)); if (b30Shader) { o.TexBump.xy = bmp + (fSimTime * fBumpTimeScale2)*float2(fBumpTimeX1,fBumpTimeY1); o.TexBump.zw = (bmp*fBumpScale) + ((fSimTime * fBumpTimeScale2)*float2(fBumpTimeX2,fBumpTimeY2))/2.0f; o.TexBump.zw = float2(o.TexBump.z * sc.y - o.TexBump.w * sc.x, o.TexBump.z * sc.x + o.TexBump.w * sc.y); } else { o.TexBump.xy = bmp + (fSimTime * fTimeScale)*float2(0.4,-0.4); o.TexBump.zw = (bmp*fBumpScale) + ((fSimTime * fTimeScale)*float2(-1.0,1.0))/2.0f; o.TexBump.zw = float2(o.TexBump.z * sc.y - o.TexBump.w * sc.x, o.TexBump.z * sc.x + o.TexBump.w * sc.y); } // Send out interpolated normal for lighting o.vNormalWS = normalize(TransformVectorToSpace(v.vNormal, mWorld)); // Send out eye pos o.vPosWS = vWorldPos; o.vEyePosWS = vCamEyePoint; // Output vertex color straight to PS // The alpha component is used to represent the relative // depth of the water, used in computing water translucenty // The color component is simply the color scaled by the // diffuse sun lighting component o.vColor.a = v.vColor.a; o.vColor.rgb = 0.5/*( 1 - fresnel2(vSunVectorWorld_Sun.xyz, o.vNormalWS.xyz) ) * 0.5*/; // Environment mapping is determined from the screen-space coordinates // of our geometry. This implies that we need to divide them by W, and then // offset/scale into a 0-1 range. Because of interpolation issues due to front // clipped geometry, the info is pre-processed and passed to the PS where the 1/W // is applied. We also apply the normal to the data to emulate reflections caused // by the animating geometry o.TexEnvMap.xyz = o.vPos.xyz+o.vPos.www; // o.TexEnvMap.xyz = o.vPos.xyz+o.vPos.www*(1.0+0.25*o.vNormalWS.xzy/fNormalScale); o.TexEnvMap.w = 2.0*o.vPos.w; o.TexScreen.xyz = float3(1,-1,1)*o.vPos.xyz+o.vPos.www; o.TexScreen.w = 2.0*o.vPos.w; // Diffuse texture coordinates o.TexBase.xy = v.vTex; // Compute per-poly fresnel o.MiscData.x = 1.0 - lerp(fFresnelFactorMin, fFresnelFactorMax, pow(smoothstep(0,1,saturate(-normalize(vWorldPos).y)),0.5)); o.MiscData.y = 0; o.MiscData.z = 0; o.MiscData.w = 0; return o; } float4 Water20PS(VSWATER20_OUTPUT Input, const bool b30Shader) : COLOR { float4 Bump; float2 BumpEnv; float4 Color; float2 specularFactor; // Renomalize the input vectors and determine the // eye vector for lighting and reflection float3 vEyeDirWS; vEyeDirWS = normalize(Input.vEyePosWS - Input.vPosWS); // Sample the base color and bumpmaps // Since this is essentially a texbem style operation, we // manually apply the matrix to the bumpmap values, we then // scale our envmap texcoords by 1/W before factoring in the // bumpmap float3 vSurfaceNorm; if (b30Shader) { Bump = tex2Dbias(Water_BumpSampler, float4(Input.TexBump.xy,0,-2.0f)) + tex2Dbias(Water_BumpSampler, float4(Input.TexBump.zw,0,-3.0f)); Bump = normalize(Bump-1.0f); vSurfaceNorm = Bump.xzy; BumpEnv = (Input.TexEnvMap.xy/Input.TexEnvMap.w)+ (0.2f*Bump.xy); } else { Bump = tex2Dbias(Water_BumpSampler, float4(Input.TexBump.xy,0,-2.0f)) + tex2Dbias(Water_BumpSampler, float4(Input.TexBump.zw,0,-3.0f)); Bump = normalize(Bump-1.0f); vSurfaceNorm = Bump.xzy; BumpEnv = (Input.TexEnvMap.xy/Input.TexEnvMap.w)+ (0.2f*Bump.xy); } // Compute the diffuse lighting component of the water. float3 vHN; float3 vHN2; vHN = normalize(vEyeDirWS.xyz + vSunVectorWorld_Sun.xyz); vHN2 = normalize(vEyeDirWS.xyz + vSunVectorWorld_Moon.xyz); specularFactor = fSpecularBlend*(pow(fSpecularBoost*saturate(float2(dot(vSurfaceNorm, vHN),fSunMoonInterpolant * dot(vSurfaceNorm, vHN2))), fSpecularPower)); // Sample the water textures and determine the final color float4 baseColor = tex2D(Water_BaseSampler, Input.TexBase); float4 envColor = tex2Dbias(Water_EnvMapSampler, float4(BumpEnv.xy,0,1 * (Input.TexScreen.z/Input.TexScreen.w))); float4 terrainColor = baseColor; float fAlpha = baseColor.a; float4 fLand = { baseColor.a, baseColor.a, baseColor.a, baseColor.a }; half fr = fresnel2( vEyeDirWS.xyz, vSurfaceNorm.xyz); Color = half4( lerp( baseColor.rgb * 2 * Input.vColor.rgb, envColor.rgb, fr ), 1); // return Color; return float4(lerp(Color.xyz + (vSunDirectional * specularFactor.x * 0.5) + (0.3 * (specularFactor.y)).xxx, terrainColor.xyz, fLand),fAlpha); } // ------- 3.0 ---------- float4 Water30PS(VSWATER20_OUTPUT Input) : COLOR { return Water20PS(Input,true); } // ------- 2.0 ---------- float4 Water20PS(VSWATER20_OUTPUT Input) : COLOR { return Water20PS(Input,false); } // ------ VS ------ VSWATER20_OUTPUT Water20VS(VSWATER20_INPUT Input) { return Water20VS(Input,false); }
//--------------------------------------------------------------------------- // Flight Simulator X - Shader Effect Files // Copyright (c) 2006, Microsoft Corporation //--------------------------------------------------------------------------- #include <Common.fxh> #include <MaterialDecl.fxh> #include <D3D9Texture.fxh> #include <FuncLibrary.fxh> #define vLightDir vSunVectorWorld // Potential textures texture Water_BaseTexture : MATERIAL_BASE_TEXTURE; texture Water_EnvTexture : MATERIAL_ENVIRONMENT_TEXTURE; texture Water_BumpTexture : MATERIAL_BUMP_TEXTURE; // Global variables float3 vCamEyePoint : VIEWPOSITION; float fTimeScale : WATER_BUMP_TIME_SCALE; float fBumpScale : WATER_BUMP_SCALE; float fBumpUVScale : WATER_BUMP_UV_SCALE; float fBumpU : WATER_BUMP_DISTANCE_SCALE; float fBumpV : WATER_BUMP_LIGHT_SCALE; float fFresnelFactorMin : WATER_FRESNEL_FACTOR_MIN; float fFresnelFactorMax : WATER_FRESNEL_FACTOR_MAX; float fSpecularPower : SPECULAR_POWER; float fSpecularBoost : SPECULAR_BOOST; float fSpecularBlend : SPECULAR_BLEND; float fBumpRotation : WATER_BUMP_ROTATION; float fBumpTimeX1 : WATER_BUMP_TIME_X1; float fBumpTimeY1 : WATER_BUMP_TIME_Y1; float fBumpTimeX2 : WATER_BUMP_TIME_X2; float fBumpTimeY2 : WATER_BUMP_TIME_Y2; float fBumpTimeScale2 : WATER_BUMP_TIME_SCALE_2; // Samples used by this shader sampler Water_BaseSampler = sampler_state { Texture = (Water_BaseTexture); AddressU = Clamp; // terrain textures must be clamped AddressV = Clamp; MinFilter = (State_MinFilter); MagFilter = (State_MagFilter); MipFilter = (State_MipFilter); MipMapLodBias = (State_MipMapLodBias); }; sampler Water_BumpSampler = sampler_state { Texture = (Water_BumpTexture); AddressU = Wrap; AddressV = Wrap; AddressW = Wrap; MinFilter = D3DTEXF_LINEAR; MagFilter = D3DTEXF_LINEAR; MipFilter = D3DTEXF_LINEAR; MipMapLodBias = (State_MipMapLodBias); }; sampler Water_EnvMapSampler = sampler_state { Texture = (Water_EnvTexture); AddressU = Clamp; AddressV = Clamp; MinFilter = (State_MinFilter); MagFilter = (State_MagFilter); MipFilter = (State_MipFilter); MipMapLodBias = (State_MipMapLodBias); }; struct VSWATER20_INPUT { float4 vPos : POSITION; float4 vColor : COLOR0; float3 vNormal : NORMAL; float2 vTex : TEXCOORD0; }; struct VSWATER20_OUTPUT { float4 vPos : POSITION; float fFog : FOG; half4 vColor : COLOR0; float4 TexBump : TEXCOORD0; float4 TexEnvMap : TEXCOORD1; float4 TexBase : TEXCOORD2; float4 MiscData : TEXCOORD3; float3 vNormalWS : TEXCOORD4; float3 vPosWS : TEXCOORD5; float3 vEyePosWS : TEXCOORD6; float4 TexScreen : TEXCOORD7; }; #define fresnMin 0.05 #define fresnMax 0.5 half fresnel2( half3 vEyeDir, half3 vSurfaceNorm ) { half frdot = min( 1 - dot(vEyeDir, vSurfaceNorm), 1 ); return lerp( fresnMin, fresnMax, frdot * frdot ); } VSWATER20_OUTPUT Water20VS(const VSWATER20_INPUT v,const bool b30Shader) { VSWATER20_OUTPUT o = (VSWATER20_OUTPUT)0; // Transform to clip space o.vPos = mul(v.vPos, mFullProj); // Compute fog o.fFog = ComputeFog(o.vPos.w, FOG_END, FOG_RECIP, FOG_SELECT_VERTEX, FOG_SELECT_TABLE); // Transform to world space float3 vWorldPos = mul(v.vPos, mWorld); // Compute eye vector float3 vEye = normalize(vCamEyePoint - vWorldPos); // Scale normal based bump based on dist //float fNormalScale = max(1.0,length(vEye)-fBumpDistScale); // Scale bumpmap texture coordinates by detail coordinates //float2 bmp = fmod(v.vPos.xz * (fBumpUVScale * 0.0001f),1024.0f); float2 bmp = fmod((vWorldPos.xz + float2(fBumpU, fBumpV) - mWorld[3].xz) * (fBumpUVScale * 0.0001f),256.0f); float2 sc = float2(sin(fBumpRotation),cos(fBumpRotation)); if (b30Shader) { o.TexBump.xy = bmp + (fSimTime * fBumpTimeScale2)*float2(fBumpTimeX1,fBumpTimeY1); o.TexBump.zw = (bmp*fBumpScale) + ((fSimTime * fBumpTimeScale2)*float2(fBumpTimeX2,fBumpTimeY2))/2.0f; o.TexBump.zw = float2(o.TexBump.z * sc.y - o.TexBump.w * sc.x, o.TexBump.z * sc.x + o.TexBump.w * sc.y); } else { o.TexBump.xy = bmp + (fSimTime * fTimeScale)*float2(0.4,-0.4); o.TexBump.zw = (bmp*fBumpScale) + ((fSimTime * fTimeScale)*float2(-1.0,1.0))/2.0f; o.TexBump.zw = float2(o.TexBump.z * sc.y - o.TexBump.w * sc.x, o.TexBump.z * sc.x + o.TexBump.w * sc.y); } // Send out interpolated normal for lighting o.vNormalWS = normalize(TransformVectorToSpace(v.vNormal, mWorld)); // Send out eye pos o.vPosWS = vWorldPos; o.vEyePosWS = vCamEyePoint; // Output vertex color straight to PS // The alpha component is used to represent the relative // depth of the water, used in computing water translucenty // The color component is simply the color scaled by the // diffuse sun lighting component o.vColor.a = v.vColor.a; o.vColor.rgb = 0.5/*( 1 - fresnel2(vSunVectorWorld_Sun.xyz, o.vNormalWS.xyz) ) * 0.5*/; // Environment mapping is determined from the screen-space coordinates // of our geometry. This implies that we need to divide them by W, and then // offset/scale into a 0-1 range. Because of interpolation issues due to front // clipped geometry, the info is pre-processed and passed to the PS where the 1/W // is applied. We also apply the normal to the data to emulate reflections caused // by the animating geometry o.TexEnvMap.xyz = o.vPos.xyz+o.vPos.www; // o.TexEnvMap.xyz = o.vPos.xyz+o.vPos.www*(1.0+0.25*o.vNormalWS.xzy/fNormalScale); o.TexEnvMap.w = 2.0*o.vPos.w; o.TexScreen.xyz = float3(1,-1,1)*o.vPos.xyz+o.vPos.www; o.TexScreen.w = 2.0*o.vPos.w; // Diffuse texture coordinates o.TexBase.xy = v.vTex; // Compute per-poly fresnel o.MiscData.x = 1.0 - lerp(fFresnelFactorMin, fFresnelFactorMax, pow(smoothstep(0,1,saturate(-normalize(vWorldPos).y)),0.5)); o.MiscData.y = 0; o.MiscData.z = 0; o.MiscData.w = 0; return o; } float4 Water20PS(VSWATER20_OUTPUT Input, const bool b30Shader) : COLOR { float4 Bump; float2 BumpEnv; float4 Color; float2 specularFactor; // Renomalize the input vectors and determine the // eye vector for lighting and reflection float3 vEyeDirWS; vEyeDirWS = normalize(Input.vEyePosWS - Input.vPosWS); // Sample the base color and bumpmaps // Since this is essentially a texbem style operation, we // manually apply the matrix to the bumpmap values, we then // scale our envmap texcoords by 1/W before factoring in the // bumpmap float3 vSurfaceNorm; if (b30Shader) { Bump = tex2Dbias(Water_BumpSampler, float4(Input.TexBump.xy,0,-2.0f)) + tex2Dbias(Water_BumpSampler, float4(Input.TexBump.zw,0,-3.0f)); Bump = normalize(Bump-1.0f); vSurfaceNorm = Bump.xzy; BumpEnv = (Input.TexEnvMap.xy/Input.TexEnvMap.w)+ (0.2f*Bump.xy); } else { Bump = tex2Dbias(Water_BumpSampler, float4(Input.TexBump.xy,0,-2.0f)) + tex2Dbias(Water_BumpSampler, float4(Input.TexBump.zw,0,-3.0f)); Bump = normalize(Bump-1.0f); vSurfaceNorm = Bump.xzy; BumpEnv = (Input.TexEnvMap.xy/Input.TexEnvMap.w)+ (0.2f*Bump.xy); } // Compute the diffuse lighting component of the water. float3 vHN; float3 vHN2; vHN = normalize(vEyeDirWS.xyz + vSunVectorWorld_Sun.xyz); vHN2 = normalize(vEyeDirWS.xyz + vSunVectorWorld_Moon.xyz); specularFactor = fSpecularBlend*(pow(fSpecularBoost*saturate(float2(dot(vSurfaceNorm, vHN),fSunMoonInterpolant * dot(vSurfaceNorm, vHN2))), fSpecularPower)); // Sample the water textures and determine the final color float4 baseColor = tex2D(Water_BaseSampler, Input.TexBase); float4 envColor = tex2Dbias(Water_EnvMapSampler, float4(BumpEnv.xy,0,1 * (Input.TexScreen.z/Input.TexScreen.w))); float4 terrainColor = baseColor; float fAlpha = baseColor.a; float4 fLand = { baseColor.a, baseColor.a, baseColor.a, baseColor.a }; half fr = fresnel2( vEyeDirWS.xyz, vSurfaceNorm.xyz); Color = half4( lerp( baseColor.rgb * 2 * Input.vColor.rgb, envColor.rgb, fr ), 1); // return Color; return float4(lerp(Color.xyz + (vSunDirectional * specularFactor.x * 0.5) + (0.3 * (specularFactor.y + saturate(dot(vSunVectorWorld_Moon,vSurfaceNorm)))).xxx, terrainColor.xyz, fLand),fAlpha); } // ------- 3.0 ---------- float4 Water30PS(VSWATER20_OUTPUT Input) : COLOR { return Water20PS(Input,true); } // ------- 2.0 ---------- float4 Water20PS(VSWATER20_OUTPUT Input) : COLOR { return Water20PS(Input,false); } // ------ VS ------ VSWATER20_OUTPUT Water20VS(VSWATER20_INPUT Input) { return Water20VS(Input,false); }