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.
584 lines
18 KiB
584 lines
18 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
// SKIP: $BUMPMAP2 && $WARPLIGHTING
|
||
|
// SKIP: $WARPLIGHTING && $DETAILTEXTURE
|
||
|
// SKIP: $ENVMAPMASK && $BUMPMAP
|
||
|
// SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK
|
||
|
// SKIP: $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK
|
||
|
// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK
|
||
|
// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM
|
||
|
// SKIP: !$FASTPATH && $FASTPATHENVMAPCONTRAST
|
||
|
// SKIP: !$FASTPATH && $FASTPATHENVMAPTINT
|
||
|
// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP
|
||
|
// SKIP: !$BUMPMAP && $BUMPMAP2
|
||
|
// SKIP: $ENVMAPMASK && $BUMPMAP2
|
||
|
// SKIP: $BASETEXTURENOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP )
|
||
|
// SKIP: $BASETEXTURE2NOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP )
|
||
|
// SKIP: $BASEALPHAENVMAPMASK && $BUMPMAP
|
||
|
// SKIP: $PARALLAXMAP && $DETAILTEXTURE
|
||
|
// SKIP: $SEAMLESS && $RELIEF_MAPPING
|
||
|
// SKIP: $SEAMLESS && $DETAILTEXTURE
|
||
|
// SKIP: $SEAMLESS && $MASKEDBLENDING
|
||
|
// SKIP: $BUMPMASK && ( $SEAMLESS || $DETAILTEXTURE || $SELFILLUM || $BASETEXTURENOENVMAP || $BASETEXTURE2 )
|
||
|
// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 1)
|
||
|
// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 2)
|
||
|
// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 1)
|
||
|
// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 2)
|
||
|
// NOSKIP: $FANCY_BLENDING && (!$FASTPATH)
|
||
|
|
||
|
// 360 compiler craps out on some combo in this family. Content doesn't use blendmode 10 anyway
|
||
|
// SKIP: $FASTPATH && $PIXELFOGTYPE && $BASETEXTURE2 && $DETAILTEXTURE && $CUBEMAP && ($DETAIL_BLEND_MODE == 10 ) [XBOX]
|
||
|
|
||
|
// debug crap:
|
||
|
// NOSKIP: $DETAILTEXTURE
|
||
|
// NOSKIP: $CUBEMAP
|
||
|
// NOSKIP: $ENVMAPMASK
|
||
|
// NOSKIP: $BASEALPHAENVMAPMASK
|
||
|
// NOSKIP: $SELFILLUM
|
||
|
|
||
|
#define USE_32BIT_LIGHTMAPS_ON_360 //uncomment to use 32bit lightmaps, be sure to keep this in sync with the same #define in materialsystem/cmatlightmaps.cpp
|
||
|
|
||
|
#include "common_ps_fxc.h"
|
||
|
#include "common_flashlight_fxc.h"
|
||
|
#include "common_lightmappedgeneric_fxc.h"
|
||
|
|
||
|
#if SEAMLESS
|
||
|
#define USE_FAST_PATH 1
|
||
|
#else
|
||
|
#define USE_FAST_PATH FASTPATH
|
||
|
#endif
|
||
|
|
||
|
const HALF4 g_EnvmapTint : register( c0 );
|
||
|
|
||
|
#if USE_FAST_PATH == 1
|
||
|
|
||
|
# if FASTPATHENVMAPCONTRAST == 0
|
||
|
static const HALF3 g_EnvmapContrast = { 0.0f, 0.0f, 0.0f };
|
||
|
# else
|
||
|
static const HALF3 g_EnvmapContrast = { 1.0f, 1.0f, 1.0f };
|
||
|
# endif
|
||
|
static const HALF3 g_EnvmapSaturation = { 1.0f, 1.0f, 1.0f };
|
||
|
static const HALF g_FresnelReflection = 1.0f;
|
||
|
static const HALF g_OneMinusFresnelReflection = 0.0f;
|
||
|
static const HALF4 g_SelfIllumTint = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||
|
# if OUTLINE
|
||
|
const float4 g_OutlineParams : register( c2 );
|
||
|
#define OUTLINE_MIN_VALUE0 g_OutlineParams.x
|
||
|
#define OUTLINE_MIN_VALUE1 g_OutlineParams.y
|
||
|
#define OUTLINE_MAX_VALUE0 g_OutlineParams.z
|
||
|
#define OUTLINE_MAX_VALUE1 g_OutlineParams.w
|
||
|
|
||
|
const float4 g_OutlineColor : register( c3 );
|
||
|
#define OUTLINE_COLOR g_OutlineColor
|
||
|
|
||
|
# endif
|
||
|
# if SOFTEDGES
|
||
|
const float4 g_EdgeSoftnessParms : register( c4 );
|
||
|
#define SOFT_MASK_MIN g_EdgeSoftnessParms.x
|
||
|
#define SOFT_MASK_MAX g_EdgeSoftnessParms.y
|
||
|
# endif
|
||
|
#else
|
||
|
|
||
|
const HALF3 g_EnvmapContrast : register( c2 );
|
||
|
const HALF3 g_EnvmapSaturation : register( c3 );
|
||
|
const HALF4 g_FresnelReflectionReg : register( c4 );
|
||
|
#define g_FresnelReflection g_FresnelReflectionReg.a
|
||
|
#define g_OneMinusFresnelReflection g_FresnelReflectionReg.b
|
||
|
const HALF4 g_SelfIllumTint : register( c7 );
|
||
|
#endif
|
||
|
|
||
|
const float4 g_DetailTint_and_BlendFactor : register( c8 );
|
||
|
#define g_DetailTint (g_DetailTint_and_BlendFactor.rgb)
|
||
|
#define g_DetailBlendFactor (g_DetailTint_and_BlendFactor.w)
|
||
|
|
||
|
const HALF3 g_EyePos : register( c10 );
|
||
|
const HALF4 g_FogParams : register( c11 );
|
||
|
const float4 g_TintValuesAndLightmapScale : register( c12 );
|
||
|
|
||
|
#define g_flAlpha2 g_TintValuesAndLightmapScale.w
|
||
|
|
||
|
const float4 g_FlashlightAttenuationFactors : register( c13 );
|
||
|
const float3 g_FlashlightPos : register( c14 );
|
||
|
const float4x4 g_FlashlightWorldToTexture : register( c15 ); // through c18
|
||
|
const float4 g_ShadowTweaks : register( c19 );
|
||
|
|
||
|
|
||
|
sampler BaseTextureSampler : register( s0 );
|
||
|
sampler LightmapSampler : register( s1 );
|
||
|
sampler EnvmapSampler : register( s2 );
|
||
|
#if FANCY_BLENDING
|
||
|
sampler BlendModulationSampler : register( s3 );
|
||
|
#endif
|
||
|
|
||
|
#if DETAILTEXTURE
|
||
|
sampler DetailSampler : register( s12 );
|
||
|
#endif
|
||
|
|
||
|
sampler BumpmapSampler : register( s4 );
|
||
|
#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA
|
||
|
sampler AlphaMapSampler : register( s9 ); // alpha
|
||
|
#else
|
||
|
#define AlphaMapSampler BumpmapSampler
|
||
|
#endif
|
||
|
|
||
|
#if BUMPMAP2 == 1
|
||
|
sampler BumpmapSampler2 : register( s5 );
|
||
|
#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA
|
||
|
sampler AlphaMapSampler2 : register( s10 ); // alpha
|
||
|
#else
|
||
|
#define AlphaMapSampler2 BumpmapSampler2
|
||
|
#endif
|
||
|
#else
|
||
|
sampler EnvmapMaskSampler : register( s5 );
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#if WARPLIGHTING
|
||
|
sampler WarpLightingSampler : register( s6 );
|
||
|
#endif
|
||
|
sampler BaseTextureSampler2 : register( s7 );
|
||
|
|
||
|
#if BUMPMASK == 1
|
||
|
sampler BumpMaskSampler : register( s8 );
|
||
|
#if NORMALMASK_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA
|
||
|
sampler AlphaMaskSampler : register( s11 ); // alpha
|
||
|
#else
|
||
|
#define AlphaMaskSampler BumpMaskSampler
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#if defined( _X360 ) && FLASHLIGHT
|
||
|
sampler FlashlightSampler : register( s13 );
|
||
|
sampler ShadowDepthSampler : register( s14 );
|
||
|
sampler RandRotSampler : register( s15 );
|
||
|
#endif
|
||
|
|
||
|
struct PS_INPUT
|
||
|
{
|
||
|
#if SEAMLESS
|
||
|
float3 SeamlessTexCoord : TEXCOORD0; // zy xz
|
||
|
float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask
|
||
|
#else
|
||
|
HALF2 baseTexCoord : TEXCOORD0;
|
||
|
// detail textures and bumpmaps are mutually exclusive so that we have enough texcoords.
|
||
|
#if ( RELIEF_MAPPING == 0 )
|
||
|
HALF4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1;
|
||
|
#endif
|
||
|
#endif
|
||
|
// CENTROID: TEXCOORD2
|
||
|
HALF4 lightmapTexCoord1And2 : TEXCOORD2;
|
||
|
// CENTROID: TEXCOORD3
|
||
|
HALF4 lightmapTexCoord3 : TEXCOORD3;
|
||
|
HALF4 worldPos_projPosZ : TEXCOORD4;
|
||
|
HALF3x3 tangentSpaceTranspose : TEXCOORD5;
|
||
|
// tangentSpaceTranspose : TEXCOORD6
|
||
|
// tangentSpaceTranspose : TEXCOORD7
|
||
|
HALF4 vertexColor : COLOR;
|
||
|
float4 vertexBlendX_fogFactorW : COLOR1;
|
||
|
|
||
|
// Extra iterators on 360, used in flashlight combo
|
||
|
#if defined( _X360 ) && FLASHLIGHT
|
||
|
float4 flashlightSpacePos : TEXCOORD8;
|
||
|
float4 vProjPos : TEXCOORD9;
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
#if LIGHTING_PREVIEW == 2
|
||
|
LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR
|
||
|
#else
|
||
|
HALF4 main( PS_INPUT i ) : COLOR
|
||
|
#endif
|
||
|
{
|
||
|
bool bBaseTexture2 = BASETEXTURE2 ? true : false;
|
||
|
bool bDetailTexture = DETAILTEXTURE ? true : false;
|
||
|
bool bBumpmap = BUMPMAP ? true : false;
|
||
|
bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false;
|
||
|
bool bCubemap = CUBEMAP ? true : false;
|
||
|
bool bEnvmapMask = ENVMAPMASK ? true : false;
|
||
|
bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false;
|
||
|
bool bSelfIllum = SELFILLUM ? true : false;
|
||
|
bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false;
|
||
|
bool bBaseTextureNoEnvmap = BASETEXTURENOENVMAP ? true : false;
|
||
|
bool bBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP ? true : false;
|
||
|
|
||
|
float4 baseColor = 0.0f;
|
||
|
float4 baseColor2 = 0.0f;
|
||
|
float4 vNormal = float4(0, 0, 1, 1);
|
||
|
float3 baseTexCoords = float3(0,0,0);
|
||
|
|
||
|
#if SEAMLESS
|
||
|
baseTexCoords = i.SeamlessTexCoord.xyz;
|
||
|
#else
|
||
|
baseTexCoords.xy = i.baseTexCoord.xy;
|
||
|
#endif
|
||
|
|
||
|
GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpmapSampler, bBaseTexture2, bBumpmap || bNormalMapAlphaEnvmapMask,
|
||
|
baseTexCoords, i.vertexColor.rgb, baseColor, baseColor2, vNormal );
|
||
|
|
||
|
#if BUMPMAP == 1 // not ssbump
|
||
|
vNormal.xyz = vNormal.xyz * 2.0f - 1.0f; // make signed if we're not ssbump
|
||
|
#endif
|
||
|
|
||
|
HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f );
|
||
|
HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f );
|
||
|
HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f );
|
||
|
#if LIGHTING_PREVIEW == 0
|
||
|
if( bBumpmap && bDiffuseBumpmap )
|
||
|
{
|
||
|
HALF2 bumpCoord1;
|
||
|
HALF2 bumpCoord2;
|
||
|
HALF2 bumpCoord3;
|
||
|
ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy,
|
||
|
bumpCoord1, bumpCoord2, bumpCoord3 );
|
||
|
|
||
|
lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 );
|
||
|
lightmapColor2 = LightMapSample( LightmapSampler, bumpCoord2 );
|
||
|
lightmapColor3 = LightMapSample( LightmapSampler, bumpCoord3 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy );
|
||
|
lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if RELIEF_MAPPING
|
||
|
// in the parallax case, all texcoords must be the same in order to free
|
||
|
// up an iterator for the tangent space view vector
|
||
|
HALF2 detailTexCoord = i.baseTexCoord.xy;
|
||
|
HALF2 bumpmapTexCoord = i.baseTexCoord.xy;
|
||
|
HALF2 envmapMaskTexCoord = i.baseTexCoord.xy;
|
||
|
#else
|
||
|
|
||
|
#if ( DETAILTEXTURE == 1 )
|
||
|
HALF2 detailTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy;
|
||
|
HALF2 bumpmapTexCoord = i.baseTexCoord.xy;
|
||
|
#elif ( BUMPMASK == 1 )
|
||
|
HALF2 detailTexCoord = 0.0f;
|
||
|
HALF2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy;
|
||
|
HALF2 bumpmap2TexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz;
|
||
|
#else
|
||
|
HALF2 detailTexCoord = 0.0f;
|
||
|
HALF2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy;
|
||
|
#endif
|
||
|
|
||
|
HALF2 envmapMaskTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz;
|
||
|
#endif // !RELIEF_MAPPING
|
||
|
|
||
|
HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f );
|
||
|
#if DETAILTEXTURE
|
||
|
|
||
|
#if SHADER_MODEL_PS_2_0
|
||
|
detailColor = tex2D( DetailSampler, detailTexCoord );
|
||
|
#else
|
||
|
detailColor = float4( g_DetailTint, 1.0f ) * tex2D( DetailSampler, detailTexCoord );
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#if ( OUTLINE || SOFTEDGES )
|
||
|
float distAlphaMask = baseColor.a;
|
||
|
|
||
|
# if OUTLINE
|
||
|
if ( ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) &&
|
||
|
( distAlphaMask <= OUTLINE_MAX_VALUE1 ) )
|
||
|
{
|
||
|
float oFactor=1.0;
|
||
|
if ( distAlphaMask <= OUTLINE_MIN_VALUE1 )
|
||
|
{
|
||
|
oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask );
|
||
|
}
|
||
|
baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor );
|
||
|
}
|
||
|
# endif
|
||
|
# if SOFTEDGES
|
||
|
baseColor.a *= smoothstep( SOFT_MASK_MAX, SOFT_MASK_MIN, distAlphaMask );
|
||
|
# else
|
||
|
baseColor.a *= distAlphaMask >= 0.5;
|
||
|
# endif
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#if LIGHTING_PREVIEW == 2
|
||
|
baseColor.xyz=GammaToLinear(baseColor.xyz);
|
||
|
#endif
|
||
|
|
||
|
float blendedAlpha = baseColor.a;
|
||
|
|
||
|
#if MASKEDBLENDING
|
||
|
float blendfactor=0.5;
|
||
|
#else
|
||
|
float blendfactor=i.vertexBlendX_fogFactorW.r;
|
||
|
#endif
|
||
|
|
||
|
if( bBaseTexture2 )
|
||
|
{
|
||
|
#if (SELFILLUM == 0) && (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (FANCY_BLENDING)
|
||
|
float4 modt=tex2D(BlendModulationSampler,i.lightmapTexCoord3.zw);
|
||
|
#if MASKEDBLENDING
|
||
|
// FXC is unable to optimize this, despite blendfactor=0.5 above
|
||
|
//float minb=modt.g-modt.r;
|
||
|
//float maxb=modt.g+modt.r;
|
||
|
//blendfactor=smoothstep(minb,maxb,blendfactor);
|
||
|
blendfactor=modt.g;
|
||
|
#else
|
||
|
float minb=saturate(modt.g-modt.r);
|
||
|
float maxb=saturate(modt.g+modt.r);
|
||
|
blendfactor=smoothstep(minb,maxb,blendfactor);
|
||
|
#endif
|
||
|
#endif
|
||
|
baseColor.rgb = lerp( baseColor, baseColor2.rgb, blendfactor );
|
||
|
blendedAlpha = lerp( baseColor.a, baseColor2.a, blendfactor );
|
||
|
}
|
||
|
|
||
|
HALF3 specularFactor = 1.0f;
|
||
|
float4 vNormalMask = float4(0, 0, 1, 1);
|
||
|
if( bBumpmap )
|
||
|
{
|
||
|
if( bBaseTextureNoEnvmap )
|
||
|
{
|
||
|
vNormal.a = 0.0f;
|
||
|
}
|
||
|
|
||
|
#if ( BUMPMAP2 == 1 )
|
||
|
{
|
||
|
#if ( BUMPMASK == 1 )
|
||
|
HALF2 b2TexCoord = bumpmap2TexCoord;
|
||
|
#else
|
||
|
HALF2 b2TexCoord = bumpmapTexCoord;
|
||
|
#endif
|
||
|
|
||
|
HALF4 vNormal2;
|
||
|
if ( BUMPMAP == 2 )
|
||
|
vNormal2 = tex2D( BumpmapSampler2, b2TexCoord );
|
||
|
else
|
||
|
vNormal2 = DecompressNormal( BumpmapSampler2, b2TexCoord, NORMAL_DECODE_MODE, AlphaMapSampler2 ); // Bump 2 coords
|
||
|
|
||
|
if( bBaseTexture2NoEnvmap )
|
||
|
{
|
||
|
vNormal2.a = 0.0f;
|
||
|
}
|
||
|
|
||
|
#if ( BUMPMASK == 1 )
|
||
|
float3 vNormal1 = DecompressNormal( BumpmapSampler, i.detailOrBumpAndEnvmapMaskTexCoord.xy, NORMALMASK_DECODE_MODE, AlphaMapSampler );
|
||
|
|
||
|
vNormal.xyz = normalize( vNormal1.xyz + vNormal2.xyz );
|
||
|
|
||
|
// Third normal map...same coords as base
|
||
|
vNormalMask = DecompressNormal( BumpMaskSampler, i.baseTexCoord.xy, NORMALMASK_DECODE_MODE, AlphaMaskSampler );
|
||
|
|
||
|
vNormal.xyz = lerp( vNormalMask.xyz, vNormal.xyz, vNormalMask.a ); // Mask out normals from vNormal
|
||
|
specularFactor = vNormalMask.a;
|
||
|
#else // BUMPMASK == 0
|
||
|
if ( FANCY_BLENDING && bNormalMapAlphaEnvmapMask )
|
||
|
{
|
||
|
vNormal = lerp( vNormal, vNormal2, blendfactor);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
vNormal.xyz = lerp( vNormal.xyz, vNormal2.xyz, blendfactor);
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif // BUMPMAP2 == 1
|
||
|
|
||
|
if( bNormalMapAlphaEnvmapMask )
|
||
|
{
|
||
|
specularFactor *= vNormal.a;
|
||
|
}
|
||
|
}
|
||
|
else if ( bNormalMapAlphaEnvmapMask )
|
||
|
{
|
||
|
specularFactor *= vNormal.a;
|
||
|
}
|
||
|
|
||
|
#if ( BUMPMAP2 == 0 )
|
||
|
if( bEnvmapMask )
|
||
|
{
|
||
|
specularFactor *= tex2D( EnvmapMaskSampler, envmapMaskTexCoord ).xyz;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if( bBaseAlphaEnvmapMask )
|
||
|
{
|
||
|
specularFactor *= 1.0 - blendedAlpha; // Reversing alpha blows!
|
||
|
}
|
||
|
float4 albedo = float4( 1.0f, 1.0f, 1.0f, 1.0f );
|
||
|
float alpha = 1.0f;
|
||
|
albedo *= baseColor;
|
||
|
if( !bBaseAlphaEnvmapMask && !bSelfIllum )
|
||
|
{
|
||
|
alpha *= baseColor.a;
|
||
|
}
|
||
|
|
||
|
if( bDetailTexture )
|
||
|
{
|
||
|
albedo = TextureCombine( albedo, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor );
|
||
|
}
|
||
|
|
||
|
// The vertex color contains the modulation color + vertex color combined
|
||
|
#if ( SEAMLESS == 0 )
|
||
|
albedo.xyz *= i.vertexColor;
|
||
|
#endif
|
||
|
alpha *= i.vertexColor.a * g_flAlpha2; // not sure about this one
|
||
|
|
||
|
// Save this off for single-pass flashlight, since we'll still need the SSBump vector, not a real normal
|
||
|
float3 vSSBumpVector = vNormal.xyz;
|
||
|
|
||
|
HALF3 diffuseLighting;
|
||
|
if( bBumpmap && bDiffuseBumpmap )
|
||
|
{
|
||
|
|
||
|
// ssbump
|
||
|
#if ( BUMPMAP == 2 )
|
||
|
diffuseLighting = vNormal.x * lightmapColor1 +
|
||
|
vNormal.y * lightmapColor2 +
|
||
|
vNormal.z * lightmapColor3;
|
||
|
diffuseLighting *= g_TintValuesAndLightmapScale.rgb;
|
||
|
|
||
|
// now, calculate vNormal for reflection purposes. if vNormal isn't needed, hopefully
|
||
|
// the compiler will eliminate these calculations
|
||
|
vNormal.xyz = normalize( bumpBasis[0]*vNormal.x + bumpBasis[1]*vNormal.y + bumpBasis[2]*vNormal.z);
|
||
|
#else
|
||
|
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;
|
||
|
|
||
|
#if ( DETAIL_BLEND_MODE == TCOMBINE_SSBUMP_BUMP )
|
||
|
dp *= 2*detailColor;
|
||
|
#endif
|
||
|
diffuseLighting = dp.x * lightmapColor1 +
|
||
|
dp.y * lightmapColor2 +
|
||
|
dp.z * lightmapColor3;
|
||
|
float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) );
|
||
|
diffuseLighting *= g_TintValuesAndLightmapScale.rgb / sum;
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
diffuseLighting = lightmapColor1 * g_TintValuesAndLightmapScale.rgb;
|
||
|
}
|
||
|
|
||
|
#if WARPLIGHTING && ( SEAMLESS == 0 )
|
||
|
float len=0.5*length(diffuseLighting);
|
||
|
// FIXME: 8-bit lookup textures like this need a "nice filtering" VTF option, which converts
|
||
|
// them to 16-bit on load or does filtering in the shader (since most hardware - 360
|
||
|
// included - interpolates 8-bit textures at 8-bit precision, which causes banding)
|
||
|
diffuseLighting *= 2.0*tex2D(WarpLightingSampler,float2(len,0));
|
||
|
#endif
|
||
|
|
||
|
#if CUBEMAP || LIGHTING_PREVIEW || ( defined( _X360 ) && FLASHLIGHT )
|
||
|
float3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose );
|
||
|
#endif
|
||
|
|
||
|
float3 diffuseComponent = albedo.xyz * diffuseLighting;
|
||
|
|
||
|
#if defined( _X360 ) && FLASHLIGHT
|
||
|
|
||
|
// ssbump doesn't pass a normal to the flashlight...it computes shadowing a different way
|
||
|
#if ( BUMPMAP == 2 )
|
||
|
bool bHasNormal = false;
|
||
|
|
||
|
float3 worldPosToLightVector = g_FlashlightPos - i.worldPos_projPosZ.xyz;
|
||
|
|
||
|
float3 tangentPosToLightVector;
|
||
|
tangentPosToLightVector.x = dot( worldPosToLightVector, i.tangentSpaceTranspose[0] );
|
||
|
tangentPosToLightVector.y = dot( worldPosToLightVector, i.tangentSpaceTranspose[1] );
|
||
|
tangentPosToLightVector.z = dot( worldPosToLightVector, i.tangentSpaceTranspose[2] );
|
||
|
|
||
|
tangentPosToLightVector = normalize( tangentPosToLightVector );
|
||
|
|
||
|
float nDotL = saturate( vSSBumpVector.x*dot( tangentPosToLightVector, bumpBasis[0]) +
|
||
|
vSSBumpVector.y*dot( tangentPosToLightVector, bumpBasis[1]) +
|
||
|
vSSBumpVector.z*dot( tangentPosToLightVector, bumpBasis[2]) );
|
||
|
#else
|
||
|
bool bHasNormal = true;
|
||
|
float nDotL = 1.0f;
|
||
|
#endif
|
||
|
|
||
|
float fFlashlight = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, i.flashlightSpacePos,
|
||
|
worldSpaceNormal, g_FlashlightAttenuationFactors.xyz,
|
||
|
g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler,
|
||
|
RandRotSampler, 0, true, false, i.vProjPos.xy / i.vProjPos.w, false, g_ShadowTweaks, bHasNormal );
|
||
|
|
||
|
diffuseComponent = albedo.xyz * ( diffuseLighting + ( fFlashlight * nDotL ) );
|
||
|
#endif
|
||
|
|
||
|
if( bSelfIllum )
|
||
|
{
|
||
|
float3 selfIllumComponent = g_SelfIllumTint * albedo.xyz;
|
||
|
diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a );
|
||
|
}
|
||
|
|
||
|
HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f );
|
||
|
#if CUBEMAP
|
||
|
if( bCubemap )
|
||
|
{
|
||
|
float3 worldVertToEyeVector = g_EyePos - i.worldPos_projPosZ.xyz;
|
||
|
float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldVertToEyeVector );
|
||
|
|
||
|
// Calc Fresnel factor
|
||
|
half3 eyeVect = normalize(worldVertToEyeVector);
|
||
|
HALF fresnel = 1.0 - dot( worldSpaceNormal, eyeVect );
|
||
|
fresnel = pow( fresnel, 5.0 );
|
||
|
fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection;
|
||
|
|
||
|
specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect );
|
||
|
specularLighting *= specularFactor;
|
||
|
|
||
|
specularLighting *= g_EnvmapTint;
|
||
|
#if FANCY_BLENDING == 0
|
||
|
HALF3 specularLightingSquared = specularLighting * specularLighting;
|
||
|
specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast );
|
||
|
HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) );
|
||
|
specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
|
||
|
#endif
|
||
|
specularLighting *= fresnel;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
HALF3 result = diffuseComponent + specularLighting;
|
||
|
|
||
|
#if LIGHTING_PREVIEW
|
||
|
worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose );
|
||
|
# if LIGHTING_PREVIEW == 1
|
||
|
float dotprod = 0.7+0.25 * dot( worldSpaceNormal, normalize( float3( 1, 2, -.5 ) ) );
|
||
|
return FinalOutput( HALF4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
|
||
|
# else
|
||
|
LPREVIEW_PS_OUT ret;
|
||
|
ret.color = float4( albedo.xyz,alpha );
|
||
|
ret.normal = float4( worldSpaceNormal,alpha );
|
||
|
ret.position = float4( i.worldPos_projPosZ.xyz, alpha );
|
||
|
ret.flags = float4( 1, 1, 1, alpha );
|
||
|
|
||
|
return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
|
||
|
# endif
|
||
|
#else // == end LIGHTING_PREVIEW ==
|
||
|
|
||
|
bool bWriteDepthToAlpha = false;
|
||
|
|
||
|
// ps_2_b and beyond
|
||
|
#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0))
|
||
|
bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 );
|
||
|
#endif
|
||
|
|
||
|
float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w );
|
||
|
|
||
|
#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT)
|
||
|
alpha = fogFactor;
|
||
|
#endif
|
||
|
|
||
|
return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w );
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
|