diff options
Diffstat (limited to 'sp/src/materialsystem/stdshaders/water_ps2x_helper.h')
| -rw-r--r-- | sp/src/materialsystem/stdshaders/water_ps2x_helper.h | 239 |
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 +} |