mirror of
https://github.com/celisej567/cool-source-archive.git
synced 2026-01-05 22:10:07 +03:00
697 lines
25 KiB
Plaintext
697 lines
25 KiB
Plaintext
//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======//
|
|
//
|
|
//=============================================================================//
|
|
// STATIC: "DETAILTEXTURE" "0..1"
|
|
// STATIC: "BUMPMAP" "0..1"
|
|
// STATIC: "CUBEMAP" "0..1"
|
|
// STATIC: "DIFFUSELIGHTING" "0..1"
|
|
// STATIC: "ENVMAPMASK" "0..1"
|
|
// STATIC: "BASEALPHAENVMAPMASK" "0..1"
|
|
// STATIC: "SELFILLUM" "0..1"
|
|
// STATIC: "SELFILLUMMASK" "0..1"
|
|
// STATIC: "SELFILLUMFRESNEL" "0..1"
|
|
// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1"
|
|
// STATIC: "HALFLAMBERT" "0..1"
|
|
// STATIC: "LIGHTWARPTEXTURE" "0..1"
|
|
// STATIC: "VERTEXCOLOR" "0..1"
|
|
// DYNAMIC: "FLASHLIGHT" "0..1"
|
|
// STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1"
|
|
// STATIC: "SEAMLESS_BASE" "0..1"
|
|
// STATIC: "SEAMLESS_DETAIL" "0..1"
|
|
// STATIC: "DISTANCEALPHA" "0..1"
|
|
// STATIC: "DISTANCEALPHAFROMDETAIL" "0..1"
|
|
// STATIC: "SOFT_MASK" "0..1"
|
|
// STATIC: "OUTLINE" "0..1"
|
|
// STATIC: "OUTER_GLOW" "0..1"
|
|
// DYNAMIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2"
|
|
// STATIC: "DEPTHBLEND" "0..1"
|
|
// STATIC: "ALPHATEST" "0..1"
|
|
|
|
// Stuff from the "skin" shader
|
|
|
|
// STATIC: "BLENDTINTBYBASEALPHA" "0..1"
|
|
|
|
// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1"
|
|
// DYNAMIC: "AMBIENT_LIGHT" "0..1"
|
|
// DYNAMIC: "PHONG" "0..1"
|
|
// DYNAMIC: "WRINKLEMAP" "0..1"
|
|
// DYNAMIC: "PHONGWARPTEXTURE" "0..1"
|
|
// DYNAMIC: "RIMLIGHT" "0..1"
|
|
|
|
// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && ( $SELFILLUM == 0 )
|
|
// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && $SEAMLESS_BASE
|
|
// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && $DISTANCEALPHA
|
|
// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && $LIGHTING_PREVIEW
|
|
// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && $FLASHLIGHT
|
|
|
|
// SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK && $SELFILLUM_ENVMAPMASK_ALPHA
|
|
// SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK
|
|
// SKIP: $NORMALMAPALPHAENVMAPMASK && $SELFILLUM_ENVMAPMASK_ALPHA
|
|
// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM_ENVMAPMASK_ALPHA
|
|
|
|
// SKIP: ($CASCADED_SHADOW) && ($FLASHLIGHT)
|
|
// SKIP: ($CASCADED_SHADOW) && ($SEAMLESS_BASE)
|
|
// SKIP: ($CASCADED_SHADOW) && ($SEAMLESS_DETAIL)
|
|
// SKIP: ($CASCADED_SHADOW) && (!$DIFFUSELIGHTING)
|
|
// SKIP: ($CASCADED_SHADOW) && (!$DIFFUSELIGHTING)
|
|
// SKIP: ($CASCADED_SHADOW) && ($VERTEXCOLOR)
|
|
// SKIP: (!$CASCADED_SHADOW) && ($TWO_SIDED_LIGHTING)
|
|
|
|
// detail blend mode 6 = ps20b only
|
|
// SKIP: $DETAIL_BLEND_MODE == 6 [ps20]
|
|
|
|
// SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 )
|
|
// SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL )
|
|
// SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL)
|
|
// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK
|
|
// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM
|
|
// SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA
|
|
// SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK)
|
|
// _SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS)
|
|
// SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL)
|
|
// SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW)
|
|
// SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL)
|
|
|
|
// We don't care about flashlight depth unless the flashlight is on
|
|
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS ) [ps20b]
|
|
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS ) [ps30]
|
|
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS ) [ps40]
|
|
|
|
// We don't care about uberlight unless the flashlight is on
|
|
// SKIP: ( $FLASHLIGHT == 0 ) && ( $UBERLIGHT == 1 ) [ps30]
|
|
|
|
// Flashlight shadow filter mode is irrelevant if there is no flashlight
|
|
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b]
|
|
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30]
|
|
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps40]
|
|
|
|
// DISTANCEALPHA-related skips
|
|
// SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA )
|
|
// SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW )
|
|
// SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER )
|
|
|
|
// SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER
|
|
// SKIP: $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA )
|
|
|
|
// BlendTintByBaseAlpha is incompatible with other interpretations of alpha
|
|
// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK)
|
|
|
|
// _SKIP: $FLASHLIGHT && $CUBEMAP
|
|
|
|
// _SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0)
|
|
|
|
// Debugging luxels only makes sense if we have lightmaps on this geometry.
|
|
// _SKIP: ($STATIC_LIGHT_LIGHTMAP == 0) && ($DEBUG_LUXELS == 1)
|
|
|
|
// Only need self illum fresnel when self illum enabled
|
|
// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 )
|
|
// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMMASK == 1 )
|
|
// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $SELFILLUMMASK == 1 )
|
|
// _SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) [PC]
|
|
// _SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) [PC]
|
|
// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 )
|
|
// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 )
|
|
// Meaningless combinations
|
|
// SKIP: $NORMALMAPALPHAENVMAPMASK && !$CUBEMAP
|
|
|
|
// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 )
|
|
|
|
// Don't do diffuse warp on flashlight
|
|
// _SKIP: ( $FLASHLIGHT == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) [PC]
|
|
|
|
#include "common_cbuffers_def_noskinning_fxc.h"
|
|
|
|
#include "shader_register_map.h"
|
|
#include "common_flashlight_fxc.h"
|
|
#include "common_vertexlitgeneric_dx11.h"
|
|
#include "vertexlitgeneric_dx11_shared.h"
|
|
|
|
cbuffer VertexLitAndUnlitGeneric_t : register(b3)
|
|
{
|
|
VertexLitAndUnlitGeneric_t c;
|
|
};
|
|
|
|
#define g_DiffuseModulation c.cModulationColor
|
|
#define g_EyePos cEyePos
|
|
|
|
#define g_SelfIllumTint c.g_SelfIllumTint_and_BlendFactor.xyz
|
|
#define g_DetailBlendFactor c.g_SelfIllumTint_and_BlendFactor.w
|
|
#define g_EnvmapSaturation c.g_EnvmapSaturation_SelfIllumMask.xyz
|
|
#define g_SelfIllumMaskControl c.g_EnvmapSaturation_SelfIllumMask.w
|
|
|
|
#define g_FresnelRanges c.g_FresnelSpecParams.xyz
|
|
#define g_SpecularBoost c.g_FresnelSpecParams.w
|
|
#define g_SpecularTint c.g_SpecularRimParams.xyz
|
|
#define g_RimExponent c.g_SpecularRimParams.w
|
|
#define g_fRimBoost c.g_RimPhongParams.x
|
|
#define g_RimMaskControl c.g_RimPhongParams.y
|
|
#define g_fBaseMapAlphaPhongMask c.g_RimPhongParams.z
|
|
#define g_fInvertPhongMask c.g_RimPhongParams.w
|
|
|
|
#define g_FlashlightAttenuationFactors cFlashlightAttenuationFactors
|
|
#define g_FlashlightPos cFlashlightPos
|
|
#define g_FlashlightWorldToTexture cFlashlightWorldToTexture
|
|
|
|
#define g_SelfIllumTwoTextureBlend c.g_EnvmapSaturation_SelfIllumMask.w
|
|
|
|
#define g_fPixelFogType c.g_ShaderControls.x
|
|
#define g_fWriteDepthToAlpha c.g_ShaderControls.y
|
|
#define g_fWriteWaterFogToDestAlpha c.g_ShaderControls.z
|
|
|
|
Texture2D BaseTexture : register( t0 );
|
|
sampler BaseTextureSampler : register( s0 );
|
|
|
|
#if PHONG
|
|
Texture2D SpecularWarpTexture : register( t3 );
|
|
sampler SpecularWarpSampler : register( s3 );
|
|
|
|
Texture2D SpecExponentTexture : register( t4 );
|
|
sampler SpecExponentSampler : register( s4 );
|
|
#endif
|
|
|
|
#if BUMPMAP
|
|
Texture2D BumpmapTexture : register( t1 );
|
|
sampler BumpmapSampler : register( s1 );
|
|
#endif
|
|
|
|
#if CUBEMAP
|
|
TextureCube EnvmapTexture : register( t2 );
|
|
sampler EnvmapSampler : register( s2 );
|
|
#endif
|
|
|
|
#if ENVMAPMASK
|
|
Texture2D EnvmapMaskTexture : register( t5 );
|
|
sampler EnvmapMaskSampler : register( s5 );
|
|
#endif
|
|
|
|
#if SELFILLUMMASK
|
|
Texture2D SelfIllumMaskTexture : register( t6 );
|
|
sampler SelfIllumMaskSampler : register( s6 ); // selfillummask
|
|
#endif
|
|
|
|
#if FLASHLIGHT
|
|
Texture2D FlashlightTexture : register( t7 );
|
|
sampler FlashlightSampler : register( s7 );
|
|
#endif
|
|
|
|
#if FLASHLIGHT && FLASHLIGHTSHADOWS
|
|
Texture2D ShadowDepthTexture : register( t8 );
|
|
sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler
|
|
#endif
|
|
|
|
#if LIGHTWARPTEXTURE
|
|
Texture2D DiffuseWarpTexture : register( t9 );
|
|
sampler DiffuseWarpSampler : register( s9 );
|
|
#else
|
|
#define DiffuseWarpTexture BaseTexture
|
|
#define DiffuseWarpSampler BaseTextureSampler
|
|
#endif
|
|
|
|
#if DEPTHBLEND
|
|
Texture2D DepthTexture : register( t10 );
|
|
sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending
|
|
#endif
|
|
|
|
#if DETAILTEXTURE
|
|
Texture2D DetailTexture : register( t11 );
|
|
sampler DetailSampler : register( s11 );
|
|
#endif
|
|
|
|
#if WRINKLEMAP
|
|
Texture2D WrinkleTexture : register( t12 );
|
|
sampler WrinkleSampler : register( t12 );
|
|
|
|
Texture2D StretchTexture : register( t13 );
|
|
sampler StretchSampler : register( s13 );
|
|
|
|
Texture2D NormalWrinkleTexture : register( t14 );
|
|
sampler NormalWrinkleSampler : register( s14 );
|
|
|
|
Texture2D NormalStretchTexture : register( t15 );
|
|
sampler NormalStretchTexture : register( s15 );
|
|
#endif
|
|
|
|
struct PS_INPUT
|
|
{
|
|
float4 projPos : SV_POSITION;
|
|
#if SEAMLESS_BASE
|
|
float3 baseTexCoord : TEXCOORD0; // Base texture coordinate
|
|
#else
|
|
float2 baseTexCoord : TEXCOORD0; // Base texture coordinate
|
|
#endif
|
|
#if SEAMLESS_DETAIL
|
|
float3 detailTexCoord : TEXCOORD1; // Seamless texture coordinate
|
|
#else
|
|
float2 detailTexCoord : TEXCOORD1; // Detail texture coordinate
|
|
#endif
|
|
float4 color : TEXCOORD2; // Vertex color (from lighting or unlit)
|
|
|
|
float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection
|
|
|
|
float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight
|
|
float4 worldPos_projPosZ : TEXCOORD5;
|
|
#if BUMPMAP
|
|
float4 vWorldTangent : TEXCOORD6;
|
|
#endif
|
|
#if WRINKLEMAP
|
|
float4 wrinkleHeight : TEXCOORD7;
|
|
#endif
|
|
#if SEAMLESS_BASE || SEAMLESS_DETAIL
|
|
float3 SeamlessWeights : COLOR0; // x y z projection weights
|
|
#endif
|
|
float3 eyeSpacePos : COLOR1;
|
|
};
|
|
|
|
#define GLOW_UV_OFFSET c.g_GlowParameters.xy
|
|
#define OUTER_GLOW_MIN_DVALUE c.g_GlowParameters.z
|
|
#define OUTER_GLOW_MAX_DVALUE c.g_GlowParameters.w
|
|
#define OUTER_GLOW_COLOR c.g_GlowColor
|
|
|
|
#define g_fPixelFogType c.g_ShaderControls.x
|
|
#define g_fWriteDepthToAlpha c.g_ShaderControls.y
|
|
#define g_fWriteWaterFogToDestAlpha c.g_ShaderControls.z
|
|
#define g_fVertexAlpha c.g_ShaderControls.w
|
|
|
|
#define SOFT_MASK_MAX c.g_DistanceAlphaParams.x
|
|
#define SOFT_MASK_MIN c.g_DistanceAlphaParams.y
|
|
|
|
#define OUTLINE_COLOR c.g_OutlineColor
|
|
|
|
// these are ordered this way for optimal ps20 swizzling
|
|
#define OUTLINE_MIN_VALUE0 c.g_OutlineParams.x
|
|
#define OUTLINE_MAX_VALUE1 c.g_OutlineParams.y
|
|
#define OUTLINE_MAX_VALUE0 c.g_OutlineParams.z
|
|
#define OUTLINE_MIN_VALUE1 c.g_OutlineParams.w
|
|
|
|
// Calculate unified fog
|
|
float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ )
|
|
{
|
|
float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.y, fogParams.z );
|
|
float fHeightFog = CalcWaterFogAlpha( fogParams.w, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.x );
|
|
return lerp( fRangeFog, fHeightFog, fPixelFogType );
|
|
}
|
|
|
|
// Blend both types of Fog and lerp to get result
|
|
float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType )
|
|
{
|
|
pixelFogFactor = saturate( pixelFogFactor );
|
|
float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog
|
|
float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) );
|
|
return lerp( fRangeResult, fHeightResult, fPixelFogType );
|
|
}
|
|
|
|
|
|
float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ )
|
|
{
|
|
float4 result = vShaderColor;
|
|
if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR )
|
|
{
|
|
result.rgb *= LINEAR_LIGHT_SCALE;
|
|
}
|
|
else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA )
|
|
{
|
|
result.rgb *= GAMMA_LIGHT_SCALE;
|
|
}
|
|
|
|
result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha );
|
|
|
|
result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, c.g_FogColor.rgb, fPixelFogType );
|
|
result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion
|
|
|
|
return result;
|
|
}
|
|
|
|
float4 main( PS_INPUT i ) : SV_TARGET
|
|
{
|
|
bool bDetailTexture = DETAILTEXTURE ? true : false;
|
|
bool bCubemap = CUBEMAP ? true : false;
|
|
bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false;
|
|
bool bDiffuseLighting = DIFFUSELIGHTING ? true : false;
|
|
bool bHasNormal = bCubemap || bDiffuseLighting;
|
|
bool bEnvmapMask = ENVMAPMASK ? true : false;
|
|
bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false;
|
|
bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false;
|
|
bool bSelfIllum = SELFILLUM ? true : false;
|
|
bool bSelfIllumFresnel = SELFILLUMFRESNEL ? true : false;
|
|
bool bVertexColor = VERTEXCOLOR ? true : false;
|
|
bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false;
|
|
bool bFlashlight = (FLASHLIGHT!=0) ? true : false;
|
|
bool bAmbientLight = AMBIENT_LIGHT ? true : false;
|
|
bool bHalfLambert = HALFLAMBERT ? true : false;
|
|
bool bPhong = PHONG ? true : false;
|
|
bool bRimLight = RIMLIGHT ? true : false;
|
|
bool bDoSpecularWarp = PHONGWARPTEXTURE ? true : false;
|
|
const int nNumLights = cLightCount.x;
|
|
|
|
#if FLASHLIGHT
|
|
return float4(1, 0,0, 1);
|
|
#endif
|
|
|
|
float3 vEyeDir = normalize( i.worldVertToEyeVector.xyz );
|
|
|
|
#if BUMPMAP
|
|
float3 vWorldBinormal = cross( i.worldSpaceNormal.xyz, i.vWorldTangent.xyz ) * i.vWorldTangent.w;
|
|
#endif
|
|
|
|
float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f );
|
|
#if SEAMLESS_BASE
|
|
baseColor =
|
|
i.SeamlessWeights.x * BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.yz )+
|
|
i.SeamlessWeights.y * BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.zx )+
|
|
i.SeamlessWeights.z * BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.xy );
|
|
#else
|
|
baseColor = BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.xy );
|
|
|
|
#endif // !SEAMLESS_BASE
|
|
|
|
|
|
#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 0)
|
|
float distAlphaMask = baseColor.a;
|
|
#endif
|
|
|
|
|
|
#if DETAILTEXTURE
|
|
#if SEAMLESS_DETAIL
|
|
float4 detailColor =
|
|
i.SeamlessWeights.x * DetailTexture.Sample( DetailSampler, i.detailTexCoord.yz )+
|
|
i.SeamlessWeights.y * DetailTexture.Sample( DetailSampler, i.detailTexCoord.zx )+
|
|
i.SeamlessWeights.z * DetailTexture.Sample( DetailSampler, i.detailTexCoord.xy );
|
|
#else
|
|
float4 detailColor = DetailTexture.Sample( DetailSampler, i.detailTexCoord.xy );
|
|
#endif
|
|
detailColor.rgb *= c.g_DetailTint;
|
|
|
|
#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 1)
|
|
float distAlphaMask = detailColor.a;
|
|
detailColor.a = 1.0; // make tcombine treat as 1.0
|
|
#endif
|
|
baseColor =
|
|
TextureCombine( baseColor, detailColor, c.g_DetailBlendMode.x, g_DetailBlendFactor );
|
|
#endif
|
|
|
|
#if DISTANCEALPHA
|
|
if ( OUTLINE )
|
|
{
|
|
float4 oFactors = smoothstep(c.g_OutlineParams.xyzw, c.g_OutlineParams.wzyx, distAlphaMask );
|
|
baseColor = lerp( baseColor, c.g_OutlineColor, oFactors.x * oFactors.y );
|
|
}
|
|
|
|
float mskUsed;
|
|
if ( SOFT_MASK )
|
|
{
|
|
mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask );
|
|
baseColor.a *= mskUsed;
|
|
}
|
|
else
|
|
{
|
|
mskUsed = distAlphaMask >= 0.5;
|
|
if (DETAILTEXTURE )
|
|
baseColor.a *= mskUsed;
|
|
else
|
|
baseColor.a = mskUsed;
|
|
}
|
|
|
|
|
|
if ( OUTER_GLOW )
|
|
{
|
|
#if DISTANCEALPHAFROMDETAIL
|
|
float4 glowTexel = DetailTexture.Sample( DetailSampler, i.detailTexCoord.xy+GLOW_UV_OFFSET );
|
|
#else
|
|
float4 glowTexel = BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.xy+GLOW_UV_OFFSET );
|
|
#endif
|
|
float4 glowc = OUTER_GLOW_COLOR*smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel.a );
|
|
baseColor = lerp( glowc, baseColor, mskUsed );
|
|
}
|
|
|
|
#endif // DISTANCEALPHA
|
|
|
|
float3 specularFactor = 1.0f;
|
|
float fSpecMask = 1.0f;
|
|
#if BUMPMAP
|
|
float4 normalTexel = BumpmapTexture.Sample( BumpmapSampler, i.baseTexCoord.xy );
|
|
float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f;
|
|
#if PHONG
|
|
tangentSpaceNormal = lerp(tangentSpaceNormal, float3(0, 0, 1), g_fBaseMapAlphaPhongMask);
|
|
fSpecMask = lerp(normalTexel.a, baseColor.a, g_fBaseMapAlphaPhongMask);
|
|
#endif
|
|
if ( bNormalMapAlphaEnvmapMask )
|
|
specularFactor = normalTexel.a;
|
|
#endif
|
|
float4 envmapMaskTexel = 1;
|
|
#if ENVMAPMASK
|
|
{
|
|
envmapMaskTexel = EnvmapMaskTexture.Sample( EnvmapMaskSampler, i.baseTexCoord.xy );
|
|
specularFactor *= envmapMaskTexel.xyz;
|
|
}
|
|
#endif
|
|
|
|
if( bBaseAlphaEnvmapMask )
|
|
{
|
|
specularFactor *= 1.0 - baseColor.a; // this blows!
|
|
}
|
|
|
|
float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f );
|
|
if( bDiffuseLighting || bVertexColor )
|
|
{
|
|
diffuseLighting = i.color.rgb;
|
|
}
|
|
else if ( bDiffuseLighting )
|
|
{
|
|
diffuseLighting = float3(0.0f, 0.0f, 0.0f);
|
|
}
|
|
|
|
float3 worldSpaceNormal = i.worldSpaceNormal.xyz;
|
|
if ( bDiffuseLighting || bFlashlight || bCubemap || bSelfIllumFresnel )
|
|
{
|
|
#if BUMPMAP
|
|
worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal, i.worldSpaceNormal, i.vWorldTangent, vWorldBinormal );
|
|
#endif
|
|
worldSpaceNormal = normalize( worldSpaceNormal );
|
|
}
|
|
|
|
#if PHONG
|
|
float fFresnelRanges = Fresnel(worldSpaceNormal, normalize(i.worldVertToEyeVector.xyz), g_FresnelRanges);
|
|
#endif
|
|
|
|
#if DIFFUSELIGHTING
|
|
//float4 vLightAtten = i.lightAtten;
|
|
float4 vLightAtten = PixelShaderDoLightAtten( i.worldPos_projPosZ.xyz, nNumLights, cLightInfo );
|
|
|
|
diffuseLighting += PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal,
|
|
float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten,
|
|
cAmbientCube, BaseTexture, BaseTextureSampler, nNumLights, cLightInfo, bHalfLambert,
|
|
false, 1.0f, bDoDiffuseWarp, DiffuseWarpTexture, DiffuseWarpSampler );
|
|
#endif
|
|
|
|
float3 albedo = baseColor;
|
|
|
|
//return float4(g_DiffuseModulation.rgb, 1.0f);
|
|
|
|
if (bBlendTintByBaseAlpha)
|
|
{
|
|
float3 tintedColor = albedo * g_DiffuseModulation.rgb;
|
|
tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, c.g_EnvmapTint_TintReplaceFactor.w);
|
|
albedo = lerp(albedo, tintedColor, baseColor.a);
|
|
}
|
|
else
|
|
{
|
|
albedo = albedo * g_DiffuseModulation.rgb;
|
|
}
|
|
|
|
float alpha = g_DiffuseModulation.a;
|
|
if ( !bBaseAlphaEnvmapMask && !bSelfIllum && !bBlendTintByBaseAlpha )
|
|
{
|
|
alpha *= baseColor.a;
|
|
}
|
|
|
|
float3 specularLighting = float3( 0.0f, 0.0f, 0.0f );
|
|
|
|
#if DIFFUSELIGHTING && PHONG
|
|
float3 rimLighting = float3(0.0f, 0.0f, 0.0f);
|
|
float fRimMask = 0.0f;
|
|
float fSpecExp = c.g_SpecExponent.x;
|
|
float4 vSpecExpMap = SpecExponentTexture.Sample(SpecExponentSampler, i.baseTexCoord.xy);
|
|
float fSpecExpMap = vSpecExpMap.r;
|
|
|
|
fRimMask = lerp( 1.0f, vSpecExpMap.a, g_RimMaskControl );
|
|
|
|
// If the exponent passed in as a constant is zero, use the value from the map as the exponent
|
|
if ( fSpecExp == 0 )
|
|
fSpecExp = 1.0f - fSpecExpMap + 150.0f * fSpecExpMap;
|
|
float3 vSpecularTint;
|
|
// If constant tint is negative, tint with albedo, based upon scalar tint map
|
|
if ( g_SpecularTint.r < 0 )
|
|
vSpecularTint = lerp( float3(1.0f, 1.0f, 1.0f), baseColor.rgb, vSpecExpMap.g );
|
|
else
|
|
vSpecularTint = g_SpecularTint.rgb;
|
|
|
|
if ( bDoSpecularWarp )
|
|
fFresnelRanges = Fresnel( worldSpaceNormal, vEyeDir, g_FresnelRanges );
|
|
|
|
PixelShaderDoSpecularLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, fSpecExp,
|
|
vEyeDir, vLightAtten, nNumLights, cLightInfo, false, 1.0f,
|
|
bDoSpecularWarp, SpecularWarpTexture, SpecularWarpSampler, fFresnelRanges,
|
|
bRimLight, g_RimExponent,
|
|
|
|
// Output
|
|
specularLighting, rimLighting );
|
|
|
|
#if FLASHLIGHT
|
|
float4 flashlightSpacePosition = mul(float4(i.worldPos_projPosZ.xyz, 1.0f), g_FlashlightWorldToTexture);
|
|
float3 flashlight = 0;
|
|
float3 flashlightspec = 0;
|
|
DoSpecularFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, worldSpaceNormal,
|
|
g_FlashlightAttenuationFactors.xyz, g_FlashlightAttenuationFactors.w,
|
|
FlashlightTexture, FlashlightSampler, ShadowDepthTexture, ShadowDepthSampler, BaseTexture, BaseTextureSampler,
|
|
FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, i.projPos.xy / i.projPos.z,
|
|
fSpecExp, vEyeDir, bDoSpecularWarp, SpecularWarpTexture, SpecularWarpSampler, fFresnelRanges,
|
|
c.g_EnvmapContrast_ShadowTweaks,
|
|
|
|
// Output
|
|
flashlight, flashlightspec );
|
|
return float4(flashlight + flashlightspec, 1.0f);
|
|
#endif
|
|
|
|
// Modulate with spec mask, boost and tint
|
|
specularLighting *= fSpecMask * g_SpecularBoost * vSpecularTint;
|
|
|
|
// If we didn't already apply Fresnel to specular warp, modulate the specular
|
|
if ( !bDoSpecularWarp )
|
|
specularLighting *= fFresnelRanges;
|
|
|
|
if (bRimLight)
|
|
{
|
|
float fRimFresnel = Fresnel4( worldSpaceNormal, vEyeDir );
|
|
|
|
// Add in rim light modulated with tint, mask and traditional Fresnel (not using Fresnel ranges)
|
|
rimLighting *= vSpecularTint * fRimMask * fRimFresnel;
|
|
|
|
// Fold rim lighting into specular term by using the max so that we don't really add light twice...
|
|
specularLighting = max( specularLighting, rimLighting );
|
|
|
|
// Add in view-ray lookup from ambient cube
|
|
specularLighting += fRimFresnel * fRimMask * vSpecularTint * g_fRimBoost * PixelShaderAmbientLight( vEyeDir, cAmbientCube) * saturate(dot(worldSpaceNormal, float3(0, 0 , 1)) );
|
|
}
|
|
|
|
#endif
|
|
|
|
// With phong, flashlight diffuse is calculated with specular
|
|
#if FLASHLIGHT && !PHONG
|
|
{
|
|
int nShadowSampleLevel = 0;
|
|
bool bDoShadows = false;
|
|
// On ps_2_b, we can do shadow mapping
|
|
#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0) ) )
|
|
nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE;
|
|
bDoShadows = true;
|
|
#endif
|
|
|
|
float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture );
|
|
|
|
// We want the N.L to happen on the flashlight pass, but can't afford it on ps20
|
|
bool bUseWorldNormal = true;
|
|
#if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) )
|
|
bUseWorldNormal = false;
|
|
#endif
|
|
|
|
float2 vProjPos = i.projPos.xy / i.projPos.w; // Screen-space position for shadow map noise
|
|
|
|
float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition,
|
|
worldSpaceNormal, g_FlashlightAttenuationFactors.xyz,
|
|
g_FlashlightAttenuationFactors.w, FlashlightTexture, FlashlightSampler, ShadowDepthTexture, ShadowDepthSampler,
|
|
/*RandRotSampler,*/ nShadowSampleLevel, bDoShadows, false, vProjPos, false, c.g_EnvmapContrast_ShadowTweaks );
|
|
|
|
return float4(flashlightColor, 1.0f);
|
|
|
|
diffuseLighting += flashlightColor;
|
|
}
|
|
#endif
|
|
|
|
if( bVertexColor && bDiffuseLighting )
|
|
{
|
|
albedo *= i.color.rgb;
|
|
}
|
|
|
|
alpha = lerp( alpha, alpha * i.color.a, g_fVertexAlpha );
|
|
|
|
float3 diffuseComponent = albedo * diffuseLighting;
|
|
|
|
#if DETAILTEXTURE
|
|
diffuseComponent =
|
|
TextureCombinePostLighting( diffuseComponent, detailColor, c.g_DetailBlendMode.x, g_DetailBlendFactor );
|
|
#endif
|
|
|
|
#if SELFILLUM_ENVMAPMASK_ALPHA
|
|
// range of alpha:
|
|
// 0 - 0.125 = lerp(diffuse,selfillum,alpha*8)
|
|
// 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows)
|
|
HALF3 selfIllumComponent = g_SelfIllumTint * albedo;
|
|
half Adj_Alpha=8*envmapMaskTexel.a;
|
|
diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent;
|
|
#else
|
|
if ( bSelfIllum )
|
|
{
|
|
#if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file
|
|
// This will apply a fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look
|
|
float3 vVertexNormal = normalize( i.worldSpaceNormal.xyz );
|
|
float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, normalize( i.worldVertToEyeVector.xyz ) ) ), c.g_SelfIllumScaleBiasExpBrightness.z ) * c.g_SelfIllumScaleBiasExpBrightness.x ) + c.g_SelfIllumScaleBiasExpBrightness.y;
|
|
|
|
float3 selfIllumComponent = g_SelfIllumTint * albedo * c.g_SelfIllumScaleBiasExpBrightness.w;
|
|
diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) );
|
|
#else
|
|
float3 selfIllumComponent = g_SelfIllumTint * albedo;
|
|
float selfIllumMask;
|
|
#if SELFILLUMMASK
|
|
selfIllumMask = SelfIllumMaskTexture.Sample( SelfIllumMaskSampler, i.baseTexCoord.xy ).r;
|
|
#else
|
|
selfIllumMask = baseColor.a;
|
|
#endif
|
|
diffuseComponent = lerp( diffuseComponent, selfIllumComponent, selfIllumMask );
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#if CUBEMAP
|
|
{
|
|
HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz );
|
|
float3 cubeSpecular = float3( 0.0f, 0.0f, 0.0f );
|
|
cubeSpecular += ENV_MAP_SCALE * EnvmapTexture.Sample( EnvmapSampler, reflectVect );
|
|
cubeSpecular *= specularFactor;
|
|
cubeSpecular *= c.g_EnvmapTint_TintReplaceFactor.rgb;
|
|
HALF3 specularLightingSquared = cubeSpecular * cubeSpecular;
|
|
cubeSpecular = lerp( cubeSpecular, specularLightingSquared, c.g_EnvmapContrast_ShadowTweaks );
|
|
HALF3 greyScale = dot( cubeSpecular, HALF3( 0.299f, 0.587f, 0.114f ) );
|
|
specularLighting += lerp( greyScale, cubeSpecular, g_EnvmapSaturation );
|
|
}
|
|
#endif
|
|
|
|
float3 result = diffuseComponent + specularLighting;
|
|
|
|
#if ALPHATEST
|
|
if ( !GreaterEqualAlphaTest( alpha, c.g_AlphaTestRef ) )
|
|
discard;
|
|
#endif
|
|
|
|
//return float4(result, alpha);
|
|
|
|
# if (DEPTHBLEND == 1)
|
|
{
|
|
float2 vScreenPos;
|
|
vScreenPos.x = i.projPos.x;
|
|
vScreenPos.y = -i.projPos.y;
|
|
vScreenPos = (vScreenPos + i.projPos.w) * 0.5f;
|
|
alpha *= DepthFeathering( DepthTexture, DepthSampler, vScreenPos / i.projPos.w,
|
|
i.projPos.w - i.projPos.z, i.projPos.w, c.g_DepthFeatheringConstants );
|
|
}
|
|
# endif
|
|
|
|
|
|
float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, c.g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, length( i.eyeSpacePos ) );
|
|
//alpha = lerp( alpha, fogFactor, g_fPixelFogType * g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog
|
|
|
|
return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType,
|
|
TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z );
|
|
|
|
}
|
|
|