You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
5.7 KiB
190 lines
5.7 KiB
// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] |
|
// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] |
|
// STATIC: "BASETEXTURE" "0..1" |
|
// STATIC: "REFLECT" "0..1" |
|
// STATIC: "REFRACT" "0..1" |
|
// STATIC: "ENVMAPMASK" "0..1" |
|
|
|
// DYNAMIC: "PIXELFOGTYPE" "0..1" |
|
// 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" |
|
|
|
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 HALF4 vRefractTint : register( c1 ); |
|
const float4 g_FresnelConstants : register( c3 ); |
|
const HALF4 vReflectTint : register( c4 ); |
|
const float4 g_ReflectRefractScale : register( c5 ); // xy - reflect scale, zw - refract scale |
|
|
|
const float4 g_PixelFogParams : register( c8 ); |
|
|
|
|
|
static const bool g_bReflect = REFLECT ? true : false; |
|
static const bool g_bRefract = REFRACT ? true : false; |
|
|
|
struct PS_INPUT |
|
{ |
|
float4 vBumpTexCoordXY_vTexCoordXY : TEXCOORD0; |
|
half3 vTangentEyeVect : TEXCOORD1; |
|
float4 vReflectXY_vRefractYX : TEXCOORD2; |
|
float W : TEXCOORD3; |
|
float4 vProjPos : TEXCOORD4; |
|
float screenCoord : TEXCOORD5; |
|
#if BASETEXTURE |
|
// CENTROID: TEXCOORD6 |
|
HALF4 lightmapTexCoord1And2 : TEXCOORD6; |
|
// CENTROID: TEXCOORD7 |
|
HALF4 lightmapTexCoord3 : TEXCOORD7; |
|
#endif |
|
|
|
float4 fogFactorW : COLOR1; |
|
}; |
|
|
|
float4 main( PS_INPUT i ) : COLOR |
|
{ |
|
// Load normal and expand range |
|
HALF4 vNormalSample = tex2D( NormalSampler, i.vBumpTexCoordXY_vTexCoordXY.xy ); |
|
HALF3 vNormal = normalize( vNormalSample * 2.0 - 1.0 ); |
|
|
|
// Perform division by W only once |
|
float ooW = 1.0f / i.W; |
|
|
|
float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW; |
|
|
|
float4 reflectRefractScale = g_ReflectRefractScale; |
|
|
|
// Compute coordinates for sampling Reflection |
|
float2 vReflectTexCoord; |
|
float2 vRefractTexCoord; |
|
|
|
// vectorize the dependent UV calculations (reflect = .xy, refract = .wz) |
|
#ifdef NV3X |
|
float4 vDependentTexCoords = vNormal.xyxy * vNormalSample.a * reflectRefractScale; |
|
#else |
|
float4 vN; |
|
vN.xy = vNormal.xy; |
|
vN.w = vNormal.x; |
|
vN.z = vNormal.y; |
|
float4 vDependentTexCoords = vN * vNormalSample.a * reflectRefractScale; |
|
#endif |
|
|
|
vDependentTexCoords += ( i.vReflectXY_vRefractYX * ooW ); |
|
vReflectTexCoord = vDependentTexCoords.xy; |
|
vRefractTexCoord = vDependentTexCoords.wz; |
|
|
|
// Sample reflection and refraction |
|
HALF4 vReflectColor = tex2D( ReflectSampler, vReflectTexCoord ); |
|
HALF4 vRefractColor = tex2D( RefractSampler, vRefractTexCoord ); |
|
vReflectColor *= vReflectTint; |
|
vRefractColor *= vRefractTint; |
|
|
|
half3 vEyeVect; |
|
vEyeVect = normalize( i.vTangentEyeVect ); |
|
|
|
// Fresnel term |
|
HALF fNdotV = saturate( dot( vEyeVect, vNormal ) ); |
|
HALF fFresnelScalar = g_FresnelConstants.x * pow( 1.0 - fNdotV, g_FresnelConstants.y ) + g_FresnelConstants.z; |
|
HALF4 fFresnel = HALF4( fFresnelScalar, fFresnelScalar, fFresnelScalar, fFresnelScalar ); |
|
|
|
#if BASETEXTURE |
|
float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoordXY_vTexCoordXY.zw ); |
|
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 |
|
|
|
float4 flMask; |
|
#if ENVMAPMASK |
|
flMask = tex2D( EnvMapMaskSampler, i.vBumpTexCoordXY_vTexCoordXY.zw ); |
|
#else |
|
flMask = float4( 1.0f, 1.0f, 1.0f, 1.0f ); |
|
#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; |
|
float flAlpha = 1.0f; |
|
if( g_bReflect && g_bRefract ) |
|
{ |
|
result = lerp( vRefractColor, vReflectColor, fFresnel ) * flMask; |
|
#if BASETEXTURE |
|
result += float4( diffuseComponent, 1.0f ); |
|
flAlpha = baseSample.a; |
|
#endif |
|
} |
|
else if( g_bReflect ) |
|
{ |
|
#if BASETEXTURE |
|
result = float4( diffuseComponent, 1.0f ) + vReflectColor * flMask; |
|
flAlpha = baseSample.a; |
|
#else |
|
result = vReflectColor; |
|
#endif |
|
} |
|
else if( g_bRefract ) |
|
{ |
|
#if BASETEXTURE |
|
result = float4( diffuseComponent, 1.0f ) + vRefractColor * flMask; |
|
flAlpha = baseSample.a; |
|
#else |
|
result = vRefractColor; |
|
#endif |
|
} |
|
else |
|
{ |
|
#if BASETEXTURE |
|
result = float4( diffuseComponent, 1.0f ); |
|
flAlpha = baseSample.a; |
|
#else |
|
result = float4( 0.0f, 0.0f, 0.0f, 0.0f ); |
|
#endif |
|
} |
|
|
|
|
|
#if ( PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) |
|
float fogFactor = CalcRangeFog( i.vProjPos.z, g_PixelFogParams.x, g_PixelFogParams.z, g_PixelFogParams.w ); |
|
#else |
|
float fogFactor = 0; |
|
#endif |
|
|
|
return FinalOutput( float4( result.rgb, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.vProjPos.z ); |
|
} |
|
|
|
|