Files
cool-source-archive/materialsystem/stdshadersdx11/lightmappedgeneric_ps40.h
Totterynine 2773eae4d7 shaderapidx11
use -dxlevel 110 to use it
2021-09-22 18:56:56 +05:00

545 lines
17 KiB
C

//========= 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)
// 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
// Define the common constant buffers we will use
#include "common_cbuffers_def_noskinning_fxc.h"
#include "common_ps_fxc.h"
#include "common_flashlight_fxc.h"
#include "common_lightmappedgeneric_fxc.h"
#include "lightmappedgeneric_dx11_shared_fxc.h"
#if SEAMLESS
#define USE_FAST_PATH 1
#else
#define USE_FAST_PATH FASTPATH
#endif
cbuffer LightmappedGeneric_PS : register( b3 )
{
LightmappedGeneric_t c;
};
#define g_OutlineParams c.g_OutlineParamsAndColor[0]
#define g_OutlineColor c.g_OutlineParamsAndColor[1]
#if USE_FAST_PATH == 1
#if FASTPATHENVMAPCONTRAST == 0
static const float3 g_EnvmapContrast = { 0.0f, 0.0f, 0.0f };
#else
static const float3 g_EnvmapContrast = { 1.0f, 1.0f, 1.0f };
#endif
static const float3 g_EnvmapSaturation = { 1.0f, 1.0f, 1.0f };
static const float g_FresnelReflection = 1.0f;
static const float g_OneMinusFresnelReflection = 0.0f;
static const float4 g_SelfIllumTint = { 1.0f, 1.0f, 1.0f, 1.0f };
#if OUTLINE
#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
#define OUTLINE_COLOR g_OutlineColor
#endif
#if SOFTEDGES
#define SOFT_MASK_MIN g_EdgeSoftnessParms.x
#define SOFT_MASK_MAX g_EdgeSoftnessParms.y
#endif
#else
#define g_EnvmapContrast c.cEnvmapContrast.xyz
#define g_EnvmapSaturation c.cEnvmapSaturation.xyz
#define g_SelfIllumTint c.cSelfIllumTint
#define g_FresnelReflection c.cFresnelReflection.a
#define g_OneMinusFresnelReflection c.cFresnelReflection.b
#endif
#define g_DetailTint (c.g_DetailTint_and_BlendFactor.rgb)
#define g_DetailBlendFactor (c.g_DetailTint_and_BlendFactor.w)
#define g_flAlpha2 c.g_TintValuesAndLightmapScale.w
#define g_EyePos cEyePos.xyz
Texture2D BaseTexture : register( t0 );
sampler BaseTextureSampler : register( s0 );
Texture2D LightmapTexture : register( t1 );
sampler LightmapSampler : register( s1 );
#if CUBEMAP
TextureCube EnvmapTexture : register( t4 );
sampler EnvmapSampler : register( s4 );
#endif
#if FANCY_BLENDING
Texture2D BlendModulationTexture : register( t8 );
sampler BlendModulationSampler : register( s8 );
#endif
#if DETAILTEXTURE
Texture2D DetailTexture : register( t2 );
sampler DetailSampler : register( s2 );
#endif
#if BUMPMAP
Texture2D BumpmapTexture : register( t3 );
sampler BumpmapSampler : register( s3 );
#else
#define BumpmapTexture BaseTexture
#define BumpmapSampler BaseTextureSampler
#endif
#if BUMPMAP2 == 1
Texture2D BumpmapTexture2 : register( t5 );
sampler BumpmapSampler2 : register( s5 );
#elif ENVMAPMASK == 1
Texture2D EnvmapMaskTexture : register( t5 );
sampler EnvmapMaskSampler : register( s5 );
#endif
#if WARPLIGHTING
Texture2D WarpLightingTexture : register( t7 );
sampler WarpLightingSampler : register( s7 );
#endif
#if BASETEXTURE2
Texture2D BaseTexture2 : register( t6 );
sampler BaseTextureSampler2 : register( s6 );
#else
#define BaseTexture2 BaseTexture
#define BaseTextureSampler2 BaseTextureSampler
#endif
#if BUMPMASK == 1
Texture2D BumpMaskTexture : register( t9 );
sampler BumpMaskSampler : register( s9 );
#endif
struct PS_INPUT
{
float4 projPos : SV_POSITION;
float4 vertexColor : COLOR;
#if SEAMLESS
float4 SeamlessTexCoord_VertexBlend : TEXCOORD0; // zy xz
#else
float3 baseTexCoord_VertexBlend : TEXCOORD0;
#endif
float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1;
float4 lightmapTexCoord1And2 : TEXCOORD2;
float4 lightmapTexCoord3 : TEXCOORD3;
float4 worldPos_projPosZ : TEXCOORD4;
#if CUBEMAP || (LIGHTING_PREVIEW)
float3x3 tangentSpaceTranspose : TEXCOORD5;
// tangentSpaceTranspose : TEXCOORD6
// tangentSpaceTranspose : TEXCOORD7
#endif
float3 eyePos : COLOR1;
};
float4 main( PS_INPUT i ) : SV_TARGET
{
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_VertexBlend.xyz;
#else
baseTexCoords.xy = i.baseTexCoord_VertexBlend.xy;
#endif
GetBaseTextureAndNormal( BaseTexture, BaseTextureSampler, BaseTexture2, BaseTextureSampler2,
BumpmapTexture, 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
float3 lightmapColor1 = float3( 1.0f, 1.0f, 1.0f );
float3 lightmapColor2 = float3( 1.0f, 1.0f, 1.0f );
float3 lightmapColor3 = float3( 1.0f, 1.0f, 1.0f );
#if LIGHTING_PREVIEW == 0
if ( bBumpmap && bDiffuseBumpmap )
{
float2 bumpCoord1;
float2 bumpCoord2;
float2 bumpCoord3;
ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy,
bumpCoord1, bumpCoord2, bumpCoord3 );
lightmapColor1 = LightMapSample( LightmapTexture, LightmapSampler, bumpCoord1 );
lightmapColor2 = LightMapSample( LightmapTexture, LightmapSampler, bumpCoord2 );
lightmapColor3 = LightMapSample( LightmapTexture, LightmapSampler, bumpCoord3 );
}
else
{
float2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy );
lightmapColor1 = LightMapSample( LightmapTexture, 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
float2 detailTexCoord = i.baseTexCoord_VertexBlend.xy;
float2 bumpmapTexCoord = i.baseTexCoord_VertexBlend.xy;
float2 envmapMaskTexCoord = i.baseTexCoord_VertexBlend.xy;
#else
#if ( DETAILTEXTURE == 1 )
float2 detailTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy;
float2 bumpmapTexCoord = i.baseTexCoord_VertexBlend.xy;
#elif ( BUMPMASK == 1 )
float2 detailTexCoord = 0.0f;
float2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy;
float2 bumpmap2TexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz;
#else
float2 detailTexCoord = 0.0f;
float2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy;
#endif
float2 envmapMaskTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz;
#endif // !RELIEF_MAPPING
float4 detailColor = float4( 1.0f, 1.0f, 1.0f, 1.0f );
#if DETAILTEXTURE
detailColor = float4( g_DetailTint, 1.0f ) * DetailTexture.Sample( DetailSampler, detailTexCoord );
#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;
#elif SEAMLESS
float blendfactor = i.SeamlessTexCoord_VertexBlend.w;
#else
float blendfactor = i.baseTexCoord_VertexBlend.z;
#endif
if ( bBaseTexture2 )
{
#if (SELFILLUM == 0) && (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (FANCY_BLENDING)
float4 modt = BlendModulationTexture.Sample( 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;
float minb = modt.g - modt.r;
float maxb = modt.g + modt.r;
#else
float minb = max( 0,modt.g - modt.r );
float maxb = min( 1,modt.g + modt.r );
//float minb=saturate(modt.g-modt.r);
//float maxb=saturate(modt.g+modt.r);
#endif
blendfactor = smoothstep( minb,maxb,blendfactor );
//#endif
#endif
//baseColor.rgb = lerp( baseColor.rgb, baseColor2.rgb, blendfactor );
baseColor.rgb = lerp( baseColor, baseColor2.rgb, blendfactor );
blendedAlpha = lerp( baseColor.a, baseColor2.a, blendfactor );
}
float3 specularFactor = 1.0f;
float4 vNormalMask = float4( 0, 0, 1, 1 );
if ( bBumpmap )
{
if ( bBaseTextureNoEnvmap )
{
vNormal.a = 0.0f;
}
#if ( BUMPMAP2 == 1 )
{
#if ( BUMPMASK == 1 )
float2 b2TexCoord = bumpmap2TexCoord;
#else
float2 b2TexCoord = bumpmapTexCoord;
#endif
float4 vNormal2;
if ( BUMPMAP == 2 )
vNormal2 = BumpmapTexture2.Sample( BumpmapSampler2, b2TexCoord );
else
vNormal2 = DecompressNormal( BumpmapTexture2, BumpmapSampler2, b2TexCoord,
NORMAL_DECODE_MODE, BumpmapTexture2, BumpmapSampler2 ); // Bump 2 coords
if ( bBaseTexture2NoEnvmap )
{
vNormal2.a = 0.0f;
}
#if ( BUMPMASK == 1 )
float3 vNormal1 = DecompressNormal( BumpmapTexture, BumpmapSampler,
i.detailOrBumpAndEnvmapMaskTexCoord.xy,
NORMALMASK_DECODE_MODE, BumpmapTexture, BumpmapSampler );
vNormal.xyz = normalize( vNormal1.xyz + vNormal2.xyz );
// Third normal map...same coords as base
vNormalMask = DecompressNormal( BumpMaskTexture, BumpMaskSampler, i.baseTexCoord_VertexBlend.xy,
NORMALMASK_DECODE_MODE, BumpMaskTexture, BumpMaskSampler );
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 ENVMAPMASK
{
specularFactor *= EnvmapMaskTexture.Sample( EnvmapMaskSampler, envmapMaskTexCoord ).xyz;
}
#endif
#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, c.g_DetailBlendMode.x, g_DetailBlendFactor );
}
// The vertex color contains the modulation color + vertex color combined
#if ( SEAMLESS == 0 )
albedo.xyz *= i.vertexColor.xyz;
#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;
float3 diffuseLighting;
if ( bBumpmap && bDiffuseBumpmap )
{
// ssbump
#if ( BUMPMAP == 2 )
diffuseLighting = vNormal.x * lightmapColor1 +
vNormal.y * lightmapColor2 +
vNormal.z * lightmapColor3;
diffuseLighting *= c.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.xyz, bumpBasis[0] ) );
dp.y = saturate( dot( vNormal.xyz, bumpBasis[1] ) );
dp.z = saturate( dot( vNormal.xyz, bumpBasis[2] ) );
dp *= dp;
if ( c.g_DetailBlendMode.x == TCOMBINE_SSBUMP_BUMP )
dp *= 2 * detailColor;
diffuseLighting = dp.x * lightmapColor1 +
dp.y * lightmapColor2 +
dp.z * lightmapColor3;
float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) );
diffuseLighting *= c.g_TintValuesAndLightmapScale.xyz / sum;
#endif
}
else
{
diffuseLighting = lightmapColor1 * c.g_TintValuesAndLightmapScale.xyz;
}
#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 * WarpLightingTexture.Sample( WarpLightingSampler,float2( len,0 ) );
#endif
#if CUBEMAP || LIGHTING_PREVIEW
float3 worldSpaceNormal = mul( vNormal.xyz, i.tangentSpaceTranspose );
#endif
float3 diffuseComponent = albedo.xyz * diffuseLighting;
//return float4( diffuseLighting, 1.0f );
if ( bSelfIllum )
{
float3 selfIllumComponent = g_SelfIllumTint.xyz * albedo.xyz;
diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a );
}
float3 specularLighting = float3( 0.0f, 0.0f, 0.0f );
#if CUBEMAP
if ( bCubemap )
{
float3 worldVertToEyeVector = g_EyePos - i.worldPos_projPosZ.xyz;
float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldVertToEyeVector );
//return float4( reflectVect, 1.0f );
// Calc Fresnel factor
half3 eyeVect = normalize( worldVertToEyeVector );
float fresnel = 1.0 - dot( worldSpaceNormal, eyeVect );
fresnel = pow( fresnel, 5.0 );
fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection;
//return float4( specularFactor, 1.0f );
specularLighting = ENV_MAP_SCALE * EnvmapTexture.Sample( EnvmapSampler, reflectVect ).rgb;
//return float4( specularLighting, 1.0f );
specularLighting *= specularFactor;
specularLighting *= c.g_EnvmapTint.rgb;
//return float4( c.g_EnvmapTint.rgb, 1.0f );
#if FANCY_BLENDING == 0
float3 specularLightingSquared = specularLighting * specularLighting;
specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast );
float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) );
specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
#endif
specularLighting *= fresnel;
//return float4( specularLighting, 1.0f );
}
#endif
float3 result = diffuseComponent + specularLighting;
#if ALPHATEST
if ( !GreaterEqualAlphaTest( alpha, c.g_AlphaTestRef ) )
discard;
#endif
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, c.g_FogParams, cEyePos.z, i.worldPos_projPosZ.z, length( i.eyePos ) );
#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT)
alpha = fogFactor;
#endif
#if ALPHATEST
if ( !GreaterEqualAlphaTest( alpha, c.g_AlphaTestRef ) )
discard;
#endif
return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, c.g_FogColor,
TONEMAP_SCALE_LINEAR, cToneMappingScale, bWriteDepthToAlpha, i.worldPos_projPosZ.w );
}