//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// // //=============================================================================// // STATIC: "DETAILTEXTURE" "0..1" // STATIC: "CUBEMAP" "0..1" // STATIC: "DIFFUSELIGHTING" "0..1" // STATIC: "ENVMAPMASK" "0..1" // STATIC: "BASEALPHAENVMAPMASK" "0..1" // STATIC: "SELFILLUM" "0..1" // STATIC: "VERTEXCOLOR" "0..1" // STATIC: "FLASHLIGHT" "0..1" // STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1" // STATIC: "DETAIL_BLEND_MODE" "0..9" // STATIC: "SEAMLESS_BASE" "0..1" // STATIC: "SEAMLESS_DETAIL" "0..1" // STATIC: "DISTANCEALPHA" "0..1" // STATIC: "DISTANCEALPHAFROMDETAIL" "0..1" // STATIC: "SOFT_MASK" "0..1" // STATIC: "OUTLINE" "0..1" // STATIC: "OUTER_GLOW" "0..1" // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] // STATIC: "DEPTHBLEND" "0..1" [ps20b] [ps30] // STATIC: "BLENDTINTBYBASEALPHA" "0..1" // STATIC: "SRGB_INPUT_ADAPTER" "0..1" [ps20b] // STATIC: "CUBEMAP_SPHERE_LEGACY" "0..1" // DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] // DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] // DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] // DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] // DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] // DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..1" [ps20b] [ps30] // DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..0" [ps20] // DYNAMIC: "DEBUG_LUXELS" "0..1" [ps20b] [ps30] // detail blend mode 6 = ps20b only // SKIP: $DETAIL_BLEND_MODE == 6 [ps20] // SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 ) // SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL ) // SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) // SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK // SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM // SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA // SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK) // SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS) [PC] // SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) // SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW) // SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL) // We don't care about flashlight depth unless the flashlight is on // SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] // SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] // Flashlight shadow filter mode is irrelevant if there is no flashlight // SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] // SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] // DISTANCEALPHA-related skips // SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA ) // SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW ) // SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER ) // SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER // SKIP: $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA ) // BlendTintByBaseAlpha is incompatible with other interpretations of alpha // SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK) // Only _XBOX allows flashlight and cubemap in the current implementation // SKIP: $FLASHLIGHT && $CUBEMAP [PC] // SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) // Debugging luxels only makes sense if we have lightmaps on this geometry. // SKIP: ($STATIC_LIGHT_LIGHTMAP == 0) && ($DEBUG_LUXELS == 1) #include "common_flashlight_fxc.h" #include "common_vertexlitgeneric_dx9.h" const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); const float4 g_DiffuseModulation : register( c1 ); const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); const float4 g_EnvmapSaturation_SelfIllumMask : register( c3 ); const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); const float4 g_ShaderControls : register( c12 ); const float4 g_DepthFeatheringConstants : register( c13 ); const float4 g_EyePos : register( c20 ); const float4 g_FogParams : register( c21 ); #define g_SelfIllumTint g_SelfIllumTint_and_BlendFactor.xyz #define g_DetailBlendFactor g_SelfIllumTint_and_BlendFactor.w #define g_EnvmapSaturation g_EnvmapSaturation_SelfIllumMask.xyz #define g_SelfIllumMaskControl g_EnvmapSaturation_SelfIllumMask.w const float4 g_FlashlightAttenuationFactors : register( c22 ); const HALF3 g_FlashlightPos : register( c23 ); const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 sampler BaseTextureSampler : register( s0 ); sampler EnvmapSampler : register( s1 ); sampler DetailSampler : register( s2 ); sampler EnvmapMaskSampler : register( s4 ); sampler RandRotSampler : register( s6 ); // RandomRotation sampler sampler FlashlightSampler : register( s7 ); sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending sampler SelfIllumMaskSampler : register( s11 ); // selfillummask sampler LightMapSampler : register( s12 ); struct PS_INPUT { #if SEAMLESS_BASE HALF3 baseTexCoord : TEXCOORD0; // Base texture coordinate #else HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate #endif #if SEAMLESS_DETAIL HALF3 detailTexCoord : TEXCOORD1; // Seamless texture coordinate #else HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate #endif float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight #if defined ( _X360 ) #if FLASHLIGHT float4 flashlightSpacePos : TEXCOORD5; #endif #endif float4 projPos : TEXCOORD6; float4 worldPos_projPosZ : TEXCOORD7; float4 fogFactorW : COLOR1; #if SEAMLESS_BASE || SEAMLESS_DETAIL float3 SeamlessWeights : COLOR0; // x y z projection weights #endif }; const float4 g_GlowParameters : register( c5 ); const float4 g_GlowColor : register( c6 ); #define GLOW_UV_OFFSET g_GlowParameters.xy #define OUTER_GLOW_MIN_DVALUE g_GlowParameters.z #define OUTER_GLOW_MAX_DVALUE g_GlowParameters.w #define OUTER_GLOW_COLOR g_GlowColor #define g_fPixelFogType g_ShaderControls.x #define g_fWriteDepthToAlpha g_ShaderControls.y #define g_fWriteWaterFogToDestAlpha g_ShaderControls.z #define g_fVertexAlpha g_ShaderControls.w const float4 g_DistanceAlphaParams : register( c7 ); #define SOFT_MASK_MAX g_DistanceAlphaParams.x #define SOFT_MASK_MIN g_DistanceAlphaParams.y const float4 g_OutlineColor : register( c8 ); #define OUTLINE_COLOR g_OutlineColor const float4 g_OutlineParams : register( c9 ); // these are ordered this way for optimal ps20 swizzling #define OUTLINE_MIN_VALUE0 g_OutlineParams.x #define OUTLINE_MAX_VALUE1 g_OutlineParams.y #define OUTLINE_MAX_VALUE0 g_OutlineParams.z #define OUTLINE_MIN_VALUE1 g_OutlineParams.w #if DETAILTEXTURE const float3 g_DetailTint : register( c10 ); #endif #if DEBUG_LUXELS const float4 g_LuxelScale : register( c11 ); #endif // Calculate unified fog float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) { float flDepthBelowWater = fPixelFogType*fogParams.y - flWorldPosZ; // above water = negative, below water = positive float flDepthBelowEye = fPixelFogType*flEyePosZ - flWorldPosZ; // above eye = negative, below eye = positive // if fPixelFogType == 0, then flDepthBelowWater == flDepthBelowEye and frac will be 1 float frac = (flDepthBelowEye == 0) ? 1 : saturate(flDepthBelowWater/flDepthBelowEye); return saturate( min(fogParams.z, flProjPosZ * fogParams.w * frac - fogParams.x) ); } // Blend both types of Fog and lerp to get result float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) { //float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog //float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); //return lerp( fRangeResult, fHeightResult, fPixelFogType ); pixelFogFactor = lerp( pixelFogFactor*pixelFogFactor, pixelFogFactor, fPixelFogType ); return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor ); } float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) { float4 result = vShaderColor; if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) { result.rgb *= LINEAR_LIGHT_SCALE; } else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) { result.rgb *= GAMMA_LIGHT_SCALE; } result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion return result; } #if LIGHTING_PREVIEW == 2 LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR #else float4 main( PS_INPUT i ) : COLOR #endif { bool bDetailTexture = DETAILTEXTURE ? true : false; bool bCubemap = CUBEMAP ? true : false; bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; bool bHasNormal = bCubemap || bDiffuseLighting; bool bEnvmapMask = ENVMAPMASK ? true : false; bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; bool bSelfIllum = SELFILLUM ? true : false; bool bVertexColor = VERTEXCOLOR ? true : false; bool bFlashlight = FLASHLIGHT ? true : false; bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); #if SEAMLESS_BASE baseColor = i.SeamlessWeights.x * tex2D( BaseTextureSampler, i.baseTexCoord.yz )+ i.SeamlessWeights.y * tex2D( BaseTextureSampler, i.baseTexCoord.zx )+ i.SeamlessWeights.z * tex2D( BaseTextureSampler, i.baseTexCoord.xy ); #else baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); #if SRGB_INPUT_ADAPTER baseColor.rgb = GammaToLinear( baseColor.rgb ); #endif #endif // !SEAMLESS_BASE #if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 0) float distAlphaMask = baseColor.a; #endif #if DETAILTEXTURE #if SEAMLESS_DETAIL float4 detailColor = i.SeamlessWeights.x * tex2D( DetailSampler, i.detailTexCoord.yz )+ i.SeamlessWeights.y * tex2D( DetailSampler, i.detailTexCoord.zx )+ i.SeamlessWeights.z * tex2D( DetailSampler, i.detailTexCoord.xy ); #else float4 detailColor = tex2D( DetailSampler, i.detailTexCoord.xy ); #endif detailColor.rgb *= g_DetailTint; #if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 1) float distAlphaMask = detailColor.a; detailColor.a = 1.0; // make tcombine treat as 1.0 #endif baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); #endif #if DISTANCEALPHA // now, do all distance alpha effects //if ( OUTLINE && ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) //{ // float oFactor=1.0; // if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) // { // oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); // } // else // { // oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); // } // baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); //} if ( OUTLINE ) { float4 oFactors = smoothstep(g_OutlineParams.xyzw, g_OutlineParams.wzyx, distAlphaMask ); baseColor = lerp( baseColor, g_OutlineColor, oFactors.x * oFactors.y ); } float mskUsed; if ( SOFT_MASK ) { mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask ); baseColor.a *= mskUsed; } else { mskUsed = distAlphaMask >= 0.5; if (DETAILTEXTURE ) baseColor.a *= mskUsed; else baseColor.a = mskUsed; } if ( OUTER_GLOW ) { #if DISTANCEALPHAFROMDETAIL float4 glowTexel = tex2D( DetailSampler, i.detailTexCoord.xy+GLOW_UV_OFFSET ); #else float4 glowTexel = tex2D( BaseTextureSampler, i.baseTexCoord.xy+GLOW_UV_OFFSET ); #endif float4 glowc = OUTER_GLOW_COLOR*smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel.a ); baseColor = lerp( glowc, baseColor, mskUsed ); } #endif // DISTANCEALPHA float3 specularFactor = 1.0f; float4 envmapMaskTexel; if( bEnvmapMask ) { envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord.xy ); specularFactor *= envmapMaskTexel.xyz; } if( bBaseAlphaEnvmapMask ) { specularFactor *= 1.0 - baseColor.a; // this blows! } float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); if( bDiffuseLighting || bVertexColor ) { diffuseLighting = i.color.rgb; } #if STATIC_LIGHT_LIGHTMAP // This matches the behavior of vertex lighting, which multiplies by cOverbright (which is not accessible here) // And converts from Gamma space to Linear space before being used. float2 lightmapTexCoords = i.baseTexCoord.xy; #if DEBUG_LUXELS lightmapTexCoords.xy *= g_LuxelScale.xy; #endif float3 f3LightmapColor = GammaToLinear( 2.0f * tex2D( LightMapSampler, lightmapTexCoords ).rgb ); diffuseLighting = f3LightmapColor; #endif float3 albedo = baseColor; if (bBlendTintByBaseAlpha) { float3 tintedColor = albedo * g_DiffuseModulation.rgb; tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); albedo = lerp(albedo, tintedColor, baseColor.a); } else { albedo = albedo * g_DiffuseModulation.rgb; } float alpha = g_DiffuseModulation.a; if ( !bBaseAlphaEnvmapMask && !bSelfIllum && !bBlendTintByBaseAlpha ) { alpha *= baseColor.a; } if( bFlashlight ) { int nShadowSampleLevel = 0; bool bDoShadows = false; // On ps_2_b, we can do shadow mapping #if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; bDoShadows = true; #endif #if defined ( _X360 ) float4 flashlightSpacePosition = i.flashlightSpacePos; #else float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); #endif // We want the N.L to happen on the flashlight pass, but can't afford it on ps20 bool bUseWorldNormal = true; #if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) ) bUseWorldNormal = false; #endif float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, i.worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, RandRotSampler, nShadowSampleLevel, bDoShadows, false, i.projPos.xy / i.projPos.w, false, g_EnvmapContrast_ShadowTweaks, bUseWorldNormal ); #if defined ( _X360 ) diffuseLighting += flashlightColor; #else diffuseLighting = flashlightColor; #endif } if( bVertexColor && bDiffuseLighting ) { albedo *= i.color.rgb; } alpha = lerp( alpha, alpha * i.color.a, g_fVertexAlpha ); float3 diffuseComponent = albedo * diffuseLighting; #if DETAILTEXTURE diffuseComponent = TextureCombinePostLighting( diffuseComponent, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); #endif HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); #if !FLASHLIGHT || defined ( _X360 ) #if SELFILLUM_ENVMAPMASK_ALPHA // range of alpha: // 0 - 0.125 = lerp(diffuse,selfillum,alpha*8) // 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows) HALF3 selfIllumComponent = g_SelfIllumTint * albedo; half Adj_Alpha=8*envmapMaskTexel.a; diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent; #else if ( bSelfIllum ) { float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoord.xy ); vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint * albedo, vSelfIllumMask ); } #endif if( bCubemap ) { #if CUBEMAP_SPHERE_LEGACY HALF3 reflectVect = normalize(CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz )); specularLighting = 0.5 * tex2D( EnvmapSampler, float2(reflectVect.x, reflectVect.y) ) * g_DiffuseModulation.rgb * diffuseLighting; #else HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz ); specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); specularLighting *= specularFactor; specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; HALF3 specularLightingSquared = specularLighting * specularLighting; specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); #endif } #endif HALF3 result = diffuseComponent + specularLighting; #if LIGHTING_PREVIEW # if LIGHTING_PREVIEW == 1 float dotprod=0.7+0.25*dot(i.worldSpaceNormal,normalize(float3(1,2,-.5))); return FinalOutput( float4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); # else LPREVIEW_PS_OUT ret; ret.flags=float4(1,1,1,1); ret.color=float4( albedo.xyz, alpha ); ret.normal=float4(i.worldSpaceNormal,alpha); ret.position=float4(i.worldPos_projPosZ.xyz, alpha); return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); # endif #else # if (DEPTHBLEND == 1) { float2 vScreenPos; vScreenPos.x = i.projPos.x; vScreenPos.y = -i.projPos.y; vScreenPos = (vScreenPos + i.projPos.w) * 0.5f; alpha *= DepthFeathering( DepthSampler, vScreenPos / i.projPos.w, i.projPos.w - i.projPos.z, i.projPos.w, g_DepthFeatheringConstants ); } # endif #if defined( SHADER_MODEL_PS_2_0 ) float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); #if (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); #endif return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.projPos.z ); #else // 2b or higher float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z ); #endif #endif }