aboutsummaryrefslogtreecommitdiff
path: root/sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc
diff options
context:
space:
mode:
Diffstat (limited to 'sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc')
-rw-r--r--sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc152
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 );
+}