Diligent Engine
 
Loading...
Searching...
No Matches
Diligent::EpipolarLightScattering Class Reference

Implements the epipolar light scattering post-process effect. More...

#include <EpipolarLightScattering.hpp>

Classes

struct  CreateInfo
 Create info. More...
 
struct  FrameAttribs
 Frame attributes that are passed to the effect at the beginning of each frame. More...
 

Public Member Functions

 EpipolarLightScattering (const CreateInfo &CI)
 Creates a new instance of the EpipolarLightScattering class.
 
void PrepareForNewFrame (FrameAttribs &FrameAttribs, EpipolarLightScatteringAttribs &PPAttribs)
 
void ComputeSunColor (const float3 &vDirectionOnSun, const float4 &f4ExtraterrestrialSunColor, float4 &f4SunColorAtGround, float4 &f4AmbientLight)
 Computes the sun color and ambient light color based on the given direction on the sun and extraterrestrial sun color.
 
void RenderSun (TEXTURE_FORMAT RTVFormat, TEXTURE_FORMAT DSVFormat, Uint8 SampleCount)
 Renders the sun.
 
void PerformPostProcessing ()
 Runs the post-processing effect.
 
IBufferGetMediaAttribsCB ()
 Returns the media attributes buffer.
 
ITextureViewGetPrecomputedNetDensitySRV ()
 Returns the precomputed net density look-up texture.
 
ITextureViewGetAmbientSkyLightSRV (IRenderDevice *pDevice, IRenderStateCache *pStateCache, IDeviceContext *pContext)
 Returns the ambient sky light texture.
 

Detailed Description

Implements the epipolar light scattering post-process effect.

EpipolarLightScattering

This post-processing effect renders realistic high-quality light scattering effects and is based on this sample from Intel. The effect works by smartly placing expensive ray-marching samples along the epipolar lines that start at the light source and interpolating the radiance between these samples.

Parameters

EpipolarLightScatteringAttribs structure The following parameters control the effect

  • uiNumEpipolarSlices - the total number of epipolar slices (lines). For high quality effect, set this value to (Screen Width + Screen Height)/2
  • uiMaxSamplesInSlice - Maximum number of samples on a single epipolar line. When epipolar light is short, the actual number of samples may be lower. For high quality effect, set this value to max(Screen Width, Screen Height)/2.
  • uiInitialSampleStepInSlice - Initial ray marching sample spacing on an epipolar line. Additional samples are added at discontinuities.
  • uiEpipoleSamplingDensityFactor - Sample density scale near the epipole where inscattering changes rapidly. Note that sampling near the epipole is very cheap since only a few steps required to perform ray marching.
  • fRefinementThreshold - Sampling refinement threshold that controls detection of discontinuities. Smaller values produce more samples and higher quality, but at a higher performance cost.
  • bShowSampling - Whether to show epipolar sampling.
  • bCorrectScatteringAtDepthBreaks - Whether to correct inscattering at depth discontinuities. Improves quality for additional cost. It may be preferable to increase the number of slices and or maximum number of samples on an epipolar line instead.
  • bShowDepthBreaks - Whether to display pixels which are classified as depth discontinuities and which will be corrected. Only has effect when bCorrectScatteringAtDepthBreaks is TRUE.
  • bShowLightingOnly - Whether to show lighting only
  • bOptimizeSampleLocations - Optimize sample locations to avoid oversampling. This should generally be TRUE.
  • bEnableLightShafts - Whether to enable light shafts or render unshadowed inscattering. Setting this to FALSE increases performance, but reduces visual quality.
  • uiInstrIntegralSteps - Number of inscattering integral steps taken when computing unshadowed inscattering Default value is OK and should not be changed.
  • f2ShadowMapTexelSize - Size of the shadowmap texel (1/width, 1/height)
  • uiMaxSamplesOnTheRay - Maximum number of ray marching samples on a single ray. Typically this value should match the maximum shadow map cascade resolution. Using lower value will improve performance but may result in moire patterns. Note that in most cases significantly less samples are actually taken.
  • uiMinMaxShadowMapResolution - Defines the number of samples at the lowest level of min-max binary tree and should match the maximum cascade shadow map resolution.
  • iNumCascades - Number of shadow map cascades
  • iFirstCascadeToRayMarch - First cascade to use for ray marching. Usually first few cascades are small, and ray marching them is inefficient.
  • fMaxShadowMapStep - Cap on the maximum shadow map step in texels.
  • bUse1DMinMaxTree - Whether to use 1D min/max binary tree optimization. This improves performance for higher shadow map resolution. Test it.
  • bIs32BitMinMaxMipMap - Whether to use 32-bit float or 16-bit UNORM min-max binary tree. Usually 16-bit UNORM is OK.
  • uiLightSctrTechnique - Light scattering evaluation technique. The following two methods are available: epipolar and brute-force. Brute force light scattering performs expensive ray marching for every screen pixel. This method can be used as the quality reference.
  • uiCascadeProcessingMode - Shadow map cascades processing mode.
  • uiRefinementCriterion - Epipolar sampling refinement criterion. The two options are depth difference and scattering difference. Scattering difference is generally preferable way.
  • uiSingleScatteringMode - Single scattering evaluation mode. The following three methods are available:
    • None - no single scattering.
    • Integration (default) - evaluate single scattering with numerical integration.
    • Look-up table - use precomputed single-scattering look-up table.
  • uiMultipleScatteringMode - Higher-order scattering evaluation mode. The following three options are available:
    • None - no multiple scattering.
    • Unoccluded (default) - evaluate multiple scattering without shadowing.
    • Occluded - evaluate multiple scattering taking shadowing into account similar to single scattering.
  • uiExtinctionEvalMode - Atmospheric extinction evaluation mode.
  • bUseCustomSctrCoeffs - Whether to use custom scattering coefficients.
  • fAerosolDensityScale - Aerosol density scale to use for scattering coefficient computation.
  • fAerosolAbsorbtionScale - Aerosol absorption scale to use for scattering coefficient computation.
  • f4CustomRlghBeta - Custom Rayleigh coefficients.
  • f4CustomMieBeta - Custom Mie coefficients.

