/*============================================================================= HeightFogCommon.usf: Copyright 1998-2010 Epic Games, Inc. All Rights Reserved. =============================================================================*/ static const float FLT_EPSILON = 0.001f; /** calculate ratio of distance between world z height and relative fog height */ float4 LinePlaneIntersection(float3 RelativeB,float4 RelativeZ) { return RelativeZ / (abs(RelativeB.z) <= FLT_EPSILON ? FLT_EPSILON : RelativeB.z); } // BIOSTART - October 19, 2010 - Wihlidal, Graham - Fix PS3 Fog Precision Issues /** used to scale fog layer distance */ float4 FogDistanceScale; /** any layer distance beyond this is clamped to full fog */ float4 FogExtinctionDistance; /** lighting contribution from fog. This uses 4 components to avoid platform-specific alignment of each element of the array. */ half4 FogInScattering[4]; /** distance at which fog will start */ float4 FogStartDistance; // BIOEND /** world space min z height */ float4 FogMinHeight; /** world space max z height */ float4 FogMaxHeight; half4 CalculateVertexHeightFog(float3 WorldPosition, float4 InCameraPosition) { float3 WorldVector = WorldPosition.xyz - InCameraPosition.xyz; float Distance = length(WorldVector); // maxfog - camera / z height float4 MinHeightPercent = LinePlaneIntersection(WorldVector,FogMinHeight - InCameraPosition.z); // minfog - camera / z height float4 MaxHeightPercent = LinePlaneIntersection(WorldVector,FogMaxHeight - InCameraPosition.z); // fog layer distance based on % over max/min fog heights half4 LayerDistance = max(half4(0,0,0,0),half4(Distance,Distance,Distance,Distance)-FogStartDistance) * abs(saturate(MaxHeightPercent) - saturate(MinHeightPercent)); // clamp anything beyond the extinction distance to 0 scattering // scattering falloff is exponential based on normalized layer distance half4 Scattering = LayerDistance < FogExtinctionDistance ? exp2(FogDistanceScale * LayerDistance) : half4(0,0,0,0); // ratio of the inscattering color to be used half4 InScattering = Scattering - 1; half4 Fog = half4(0,0,0,1); for(int LayerIndex = 0;LayerIndex < 4;LayerIndex++) { Fog *= Scattering[LayerIndex]; Fog.rgb += InScattering[LayerIndex] * FogInScattering[LayerIndex]; } return Fog; }