sqwarmed/sdk_src/materialsystem/stdshaders/lightmappedreflective_ps2x.fxc

185 lines
6.0 KiB
Plaintext

//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "BASETEXTURE" "0..1"
// STATIC: "REFLECT" "0..1"
// STATIC: "REFRACT" "0..1"
// STATIC: "ENVMAPMASK" "0..1"
#include "common_fog_ps_fxc.h"
// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC]
// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX]
#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 RefractSampler : register( s0 );
sampler BaseTextureSampler : register( s1 );
sampler ReflectSampler : register( s2 );
#if BASETEXTURE
sampler LightmapSampler : register( s3 );
#endif
#if ENVMAPMASK
sampler EnvMapMaskSampler : register( s6 );
#endif
sampler NormalSampler : register( s4 );
const float4 g_vRefractTint : register( c1 );
const float g_flReflectance : register( c3 );
const float4 g_vReflectTint : register( c4 );
const float4 g_ReflectRefractScale : register( c5 ); // xy - reflect scale, zw - refract scale
const float4 g_PixelFogParams : register( PSREG_FOG_PARAMS );
const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT );
static const bool g_bReflect = REFLECT ? true : false;
static const bool g_bRefract = REFRACT ? true : false;
struct PS_INPUT
{
float4 vBumpTexCoordXY_vTexCoordXY : TEXCOORD0;
float4 vPositionToCameraRayTs_projW : TEXCOORD1;
float4 vReflectXY_vRefractYX : TEXCOORD2;
float4 vProjPos : TEXCOORD4;
float3 worldPos : TEXCOORD5;
#if BASETEXTURE
// CENTROID: TEXCOORD6
float4 lightmapTexCoord1And2 : TEXCOORD6;
// CENTROID: TEXCOORD7
float4 lightmapTexCoord3 : TEXCOORD7;
#endif
};
float4 main( PS_INPUT i ) : COLOR
{
// Load normal and expand range
float4 vNormalTexel = tex2D( NormalSampler, i.vBumpTexCoordXY_vTexCoordXY.xy );
float3 vNormalTs = normalize( ( vNormalTexel.xyz * 2.0 ) - 1.0 );
// Perform division by W only once
float ooW = 1.0f / i.vPositionToCameraRayTs_projW.w;
//float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW;
// Vectorize the dependent UV calculations (reflect = .xy, refract = .wz)
#ifdef NV3X
float4 vDependentTexCoords = vNormalTs.xyxy * vNormalTexel.a * g_ReflectRefractScale.xyzw;
#else
float4 vN;
vN.xy = vNormalTs.xy;
vN.w = vNormalTs.x;
vN.z = vNormalTs.y;
float4 vDependentTexCoords = vN * vNormalTexel.a * g_ReflectRefractScale.xyzw;
#endif
vDependentTexCoords.xyzw += i.vReflectXY_vRefractYX.xyzw * ooW;
float2 vReflectTexCoord = vDependentTexCoords.xy;
float2 vRefractTexCoord = vDependentTexCoords.wz;
// Sample reflection
float3 vReflectColor = float3( 0.0f, 0.0f, 0.0f );
#if ( REFLECT )
{
vReflectColor.rgb = tex2D( ReflectSampler, vReflectTexCoord ).rgb;
vReflectColor.rgb *= g_vReflectTint.rgb;
}
#endif
// Sample refraction
float3 vRefractColor = float3( 0.0f, 0.0f, 0.0f );
#if ( REFRACT )
{
vRefractColor = tex2D( RefractSampler, vRefractTexCoord );
vRefractColor.rgb *= g_vRefractTint.rgb;
}
#endif
// Schlick Fresnel
float3 vPositionToCameraDirTs = normalize( i.vPositionToCameraRayTs_projW.xyz );
float flNdotV = saturate( dot( vPositionToCameraDirTs.xyz, vNormalTs.xyz ) );
float flFresnel = g_flReflectance + ( ( 1.0f - g_flReflectance ) * pow( 1.0f - flNdotV, 5.0f ) );
//flFresnel = 1.0f - flFresnel;
//return flFresnel;
float flRefractMask = 0.0f;
#if BASETEXTURE
float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoordXY_vTexCoordXY.zw );
flRefractMask = baseSample.a;
float2 bumpCoord1;
float2 bumpCoord2;
float2 bumpCoord3;
ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy,
bumpCoord1, bumpCoord2, bumpCoord3 );
float4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 );
float3 lightmapColor1 = lightmapSample1.rgb;
float3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 );
float3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 );
float3 dp;
dp.x = saturate( dot( vNormalTs, bumpBasis[0] ) );
dp.y = saturate( dot( vNormalTs, bumpBasis[1] ) );
dp.z = saturate( dot( vNormalTs, 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;
float3 diffuseComponent = baseSample.rgb * diffuseLighting;
#endif
// Mask
float3 vSpecMask = float3( 1.0f, 1.0f, 1.0f );
#if ( REFLECT && ENVMAPMASK )
{
vSpecMask.rgb = tex2D( EnvMapMaskSampler, i.vBumpTexCoordXY_vTexCoordXY.zw ).rgb;
}
#endif
// NOTE: the BASETEXTURE path hasn't been tested (or really written for that matter, just copied from water)
// What I think should happen is that the alpha of base texture should be its 'translucency'
// which should indicate how much refraction to use.
// We should add an envmapmask to deal with how much reflection to use
// along with all the focus, etc. features
float4 result = float4( 0.0f, 0.0f, 0.0f, 1.0f );
#if ( REFLECT || REFRACT )
{
// Refraction
result.rgb = vRefractColor.rgb * ( 1.0f - flFresnel );
// Add in diffuse component applying fresnel to pixels with no spec mask
#if ( BASETEXTURE )
{
result.rgb += lerp( diffuseComponent.rgb, diffuseComponent.rgb * ( 1.0f - flFresnel ), vSpecMask.rgb );
}
#endif
// Add reflection
result.rgb += ( vReflectColor.rgb * flFresnel ) * vSpecMask.rgb;
}
#else // No reflect or refract
{
#if ( BASETEXTURE )
{
result.rgba = float4( diffuseComponent.rgb, flRefractMask );
}
#endif
}
#endif
float fogFactor = 0.0f;
#if ( PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE )
{
fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_PixelFogParams, g_EyePos.xyz, i.worldPos.xyz, i.vProjPos.z );
}
#endif
return FinalOutput( result.rgba, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, ( WRITE_DEPTH_TO_DESTALPHA != 0 ), i.vProjPos.z );
}