aboutsummaryrefslogtreecommitdiff
path: root/sp/src/materialsystem/stdshaders/water_ps2x_helper.h
diff options
context:
space:
mode:
Diffstat (limited to 'sp/src/materialsystem/stdshaders/water_ps2x_helper.h')
-rw-r--r--sp/src/materialsystem/stdshaders/water_ps2x_helper.h239
1 files changed, 239 insertions, 0 deletions
diff --git a/sp/src/materialsystem/stdshaders/water_ps2x_helper.h b/sp/src/materialsystem/stdshaders/water_ps2x_helper.h
new file mode 100644
index 00000000..b15b9986
--- /dev/null
+++ b/sp/src/materialsystem/stdshaders/water_ps2x_helper.h
@@ -0,0 +1,239 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+#include "common_ps_fxc.h"
+
+struct DrawWater_params_t
+{
+ float2 vBumpTexCoord;
+#if MULTITEXTURE
+ float4 vExtraBumpTexCoord;
+#endif
+ float4 vReflectXY_vRefractYX;
+ float w;
+ float4 vReflectRefractScale;
+ float fReflectOverbright;
+ float4 vReflectTint;
+ float4 vRefractTint;
+ half3 vTangentEyeVect;
+ float4 waterFogColor;
+#if BASETEXTURE
+ HALF4 lightmapTexCoord1And2;
+ HALF4 lightmapTexCoord3;
+#endif
+ float4 vProjPos;
+ float4 pixelFogParams;
+ float fWaterFogStart;
+ float fWaterFogEndMinusStart;
+};
+
+void DrawWater( in DrawWater_params_t i,
+#if BASETEXTURE
+ in sampler BaseTextureSampler,
+ in sampler LightmapSampler,
+#endif
+ in sampler NormalSampler,
+ in sampler RefractSampler,
+ in sampler ReflectSampler,
+ out float4 result, out float fogFactor )
+{
+ bool bReflect = REFLECT ? true : false;
+ bool bRefract = REFRACT ? true : false;
+
+#if MULTITEXTURE
+ float4 vNormal = tex2D( NormalSampler, i.vBumpTexCoord );
+ float4 vNormal1 = tex2D( NormalSampler, i.vExtraBumpTexCoord.xy );
+ float4 vNormal2 = tex2D( NormalSampler, 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) );
+ vNormal.a = 1.0f;
+#else
+ vNormal.xyz = 2.0 * vNormal.xyz - 1.0;
+#endif
+
+#else
+ float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord, NORMAL_DECODE_MODE );
+#endif
+
+ // Perform division by W only once
+ float ooW = 1.0f / i.w;
+
+ float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW;
+
+#if ABOVEWATER
+ float waterFogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a;
+#else
+ // We don't actually have valid depth values in alpha when we are underwater looking out, so
+ // just set to farthest value.
+ float waterFogDepthValue = 1.0f;
+#endif
+ float4 reflectRefractScale = i.vReflectRefractScale;
+#if !BASETEXTURE
+#if ( BLURRY_REFRACT == 0 )
+ reflectRefractScale *= waterFogDepthValue;
+#endif
+#endif
+
+ // Compute coordinates for sampling Reflection
+ float2 vReflectTexCoord;
+ float2 vRefractTexCoord;
+
+ // vectorize the dependent UV calculations (reflect = .xy, refract = .wz)
+ float4 vN;
+ vN.xy = vNormal.xy;
+ vN.w = vNormal.x;
+ vN.z = vNormal.y;
+ float4 vDependentTexCoords = vN * vNormal.a * reflectRefractScale;
+
+ vDependentTexCoords += ( i.vReflectXY_vRefractYX * ooW );
+ vReflectTexCoord = vDependentTexCoords.xy;
+ vRefractTexCoord = vDependentTexCoords.wz;
+
+ HALF4 vReflectColor = tex2D( ReflectSampler, vReflectTexCoord );
+#if BLURRY_REFRACT
+ // Sample reflection and refraction
+ float2 ddx1=float2(0.005,0);
+ float2 ddy1=float2(0,0.005);
+ float4 vRefractColor=float4(0,0,0,0);
+
+#if 0
+ float sumweights=0;
+ for(int ix=-2;ix<=2;ix++)
+ {
+ for(int iy=-2;iy<=2;iy++)
+ {
+ float weight=1; ///(1+abs(ix)+abs(iy));
+ vRefractColor += weight*tex2D( RefractSampler, vRefractTexCoord+ix*ddx1+iy*ddy1);
+ sumweights+=weight;
+ }
+ }
+#else
+ // NOTE: Generated by genwaterloop.pl in the stdshaders directory.
+ // Need to unroll for 360 to avoid shader compilation problems.
+ // Modified genwaterloop.pl and regenerate if you need different params
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -2 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 0 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 2 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -2 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 0 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 2 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -2 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 0 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 2 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -2 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 0 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 2 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -2 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 0 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 1 * ddy1 );
+ vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 2 * ddy1 );
+ float sumweights = 25;
+ // NOTE: end of generated code.
+#endif
+
+ vRefractColor *= (1.0/sumweights);
+ vReflectColor *= i.fReflectOverbright;
+ vReflectColor *= i.vReflectTint;
+ vRefractColor *= i.vRefractTint;
+# if ABOVEWATER
+ // Don't mess with this in the underwater case since we don't really have
+ // depth values there.
+ // get the blurred depth value to be used for fog.
+ waterFogDepthValue = vRefractColor.a;
+# endif
+#else
+ vReflectColor *= i.vReflectTint;
+ HALF4 vRefractColor = tex2D( RefractSampler, vRefractTexCoord );
+ // get the depth value from the refracted sample to be used for fog.
+# if ABOVEWATER
+ // Don't mess with this in the underwater case since we don't really have
+ // depth values there.
+ waterFogDepthValue = tex2D( RefractSampler, vRefractTexCoord ).a;
+# endif
+#endif
+
+ half3 vEyeVect;
+ vEyeVect = normalize( i.vTangentEyeVect );
+
+ // Fresnel term
+ HALF fNdotV = saturate( dot( vEyeVect, vNormal ) );
+ HALF fFresnel = pow( 1.0 - fNdotV, 5 );
+
+#if !BASETEXTURE
+ // fFresnel == 1.0f means full reflection
+ fFresnel *= saturate( ( waterFogDepthValue - 0.05f ) * 20.0f );
+#endif
+
+
+ // blend between refraction and fog color.
+#if ABOVEWATER
+ vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, saturate( waterFogDepthValue - 0.05f ) );
+#else
+ float waterFogFactor = saturate( ( i.vProjPos.z - i.fWaterFogStart ) / i.fWaterFogEndMinusStart );
+ vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, waterFogFactor );
+#endif
+
+#if BASETEXTURE
+ float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoord.xy );
+ HALF2 bumpCoord1;
+ HALF2 bumpCoord2;
+ HALF2 bumpCoord3;
+ ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy,
+ bumpCoord1, bumpCoord2, bumpCoord3 );
+
+ HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 );
+ HALF3 lightmapColor1 = lightmapSample1.rgb;
+ HALF3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 );
+ HALF3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 );
+
+ float3 dp;
+ dp.x = saturate( dot( vNormal, bumpBasis[0] ) );
+ dp.y = saturate( dot( vNormal, bumpBasis[1] ) );
+ dp.z = saturate( dot( vNormal, bumpBasis[2] ) );
+ dp *= dp;
+
+ float3 diffuseLighting = dp.x * lightmapColor1 +
+ dp.y * lightmapColor2 +
+ dp.z * lightmapColor3;
+ float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) );
+ diffuseLighting *= LIGHT_MAP_SCALE / sum;
+ HALF3 diffuseComponent = baseSample.rgb * diffuseLighting;
+#endif
+
+ if( bReflect && bRefract )
+ {
+ result = lerp( vRefractColor, vReflectColor, fFresnel );
+ }
+ else if( bReflect )
+ {
+#if BASETEXTURE
+ result = float4( diffuseComponent, 1.0f ) + vReflectColor * fFresnel * baseSample.a;
+#else
+ result = vReflectColor;
+#endif
+ }
+ else if( bRefract )
+ {
+ result = vRefractColor;
+ }
+ else
+ {
+ result = float4( 0.0f, 0.0f, 0.0f, 0.0f );
+ }
+
+#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE)
+ fogFactor = CalcRangeFog( i.vProjPos.z, i.pixelFogParams.x, i.pixelFogParams.z, i.pixelFogParams.w );
+#else
+ fogFactor = 0;
+#endif
+}