58 lines
1.8 KiB
HLSL
58 lines
1.8 KiB
HLSL
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
|
|
#ifndef __VOLUMETRIC_FOG__
|
|
#define __VOLUMETRIC_FOG__
|
|
|
|
#include "./Flax/Noise.hlsl"
|
|
|
|
#define VOLUMETRIC_FOG_GRID_Z_LINEAR 1
|
|
|
|
// Structure that contains information about volumetric fog
|
|
struct VolumetricFogData
|
|
{
|
|
float4 GridSliceParameters;
|
|
float2 ScreenSize;
|
|
float2 VolumeTexelSize; // Scaled for dithering
|
|
};
|
|
|
|
float GetDepthFromSlice(float4 gridSliceParameters, float zSlice)
|
|
{
|
|
#if VOLUMETRIC_FOG_GRID_Z_LINEAR
|
|
return zSlice * gridSliceParameters.x;
|
|
#else
|
|
return (exp2(zSlice / gridSliceParameters.z) - gridSliceParameters.y) / gridSliceParameters.x;
|
|
#endif
|
|
}
|
|
|
|
float GetSliceFromDepth(float4 gridSliceParameters, float sceneDepth)
|
|
{
|
|
#if VOLUMETRIC_FOG_GRID_Z_LINEAR
|
|
return sceneDepth * gridSliceParameters.y;
|
|
#else
|
|
return (log2(sceneDepth * gridSliceParameters.x + gridSliceParameters.y) * gridSliceParameters.z);
|
|
#endif
|
|
}
|
|
|
|
float4 SampleVolumetricFog(Texture3D volumetricFogTexture, VolumetricFogData volumetricFogData, float3 viewVector, float2 uv, float4 temporalAAJitter = 0)
|
|
{
|
|
// Project view vector to get 3D frustum UVW coordinates
|
|
float sceneDepth = length(viewVector);
|
|
float zSlice = GetSliceFromDepth(volumetricFogData.GridSliceParameters, sceneDepth) * volumetricFogData.GridSliceParameters.w;
|
|
float3 volumeUV = float3(uv, zSlice);
|
|
|
|
// Dither to reduce banding artifacts
|
|
float2 noiseUV = volumeUV.xy + temporalAAJitter.xy;
|
|
float2 noise = rand2dTo2d(noiseUV * volumetricFogData.ScreenSize) * 2.0f - 1.0f;
|
|
volumeUV.xy += noise * volumetricFogData.VolumeTexelSize;
|
|
|
|
// Sample 3D texture
|
|
return volumetricFogTexture.SampleLevel(SamplerLinearClamp, volumeUV, 0);
|
|
}
|
|
|
|
float4 CombineVolumetricFog(float4 fog, float4 volumetricFog)
|
|
{
|
|
return float4(volumetricFog.rgb + fog.rgb * volumetricFog.a, volumetricFog.a * fog.a);
|
|
}
|
|
|
|
#endif
|