1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-19 12:06:07 +08:00
Files
hl2sdk/materialsystem/stdshaders/refract_ps2x.fxc
Scott Ehlert fdd0bbf277 SDK sync.
2012-07-06 20:35:59 -05:00

249 lines
8.7 KiB
Plaintext

//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "MAGNIFY" "0..1"
// 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: "MIRRORABOUTVIEWPORTEDGES" "0..1" [XBOX]
// STATIC: "MIRRORABOUTVIEWPORTEDGES" "0..0" [PC]
#include "common_fog_ps_fxc.h"
// 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
#ifdef _X360
#define SHADER_SRGB_READ 1
#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
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_NormalizedViewportMinXYMaxWZ : register( c4 );
const float4 g_c5 : register( c5 );
#define g_RefractScale g_c5.x
#define g_flTime g_c5.w
const float4 g_c6 : register( c6 );
#define g_vMagnifyCenter g_c6.xy
#define g_flInverseMagnifyScale g_c6.z
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 main( PS_INPUT i ) : COLOR
{
float3 result;
float pixelFogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w );
#if FADEOUTONSILHOUETTE || CUBEMAP
float3 vWorldNormal = i.vWorldNormal;
#endif
#if FADEOUTONSILHOUETTE
//float blend = -i.projNormal.z;
float blend = saturate( dot( -i.vWorldViewVector.xyz, vWorldNormal.xyz ) );
blend = blend * blend * blend;
#else
float blend = 1.0f;
#endif
// Sample normal
float4 normalTexel = tex2D( NormalSampler, i.vBumpTexCoord.xy );
float4 vNormal = float4( normalTexel.xyz * 2.0f - 1.0f, normalTexel.a );
#if SECONDARY_NORMAL
float3 vNormal2 = tex2D( NormalSampler, i.vBumpTexCoord.wz ).xyz * 2.0f - 1.0f;
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;
#if ( MAGNIFY )
{
vRefractTexCoord += float2( 0.5, 0.5 ) + float2( g_vMagnifyCenter.x, g_vMagnifyCenter.y );
vRefractTexCoord += ( vRefractTexCoordNoWarp - float2( 0.5, 0.5 ) - float2( g_vMagnifyCenter.x, g_vMagnifyCenter.y ) ) * g_flInverseMagnifyScale;
}
#else
{
vRefractTexCoord += vRefractTexCoordNoWarp;
}
#endif
#if ( MIRRORABOUTVIEWPORTEDGES )
{
//
// need to mirror the texcoords on every border so that one splitscreen viewport doesn't bleed into another one.
//
// mirror on the min viewport in both dimensions
vRefractTexCoord.xy -= g_NormalizedViewportMinXYMaxWZ.xy;
vRefractTexCoord.xy = abs( vRefractTexCoord.xy );
vRefractTexCoord.xy += g_NormalizedViewportMinXYMaxWZ.xy;
// mirror on the max viewport in both dimensions
vRefractTexCoord.xy = g_NormalizedViewportMinXYMaxWZ.wz - vRefractTexCoord.xy;
vRefractTexCoord.xy = abs( vRefractTexCoord.xy );
vRefractTexCoord.xy = g_NormalizedViewportMinXYMaxWZ.wz - vRefractTexCoord.xy;
}
#endif
#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 ( IsX360() )
{
result.rgb = X360GammaToLinear( result.rgb );
}
float3 unblurredColor = tex2Dsrgb(RefractSampler, vRefractTexCoordNoWarp.xy);
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 ) );
}
}
if ( IsX360() )
{
result.rgb = X360GammaToLinear( result.rgb );
}
int width = g_BlurCount * 2 + 1;
result *= 1.0f / ( width * width );
// result is the blurred one now. . .now lerp.
float3 unblurredColor = tex2Dsrgb( RefractSampler, vRefractTexCoordNoWarp.xy );
result = lerp( unblurredColor, result * refractTintColor, blend );
#else
#if MASKED
float4 fMaskedResult = tex2Dsrgb( RefractSampler, vRefractTexCoord.xy );
return FinalOutput( fMaskedResult, pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE );
#else
float3 colorWarp = tex2Dsrgb( RefractSampler, vRefractTexCoord.xy );
float3 colorNoWarp = tex2Dsrgb( RefractSampler, vRefractTexCoordNoWarp.xy );
colorWarp *= refractTintColor;
result = lerp( colorNoWarp, colorWarp, blend );
#endif
#endif
#if CUBEMAP
float specularFactor = vNormal.a;
float3 worldSpaceNormal = Vec3TangentToWorld( vNormal.xyz, 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 );
}