|
|
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "BACK_SURFACE" "0..1" // STATIC: "LIGHT_WARP" "0..1" // STATIC: "FRESNEL_WARP" "0..1" // STATIC: "HIGH_PRECISION_DEPTH" "0..1" // STATIC: "INTERIOR_LAYER" "0..1" // STATIC: "OPACITY_TEXTURE" "0..1" // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..3" [ps20b] [PC] // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [CONSOLE] // STATIC: "CONTACT_SHADOW" "0..1" // DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] // DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] // DYNAMIC: "FLASHLIGHT" "0..1" // DYNAMIC: "FLASHLIGHTSHADOWS" "0..1"
// For now, 'BACK_SURFACE' is a dead-simple path (just writes depth into dest alpha), so skip all non-HW-config combos: // SKIP: ( $BACK_SURFACE == 1 ) && ( $LIGHT_WARP > 0 ) // SKIP: ( $BACK_SURFACE == 1 ) && ( $FRESNEL_WARP > 0 ) // SKIP: ( $BACK_SURFACE == 1 ) && ( $INTERIOR_LAYER > 0 ) // SKIP: ( $BACK_SURFACE == 1 ) && ( $OPACITY_TEXTURE > 0 ) // SKIP: ( $BACK_SURFACE == 1 ) && ( $CONTACT_SHADOW > 0 )
#include "common_ps_fxc.h" #include "common_vertexlitgeneric_dx9.h" #include "common_flashlight_fxc.h" #include "shader_constant_register_map.h"
// SAMPLERS sampler g_tBase : register( s0 ); sampler g_tBump : register( s1 ); sampler g_tScreen : register( s2 ); sampler g_tSpecMask : register( s3 ); sampler g_tLightWarp : register( s4 ); sampler g_tFresnelWarp : register( s5 ); sampler g_tOpacity : register( s6 ); samplerCUBE g_tEnvironment : register( s7 ); sampler g_tShadowDepth : register( s8 ); // Flashlight shadow depth map sampler sampler g_tNormalizeRandRot : register( s9 ); // Normalization / RandomRotation samplers sampler g_tFlashlightCookie : register( s10 ); // Flashlight cookie
// SHADER CONSTANTS const float4 g_vMisc : register( c0 ); #define g_flBumpStrength g_vMisc.x #define g_flDepthScale g_vMisc.y #define g_flInnerFogStrength g_vMisc.z #define g_flRefractStrength g_vMisc.w
const float4 g_vTranslucentFresnelParams_InteriorBoost : register( c1 ); #define g_vTranslucentFresnelParams g_vTranslucentFresnelParams_InteriorBoost.xyz #define g_flInteriorBoost g_vTranslucentFresnelParams_InteriorBoost.w
const float4 g_vMisc2 : register( c3 ); #define g_flRimLightExp g_vMisc2.x #define g_flRimLightScale g_vMisc2.y #define g_flSpecScale g_vMisc2.z #define g_flSpecExp2 g_vMisc2.w
const float4 g_vMisc3 : register( c10 ); #define g_flSpecScale2 g_vMisc3.x #define g_flFresnelBumpStrength g_vMisc3.y #define g_flDiffuseScale g_vMisc3.z #define g_flInteriorLightScale g_vMisc3.w
const float4 g_vEyePos_SpecExp : register( PSREG_EYEPOS_SPEC_EXPONENT ); #define g_vEyePos g_vEyePos_SpecExp.xyz #define g_flSpecExp g_vEyePos_SpecExp.w
const float4 g_ShaderControls : register( c12 ); #define g_fWriteDepthToAlpha g_ShaderControls.x
const float4 g_vBaseTint_InteriorBackLightScale : register( c19 ); #define g_cBaseTint g_vBaseTint_InteriorBackLightScale.rgb #define g_flInteriorBackLightScale g_vBaseTint_InteriorBackLightScale.w
#define g_cInteriorColor float3( 0.1f, 0.6f, 0.9f ) #define g_flRefractBlur 0.4f #define g_cEnvMapTint float3( 1.0f, 1.0f, 1.0f ) #define g_flFogNormalBoost 8.5f
// TODO: unify this across pixel shaders (declare the constants in common_ps_fxc.h, as is already done for vertex shader ambient) const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE );
const PixelShaderLightInfo g_sLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total
const float4 g_vFlashlightAttenuationFactors_FarZ : register( PSREG_FLASHLIGHT_ATTENUATION ); #define g_vFlashlightAttenuationFactors g_vFlashlightAttenuationFactors_FarZ.xyz #define g_flFlashlightFarZ g_vFlashlightAttenuationFactors_FarZ.w const float4 g_vFlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); #define g_vFlashlightPos g_vFlashlightPos_RimBoost.xyz const float4x4 g_mFlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS );
// COMBO-DERIVED CONSTANTS static const bool bLightWarp = LIGHT_WARP ? true : false; static const bool bFlashLight = FLASHLIGHT ? true : false;
// INPUT STRUCT struct PS_INPUT { float4 vWorldNormal : TEXCOORD0; // w is proj. z coord (for depth stuff) float4 vClosestSurfaceDir : TEXCOORD1; // Used if CONTACT_SHADOW is on float4 vWorldPos : TEXCOORD2; // w is proj. w coord float4 vUV0 : TEXCOORD3; float4 vUV1 : TEXCOORD4; float4 vLightAtten : TEXCOORD5; float3 vLightCube : TEXCOORD6; };
//============================================================================================================================================================== float Luminance( const float3 colour ) { return dot( colour, float3( 0.3, 0.59, 0.11 ) ); }
//============================================================================================================================================================== float3 ComputeTextureBlendWeights( float3 vWorldNormal ) { float3 vBlendWeights = max( ( abs( vWorldNormal.xyz ) - 0.2 ) * 7.0, 0.0 ); vBlendWeights /= dot( vBlendWeights, float3(1, 1, 1) ); // normalize return vBlendWeights; }
//============================================================================================================================================================== float4 BlendedTexFetch( sampler s, float2 vUV0, float2 vUV1, float2 vUV2, float3 vBlendWeights ) { float4 vFetch0 = tex2D( s, vUV0 ); float4 vFetch1 = tex2D( s, vUV1 ); float4 vFetch2 = tex2D( s, vUV2 ); return vBlendWeights.x * vFetch0 + vBlendWeights.y * vFetch1 + vBlendWeights.z * vFetch2; }
//============================================================================================================================================================== float3 BumpedToWorldNormal( float3 vBumpedNormal, float3 vVertexNormal, // should be normalized float3 vTangentDir ) { float3x3 mTanToWorld; mTanToWorld[2] = vVertexNormal; mTanToWorld[0] = vTangentDir - dot( vTangentDir, vVertexNormal ) * vVertexNormal; mTanToWorld[0] = normalize( mTanToWorld[0] ); mTanToWorld[1] = cross( mTanToWorld[0], mTanToWorld[2] ); return normalize( mul( vBumpedNormal, mTanToWorld ) ); }
//============================================================================================================================================================== void BlendedTexFetchNormal( sampler s, float2 vUV0, float2 vUV1, float2 vUV2, float3 vBlendWeights, float3 vWorldNormal, // Function outputs: out float2 vBumpedTSNormal, out float3 vBumpedWorldNormal, out float3 vFresnelWorldNormal ) { // minimize instruction /*vBumpedTSNormal = float2(0,0); vBumpedWorldNormal = vFresnelWorldNormal = vWorldNormal;*/
float3 vNormalTS1 = 2.0 * tex2D( g_tBump, vUV0 ).xyz - 1.0; float3 vNormalTS2 = 2.0 * tex2D( g_tBump, vUV1 ).xyz - 1.0; float3 vNormalTS3 = 2.0 * tex2D( g_tBump, vUV2 ).xyz - 1.0; vBumpedTSNormal = vBlendWeights.x * vNormalTS1.xy + vBlendWeights.y * vNormalTS2.xy + vBlendWeights.z * vNormalTS3.xy;
float3 vBumpedNormal1 = BumpedToWorldNormal( vNormalTS1, vWorldNormal, float3( 0, 1, 0 ) ); float3 vBumpedNormal2 = BumpedToWorldNormal( vNormalTS2, vWorldNormal, float3( 1, 0, 0 ) ); float3 vBumpedNormal3 = BumpedToWorldNormal( vNormalTS3, vWorldNormal, float3( 1, 0, 0 ) ); vBumpedWorldNormal = vBlendWeights.x * vBumpedNormal1 + vBlendWeights.y * vBumpedNormal2 + vBlendWeights.z * vBumpedNormal3;
// Apply bump strength in world space (this is cheaper because we have to do it twice, for normal and fresnel bumpstrength) float3 vBumpStrengthDir = vBumpedWorldNormal - dot( vBumpedWorldNormal, vWorldNormal ) * vWorldNormal; vFresnelWorldNormal = normalize( vBumpedWorldNormal + ( g_flFresnelBumpStrength - 1.0 ) * vBumpStrengthDir ); vBumpedWorldNormal = normalize( vBumpedWorldNormal + ( g_flBumpStrength - 1.0 ) * vBumpStrengthDir ); }
//============================================================================================================================================================== void ComputeOpacityAndFresnel( float2 vUV0, float2 vUV1, float2 vUV2, float3 vBlendWeights, float3 vEyeDir, float3 vWorldNormal, // Function outputs: out float flSkinOpacity, out float flFresnel ) { flSkinOpacity = 1; #if OPACITY_TEXTURE == 1 flSkinOpacity = BlendedTexFetch( g_tOpacity, vUV0, vUV1, vUV2, vBlendWeights ).x; #endif
flFresnel = saturate( 1.0 - dot( vEyeDir.xyz, vWorldNormal.xyz ) ); #if FRESNEL_WARP == 1 float fTranslucentFresnel = tex1D( g_tFresnelWarp, flFresnel ).x; #else float fTranslucentFresnel = lerp( g_vTranslucentFresnelParams.x, g_vTranslucentFresnelParams.y, pow( flFresnel, g_vTranslucentFresnelParams.z ) ); flSkinOpacity *= fTranslucentFresnel; #endif }
//============================================================================================================================================================== float3 CubeAverage( void ) { // FIXME: Pass this average light color in as a const float3 cAvgLight = 0.0; for( int j = 0; j < 6; j++ ) cAvgLight += cAmbientCube[j] / 6.0; return cAvgLight; }
//============================================================================================================================================================== float3 IceAmbientLight( float3 vVertexAmbient, float3 vEyeDir, float3 vWorldNormal, float flFresnel, // Function outputs: out float3 cAmbient, out float3 cAvgAmbient ) { // Ambient lighting now comes from VS cAmbient = vVertexAmbient;
// TODO: Replace lambert diffuse with pixelshader-ambient term of full lighting env. //cAmbient = PixelShaderAmbientLight( vBumpedWorldNormal, cAmbientCube );
// TODO: Ambient sheen on the outer layer //float3 cAmbientSheen = PixelShaderAmbientLight( reflect( -vEyeDir, vBumpedWorldNormal ), cAmbientCube ); //cAmbient = lerp( cAmbient, cAmbientSheen, flFresnel );
cAvgAmbient = CubeAverage();
return cAmbient; }
//============================================================================================================================================================== void IceDynamicLight( float3 vWorldPos, float3 vEyeDir, float3 vBumpedWorldNormal, float4 vLightAtten, float flFresnel, // Function outputs: out float3 cDiffuse, out float3 cSpec, out float3 cSpec2, out float3 cRim ) { cDiffuse = cSpec = cSpec2 = cRim = 0;
for ( int l = 0; l < NUM_LIGHTS; l++ ) { cDiffuse.rgb += vLightAtten[l] * PixelShaderGetLightColor( g_sLightInfo, l ) * DiffuseTerm( true, vBumpedWorldNormal, PixelShaderGetLightVector( vWorldPos, g_sLightInfo, l ), bLightWarp, g_tLightWarp );
// spec 1 float3 cCurrSpec, cCurrRim; bool bYesRimLight = true; SpecularAndRimTerms( vBumpedWorldNormal, PixelShaderGetLightVector( vWorldPos, g_sLightInfo, l ), g_flSpecExp, vEyeDir, false, g_tBump, 1.0, // dummy spec warp sampler & fresnel PixelShaderGetLightColor( g_sLightInfo, l ), bYesRimLight, g_flRimLightExp, cCurrSpec, cCurrRim ); cSpec += vLightAtten[l] * cCurrSpec; cRim += vLightAtten[l] * cCurrRim;
// spec 2 float3 cCurrSpec2, cDummy; bool bNoRimLight = false; SpecularAndRimTerms( vBumpedWorldNormal, PixelShaderGetLightVector( vWorldPos, g_sLightInfo, l ), g_flSpecExp2, vEyeDir, false, g_tBump, 1.0, // dummy spec warp sampler & fresnel PixelShaderGetLightColor( g_sLightInfo, l ), bNoRimLight, g_flRimLightExp, cCurrSpec2, cDummy ); cSpec2 += vLightAtten[l] * cCurrSpec2; // FIXME: no rim2 term? }
cRim *= flFresnel * flFresnel * flFresnel * flFresnel; }
//============================================================================================================================================================== void IceFlashlight( float3 vWorldPos, float3 vEyeDir, float3 vWorldNormal, float2 vScreenPos, float flSpecularExponent, // Function outputs: out float3 cOutFlashlightDiffuse, out float3 cOutFlashlightSpec, out float3 cOutFlashlightColor ) { float3 delta = g_vFlashlightPos - vWorldPos; float3 vLightVec = normalize( delta ); float distSquared = dot( delta, delta ); float dist = sqrt( distSquared );
// Attenuation for light and to fade out shadow over distance float fAtten = saturate( dot( g_vFlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); float endFalloffFactor = RemapValClamped( dist, g_flFlashlightFarZ, 0.6f * g_flFlashlightFarZ, 0.0f, 1.0f );
// Project into flashlight texture float4 flashlightSpacePosition = mul( float4( vWorldPos, 1.0f ), g_mFlashlightWorldToTexture ); // TODO: this can be moved to VS float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w;
// Flashlight colour cOutFlashlightColor = tex2D( g_tFlashlightCookie, vProjCoords ); #if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) cOutFlashlightColor *= cFlashlightColor.xyz; #endif cOutFlashlightColor *= endFalloffFactor * fAtten;
// Flashlight shadow #if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) if ( FLASHLIGHTSHADOWS ) { float flShadow = DoFlashlightShadow( g_tShadowDepth, g_tNormalizeRandRot, vProjCoords, vScreenPos, FLASHLIGHTDEPTHFILTERMODE, g_vShadowTweaks ); float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation cOutFlashlightColor *= flShadow; // Shadow term } #endif
// Flashlight diffuse term cOutFlashlightDiffuse = cOutFlashlightColor * DiffuseTerm( true, vWorldNormal, vLightVec, bLightWarp, g_tLightWarp );
// Flashlight specular term float3 cDummy; SpecularAndRimTerms( vWorldNormal, vLightVec, flSpecularExponent, -vEyeDir, false, g_tBump, 1.0, // dummy spec warp sampler & fresnel cOutFlashlightColor, false, g_flRimLightExp, cOutFlashlightSpec, cDummy ); }
//============================================================================================================================================================== float4 SampleBackgroundBlurred( float2 vBumpedTSNormal, float3 vWorldNormal, float2 vScreenPos, float flCamDist, float flFresnel ) { // Bumped refract float flRefractStrength = (2.0f - flFresnel) * 80.0 * g_flRefractStrength / flCamDist; float2 vBackgroundUV = flRefractStrength * vBumpedTSNormal + vScreenPos;
float4 cOut = /*1.0/8.0 * */tex2D( g_tScreen, vBackgroundUV ); return cOut; }
float3 IceInterior( float3 vWorldNormal, float2 vBumpedTSNormal, float3 vEyeDir, float flFresnel, float2 vScreenPos, float flPixelDepth, float flCamDist, float3 cAvgAmbient, float3 cFlashlightColor ) { float3 cInterior = 0;
// Sample the background (TODO: and inner ice geometry?) float4 cBackground = SampleBackgroundBlurred( vBumpedTSNormal, vWorldNormal, vScreenPos, flCamDist, flFresnel ); // Boost bright background pixels float flLuminance = Luminance( cBackground.rgb ); cBackground.rgb *= 1.0 + g_flInteriorBoost * flLuminance * flLuminance;
// Fake refract-like vector without any total internal reflection crappiness float3 vRefract = normalize( -( vEyeDir + vWorldNormal ) );
// Interior lighting through ambient cube float3 interiorColor = g_cBaseTint; float3 cBackLight = PixelShaderAmbientLight( vRefract, cAmbientCube ); float3 cAvgLight = cAvgAmbient + ( 0.6 * cFlashlightColor ); cBackLight = max( g_flInteriorLightScale * cAvgLight, g_flInteriorBackLightScale * cBackLight );
#if 0 // Disabled because dest alpha depth isn't currently working
// Get eye ray travel distance through the ice float flBackgroundDepth = cBackground.a * g_flDepthScale; float flDistThroughIce = flBackgroundDepth - flPixelDepth; #if HIGH_PRECISION_DEPTH == 0 // Fade to constant interior fogginess as we run against the low-precision destalpha depth limit flDistThroughIce = lerp( flDistThroughIce, g_flDepthScale, saturate( cBackground.a*cBackground.a*cBackground.a ) ); #endif
// Modify thickness based on normals (assume edge-on ice is thicker w.r.t the camera) // TODO: this gives a bit of depth variation based on normals - draw ice back surfaces into depth to improve this float facing = saturate( dot( vEyeDir, vWorldNormal ) ) - 1; float flFogNormalBoost = g_flFogNormalBoost; flDistThroughIce *= 1 + flFogNormalBoost*facing*facing;
// So that ice in dark areas doesn't glow, reduce thickness based on ambient/backlight luminance float flBackLightLuminance = Luminance( cBackLight ); flDistThroughIce *= flBackLightLuminance;
// Compute the opacity ('fog') of the ice interior volume, based on its thickness float flFogAtten = pow( 2.0, -flDistThroughIce * g_flInnerFogStrength ); // exponential falloff //float flFogAtten = saturate( 0.5 - 0.011 * flDistThroughIce ); // linear falloff
// TODO: add a depth-based colour warp //interiorColor = saturate( interiorColor - 0.5*( 1 - flFogAtten)*(1-flFogAtten) );
// Composite the fog interior lighting/fog over the background cBackLight *= interiorColor; cInterior = lerp( cBackLight, cBackground.rgb, flFogAtten );
//float flInScattering = flDistThroughIce * 0.002; //cInterior.rgb += flInScattering * i.vLightCube.rgb; #endif // 0
float flRimEffect = saturate( dot( vEyeDir, vWorldNormal ) ); cInterior = lerp( cBackLight, cBackground.rgb, sqrt( flRimEffect ) );
return cInterior; }
//============================================================================================================================================================== float IceContactShadow( float3 vWorldNormal, float4 vClosestSurfaceDir ) { // contact darkening for ice regions that touch a surface float3 vSurfaceDir = normalize( vClosestSurfaceDir.xyz ) * vClosestSurfaceDir.w; float flContactShadow = saturate( 0.8 * ( 1.0 - dot( vSurfaceDir, vWorldNormal ) ) + 0.2 ); flContactShadow = lerp ( 0.3, 1.0, flContactShadow * flContactShadow * flContactShadow ); return flContactShadow; }
//============================================================================================================================================================== float3 noise( float3 coord ) { coord.z *= 50.0; float zfrac = frac( coord.z ); float2 zhash = float2( coord.z, 1 + coord.z ); zhash -= frac( zhash ); zhash = ( zhash * zhash ); zhash -= 31.0 * floor( zhash / 31.0 ); zhash = ( zhash * zhash ); zhash -= 31.0 * floor( zhash / 31.0 ); zhash *= 1.0/31.0; float3 c0 = tex2D( g_tBase, float4( coord.xy + float2( 0, zhash.x ), 0, 0 ) ).rgb; float3 c1 = tex2D( g_tBase, float4( coord.xy + float2( 0, zhash.y ), 0, 0 ) ).rgb;
float3 rslt = lerp( c0, c1, zfrac ); return rslt; }
//============================================================================================================================================================== float4_color_return_type main( PS_INPUT i ) : COLOR { float4 cOut = { 0, 0, 0, 1 };
// Set up misc camera variables float flPixelDepth = i.vWorldNormal.w; float2 vScreenPos = i.vUV1.wz / i.vWorldPos.w; float3 vEyeDir = g_vEyePos.xyz - i.vWorldPos.xyz; float flCamDist = length( vEyeDir ); vEyeDir /= flCamDist;
// For now, 'BACK_SURFACE' is a dead-simple path (just writes depth into dest alpha) #if ( BACK_SURFACE == 1 ) cOut = tex2D( g_tScreen, vScreenPos ); return FinalOutput( cOut, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, flPixelDepth ); #endif
// Blend weights for 3 blended planar projections float3 vWorldNormal = normalize( i.vWorldNormal.xyz ); float3 vBlendWeights = ComputeTextureBlendWeights( vWorldNormal );
// Base+spec maps // FIXME: the outer layer doesn't really need a base texture - it's just frost, so, it just needs opacity float4 cBase = BlendedTexFetch( g_tBase, i.vUV0.xy, i.vUV0.wz, i.vUV1.xy, vBlendWeights ); float flSpecMask = BlendedTexFetch( g_tSpecMask, i.vUV0.xy, i.vUV0.wz, i.vUV1.xy, vBlendWeights ).x;
// Normal mapping float3 vBumpedWorldNormal, vFresnelWorldNormal; float2 vBumpedTSNormal; BlendedTexFetchNormal( g_tBump, i.vUV0.xy, i.vUV0.zw, i.vUV1.xy, vBlendWeights, vWorldNormal, vBumpedTSNormal, vBumpedWorldNormal, vFresnelWorldNormal );
// Opacity and fresnel float flSkinOpacity, flFresnel; ComputeOpacityAndFresnel( i.vUV0.xy, i.vUV0.wz, i.vUV1.xy, vBlendWeights, vEyeDir, vFresnelWorldNormal, flSkinOpacity, flFresnel );
// Ambient light float3 cAmbient, cAvgAmbient; IceAmbientLight( i.vLightCube, vEyeDir, vBumpedWorldNormal, flFresnel, cAmbient, cAvgAmbient );
// Dynamic lights float3 cDiffuse, cSpec, cSpec2, cRim; IceDynamicLight( i.vWorldPos.xyz, vEyeDir, vBumpedWorldNormal, i.vLightAtten, flFresnel, cDiffuse, cSpec, cSpec2, cRim );
// Environment reflection float3 vViewDirReflected = reflect( -vEyeDir, vBumpedWorldNormal ); // Must use environment map scale to get proper behavior across platforms with different texture formats (divide by 16 because code was written on PC where env_map_scale is 16.0) float3 cEnvironment = flFresnel * 0.67f * g_cEnvMapTint * texCUBE( g_tEnvironment, vViewDirReflected ).rgb * ( ENV_MAP_SCALE / 16.0f );
// Scale envmap with diffuse light cEnvironment *= ( 1.0f + cAmbient.rgb + cDiffuse.rgb );
// Flashlight float3 cFlashlightColor = 0; /*#if FLASHLIGHT == 1 float3 cFlashlightDiffuse, cFlashlightSpec; IceFlashlight( i.vWorldPos.xyz, vEyeDir, vBumpedWorldNormal, vScreenPos, g_flSpecExp2, cFlashlightDiffuse, cFlashlightSpec, cFlashlightColor ); cDiffuse.rgb += cFlashlightDiffuse; cSpec2 += cFlashlightSpec; #endif*/
// Scale light terms cDiffuse *= g_flDiffuseScale; cSpec *= g_flSpecScale; cSpec2 *= g_flSpecScale2; cRim *= g_flRimLightScale;
// Slight emissive term so we can see paint in the dark. Also needs to match lightmappedpaint. cDiffuse.rgb = ( ( cDiffuse.rgb * 0.82f ) + 0.04f );
// FIXME: expose this as a materialvar (or I guess tweak actual scene lights) cDiffuse.rgb *= float3(0.8,0.85,1.0);
#if ( INTERIOR_LAYER == 0 ) // Outer layer only cOut.rgb = cBase.rgb * ( cAmbient.rgb + cDiffuse.rgb ) + flSpecMask * ( cSpec + cSpec2 ) + cRim + cEnvironment; #else // Outer layer blended over inner/background colour float3 cExterior = cBase.rgb * ( cAmbient.rgb + cDiffuse.rgb ) + flSpecMask * ( cSpec2 + cRim ); float3 cInterior = IceInterior( vWorldNormal, vBumpedTSNormal, vEyeDir, flFresnel, vScreenPos, flPixelDepth, flCamDist, cAvgAmbient, cFlashlightColor ); //float3 cInterior = SampleBackgroundBlurred( vBumpedTSNormal, vWorldNormal, vScreenPos, flCamDist ); // Inner layer is meant to be smooth, glassy ice, so give it unmasked envmap and spec cInterior.rgb *= cBase.rgb; cInterior.rgb += cSpec + cEnvironment; cOut.rgb = lerp( cInterior.rgb, cExterior, flSkinOpacity ); #endif
#if CONTACT_SHADOW == 1 cOut.rgb *= IceContactShadow( vWorldNormal, i.vClosestSurfaceDir ); #endif
// TODO: Support fog cOut.a = 1; return FinalOutput( cOut, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, flPixelDepth ); }
|