//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======= // STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] // STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] // STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] // DYNAMIC: "PIXELFOGTYPE" "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: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] // 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 ); sampler 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; float2 lightAtten01 : TEXCOORD6; float2 lightAtten23 : TEXCOORD7; }; #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 main( PS_INPUT i ) : COLOR { bool bAmbientLight = AMBIENT_LIGHT ? true : false; int nNumLights = NUM_LIGHTS; float4 vLightAtten = float4( i.lightAtten01, i.lightAtten23 ); 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, 0, false, NormalizeSampler ); #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, 1.0f, false, NormalizeSampler, 1.0f, false, 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.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); return FinalOutput( float4(result, 1.0f), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); }