1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-01-07 09:43:40 +08:00
hl2sdk/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc
Scott Ehlert fdd0bbf277 SDK sync.
2012-07-06 20:35:59 -05:00

360 lines
15 KiB
Plaintext

//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "CUBEMAP" "0..1"
// STATIC: "DIFFUSELIGHTING" "0..1"
// STATIC: "LIGHTWARPTEXTURE" "0..1"
// STATIC: "SELFILLUM" "0..1"
// STATIC: "SELFILLUMFRESNEL" "0..1"
// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1"
// STATIC: "HALFLAMBERT" "0..1"
// STATIC: "FLASHLIGHT" "0..1"
// STATIC: "DETAILTEXTURE" "0..1"
// STATIC: "DETAIL_BLEND_MODE" "0..6"
// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC]
// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC]
// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX]
// STATIC: "SHADER_SRGB_READ" "0..1" [XBOX]
// STATIC: "SHADER_SRGB_READ" "0..0" [PC]
// STATIC: "STATICLIGHT3" "0..0" [XBOX]
// STATIC: "STATICLIGHT3" "0..0" [PC]
// STATIC: "WORLD_NORMAL" "0..0" [ps20] [PC]
// STATIC: "WORLD_NORMAL" "0..0" [ps20b] [PC]
// STATIC: "WORLD_NORMAL" "0..1" [ps30] [PC]
// STATIC: "WORLD_NORMAL" "0..0" [XBOX]
// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1"
// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20]
// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b]
// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30]
// DYNAMIC: "AMBIENT_LIGHT" "0..1"
// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b]
// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] [PC]
// DYNAMIC: "UBERLIGHT" "0..1" [ps30] [PC]
// We don't use light combos when doing the flashlight
// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) [PC]
// We don't care about flashlight depth unless the flashlight is on
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b]
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30]
// We don't care about uberlight unless the flashlight is on
// SKIP: ( $FLASHLIGHT == 0 ) && ( $UBERLIGHT == 1 ) [ps30]
// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 )
// Don't do diffuse warp on flashlight
// Only warp diffuse if we have it at all
// SKIP: ( $DIFFUSELIGHTING == 0 ) && ( $LIGHTWARPTEXTURE == 1 )
// Skip this since it blows ps20 instruction limits
// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 )
// Only need self illum fresnel when self illum enabled
// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 )
// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) [PC]
// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 )
// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 )
// Only do world normals in constrained case
// SKIP: ( $WORLD_NORMAL == 1 ) && ( $FLASHLIGHTSHADOWS != 0 ) && ( $AMBIENT_LIGHT != 0 ) && ( $NUM_LIGHTS != 0 ) [ps30]
#include "common_fog_ps_supportsvertexfog_fxc.h"
#include "shader_constant_register_map.h"
#include "common_flashlight_fxc.h"
#include "common_vertexlitgeneric_dx9.h"
// new-UP-bump-basis
static const HALF3 upBumpBasis[3] =
{
HALF3( 0.0f, 0.81649661064147949f, OO_SQRT_3 ),
HALF3( -0.70710676908493042f, -0.40824833512306213f, OO_SQRT_3 ),
HALF3( 0.7071068286895752f, -0.40824821591377258f, OO_SQRT_3 )
};
const float4 g_EnvmapTint : register( c0 );
const float4 g_DiffuseModulation : register( c1 );
const float4 g_EnvmapContrast_ShadowTweaks : register( c2 );
const float3 g_EnvmapSaturation : register( c3 );
const float4 g_SelfIllumTint_and_BlendFactor: register( c4 );
#define g_SelfIllumTint ( g_SelfIllumTint_and_BlendFactor.rgb)
#define g_DetailBlendFactor (g_SelfIllumTint_and_BlendFactor.w)
const float3 cAmbientCube[6] : register( c5 );
// 11, 12 not used?
#if ( SELFILLUMFRESNEL == 1 )
const float4 g_SelfIllumScaleBiasExpBrightness : register( c11 );
#endif
const float4 g_ShaderControls : register( c12 );
#define g_fInverseBlendTintByBaseAlpha g_ShaderControls.x
#define g_fWriteDepthToAlpha g_ShaderControls.y
//#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z
// 2 registers each - 6 registers total
PixelShaderLightInfo cLightInfo[3] : register( c13 ); // through c18
const float4 g_EyePos_BaseTextureTranslucency : register( c20 );
const float4 g_FogParams : register( c21 );
const float4 g_FlashlightAttenuationFactors : register( c22 );
const float3 g_FlashlightPos : register( c23 );
const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27
#if UBERLIGHT && defined( SHADER_MODEL_PS_3_0 )
const float3 g_vSmoothEdge0 : register( PSREG_UBERLIGHT_SMOOTH_EDGE_0 ); // ps_3_0 and up (over 32 registers)
const float3 g_vSmoothEdge1 : register( PSREG_UBERLIGHT_SMOOTH_EDGE_1 );
const float3 g_vSmoothOneOverWidth : register( PSREG_UBERLIGHT_SMOOTH_EDGE_OOW );
const float4 g_vShearRound : register( PSREG_UBERLIGHT_SHEAR_ROUND );
const float4 g_aAbB : register( PSREG_UBERLIGHT_AABB );
const float4x4 g_FlashlightWorldToLight : register( PSREG_UBERLIGHT_WORLD_TO_LIGHT );
#endif
sampler BaseTextureSampler : register( s0 );
sampler EnvmapSampler : register( s1 );
sampler DetailSampler : register( s2 );
sampler BumpmapSampler : register( s3 );
sampler EnvmapMaskSampler : register( s4 );
sampler NormalizeSampler : register( s5 );
sampler RandRotSampler : register( s6 ); // RandomRotation sampler
sampler FlashlightSampler : register( s7 );
sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler
sampler DiffuseWarpSampler : register( s9 ); // Lighting warp sampler (1D texture for diffuse lighting modification)
struct PS_INPUT
{
float4 baseTexCoord2_light0e01 : TEXCOORD0;
#if STATICLIGHT3
float4 light1e012_light0e2 : TEXCOORD1;
#else
float3 lightAtten : TEXCOORD1;
#endif
float4 worldVertToEyeVectorXYZ_light2e0 : TEXCOORD2;
float4 vWorldNormal_light2e1 : TEXCOORD3;
float4 vWorldTangent : TEXCOORD4;
#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)))
float4 vProjPos : TEXCOORD5;
#else
float3 vWorldBinormal : TEXCOORD5;
#endif
float4 worldPos_projPosZ : TEXCOORD6;
float4 detailTexCoord_atten3_or_light2e2_fogFactorW : TEXCOORD7;
#if defined( _X360 )
#if FLASHLIGHT
float4 flashlightSpacePos : TEXCOORD8;
#endif
#endif
};
float4 main( PS_INPUT i ) : COLOR
{
bool bCubemap = CUBEMAP ? true : false;
bool bDiffuseLighting = DIFFUSELIGHTING ? true : false;
bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false;
bool bSelfIllum = SELFILLUM ? true : false;
bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false;
bool bHalfLambert = HALFLAMBERT ? true : false;
bool bFlashlight = (FLASHLIGHT!=0) ? true : false;
bool bAmbientLight = AMBIENT_LIGHT ? true : false;
bool bDetailTexture = DETAILTEXTURE ? true : false;
int nNumLights = NUM_LIGHTS;
float3 vWorldNormal = i.vWorldNormal_light2e1.xyz;
#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)))
float3 vWorldBinormal = cross( vWorldNormal, i.vWorldTangent.xyz ) * i.vWorldTangent.w;
#else
float3 vWorldBinormal = i.vWorldBinormal;
#endif
#if STATICLIGHT3
// Unpack vertex lighting
float3 cLight0 = float3( i.baseTexCoord2_light0e01.zw, i.light1e012_light0e2.w );
float3 cLight1 = i.light1e012_light0e2.xyz;
float3 cLight2 = float3( i.worldVertToEyeVectorXYZ_light2e0.w, i.vWorldNormal_light2e1.w, i.detailTexCoord_atten3_or_light2e2_fogFactorW.z );
#else
// Unpack four light attenuations
float4 vLightAtten = float4( i.lightAtten, i.detailTexCoord_atten3_or_light2e2_fogFactorW.z );
#endif
float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f );
baseColor = tex2Dsrgb( BaseTextureSampler, i.baseTexCoord2_light0e01.xy );
#if DETAILTEXTURE
float4 detailColor = tex2D( DetailSampler, i.detailTexCoord_atten3_or_light2e2_fogFactorW.xy );
baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor );
#endif
float specularFactor = 1.0f;
float4 normalTexel = tex2D( BumpmapSampler, i.baseTexCoord2_light0e01.xy );
float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f;
if ( bNormalMapAlphaEnvmapMask )
specularFactor = normalTexel.a;
float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f );
float3 worldSpaceNormal = float3( 0.0f, 0.0f, 1.0f );
if ( bDiffuseLighting )
{
worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal.xyz, vWorldNormal, i.vWorldTangent, vWorldBinormal );
#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) )
worldSpaceNormal = normalize( worldSpaceNormal );
#else
worldSpaceNormal = NormalizeWithCubemap( NormalizeSampler, worldSpaceNormal );
#endif
#if STATICLIGHT3
float3 dp;
dp.x = saturate( dot( tangentSpaceNormal, upBumpBasis[0] ) );
dp.y = saturate( dot( tangentSpaceNormal, upBumpBasis[1] ) );
dp.z = saturate( dot( tangentSpaceNormal, upBumpBasis[2] ) );
dp *= dp;
diffuseLighting.rgb = dp.x * cLight0 + dp.y * cLight1 + dp.z * cLight2;
if ( bDoDiffuseWarp )
{
float fDiffuseScale = 0.5 * length( diffuseLighting.rgb );
diffuseLighting.rgb *= 2.0 * tex2D( DiffuseWarpSampler, float2( fDiffuseScale, 0 ) );
}
#else
diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal,
float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten,
cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert,
bDoDiffuseWarp, DiffuseWarpSampler );
#endif
}
float3 albedo = float3( 1.0f, 1.0f, 1.0f );
float alpha = 1.0f;
albedo *= baseColor;
if ( !bSelfIllum )
{
alpha *= lerp( 1.0f, baseColor.a, g_EyePos_BaseTextureTranslucency.w );
}
#if FLASHLIGHT
if( bFlashlight )
{
int nShadowSampleLevel = 0;
bool bDoShadows = false;
float2 vProjPos = float2(0, 0);
// On ps_2_b, we can do shadow mapping
#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) )
nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE;
bDoShadows = FLASHLIGHTSHADOWS;
vProjPos = i.vProjPos.xy / i.vProjPos.w; // Screen-space position for shadow map noise
#endif
worldSpaceNormal = Vec3TangentToWorldNormalized( tangentSpaceNormal.xyz, vWorldNormal, i.vWorldTangent, vWorldBinormal );
#if defined ( _X360 )
float4 flashlightSpacePosition = i.flashlightSpacePos;
#else
float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture );
#endif
float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition,
worldSpaceNormal, g_FlashlightAttenuationFactors.xyz,
g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler,
RandRotSampler, nShadowSampleLevel, bDoShadows, false, vProjPos, false, g_EnvmapContrast_ShadowTweaks );
#if UBERLIGHT && defined( SHADER_MODEL_PS_3_0 )
float4 uberLightPosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToLight ).yzxw;
flashlightColor *= uberlight( uberLightPosition, g_vSmoothEdge0, g_vSmoothEdge1,
g_vSmoothOneOverWidth, g_vShearRound.xy, g_aAbB, g_vShearRound.zw );
#endif
#if defined ( _X360 )
diffuseLighting += flashlightColor;
#else
diffuseLighting = flashlightColor;
#endif
}
#endif
// Optionally use basealpha to blend in the diffuse modulation (saturated add of g_fInverseBlendTintByBaseAlpha turns this on/off)
diffuseLighting *= lerp( float3( 1.0f, 1.0f, 1.0f ), g_DiffuseModulation.rgb, saturate( baseColor.a + g_fInverseBlendTintByBaseAlpha ) );
alpha *= g_DiffuseModulation.a;
float3 diffuseComponent = albedo * diffuseLighting;
#if !FLASHLIGHT || defined ( _X360 )
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
#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)))
float3 vVertexNormal = normalize( vWorldNormal.xyz );
float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, normalize( i.worldVertToEyeVectorXYZ_light2e0.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y;
float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w;
diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) );
#else
float3 vVertexNormal = vWorldNormal.xyz;
float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, ( i.worldVertToEyeVectorXYZ_light2e0.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y;
float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w;
diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) );
#endif
#else
float3 selfIllumComponent = g_SelfIllumTint * albedo;
diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a );
#endif
}
#endif
float3 specularLighting = float3( 0.0f, 0.0f, 0.0f );
#if !FLASHLIGHT || defined ( _X360 )
if( bCubemap )
{
worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal.xyz, vWorldNormal, i.vWorldTangent, vWorldBinormal );
float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.worldVertToEyeVectorXYZ_light2e0.xyz );
specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect );
specularLighting *= specularFactor;
specularLighting *= g_EnvmapTint;
float3 specularLightingSquared = specularLighting * specularLighting;
specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks );
float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) );
specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
}
#endif
float3 result = diffuseComponent + specularLighting;
float flVertexFogFactor = 0.0f;
#if ( !HARDWAREFOGBLEND && !DOPIXELFOG )
{
flVertexFogFactor = i.detailTexCoord_atten3_or_light2e2_fogFactorW.w;
}
#endif
float fogFactor = CalcPixelFogFactorSupportsVertexFog( PIXELFOGTYPE, g_FogParams, g_EyePos_BaseTextureTranslucency.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w, flVertexFogFactor );
#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT)
alpha = fogFactor;
#endif
#if ( ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) && WORLD_NORMAL )
// Vertex normal
return float4( normalize( vWorldNormal ), i.worldPos_projPosZ.w );
#else
return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.worldPos_projPosZ.w );
#endif
}