/*============================================================================= FogVolumeApplyPixelShader.usf: looks up the integral accumulation and applies the fog to scene color Copyright 1998-2010 Epic Games, Inc. All Rights Reserved. =============================================================================*/ #include "Common.usf" #include "Material.usf" #include "VertexFactory.usf" /* Texture containing the accumulated integral for frontfaces */ SAMPLER2D(AccumulatedFrontfacesLineIntegralTexture); /* Texture containing the accumulated integral for backfaces */ SAMPLER2D(AccumulatedBackfacesLineIntegralTexture); /* Maximum integral allowed for the density function */ float MaxIntegral; /* * Decodes the floating point integral from a fixed point buffer. * This is not called for platforms that use floating point blending to accumulate the integral. */ float DecodeIntegral(float4 EncodedIntegral) { /* //extract the integral from G16R16 float2 Shift = float2(1.0f / 65536.0f, 1.0f); return dot(EncodedIntegral.xy, Shift) * MaxIntegral; */ //24bits, from the lowest 6 bits of RGBA8. 2 are left over for overflow in each channel, for a max of 4 additive blends //shift down 18, 12, 6, 0 bits float4 Shift = float4(1.0f / 262144.0f, 1.0f / 4096.0f, 1.0f / 64.0f, 1.0f); //shift all channels up 2 bits first, since they were shifted down to make room for overflow //then shift each channel by its offset, combine and denormalize return dot(EncodedIntegral.xyzw * 4.0f, Shift) * MaxIntegral; } /* * Applies fog calculated for a fog volume to scene color. * The material's emssive is used as the fog color, and the opacity is used to modulate the fog factor. */ void Main( FVertexFactoryInterpolants Interpolants, float4 PixelPosition : TEXCOORD5, // BIOSTART - September 15, 2010 - Wihlidal, Graham - PS3 Fragment and Vertex Shader Optimizations in half4 CameraVectorOrVertexColor : TEXCOORD6, // BIOEND OPTIONAL_FacingSign out float4 OutColor : SV_Target0 ) { FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Interpolants); CalcMaterialParameters(MaterialParameters,FacingSign,CameraVectorOrVertexColor,PixelPosition); //use the material's emissive input as fog color half3 FogColor = GetMaterialEmissive(MaterialParameters); //these coordinates are valid even if the integral buffers are downsampled, //since texture coordinates do not factor in texture size. float2 PerspectiveCorrectScreenPosition = MaterialParameters.ScreenPosition.xy / MaterialParameters.ScreenPosition.w * ScreenPositionScaleBias.xy + ScreenPositionScaleBias.wz; #if SM2_PROFILE || XBOX float FrontfacesIntegral = DecodeIntegral(tex2D(AccumulatedFrontfacesLineIntegralTexture,PerspectiveCorrectScreenPosition)); float BackfacesIntegral = DecodeIntegral(tex2D(AccumulatedBackfacesLineIntegralTexture,PerspectiveCorrectScreenPosition)); float AccumulatedLineIntegral = BackfacesIntegral - FrontfacesIntegral; #else float AccumulatedLineIntegral = tex2D(AccumulatedBackfacesLineIntegralTexture,PerspectiveCorrectScreenPosition).r; #endif //evaluate the transmittance function, f = exp(-LineIntegral) //use material opacity to scale the fog integral float FogFactor = saturate(exp2(-AccumulatedLineIntegral * GetMaterialOpacity(MaterialParameters))); //combine with scene color, SrcColor * f + (1-f) * FogColor OutColor = RETURN_COLOR(half4(FogColor, FogFactor)); }