mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 12:06:07 +08:00
133 lines
4.1 KiB
Plaintext
133 lines
4.1 KiB
Plaintext
// STATIC: "MULTITEXTURE" "0..1"
|
|
// STATIC: "FRESNEL" "0..1"
|
|
// STATIC: "BLEND" "0..1"
|
|
// STATIC: "REFRACTALPHA" "0..1"
|
|
// STATIC: "HDRTYPE" "0..2"
|
|
|
|
// DYNAMIC: "HDRENABLED" "0..1"
|
|
// DYNAMIC: "FOGTYPE" "0..2"
|
|
|
|
#include "common_ps_fxc.h"
|
|
|
|
const HALF3 g_FogColor : register( c0 );
|
|
const HALF4 g_CheapWaterParams : register( c1 );
|
|
const HALF4 g_ReflectTint : register( c2 );
|
|
|
|
#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;
|
|
HALF4 worldSpaceEyeVect : TEXCOORD1;
|
|
HALF3x3 tangentSpaceTranspose : TEXCOORD2;
|
|
#if REFRACTALPHA
|
|
float3 vRefract_W : TEXCOORD5;
|
|
#endif
|
|
#if MULTITEXTURE
|
|
float4 vExtraBumpTexCoord : TEXCOORD6;
|
|
#endif
|
|
float4 fogFactorW : COLOR1;
|
|
};
|
|
|
|
HDR_PS_OUTPUT main( PS_INPUT i ) : COLOR
|
|
{
|
|
bool bBlend = BLEND ? true : false;
|
|
|
|
HALF4 normalTexel = tex2D( NormalMapSampler, i.normalMapTexCoord );
|
|
#if MULTITEXTURE
|
|
HALF4 vNormalSample1 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.xy );
|
|
HALF4 vNormalSample2 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.zw );
|
|
normalTexel=0.33*(normalTexel+vNormalSample1+vNormalSample2);
|
|
#endif
|
|
HALF3 tangentNormal = 2.0 * normalTexel - 1.0;
|
|
|
|
HALF3 worldSpaceNormal = mul( tangentNormal, 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.z;
|
|
float2 unwarpedRefractTexCoord = i.vRefract_W * 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_FogColor, specularLighting, flFresnelFactor );
|
|
#else
|
|
specularLighting = lerp( GammaToLinear( g_FogColor ), specularLighting, flFresnelFactor );
|
|
#endif
|
|
}
|
|
|
|
|
|
// multiply the color by alpha.since we are using alpha blending to blend against dest alpha for borders.
|
|
return LinearColorToHDROutput( HALF4( specularLighting, flAlpha ), i.fogFactorW.w );
|
|
}
|