diff options
Diffstat (limited to 'sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc')
| -rw-r--r-- | sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc b/sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc new file mode 100644 index 00000000..4ca66570 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc @@ -0,0 +1,152 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "MULTITEXTURE" "0..1" +// STATIC: "FRESNEL" "0..1" +// STATIC: "BLEND" "0..1" +// STATIC: "REFRACTALPHA" "0..1" +// STATIC: "HDRTYPE" "0..2" +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] + +// DYNAMIC: "HDRENABLED" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" + +const HALF3 g_WaterFogColor : register( c0 ); +const HALF4 g_CheapWaterParams : register( c1 ); +const HALF4 g_ReflectTint : register( c2 ); +const float4 g_PixelFogParams : register( c3 ); + +#define g_CheapWaterStart g_CheapWaterParams.x +#define g_CheapWaterEnd g_CheapWaterParams.y +#define g_CheapWaterDeltaRecip g_CheapWaterParams.z +#define g_CheapWaterStartDivDelta g_CheapWaterParams.w + +sampler EnvmapSampler : register( s0 ); +sampler NormalMapSampler : register( s1 ); +#if REFRACTALPHA +sampler RefractSampler : register( s2 ); +#endif +sampler NormalizeSampler : register( s6 ); + +struct PS_INPUT +{ + float2 normalMapTexCoord : TEXCOORD0; + HALF3 worldSpaceEyeVect : TEXCOORD1; + HALF3x3 tangentSpaceTranspose : TEXCOORD2; + float4 vRefract_W_ProjZ : TEXCOORD5; + +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bBlend = BLEND ? true : false; + +#if MULTITEXTURE + float3 vNormal = tex2D( NormalMapSampler, i.normalMapTexCoord ); + float3 vNormal1 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.xy ); + float3 vNormal2 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.zw ); + vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 ); + +#if ( NORMAL_DECODE_MODE == NORM_DECODE_ATI2N ) + vNormal.xy = vNormal.xy * 2.0f - 1.0f; + vNormal.z = sqrt( 1.0f - dot(vNormal.xy, vNormal.xy) ); +#else + vNormal = 2.0 * vNormal - 1.0; +#endif + +#else + float3 vNormal = DecompressNormal( NormalMapSampler, i.normalMapTexCoord, NORMAL_DECODE_MODE ); +#endif + + HALF3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); + HALF3 worldSpaceEye; + + HALF flWorldSpaceDist = 1.0f; + +#ifdef NV3X + // for some reason, fxc doesn't convert length( half3 v ) into all _pp opcodes. + if (bBlend) + { + worldSpaceEye = i.worldSpaceEyeVect; + HALF worldSpaceDistSqr = dot( worldSpaceEye, worldSpaceEye ); + HALF rcpWorldSpaceDist = rsqrt( worldSpaceDistSqr ); + worldSpaceEye *= rcpWorldSpaceDist; + flWorldSpaceDist = worldSpaceDistSqr * rcpWorldSpaceDist; + } + else + { + worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); + } +#else // !NV3X + if (bBlend) + { + worldSpaceEye = i.worldSpaceEyeVect; + flWorldSpaceDist = length( worldSpaceEye ); + worldSpaceEye /= flWorldSpaceDist; + } + else + { + worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); + } +#endif + + HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldSpaceEye ); + HALF3 specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= g_ReflectTint; + +#if FRESNEL + // FIXME: It's unclear that we want to do this for cheap water + // but the code did this previously and I didn't want to change it + HALF flDotResult = dot( worldSpaceEye, worldSpaceNormal ); + flDotResult = 1.0f - max( 0.0f, flDotResult ); + + HALF flFresnelFactor = flDotResult * flDotResult; + flFresnelFactor *= flFresnelFactor; + flFresnelFactor *= flDotResult; +#else + HALF flFresnelFactor = g_ReflectTint.a; +#endif + + HALF flAlpha; + if (bBlend) + { + HALF flReflectAmount = saturate( flWorldSpaceDist * g_CheapWaterDeltaRecip - g_CheapWaterStartDivDelta ); + flAlpha = saturate( flFresnelFactor + flReflectAmount ); + +#if REFRACTALPHA + // Perform division by W only once + float ooW = 1.0f / i.vRefract_W_ProjZ.z; + float2 unwarpedRefractTexCoord = i.vRefract_W_ProjZ * ooW; + float fogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a; + // Fade on the border between the water and land. + flAlpha *= saturate( ( fogDepthValue - .05f ) * 20.0f ); +#endif + } + else + { + flAlpha = 1.0f; +#if HDRTYPE == 0 || HDRENABLED == 0 + specularLighting = lerp( g_WaterFogColor, specularLighting, flFresnelFactor ); +#else + specularLighting = lerp( GammaToLinear( g_WaterFogColor ), specularLighting, flFresnelFactor ); +#endif + } + + // multiply the color by alpha.since we are using alpha blending to blend against dest alpha for borders. + + + +#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE) + float fogFactor = CalcRangeFog( i.vRefract_W_ProjZ.w, g_PixelFogParams.x, g_PixelFogParams.z, g_PixelFogParams.w ); +#else + float fogFactor = 0; +#endif + + return FinalOutput( float4( specularLighting, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} |