//========= 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] // STATIC: "BUMPMAP" "0..1" // Includes ======================================================================================= #include "common_vertexlitgeneric_dx9.h" // Texture Samplers =============================================================================== sampler g_tRefractionSampler : register( s0 ); #if BUMPMAP sampler g_tBumpSampler : register( s1 ); #endif sampler EnvmapSampler : register( s2 ); sampler EnvmapMaskSampler : register( s3 ); // Shaders Constants and Globals ================================================================== const float4 g_mViewProj0 : register( c0 ); // 1st row of matrix const float4 g_mViewProj1 : register( c1 ); // 2nd row of matrix const float4 g_vCameraPosition : register( c5 ); const float4 g_vPackedConst6 : register( c6 ); const float4 g_vPackedConst7 : register( c7 ); const float4 g_cCloakColorTint : register( c8 ); #define g_flSheenMapMaskScaleX g_vPackedConst6.x // Default = 1.0f #define g_flSheenMapMaskScaleY g_vPackedConst6.y // Default = 1.0f #define g_flSheenMapMaskOffsetX g_vPackedConst6.z // Default = 0.0f #define g_flSheenMapMaskOffsetY g_vPackedConst6.w // Default = 0.0f #define g_flSheenDirection g_vPackedConst7.x // 0,1,2 -> XYZ #define g_flEffectIndex g_vPackedConst7.y // W // 8 2D Poisson offsets (designed to use .xy and .wz swizzles (not .zw) static const float4 g_vPoissonOffset[4] = { float4 (-0.0876f, 0.9703f, 0.5651f, 0.4802f ), float4 ( 0.1851f, 0.1580f, -0.0617f, -0.2616f ), float4 (-0.5477f, -0.6603f, 0.0711f, -0.5325f ), float4 (-0.0751f, -0.8954f, 0.4054f, 0.6384f ) }; // Interpolated values ============================================================================ struct PS_INPUT { float3 vWorldNormal : TEXCOORD0; // World-space normal float3 vProjPosForRefract : TEXCOORD1; float3 vWorldViewVector : TEXCOORD2; float3x3 mTangentSpaceTranspose : TEXCOORD3; // second row : TEXCOORD4; // third row : TEXCOORD5; float2 vTexCoord0 : TEXCOORD6; float4 vModelSpacePos : TEXCOORD7; }; // Main =========================================================================================== float4 main( PS_INPUT i ) : COLOR { float3 vWorldNormal = normalize( i.vWorldNormal.xyz ); #if BUMPMAP float4 vBumpTexel = tex2D( g_tBumpSampler, i.vTexCoord0.xy ); float3 vTangentNormal = ( 2.0f * vBumpTexel ) - 1.0f; vWorldNormal.xyz = mul( i.mTangentSpaceTranspose, vTangentNormal.xyz ); #endif float4 result; // Staging test for weapon patterns if ( g_flEffectIndex == 2 ) { float3 ppos = i.vModelSpacePos; float2 temp = 0; // 'Scaling' of texture to get it to map to the weapons // No Skewing, just move left to right if ( g_flSheenDirection == 0 ) { temp.x = ppos.z; temp.y = ppos.y; } else if ( g_flSheenDirection == 1 ) { temp.x = ppos.z; temp.y = ppos.x; } else { temp.x = ppos.y; temp.y = ppos.x; } temp.x -= ( g_flSheenMapMaskOffsetX ); // offset temp.y -= ( g_flSheenMapMaskOffsetY ); // offset temp.x /= g_flSheenMapMaskScaleX; // scale temp.y /= g_flSheenMapMaskScaleY; temp.y = 1.0 - temp.y; // Sample Texture // Sample Mask //float4 patternTexel = tex2D( EnvmapSampler, temp ); float4 patternTexel = tex2D( EnvmapSampler, i.vTexCoord0.xy ); float4 maskTexel = tex2D( EnvmapMaskSampler, i.vTexCoord0.xy ); //result.rgba = float4( patternTexel.xyz * 1.0, maskTexel.x * 1.0); // 0.3 is a hack to preserve rimlight //result.rgba = float4( patternTexel.xyz, 1.0); // 0.3 is a hack to preserve rimlight result.rgba = float4( 0.0,0.0,0.0,0.0); // 0.3 is a hack to preserve rimlight } else { // generate a hard reflection in to the cube map float3 vEyeDir = -normalize(i.vWorldViewVector.xyz); float3 worldSpaceNormal, tangentSpaceNormal; tangentSpaceNormal = float3(0, 0, 1); worldSpaceNormal = normalize( mul( i.mTangentSpaceTranspose, tangentSpaceNormal ) ); float3 vReflect = 2 * worldSpaceNormal * dot(worldSpaceNormal, vEyeDir) - vEyeDir; float3 envMapColor = float3( 0.0f, 0.0f, 0.0f ); envMapColor = ENV_MAP_SCALE * texCUBE( EnvmapSampler, vReflect ) * g_cCloakColorTint.xyz; envMapColor *= 10.0f; // Sample the Mask float4 envmapMaskTexel; float2 temp = 0; float3 ppos = i.vModelSpacePos; // // skew the sampling based on sheen direction //if ( g_flSheenDirection == 0 ) //{ // temp.x = ppos.z - ppos.y; // temp.y = (ppos.x + ppos.y); //} //else if ( g_flSheenDirection == 1 ) //{ // temp.x = ppos.x - ppos.z; // temp.y = (ppos.y + ppos.z); //} //else //{ // temp.x = ppos.y - ppos.x; // temp.y = (ppos.z + ppos.x); //} // No Skewing, just move left to right if ( g_flSheenDirection == 0 ) { temp.x = ppos.z; temp.y = ppos.y; } else if ( g_flSheenDirection == 1 ) { temp.x = ppos.z; temp.y = ppos.x; } else { temp.x = ppos.y; temp.y = ppos.x; } temp.x -= ( g_flSheenMapMaskOffsetX ); // offset temp.y -= ( g_flSheenMapMaskOffsetY ); // offset temp.x /= g_flSheenMapMaskScaleX; // scale temp.y /= g_flSheenMapMaskScaleY; temp.y = 1.0 - temp.y; envmapMaskTexel = tex2D( EnvmapMaskSampler, temp ); // Build result, only have alpha if there was value in the mask. // High alpha (white) will override the underlying texture while low to none will show model underneath //float4 result; //result.rgba = float4( envMapColor, envmapMaskTexel.x * g_cCloakColorTint.w ); if ( g_flEffectIndex == 1 ) { //float alpha = max( max( envmapMaskTexel.x, envmapMaskTexel.y), envmapMaskTexel.z ); //result.rgba = float4( envMapColor.xyz * envmapMaskTexel.xyz, alpha ); float alpha = max( max( envMapColor.x, envMapColor.y), envMapColor.z ); result.rgba = float4( envMapColor.xyz * envmapMaskTexel.xyz, alpha * envmapMaskTexel.x ); result.rgba = result.rgba * 1.8f; } else { float alpha = max( max( envMapColor.x, envMapColor.y), envMapColor.z ); result.rgba = float4( envMapColor.xyz * envmapMaskTexel.xyz, alpha * envmapMaskTexel.x ); } } return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); }