|
|
//========== Copyright (c) Valve Corporation, All rights reserved. ==========// // // Purpose: // //===========================================================================//
// vertexshaders that pair with this pixel shader: // lightmappedgeneric_flashlight_vs20 // vertexlitgeneric_flashlight_vs20
// STATIC: "SFM" "0..0" [ps20] [ps20b] [PC] // STATIC: "SFM" "0..1" [ps30] [PC] // STATIC: "SFM" "0..0" [CONSOLE]
// STATIC: "NORMALMAP" "0..2" // STATIC: "NORMALMAP2" "0..1" // STATIC: "WORLDVERTEXTRANSITION" "0..1" // STATIC: "SEAMLESS" "0..1" // STATIC: "DETAILTEXTURE" "0..1" // STATIC: "DETAIL_BLEND_MODE" "0..11" // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..3" [ps20b] [PC] // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [CONSOLE]
// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] [ps30] // DYNAMIC: "UBERLIGHT" "0..1" [ps30] [PC]
// SKIP: ( $SFM == 0 ) && ( $UBERLIGHT == 1 )
// SKIP: !$WORLDVERTEXTRANSITION && $NORMALMAP2 // SKIP: !$NORMALMAP && $NORMALMAP2 // SKIP: !$DETAILTEXTURE && ( $DETAIL_BLEND_MODE != 0 )
#include "common_fog_ps_supportsvertexfog_fxc.h" #include "shader_constant_register_map.h" #include "common_flashlight_fxc.h" #include "common_lightmappedgeneric_fxc.h"
const float4 g_DetailConstants : register( c0 ); const float3 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); const float4 g_FogParams : register( PSREG_FOG_PARAMS ); const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); const float4 g_FlashlightAttenuation : register( PSREG_FLASHLIGHT_ATTENUATION );
#if !defined( SHADER_MODEL_PS_2_0 ) const float4 g_FlashlightPos : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); #else // Lock flashlight pos to eye pos in ps_2_0 #define g_FlashlightPos g_EyePos #endif
#if ( UBERLIGHT ) const float3 g_vSmoothEdge0 : register( PSREG_UBERLIGHT_SMOOTH_EDGE_0 ); 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 SpotSampler : register( s0 ); sampler BaseTextureSampler : register( s1 ); samplerCUBE NormalizingCubemapSampler : register( s2 );
// use a normalizing cube map here if we aren't normal mapping sampler BumpMapSampler : register( s3 ); sampler BaseTextureSampler2 : register( s4 );
#ifdef WORLDVERTEXTRANSITION sampler NormalMap2Sampler : register( s6 ); #endif
#if DETAILTEXTURE sampler DetailSampler : register( s8 ); #endif
#if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) ) sampler RandomRotationSampler : register( s5 ); // Random rotation sampler sampler FlashlightDepthSampler : register( s7 ); #endif
struct PS_INPUT { float4 spotTexCoord : TEXCOORD0; #if SEAMLESS float3 SeamlessTexCoord : TEXCOORD1; #else float2 baseTexCoord : TEXCOORD1; #endif #if NORMALMAP float3 tangentPosToLightVector : TEXCOORD2; float2 normalMapTexCoord : TEXCOORD3; #else float3 worldPosToLightVector : TEXCOORD2; float3 normal : TEXCOORD3; #endif
float2 detailCoords : TEXCOORD4; float4 worldPos_worldTransition : TEXCOORD5; #if HARDWAREFOGBLEND || DOPIXELFOG float3 projPos_fogFactorW : TEXCOORD6; #else float4 projPos_fogFactorW : TEXCOORD6; #endif
float4 vNormalSqr : COLOR1; };
float4 SampleNormal( sampler s, PS_INPUT i ) { #if SEAMLESS float4 szy=tex2D( s, i.SeamlessTexCoord.zy ); float4 sxz=tex2D( s, i.SeamlessTexCoord.xz ); float4 syx=tex2D( s, i.SeamlessTexCoord.xy ); return i.vNormalSqr.r*szy + i.vNormalSqr.g*sxz + i.vNormalSqr.b*syx; #else #if NORMALMAP return tex2D( s, i.normalMapTexCoord.xy); #else return float4(0,0,1,1); #endif #endif
}
float4_color_return_type main( PS_INPUT i ) : COLOR { bool bBase2 = WORLDVERTEXTRANSITION ? true : false; bool bBump = (NORMALMAP != 0) ? true : false;
// Do spot stuff early since we can bail out float3 spotColor = float3(0,0,0); float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w;
#if ( defined( _X360 ) )
float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f );
[branch] if ( dot(ltz + gto, float3(1,1,1)) > 0 ) { clip (-1); return float4(0,0,0,0); } else { spotColor = tex2D( SpotSampler, vProjCoords );
[branch] if ( dot(spotColor.xyz, float3(1,1,1)) <= 0 ) { clip(-1); return float4(0,0,0,0); } else { #else spotColor = tex2D( SpotSampler, vProjCoords ).rgb;
#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) spotColor *= i.spotTexCoord.www > float3(0,0,0); // Catch back projection (PC-only at the moment) #endif
#endif
HALF4 baseColor = 0.0f; HALF4 baseColor2 = 0.0f; HALF4 vNormal = float4(0, 0, 1, 1); float3 baseTexCoords = float3(0,0,0); float3 normalTexCoords = float3( 0, 0, 0 );
#if SEAMLESS baseTexCoords = i.SeamlessTexCoord.xyz; normalTexCoords = baseTexCoords; #else baseTexCoords.xy = i.baseTexCoord.xy; #if ( NORMALMAP != 0 ) normalTexCoords.xy = i.normalMapTexCoord.xy; #else normalTexCoords = baseTexCoords; #endif #endif
GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpMapSampler, bBase2, bBump, baseTexCoords.xyz, baseTexCoords.xyz, normalTexCoords.xy, i.vNormalSqr.xyz, baseColor.rgba, baseColor2.rgba, vNormal.xyzw );
#if DETAILTEXTURE float4 detailColor = float4( g_DetailConstants.xyz, 1.0f ) * tex2D( DetailSampler, i.detailCoords ); #endif #if WORLDVERTEXTRANSITION float lerpAlpha = 1-i.worldPos_worldTransition.a; #endif
#if ( NORMALMAP == 0 ) vNormal.xyz = normalize( i.normal.xyz ); #endif
#if ( NORMALMAP == 1 ) vNormal.xyz = vNormal.xyz * 2.0f - 1.0f; // signed
# if NORMALMAP2 float3 normal2 = SampleNormal( NormalMap2Sampler, i ).xyz * 2.0f - 1.0f; vNormal.xyz = lerp( normal2, vNormal.xyz, lerpAlpha ); # endif #endif
// ssbump #if ( NORMALMAP == 2 )
# if NORMALMAP2 float3 normal2 = SampleNormal( NormalMap2Sampler, i ).xyz; vNormal.xyz = lerp( normal2, vNormal.xyz, lerpAlpha ); # endif #if ( DETAILTEXTURE && ( DETAIL_BLEND_MODE == TCOMBINE_SSBUMP_BUMP ) ) vNormal.xyz *= lerp( float3( 1, 1, 1 ), 2.0 * detailColor.xyz, baseColor.a ); baseColor.a = 1; #endif
#else // Normalize normal after all of the lerps above (including the tri/bilinear texel fetches) vNormal.xyz = normalize( vNormal.xyz ); #endif
spotColor.rgb *= cFlashlightColor.rgb;
// Compute per-pixel distance attenuation float3 delta = g_FlashlightPos.xyz - i.worldPos_worldTransition.xyz; float distSquared = dot( delta, delta ); float dist = sqrt( distSquared ); float farZAtten = g_FlashlightAttenuation.w; float endFalloffFactor = RemapValClamped( dist, farZAtten, 0.6f * farZAtten, 0.0f, 1.0f ); float flAtten = saturate(endFalloffFactor * dot( g_FlashlightAttenuation.xyz, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) );
#if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) ) float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos_fogFactorW.xy / i.projPos_fogFactorW.z, FLASHLIGHTDEPTHFILTERMODE, g_vShadowTweaks ); float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated flShadow = saturate(lerp( flAttenuated, flShadow, flAtten )); // Blend between shadow and above, according to light attenuation spotColor *= flShadow; #endif
#if ( UBERLIGHT ) // Transform from world space position to light space position float3 flashlightSpacePosition = mul( float4( i.worldPos_worldTransition.xyz, 1.0f ), g_FlashlightWorldToLight ).yzx; spotColor *= uberlight( flashlightSpacePosition, g_vSmoothEdge0, g_vSmoothEdge1, g_vSmoothOneOverWidth, g_vShearRound.xy, g_aAbB, g_vShearRound.zw ); #endif
#if WORLDVERTEXTRANSITION baseColor.xyz = lerp( baseColor2.xyz, baseColor.xyz, lerpAlpha ); #endif
#if DETAILTEXTURE float4 vBase = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailConstants.w ); baseColor.xyz = vBase.xyz; #endif
#if NORMALMAP == 0 float3 worldPosToLightVector = texCUBE( NormalizingCubemapSampler, i.worldPosToLightVector ).rgb * 2.0f - 1.0f; float nDotL = dot( worldPosToLightVector, vNormal.xyz ); #endif
#if NORMALMAP == 1 // flashlightfixme: wrap this! float3 tangentPosToLightVector = texCUBE( NormalizingCubemapSampler, i.tangentPosToLightVector ).rgb * 2.0f - 1.0f; float nDotL = dot( tangentPosToLightVector, vNormal.xyz ); #endif
#if NORMALMAP == 2 float3 tangentPosToLightVector = normalize( i.tangentPosToLightVector );
float nDotL = vNormal.x*dot( tangentPosToLightVector, bumpBasis[0]) + vNormal.y*dot( tangentPosToLightVector, bumpBasis[1]) + vNormal.z*dot( tangentPosToLightVector, bumpBasis[2]); #endif
float3 outColor; outColor = g_DiffuseModulation * spotColor * baseColor.xyz * saturate( nDotL ); outColor *= flAtten;
float flVertexFogFactor = 0.0f; #if ( !HARDWAREFOGBLEND && !DOPIXELFOG ) { flVertexFogFactor = i.projPos_fogFactorW.w; } #endif float fogFactor = CalcPixelFogFactorSupportsVertexFog( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_worldTransition.xyz, i.projPos_fogFactorW.z, flVertexFogFactor ); return FinalOutput( float4(outColor, baseColor.a), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR );
// so we can jump over all of the above #if ( defined( _X360 ) ) } } #endif
}
|