using System ;
using UnityEngine.Rendering ;
using System.Collections.Generic ;
using System.Runtime.InteropServices ;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
Count
} // enum VolumetricLightingPreset
[Serializable]
public struct ControllerParameters
{
public float vBufferNearPlane ; // Distance in meters
public float vBufferFarPlane ; // Distance in meters
public float depthSliceDistributionUniformity ; // Controls the exponential depth distribution: [0, 1]
} // struct ControllerParameters
public class VBuffer
public struct VBufferParameters
public struct Parameters
{
public Vector4 resolution ;
public Vector2 sliceCount ;
public Vector4 depthEncodingParams ;
public Vector4 depthDecodingParams ;
public Parameters ( int w , int h , int d , ControllerParameters controlParams )
{
resolution = new Vector4 ( w , h , 1.0f / w , 1.0f / h ) ;
sliceCount = new Vector2 ( d , 1.0f / d ) ;
depthEncodingParams = Vector4 . zero ; // C# doesn't allow function calls before all members have been init
depthDecodingParams = Vector4 . zero ; // C# doesn't allow function calls before all members have been init
Update ( controlParams ) ;
}
public void Update ( ControllerParameters controlParams )
{
float n = controlParams . vBufferNearPlane ;
float f = controlParams . vBufferFarPlane ;
float c = 2 - 2 * controlParams . depthSliceDistributionUniformity ; // remap [0, 1] -> [2, 0]
depthEncodingParams = ComputeLogarithmicDepthEncodingParams ( n , f , c ) ;
depthDecodingParams = ComputeLogarithmicDepthDecodingParams ( n , f , c ) ;
}
} // struct Parameters
const int k_NumFrames = 2 ; // Double-buffer history and feedback
const int k_NumBuffers = 4 ; // See the list below
const int k_IndexDensity = 0 ;
const int k_IndexIntegral = 1 ;
const int k_IndexHistory = 2 ; // Depends on frame ID
const int k_IndexFeedback = 3 ; // Depends on frame ID
long m_ViewID = - 1 ; // (m_ViewID > 0) if valid
RenderTexture [ ] m_Textures = null ;
RenderTargetIdentifier [ ] m_Identifiers = null ;
Parameters [ ] m_Params = null ; // For the current and the previous frame
public long GetViewID ( )
{
return m_ViewID ;
}
public Vector4 resolution ;
public Vector2 sliceCount ;
public Vector4 uvScaleAndLimit ; // Necessary to work with sub-allocation (resource aliasing) in the RTHandle system
public Vector4 depthEncodingParams ;
public Vector4 depthDecodingParams ;
public bool IsValid ( )
public VBufferParameters ( Vector3Int viewportResolution , Vector3Int bufferResolution , Vector2 depthRange , float depthDistributionUniformity )
return m_ViewID > 0 & & m_Textures ! = null & & m_Textures [ 0 ] ! = null ;
}
int w = viewportResolution . x ;
int h = viewportResolution . y ;
int d = viewportResolution . z ;
public Parameters GetParameters ( uint frameIndex )
{
return m_Params [ frameIndex & 1 ] ;
}
// The depth is fixed for now.
Vector2 uvScale = new Vector2 ( ( float ) w / ( float ) bufferResolution . x ,
( float ) h / ( float ) bufferResolution . y ) ;
public void SetParameters ( Parameters parameters , uint frameIndex )
{
m_Params [ frameIndex & 1 ] = parameters ;
}
// vp_scale = vp_dim / tex_dim.
// clamp to (vp_dim - 0.5) / tex_dim = vp_scale - 0.5 * (1 / tex_dim) =
// vp_scale - 0.5 * (vp_scale / vp_dim) = vp_scale * (1 - 0.5 / vp_dim).
Vector2 uvLimit = new Vector2 ( ( w - 0.5f ) / ( float ) bufferResolution . x ,
( h - 0.5f ) / ( float ) bufferResolution . y ) ;
public RenderTargetIdentifier GetDensityBuffer ( )
{
Debug . Assert ( IsValid ( ) ) ;
return m_Identifiers [ k_IndexDensity ] ;
}
public RenderTargetIdentifier GetLightingIntegralBuffer ( ) // Of the current frame
{
Debug . Assert ( IsValid ( ) ) ;
return m_Identifiers [ k_IndexIntegral ] ;
}
resolution = new Vector4 ( w , h , 1.0f / w , 1.0f / h ) ;
sliceCount = new Vector2 ( d , 1.0f / d ) ;
uvScaleAndLimit = new Vector4 ( uvScale . x , uvScale . y , uvLimit . x , uvLimit . y ) ;
public RenderTargetIdentifier GetLightingHistoryBuffer ( uint frameIndex ) // From the previous frame
{
Debug . Assert ( IsValid ( ) ) ;
return m_Identifiers [ k_IndexHistory + ( frameIndex & 1 ) ] ;
}
float n = depthRange . x ;
float f = depthRange . y ;
float c = 2 - 2 * depthDistributionUniformity ; // remap [0, 1] -> [2, 0]
public RenderTargetIdentifier GetLightingFeedbackBuffer ( uint frameIndex ) // For the next frame
{
Debug . Assert ( IsValid ( ) ) ;
return m_Identifiers [ k_IndexFeedback - ( frameIndex & 1 ) ] ;
depthEncodingParams = ComputeLogarithmicDepthEncodingParams ( n , f , c ) ;
depthDecodingParams = ComputeLogarithmicDepthDecodingParams ( n , f , c ) ;
public void Create ( long viewID , int w , int h , int d , ControllerParameters controlParams )
{
Debug . Assert ( viewID > 0 ) ;
Debug . Assert ( w > 0 & & h > 0 & & d > 0 ) ;
// Clean up first.
Destroy ( ) ;
m_ViewID = viewID ;
m_Textures = new RenderTexture [ k_NumBuffers ] ;
m_Identifiers = new RenderTargetIdentifier [ k_NumBuffers ] ;
m_Params = new Parameters [ k_NumFrames ] ;
for ( int i = 0 ; i < k_NumBuffers ; i + + )
{
m_Textures [ i ] = new RenderTexture ( w , h , 0 , RenderTextureFormat . ARGBHalf , RenderTextureReadWrite . Linear ) ;
m_Textures [ i ] . hideFlags = HideFlags . HideAndDontSave ;
m_Textures [ i ] . filterMode = FilterMode . Trilinear ; // Custom
m_Textures [ i ] . dimension = TextureDimension . Tex3D ; // TODO: request the thick 3D tiling layout
m_Textures [ i ] . volumeDepth = d ;
m_Textures [ i ] . enableRandomWrite = true ;
m_Textures [ i ] . name = CoreUtils . GetRenderTargetAutoName ( w , h , RenderTextureFormat . ARGBHalf , String . Format ( "VBuffer{0}" , i ) ) ;
m_Textures [ i ] . Create ( ) ;
// TODO: clear the texture. Clearing 3D textures does not appear to work right now.
m_Identifiers [ i ] = new RenderTargetIdentifier ( m_Textures [ i ] ) ;
}
// Start with the same parameters for both frames. Then incrementally update them.
Parameters parameters = new Parameters ( w , h , d , controlParams ) ;
m_Params [ 0 ] = parameters ;
m_Params [ 1 ] = parameters ;
}
public void Destroy ( )
{
if ( m_Textures ! = null )
{
for ( int i = 0 ; i < k_NumBuffers ; i + + )
{
if ( m_Textures [ i ] ! = null )
{
m_Textures [ i ] . Release ( ) ;
}
}
}
m_ViewID = - 1 ;
m_Textures = null ;
m_Identifiers = null ;
m_Params = null ;
}
} // class VBuffer
} // struct Parameters
public VolumetricLightingPreset preset { get { return ( VolumetricLightingPreset ) Math . Min ( ShaderConfig . s_VolumetricLightingPreset , ( int ) VolumetricLightingPreset . Count ) ; } }
List < VBuffer > m_VBuffers = null ;
List < OrientedBBox > m_VisibleVolumeBounds = null ;
List < DensityVolumeData > m_VisibleVolumeData = null ;
public const int k_MaxVisibleVolumeCount = 5 1 2 ;
static ComputeBuffer s_VisibleVolumeDataBuffer = null ;
// These two buffers do not depend on the frameID and are therefore shared by all views.
RTHandleSystem . RTHandle m_DensityBufferHandle ;
RTHandleSystem . RTHandle m_LightingBufferHandle ;
m_VolumeVoxelizationCS = asset . renderPipelineResources . volumeVoxelizationCS ;
m_VolumetricLightingCS = asset . renderPipelineResources . volumetricLightingCS ;
m_VBuffers = new List < VBuffer > ( ) ;
m_VisibleVolumeBounds = new List < OrientedBBox > ( ) ;
m_VisibleVolumeData = new List < DensityVolumeData > ( ) ;
s_VisibleVolumeBoundsBuffer = new ComputeBuffer ( k_MaxVisibleVolumeCount , System . Runtime . InteropServices . Marshal . SizeOf ( typeof ( OrientedBBox ) ) ) ;
s_VisibleVolumeDataBuffer = new ComputeBuffer ( k_MaxVisibleVolumeCount , System . Runtime . InteropServices . Marshal . SizeOf ( typeof ( DensityVolumeData ) ) ) ;
m_VolumeVoxelizationCS = asset . renderPipelineResources . volumeVoxelizationCS ;
m_VolumetricLightingCS = asset . renderPipelineResources . volumetricLightingCS ;
CreateBuffers ( ) ;
public void Cleanup ( )
// RTHandleSystem API expects a function which computes the resolution. We define it here.
Vector2Int ComputeVBuffeResolutionXY ( Vector2Int screenSize )
if ( preset = = VolumetricLightingPreset . Off ) return ;
m_VolumeVoxelizationCS = null ;
m_VolumetricLightingCS = null ;
Vector3Int resolution = ComputeVBufferResolution ( preset , screenSize . x , screenSize . y ) ;
for ( int i = 0 , n = m_VBuffers . Count ; i < n ; i + + )
// Since the buffers owned by the VolumetricLightingSystem may have different lifetimes compared
// to those owned by the HDCamera, we need to make sure that the buffer resolution is the same
// (in order to share the UV scale and the UV limit).
if ( m_LightingBufferHandle ! = null )
m_VBuffers [ i ] . Destroy ( ) ;
resolution . x = Math . Max ( resolution . x , m_LightingBufferHandle . rt . width ) ;
resolution . y = Math . Max ( resolution . y , m_LightingBufferHandle . rt . height ) ;
m_VBuffers = null ;
m_VisibleVolumeBounds = null ;
m_VisibleVolumeData = null ;
CoreUtils . SafeRelease ( s_VisibleVolumeBoundsBuffer ) ;
CoreUtils . SafeRelease ( s_VisibleVolumeDataBuffer ) ;
return new Vector2Int ( resolution . x , resolution . y ) ;
public void ResizeVBufferAndUpdateProperties ( HDCamera camera , uint frameIndex )
// BufferedRTHandleSystem API expects an allocator function. We define it here.
RTHandleSystem . RTHandle HistoryBufferAllocatorFunction ( string viewName , int frameIndex , RTHandleSystem rtHandleSystem )
if ( preset = = VolumetricLightingPreset . Off ) return ;
var visualEnvironment = VolumeManager . instance . stack . GetComponent < VisualEnvironment > ( ) ;
if ( visualEnvironment = = null | | visualEnvironment . fogType ! = FogType . Volumetric ) return ;
frameIndex & = 1 ;
var controller = camera . camera . GetComponent < VolumetricLightingController > ( ) ;
int d = ComputeVBufferSliceCount ( preset ) ;
if ( camera . camera . cameraType = = CameraType . SceneView )
{
// HACK: since it's not possible to add a component to a scene camera,
// we take one from the "main" camera (if present).
Camera mainCamera = Camera . main ;
return rtHandleSystem . Alloc ( scaleFunc : ComputeVBuffeResolutionXY ,
slices : d ,
dimension : TextureDimension . Tex3D ,
colorFormat : RenderTextureFormat . ARGBHalf ,
sRGB : false ,
enableRandomWrite : true ,
enableMSAA : false ,
/* useDynamicScale: true, // <- TODO */
name : string . Format ( "{0}_VBufferHistory{1}" , viewName , frameIndex )
) ;
}
if ( mainCamera ! = null )
{
controller = mainCamera . GetComponent < VolumetricLightingController > ( ) ;
}
}
void CreateBuffers ( )
{
Debug . Assert ( m_VolumetricLightingCS ! = null ) ;
if ( controller = = null ) return ;
m_VisibleVolumeBounds = new List < OrientedBBox > ( ) ;
m_VisibleVolumeData = new List < DensityVolumeData > ( ) ;
s_VisibleVolumeBoundsBuffer = new ComputeBuffer ( k_MaxVisibleVolumeCount , Marshal . SizeOf ( typeof ( OrientedBBox ) ) ) ;
s_VisibleVolumeDataBuffer = new ComputeBuffer ( k_MaxVisibleVolumeCount , Marshal . SizeOf ( typeof ( DensityVolumeData ) ) ) ;
int screenWidth = ( int ) camera . screenSize . x ;
int screenHeight = ( int ) camera . screenSize . y ;
long viewID = camera . GetViewID ( ) ;
int d = ComputeVBufferSliceCount ( preset ) ;
Debug . Assert ( viewID > 0 ) ;
m_DensityBufferHandle = RTHandles . Alloc ( scaleFunc : ComputeVBuffeResolutionXY ,
slices : d ,
dimension : TextureDimension . Tex3D ,
colorFormat : RenderTextureFormat . ARGBHalf ,
sRGB : false ,
enableRandomWrite : true ,
enableMSAA : false ,
/* useDynamicScale: true, // <- TODO */
name : "VBufferDensity" ) ;
int w = 0 , h = 0 , d = 0 ;
ComputeVBufferResolutionAndScale ( preset , screenWidth , screenHeight , ref w , ref h , ref d ) ;
m_LightingBufferHandle = RTHandles . Alloc ( scaleFunc : ComputeVBuffeResolutionXY ,
slices : d ,
dimension : TextureDimension . Tex3D ,
colorFormat : RenderTextureFormat . ARGBHalf ,
sRGB : false ,
enableRandomWrite : true ,
enableMSAA : false ,
/* useDynamicScale: true, // <- TODO */
name : "VBufferIntegral" ) ;
}
VBuffer vBuffer = FindVBuffer ( viewID ) ;
// For the initial allocation, no suballocation happens (the texture is full size).
VBufferParameters ComputeVBufferParameters ( HDCamera camera , bool isInitialAllocation )
{
Vector3Int viewportResolution = ComputeVBufferResolution ( preset , camera . camera . pixelWidth , camera . camera . pixelHeight ) ;
Vector3Int bufferResolution ; // Could be higher due to sub-allocation (resource aliasing) in the RTHandle system
if ( vBuffer ! = null )
if ( isInitialAllocation )
VBuffer . Parameters frameParams = vBuffer . GetParameters ( frameIndex ) ;
// Found, check resolution.
if ( w = = frameParams . resolution . x & &
h = = frameParams . resolution . y & &
d = = frameParams . sliceCount . x )
{
// The resolution matches.
// Depth parameters may have changed, so update those.
frameParams . Update ( controller . parameters ) ;
vBuffer . SetParameters ( frameParams , frameIndex ) ;
return ;
}
bufferResolution = viewportResolution ;
// Not found - grow the array.
vBuffer = new VBuffer ( ) ;
m_VBuffers . Add ( vBuffer ) ;
// All V-Buffers of the current frame should have the same size (you have to double-buffer history, of course).
bufferResolution = new Vector3Int ( m_LightingBufferHandle . rt . width , m_LightingBufferHandle . rt . height , m_LightingBufferHandle . rt . volumeDepth ) ;
vBuffer . Create ( viewID , w , h , d , controller . parameters ) ;
var controller = VolumeManager . instance . stack . GetComponent < VolumetricLightingController > ( ) ;
// We must not allow the V-Buffer to extend outside of the camera's frustum.
float n = camera . camera . nearClipPlane ;
float f = camera . camera . farClipPlane ;
Vector2 vBufferDepthRange = controller . depthRange . value ;
vBufferDepthRange . y = Mathf . Clamp ( vBufferDepthRange . y , n , f ) ; // far
vBufferDepthRange . x = Mathf . Clamp ( vBufferDepthRange . x , n , vBufferDepthRange . y ) ; // near
float vBufferDepthDistributionUniformity = controller . depthDistributionUniformity . value ;
return new VBufferParameters ( viewportResolution , bufferResolution , vBufferDepthRange , vBufferDepthDistributionUniformity ) ;
VBuffer FindVBuffer ( long viewID )
public void InitializePerCameraData ( HDCamera camera )
Debug . Assert ( viewID > 0 ) ;
if ( preset = = VolumetricLightingPreset . Off ) return ;
VBuffer vBuffer = null ;
// Start with the same parameters for both frames. Then update them one by one every frame.
var parameters = ComputeVBufferParameters ( camera , true ) ;
camera . vBufferParams = new VBufferParameters [ 2 ] ;
camera . vBufferParams [ 0 ] = parameters ;
camera . vBufferParams [ 1 ] = parameters ;
if ( m_VBuffers ! = null )
if ( camera . camera . cameraType = = CameraType . Game | |
camera . camera . cameraType = = CameraType . SceneView )
int n = m_VBuffers . Count ;
for ( int i = 0 ; i < n ; i + + )
{
// Check whether domain reload killed it...
if ( viewID = = m_VBuffers [ i ] . GetViewID ( ) & & m_VBuffers [ i ] . IsValid ( ) )
{
vBuffer = m_VBuffers [ i ] ;
}
}
// We don't need reprojection for other view types, such as reflection and preview.
camera . AllocHistoryFrameRT ( ( int ) HDCameraFrameHistoryType . VolumetricLighting , HistoryBufferAllocatorFunction ) ;
}
return vBuffer ;
// This function relies on being called once per camera per frame.
// The results are undefined otherwise.
public void UpdatePerCameraData ( HDCamera camera )
{
if ( preset = = VolumetricLightingPreset . Off ) return ;
var parameters = ComputeVBufferParameters ( camera , false ) ;
// Double-buffer. I assume the cost of copying is negligible (don't want to use the frame index).
camera . vBufferParams [ 1 ] = camera . vBufferParams [ 0 ] ;
camera . vBufferParams [ 0 ] = parameters ;
// Note: resizing of history buffer is automatic (handled by the BufferedRTHandleSystem).
}
void DestroyBuffers ( )
{
RTHandles . Release ( m_DensityBufferHandle ) ;
RTHandles . Release ( m_LightingBufferHandle ) ;
CoreUtils . SafeRelease ( s_VisibleVolumeBoundsBuffer ) ;
CoreUtils . SafeRelease ( s_VisibleVolumeDataBuffer ) ;
m_VisibleVolumeBounds = null ;
m_VisibleVolumeData = null ;
}
public void Cleanup ( )
{
if ( preset = = VolumetricLightingPreset . Off ) return ;
DestroyBuffers ( ) ;
m_VolumeVoxelizationCS = null ;
m_VolumetricLightingCS = null ;
}
static int ComputeVBufferTileSize ( VolumetricLightingPreset preset )
}
}
// Since a single voxel corresponds to a tile (e.g. 8x8) of pixels,
// the VBuffer can potentially extend past the boundaries of the viewport.
// The function returns the fraction of the {width, height} of the VBuffer visible on screen.
// Note: for performance reasons, the scale is unused (implicitly 1). The error is typically under 1%.
static Vector2 ComputeVBufferResolutionAndScale ( VolumetricLightingPreset preset ,
int screenWidth , int screenHeight ,
ref int w , ref int h , ref int d )
static Vector3Int ComputeVBufferResolution ( VolumetricLightingPreset preset ,
int screenWidth , int screenHeight )
// Ceil(ScreenSize / TileSize).
w = ( screenWidth + t - 1 ) / t ;
h = ( screenHeight + t - 1 ) / t ;
d = ComputeVBufferSliceCount ( preset ) ;
// ceil(ScreenSize / TileSize).
int w = ( screenWidth + ( t - 1 ) ) / t ;
int h = ( screenHeight + ( t - 1 ) ) / t ;
int d = ComputeVBufferSliceCount ( preset ) ;
return new Vector2 ( ( float ) screenWidth / ( float ) ( w * t ) , ( float ) screenHeight / ( float ) ( h * t ) ) ;
return new Vector3Int ( w , h , d ) ;
}
// See EncodeLogarithmicDepthGeneralized().
return depthParams ;
}
void SetPreconvolvedAmbientLightProbe ( CommandBuffer cmd , float asymmetr y )
void SetPreconvolvedAmbientLightProbe ( CommandBuffer cmd , float anisotrop y )
ZonalHarmonicsL2 phaseZH = ZonalHarmonicsL2 . GetCornetteShanksPhaseFunction ( asymmetr y ) ;
ZonalHarmonicsL2 phaseZH = ZonalHarmonicsL2 . GetCornetteShanksPhaseFunction ( anisotrop y ) ;
float CornetteShanksPhasePartConstant ( float asymmetr y )
float CornetteShanksPhasePartConstant ( float anisotrop y )
float g = asymmetr y ;
float g = anisotrop y ;
return ( 1.0f / ( 4.0f * Mathf . PI ) ) * 1.5f * ( 1.0f - g * g ) / ( 2.0f + g * g ) ;
}
if ( preset = = VolumetricLightingPreset . Off ) return ;
var visualEnvironment = VolumeManager . instance . stack . GetComponent < VisualEnvironment > ( ) ;
if ( visualEnvironment . fogType ! = FogType . Volumetric ) return ;
// VisualEnvironment sets global fog parameters: _GlobalAsymmetry, _GlobalScattering, _GlobalExtinction.
// VisualEnvironment sets global fog parameters: _GlobalAnisotropy, _GlobalScattering, _GlobalExtinction.
VBuffer vBuffer = FindVBuffer ( camera . GetViewID ( ) ) ;
if ( vBuffer = = null )
if ( visualEnvironment . fogType ! = FogType . Volumetric )
{
// Set the neutral black texture.
cmd . SetGlobalTexture ( HDShaderIDs . _VBufferLighting , CoreUtils . blackVolumeTexture ) ;
// Get the interpolated asymmetry value.
// Get the interpolated anisotropy value.
SetPreconvolvedAmbientLightProbe ( cmd , fog . asymmetry ) ;
SetPreconvolvedAmbientLightProbe ( cmd , fog . anisotropy ) ;
var currFrameParams = vBuffer . GetParameters ( frameIndex ) ;
var prevFrameParams = vBuffer . GetParameters ( frameIndex - 1 ) ;
var currFrameParams = camera . vBufferParams [ 0 ] ;
var prevFrameParams = camera . vBufferParams [ 1 ] ;
cmd . SetGlobalVector ( HDShaderIDs . _VBufferUvScaleAndLimit , currFrameParams . uvScaleAndLimit ) ;
cmd . SetGlobalVector ( HDShaderIDs . _VBufferPrevUvScaleAndLimit , prevFrameParams . uvScaleAndLimit ) ;
cmd . SetGlobalTexture ( HDShaderIDs . _VBufferLighting , vBuffer . GetLightingIntegralBuffer ( ) ) ;
cmd . SetGlobalTexture ( HDShaderIDs . _VBufferLighting , m_LightingBufferHandle ) ;
}
public DensityVolumeList PrepareVisibleDensityVolumeList ( HDCamera camera , CommandBuffer cmd )
var visualEnvironment = VolumeManager . instance . stack . GetComponent < VisualEnvironment > ( ) ;
if ( visualEnvironment . fogType ! = FogType . Volumetric ) return densityVolumes ;
VBuffer vBuffer = FindVBuffer ( camera . GetViewID ( ) ) ;
if ( vBuffer = = null ) return densityVolumes ;
using ( new ProfilingSample ( cmd , "Prepare Visible Density Volume List" ) )
{
m_VisibleVolumeData . Clear ( ) ;
// Collect all visible finite volume data, and upload it to the GPU.
DensityVolume [ ] volumes = DensityVolumeManager . manager . PrepareDensityVolumeData ( cmd ) ;
DensityVolume [ ] volumes = DensityVolumeManager . manager . PrepareDensityVolumeData ( cmd ) ;
for ( int i = 0 ; i < Math . Min ( volumes . Length , k_MaxVisibleVolumeCount ) ; i + + )
{
obb . center - = camOffset ;
// Frustum cull on the CPU for now. TODO: do it on the GPU.
// TODO: account for custom near and far planes of the V-Buffer's frustum.
// It's typically much shorter (along the Z axis) than the camera's frustum.
if ( GeometryUtils . Overlap ( obb , camera . frustum , 6 , 8 ) )
{
// TODO: cache these?
var visualEnvironment = VolumeManager . instance . stack . GetComponent < VisualEnvironment > ( ) ;
if ( visualEnvironment . fogType ! = FogType . Volumetric ) return ;
VBuffer vBuffer = FindVBuffer ( camera . GetViewID ( ) ) ;
if ( vBuffer = = null ) return ;
using ( new ProfilingSample ( cmd , "Volume Voxelization" ) )
{
int kernel = m_VolumeVoxelizationCS . FindKernel ( enableClustered ? "VolumeVoxelizationClustered"
: "VolumeVoxelizationBruteforce" ) ;
var frameParams = vBuffer . GetParameters ( frameIndex ) ;
var frameParams = camera . vBufferParams [ 0 ] ;
Vector4 resolution = frameParams . resolution ;
float vFoV = camera . camera . fieldOfView * Mathf . Deg2Rad ;
volumeAtlasDimensions . y = 1.0f / volumeAtlas . width ;
}
cmd . SetComputeTextureParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VBufferDensity , vBuffer . GetDensityBuffer ( ) ) ;
cmd . SetComputeTextureParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VBufferDensity , m_DensityBufferHandle ) ;
cmd . SetComputeBufferParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VolumeBounds , s_VisibleVolumeBoundsBuffer ) ;
cmd . SetComputeBufferParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VolumeData , s_VisibleVolumeDataBuffer ) ;
cmd . SetComputeTextureParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VolumeMaskAtlas , volumeAtlas ) ;
var visualEnvironment = VolumeManager . instance . stack . GetComponent < VisualEnvironment > ( ) ;
if ( visualEnvironment . fogType ! = FogType . Volumetric ) return ;
VBuffer vBuffer = FindVBuffer ( camera . GetViewID ( ) ) ;
if ( vBuffer = = null ) return ;
using ( new ProfilingSample ( cmd , "Volumetric Lighting" ) )
{
: "VolumetricLightingBruteforce" ) ;
}
var frameParams = vBuffer . GetParameters ( frameIndex ) ;
var frameParams = camera . vBufferParams [ 0 ] ;
Vector4 resolution = frameParams . resolution ;
float vFoV = camera . camera . fieldOfView * Mathf . Deg2Rad ;
// Compose the matrix which allows us to compute the world space view direction.
// Currently, we assume that they are completely uncorrelated, but maybe we should correlate them somehow.
Vector4 offset = new Vector4 ( xySeq [ sampleIndex ] . x , xySeq [ sampleIndex ] . y , zSeq [ sampleIndex ] , frameIndex ) ;
// Get the interpolated asymmetr y value.
// Get the interpolated anisotrop y value.
var fog = VolumeManager . instance . stack . GetComponent < VolumetricFog > ( ) ;
// TODO: set 'm_VolumetricLightingPreset'.
cmd . SetComputeFloatParam ( m_VolumetricLightingCS , HDShaderIDs . _CornetteShanksConstant , CornetteShanksPhasePartConstant ( fog . asymmetry ) ) ;
cmd . SetComputeTextureParam ( m_VolumetricLightingCS , kernel , HDShaderIDs . _VBufferDensity , vBuffer . GetDensityBuffer ( ) ) ; // Read
cmd . SetComputeTextureParam ( m_VolumetricLightingCS , kernel , HDShaderIDs . _VBufferLightingIntegral , vBuffer . GetLightingIntegralBuffer ( ) ) ; // Write
cmd . SetComputeFloatParam ( m_VolumetricLightingCS , HDShaderIDs . _CornetteShanksConstant , CornetteShanksPhasePartConstant ( fog . anisotropy ) ) ;
cmd . SetComputeTextureParam ( m_VolumetricLightingCS , kernel , HDShaderIDs . _VBufferDensity , m_DensityBufferHandle ) ; // Read
cmd . SetComputeTextureParam ( m_VolumetricLightingCS , kernel , HDShaderIDs . _VBufferLightingIntegral , m_LightingBufferHandle ) ; // Write
cmd . SetComputeTextureParam ( m_VolumetricLightingCS , kernel , HDShaderIDs . _VBufferLightingFeedback , vBuffer . GetLightingFeedbackBuffer ( frameIndex ) ) ; // Write
cmd . SetComputeTextureParam ( m_VolumetricLightingCS , kernel , HDShaderIDs . _VBufferLightingHistory , vBuffer . GetLightingHistoryBuffer ( frameIndex ) ) ; // Read
cmd . SetComputeTextureParam ( m_VolumetricLightingCS , kernel , HDShaderIDs . _VBufferLightingHistory , camera . GetPreviousFrameRT ( ( int ) HDCameraFrameHistoryType . VolumetricLighting ) ) ; // Read
cmd . SetComputeTextureParam ( m_VolumetricLightingCS , kernel , HDShaderIDs . _VBufferLightingFeedback , camera . GetCurrentFrameRT ( ( int ) HDCameraFrameHistoryType . VolumetricLighting ) ) ; // Write
}
int w = ( int ) resolution . x ;