//========== Copyright (c) Valve Corporation, All rights reserved. ==========// #include "common_fog_ps_fxc.h" // DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] // DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] // DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] // DYNAMIC: "AMBIENT_LIGHT" "0..1" // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [CONSOLE] // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] #if defined( SHADER_MODEL_PS_2_0 ) # define WRITE_DEPTH_TO_DESTALPHA 0 #endif #include "shader_constant_register_map.h" const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); const float4 g_FogParams : register( PSREG_FOG_PARAMS ); const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total sampler BaseTextureSampler : register( s0 ); sampler BumpTextureSampler : register( s1 ); samplerCUBE NormalizeSampler : register( s2 ); struct PS_INPUT { float2 baseTexCoord : TEXCOORD0; float4 worldVertToEyeVector_Darkening : TEXCOORD1; float3x3 tangentSpaceTranspose : TEXCOORD2; // second row : TEXCOORD3; // third row : TEXCOORD4; float4 worldPos_projPosZ : TEXCOORD5; float4 lightAtten0123 : TEXCOORD6; }; #if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) #define worldVertToEyeVector i.worldVertToEyeVector_Darkening.xyz #define fDarkening i.worldVertToEyeVector_Darkening.w #endif float4_color_return_type main( PS_INPUT i ) : COLOR { bool bAmbientLight = AMBIENT_LIGHT ? true : false; int nNumLights = NUM_LIGHTS; float4 vLightAtten = i.lightAtten0123; float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); float3 worldSpaceNormal, tangentSpaceNormal = float3(0, 0, 1); float fSpecExp = g_EyePos_SpecExponent.w; float4 normalTexel = tex2D( BumpTextureSampler, i.baseTexCoord ); tangentSpaceNormal = 2.0f * normalTexel.xyz - 1.0f; worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) ); // 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 * ( 1.0f - normalTexel.w ) + 150.0f * normalTexel.w; // Summation of diffuse illumination from all local lights float3 diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten, cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, true, false, BaseTextureSampler ); // this last sampler is unused, we just need to pass in a value #if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) float3 vDummy, specularLighting; // Summation of specular from all local lights PixelShaderDoSpecularLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, fSpecExp, normalize(worldVertToEyeVector), vLightAtten, nNumLights, cLightInfo, false, BaseTextureSampler, // this sampler is not used, we just need to pass a value in 1.0f, false, 1.0f, 1.0f, // Outputs specularLighting, vDummy ); // Specular plus diffuse, all darkened as a function of mouth openness float3 result = (specularLighting * baseSample.a + baseSample.rgb * diffuseLighting) * fDarkening; #else float3 result = baseSample.rgb * diffuseLighting * i.worldVertToEyeVector_Darkening.w; #endif float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); return FinalOutput( float4(result, 1.0f), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); }