diff options
Diffstat (limited to 'materialsystem/stdshaders/refract_ps2x.fxc')
| -rw-r--r-- | materialsystem/stdshaders/refract_ps2x.fxc | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/materialsystem/stdshaders/refract_ps2x.fxc b/materialsystem/stdshaders/refract_ps2x.fxc new file mode 100644 index 0000000..2f97423 --- /dev/null +++ b/materialsystem/stdshaders/refract_ps2x.fxc @@ -0,0 +1,250 @@ +//====== Copyright � 1996-2007, Valve Corporation, All rights reserved. ======= +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "BLUR" "0..1" +// STATIC: "FADEOUTONSILHOUETTE" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "REFRACTTINTTEXTURE" "0..1" +// STATIC: "MASKED" "0..1" +// STATIC: "COLORMODULATE" "0..1" +// STATIC: "SECONDARY_NORMAL" "0..1" +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] +// STATIC: "SHADER_SRGB_READ" "0..1" [ps20b] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// SKIP: $MASKED && $BLUR + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler NormalSampler2 : register( s1 ); +sampler RefractSampler : register( s2 ); +sampler NormalSampler : register( s3 ); +#if CUBEMAP +sampler EnvmapSampler : register( s4 ); +#endif +#if REFRACTTINTTEXTURE +sampler RefractTintSampler : register( s5 ); +#endif + +#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA +sampler AlphaMapSampler : register( s6 ); // alpha +sampler AlphaMapSampler2 : register( s7 ); +#else +#define AlphaMapSampler2 NormalSampler +#define AlphaMapSampler NormalSampler2 +#endif + +const float3 g_EnvmapTint : register( c0 ); +const float3 g_RefractTint : register( c1 ); +const float3 g_EnvmapContrast : register( c2 ); +const float3 g_EnvmapSaturation : register( c3 ); +const float4 g_c5 : register( c5 ); +#define g_RefractScale g_c5.x +#define g_flTime g_c5.w + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +static const int g_BlurCount = BLUR; +static const float g_BlurFraction = 1.0f / 512.0f; +static const float g_HalfBlurFraction = 0.5 * g_BlurFraction; +static const float4 g_BlurFractionVec = float4( g_BlurFraction, g_HalfBlurFraction, + -g_BlurFraction,-g_HalfBlurFraction ); + +struct PS_INPUT +{ + float4 vBumpTexCoord : TEXCOORD0; // NormalMap1 in xy, NormalMap2 in wz + float3 vTangentVertToEyeVector : TEXCOORD1; + float3 vWorldNormal : TEXCOORD2; + float3 vWorldTangent : TEXCOORD3; + float3 vWorldBinormal : TEXCOORD4; + float3 vRefractXYW : TEXCOORD5; + float3 vWorldViewVector : TEXCOORD6; +#if COLORMODULATE + float4 ColorModulate : COLOR0; +#endif + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 result; + + float pixelFogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + +#if FADEOUTONSILHOUETTE + //float blend = -i.projNormal.z; + float blend = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) ); + blend = blend * blend * blend; +#else + float blend = 1.0f; +#endif + + // Decompress normal + float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord.xy, NORMAL_DECODE_MODE, AlphaMapSampler ); + +#if SECONDARY_NORMAL + float3 vNormal2 = DecompressNormal( NormalSampler2, i.vBumpTexCoord.wz, NORMAL_DECODE_MODE, AlphaMapSampler2 ); + vNormal.xyz = normalize( vNormal.xyz + vNormal2.xyz ); +#endif + +#if REFRACTTINTTEXTURE + float3 refractTintColor = 2.0 * g_RefractTint * tex2D( RefractTintSampler, i.vBumpTexCoord.xy ); +#else + float3 refractTintColor = g_RefractTint; +#endif + +#if COLORMODULATE + refractTintColor *= i.ColorModulate.rgb; +#endif + + // Perform division by W only once + float ooW = 1.0f / i.vRefractXYW.z; + + // Compute coordinates for sampling refraction + float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW; + float2 vRefractTexCoord = vNormal.xy; + float scale = vNormal.a * g_RefractScale; +#if COLORMODULATE + scale *= i.ColorModulate.a; +#endif + vRefractTexCoord *= scale; + vRefractTexCoord += vRefractTexCoordNoWarp; + +#if (BLUR==1) // use polyphase magic to convert 9 lookups into 4 + + // basic principle behind this transformation: + // [ A B C ] + // [ D E F ] + // [ G H I ] + // use bilinear filtering hardware to weight upper 2x2 samples evenly (0.25* [A + B + D + E]). + // scale the upper 2x2 by 4/9 (total area of kernel occupied) + // use bilinear filtering hardware to weight right 1x2 samples evenly (0.5*[C + F]) + // scale right 1x2 by 2/9 + // use bilinear filtering hardware to weight lower 2x1 samples evenly (0.5*[G + H]) + // scale bottom 2x1 by 2/9 + // fetch last sample (I) and scale by 1/9. + + float2 upper_2x2_loc = vRefractTexCoord.xy - float2(g_HalfBlurFraction, g_HalfBlurFraction); + float2 right_1x2_loc = vRefractTexCoord.xy + float2(g_BlurFraction, -g_HalfBlurFraction); + float2 lower_2x1_loc = vRefractTexCoord.xy + float2(-g_HalfBlurFraction, g_BlurFraction); + float2 singleton_loc = vRefractTexCoord.xy + float2(g_BlurFraction, g_BlurFraction); + result = tex2D(RefractSampler, upper_2x2_loc) * 0.4444444; + result += tex2D(RefractSampler, right_1x2_loc) * 0.2222222; + result += tex2D(RefractSampler, lower_2x1_loc) * 0.2222222; + result += tex2D(RefractSampler, singleton_loc) * 0.1111111; + + #if ( SHADER_SRGB_READ == 1 ) + { + // Just do this once rather than after every blur step, which is wrong, but much more efficient + result = GammaToLinear( result ); + } + #endif + + float3 unblurredColor = tex2D(RefractSampler, vRefractTexCoordNoWarp.xy); + #if ( SHADER_SRGB_READ == 1 ) + { + unblurredColor = GammaToLinear( unblurredColor ); + } + #endif + + result = lerp(unblurredColor, result * refractTintColor, blend); + +#elif (BLUR>0) // iteratively step through render target + int x, y; + + result = float3( 0.0f, 0.0f, 0.0f ); + for( x = -g_BlurCount; x <= g_BlurCount; x++ ) + { + for( y = -g_BlurCount; y <= g_BlurCount; y++ ) + { + result += tex2D( RefractSampler, vRefractTexCoord.xy + float2( g_BlurFraction * x, g_BlurFraction * y ) ); + } + } + + int width = g_BlurCount * 2 + 1; + result *= 1.0f / ( width * width ); + + #if ( SHADER_SRGB_READ == 1 ) + { + // Just do this once rather than after every blur step, which is wrong, but much more efficient + result = GammaToLinear( result ); + } + #endif + + // result is the blurred one now. . .now lerp. + float3 unblurredColor = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + unblurredColor = GammaToLinear( unblurredColor ); + } + #endif + + result = lerp( unblurredColor, result * refractTintColor, blend ); +#else +# if MASKED + float4 fMaskedResult = tex2D( RefractSampler, vRefractTexCoord.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + fMaskedResult = GammaToLinear( fMaskedResult ); + } + #endif + + return FinalOutput( fMaskedResult, pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE ); +# else + float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + colorWarp = GammaToLinear( colorWarp ); + } + #endif + float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + colorNoWarp = GammaToLinear( colorNoWarp ); + } + #endif + + colorWarp *= refractTintColor; + result = lerp( colorNoWarp, colorWarp, blend ); +# endif +#endif + +#if CUBEMAP + float specularFactor = vNormal.a; + + float3 worldSpaceNormal = Vec3TangentToWorld( vNormal.xyz, i.vWorldNormal, i.vWorldTangent, i.vWorldBinormal ); + + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vTangentVertToEyeVector ); + float3 specularLighting = texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint; + float3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); + float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); + result += specularLighting; +#endif + +#if COLORMODULATE + float resultAlpha = i.ColorModulate.a * vNormal.a; +#else + float resultAlpha = vNormal.a; +#endif + + return FinalOutput( float4( result, resultAlpha ), pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} |