Integration

The effect requires the following data:

  • Shader and render target views of the original color buffer
  • Shader and depth-stencil views of the original depth buffer
  • Shadow map
  • Light and color attributes

The code snippet below shows how to use the epipolar light scattering post-processing effect. For the full source code, see Atmospheric scattering sample.

FrameAttribs.pDevice = m_pDevice;
FrameAttribs.pDeviceContext = m_pImmediateContext;
FrameAttribs.dElapsedTime = m_fElapsedTime;
m_PPAttribs.iNumCascades = m_TerrainRenderParams.m_iNumShadowCascades;
m_PPAttribs.fNumCascades = (float)m_TerrainRenderParams.m_iNumShadowCascades;
FrameAttribs.pcbLightAttribs = m_pcbLightAttribs;
FrameAttribs.pcbCameraAttribs = m_pcbCameraAttribs;
m_PPAttribs.fMaxShadowMapStep = static_cast<float>(m_uiShadowMapResolution / 4);
m_PPAttribs.f2ShadowMapTexelSize = float2( 1.f / static_cast<float>(m_uiShadowMapResolution), 1.f / static_cast<float>(m_uiShadowMapResolution) );
m_PPAttribs.uiMaxSamplesOnTheRay = m_uiShadowMapResolution;
// During the ray marching, on each step we move by the texel size in either horz
// or vert direction. So resolution of min/max mipmap should be the same as the
// resolution of the original shadow map
m_PPAttribs.uiMinMaxShadowMapResolution = m_uiShadowMapResolution;
m_PPAttribs.uiInitialSampleStepInSlice = std::min( m_PPAttribs.uiInitialSampleStepInSlice, m_PPAttribs.uiMaxSamplesInSlice );
m_PPAttribs.uiEpipoleSamplingDensityFactor = std::min( m_PPAttribs.uiEpipoleSamplingDensityFactor, m_PPAttribs.uiInitialSampleStepInSlice );
FrameAttribs.ptex2DSrcColorBufferSRV = m_pOffscreenColorBuffer->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
FrameAttribs.ptex2DSrcColorBufferRTV = m_pOffscreenColorBuffer->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET);
FrameAttribs.ptex2DSrcDepthBufferSRV = m_pOffscreenDepthBuffer->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
FrameAttribs.ptex2DSrcDepthBufferDSV = m_pOffscreenDepthBuffer->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL);
FrameAttribs.ptex2DShadowMapSRV = m_pShadowMapSRV;
FrameAttribs.pDstRTV = nullptr;// mpBackBufferRTV;
// Perform the post processing
m_pLightSctrPP->PerformPostProcessing(FrameAttribs, m_PPAttribs);
@ TEXTURE_VIEW_SHADER_RESOURCE
Definition GraphicsTypes.h:327
@ TEXTURE_VIEW_RENDER_TARGET
Definition GraphicsTypes.h:331
@ TEXTURE_VIEW_DEPTH_STENCIL
Definition GraphicsTypes.h:335
Frame attributes that are passed to the effect at the beginning of each frame.
Definition EpipolarLightScattering.hpp:180
const CameraAttribs * pCameraAttribs
A pointer to the camera attributes CPU data.
Definition EpipolarLightScattering.hpp:197
double dElapsedTime
The time elapsed since the last frame.
Definition EpipolarLightScattering.hpp:191
const LightAttribs * pLightAttribs
A pointer to the light attributes CPU data.
Definition EpipolarLightScattering.hpp:194
ITextureView * ptex2DSrcColorBufferSRV
Shader resource view of the source color buffer.
Definition EpipolarLightScattering.hpp:206
IBuffer * pcbLightAttribs
If this parameter is null, the effect will use its own buffer.
Definition EpipolarLightScattering.hpp:200
ITextureView * ptex2DShadowMapSRV
Shadow map shader resource view.
Definition EpipolarLightScattering.hpp:218
ITextureView * ptex2DSrcDepthBufferSRV
Shader resource view of the source depth.
Definition EpipolarLightScattering.hpp:209
IBuffer * pcbCameraAttribs
If this parameter is null, the effect will use its own buffer.
Definition EpipolarLightScattering.hpp:203
IDeviceContext * pDeviceContext
Device context that will record the rendering commands.
Definition EpipolarLightScattering.hpp:188
IRenderDevice * pDevice
Render device that may be used to create new objects needed for this frame, if any.
Definition EpipolarLightScattering.hpp:182

Member Function Documentation

◆ PrepareForNewFrame()

void Diligent::EpipolarLightScattering::PrepareForNewFrame ( FrameAttribs & FrameAttribs,
EpipolarLightScatteringAttribs & PPAttribs )

The method prepares internal resources and states for processing the next frame. It must be called at the beginning of every frame before any other rendering method (RenderSun, PerformPostProcessing) can be called.