if ( preset = = VolumetricLightingPreset . Off ) return densityVolumes ;
Vector3 camPosition = camera . camera . transform . position ;
Vector3 camOffset = Vector3 . zero ; // World-origin-relative
if ( ShaderConfig . s_CameraRelativeRendering ! = 0 )
using ( new ProfilingSample ( cmd , "Prepare Visible Density Volume List" ) )
camOffset = camPosition ; // Camera-relative
}
Vector3 camPosition = camera . camera . transform . position ;
Vector3 camOffset = Vector3 . zero ; // World-origin-relative
m_VisibleVolumeBounds . Clear ( ) ;
m_VisibleVolumeProperties . Clear ( ) ;
if ( ShaderConfig . s_CameraRelativeRendering ! = 0 )
{
camOffset = camPosition ; // Camera-relative
}
// Collect all visible finite volume data, and upload it to the GPU.
HomogeneousDensityVolume [ ] volumes = Object . FindObjectsOfType ( typeof ( HomogeneousDensityVolume ) ) as HomogeneousDensityVolume [ ] ;
m_VisibleVolumeBounds . Clear ( ) ;
m_VisibleVolumeProperties . Clear ( ) ;
for ( int i = 0 ; i < Math . Min ( volumes . Length , k_MaxVisibleVolumeCount ) ; i + + )
{
HomogeneousDensityVolume volume = volumes [ i ] ;
// Collect all visible finite volume data, and upload it to the GPU.
HomogeneousDensityVolume [ ] volumes = Object . FindObjectsOfType ( typeof ( HomogeneousDensityVolume ) ) as HomogeneousDensityVolume [ ] ;
// Only test active finite volumes.
if ( volume . enabled & & volume . parameters . IsLocalVolume ( ) )
for ( int i = 0 ; i < Math . Min ( volumes . Length , k_MaxVisibleVolumeCount ) ; i + + )
// TODO: cache these?
var obb = OrientedBBox . Create ( volume . transform ) ;
HomogeneousDensityVolume volume = volumes [ i ] ;
// Handle camera-relative rendering.
obb . center - = camOffset ;
// Frustum cull on the CPU for now. TODO: do it on the GPU.
if ( GeometryUtils . Overlap ( obb , camera . frustum , 6 , 8 ) )
// Only test active finite volumes.
if ( volume . enabled & & volume . parameters . IsLocalVolume ( ) )
var properties = volume . parameters . GetProperties ( ) ;
var obb = OrientedBBox . Create ( volume . transform ) ;
// Handle camera-relative rendering.
obb . center - = camOffset ;
m_VisibleVolumeBounds . Add ( obb ) ;
m_VisibleVolumeProperties . Add ( properties ) ;
// Frustum cull on the CPU for now. TODO: do it on the GPU.
if ( GeometryUtils . Overlap ( obb , camera . frustum , 6 , 8 ) )
{
// TODO: cache these?
var properties = volume . parameters . GetProperties ( ) ;
m_VisibleVolumeBounds . Add ( obb ) ;
m_VisibleVolumeProperties . Add ( properties ) ;
}
}
s_VisibleVolumeBoundsBuffer . SetData ( m_VisibleVolumeBounds ) ;
s_VisibleVolumePropertiesBuffer . SetData ( m_VisibleVolumeProperties ) ;
s_VisibleVolumeBoundsBuffer . SetData ( m_VisibleVolumeBounds ) ;
s_VisibleVolumePropertiesBuffer . SetData ( m_VisibleVolumeProperties ) ;
// Fill the struct with pointers in order to share the data with the light loop.
densityVolumes . bounds = m_VisibleVolumeBounds ;
densityVolumes . properties = m_VisibleVolumeProperties ;
// Fill the struct with pointers in order to share the data with the light loop.
densityVolumes . bounds = m_VisibleVolumeBounds ;
densityVolumes . properties = m_VisibleVolumeProperties ;
return densityVolumes ;
return densityVolumes ;
}
}
public void VolumeVoxelizationPass ( DensityVolumeList densityVolumes , HDCamera camera , CommandBuffer cmd , FrameSettings settings )
int numVisibleVolumes = m_VisibleVolumeBounds . Count ;
using ( new ProfilingSample ( cmd , "Volume Voxelization" ) )
{
int numVisibleVolumes = m_VisibleVolumeBounds . Count ;
if ( numVisibleVolumes = = 0 )
{
// Clear the render target instead of running the shader.
// CoreUtils.SetRenderTarget(cmd, vBuffer.GetDensityBuffer(), ClearFlag.Color, CoreUtils.clearColorAllBlack);
// return;
if ( numVisibleVolumes = = 0 )
{
// Clear the render target instead of running the shader.
// CoreUtils.SetRenderTarget(cmd, vBuffer.GetDensityBuffer(), ClearFlag.Color, CoreUtils.clearColorAllBlack);
// return;
// Clearing 3D textures does not seem to work!
// Use the workaround by running the full shader with 0 density.
}
// Clearing 3D textures does not seem to work!
// Use the workaround by running the full shader with 0 density.
}
VBuffer vBuffer = FindVBuffer ( camera . GetViewID ( ) ) ;
Debug . Assert ( vBuffer ! = null ) ;
VBuffer vBuffer = FindVBuffer ( camera . GetViewID ( ) ) ;
Debug . Assert ( vBuffer ! = null ) ;
int w = 0 , h = 0 , d = 0 ;
vBuffer . GetResolution ( ref w , ref h , ref d ) ;
int w = 0 , h = 0 , d = 0 ;
vBuffer . GetResolution ( ref w , ref h , ref d ) ;
bool enableClustered = settings . lightLoopSettings . enableTileAndCluster ;
bool enableClustered = settings . lightLoopSettings . enableTileAndCluster ;
int kernel = m_VolumeVoxelizationCS . FindKernel ( enableClustered ? "VolumeVoxelizationClustered"
: "VolumeVoxelizationBruteforce" ) ;
int kernel = m_VolumeVoxelizationCS . FindKernel ( enableClustered ? "VolumeVoxelizationClustered"
: "VolumeVoxelizationBruteforce" ) ;
float vFoV = camera . camera . fieldOfView * Mathf . Deg2Rad ;
Vector4 resolution = new Vector4 ( w , h , 1.0f / w , 1.0f / h ) ;
Matrix4x4 transform = HDUtils . ComputePixelCoordToWorldSpaceViewDirectionMatrix ( vFoV , resolution , camera . viewMatrix , false ) ;
camera . SetupComputeShader ( m_VolumeVoxelizationCS , cmd ) ;
cmd . SetComputeBufferParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VolumeBounds , s_VisibleVolumeBoundsBuffer ) ;
cmd . SetComputeBufferParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VolumeProperties , s_VisibleVolumePropertiesBuffer ) ;
cmd . SetComputeTextureParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VBufferDensity , vBuffer . GetDensityBuffer ( ) ) ;
camera . SetupComputeShader ( m_VolumeVoxelizationCS , cmd ) ;
cmd . SetComputeTextureParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VBufferDensity , vBuffer . GetDensityBuffer ( ) ) ;
cmd . SetComputeBufferParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VolumeBounds , s_VisibleVolumeBoundsBuffer ) ;
cmd . SetComputeBufferParam ( m_VolumeVoxelizationCS , kernel , HDShaderIDs . _VolumeProperties , s_VisibleVolumePropertiesBuffer ) ;
// TODO: set the constant buffer data only once.
cmd . SetComputeMatrixParam ( m_VolumeVoxelizationCS , HDShaderIDs . _VBufferCoordToViewDirWS , transform ) ;
cmd . SetComputeIntParam ( m_VolumeVoxelizationCS , HDShaderIDs . _NumVisibleDensityVolumes , numVisibleVolumes ) ;
// The shader defines GROUP_SIZE_1D = 8.
cmd . DispatchCompute ( m_VolumeVoxelizationCS , kernel , ( w + 7 ) / 8 , ( h + 7 ) / 8 , 1 ) ;
// The shader defines GROUP_SIZE_1D = 8.
cmd . DispatchCompute ( m_VolumeVoxelizationCS , kernel , ( w + 7 ) / 8 , ( h + 7 ) / 8 , 1 ) ;
}
}
// Ref: https://en.wikipedia.org/wiki/Close-packing_of_equal_spheres
Vector4 offset = new Vector4 ( xySeq [ sampleIndex ] . x , xySeq [ sampleIndex ] . y , zSeq [ sampleIndex ] , rfc ) ;
// TODO: set 'm_VolumetricLightingPreset'.
// TODO: set the constant buffer data only once.
cmd . SetComputeMatrixParam ( m_VolumetricLightingCS , HDShaderIDs . _VBufferCoordToViewDirWS , transform ) ;
cmd . SetComputeVectorParam ( m_VolumetricLightingCS , HDShaderIDs . _VBufferSampleOffset , offset ) ;
cmd . SetComputeVectorParam ( m_VolumetricLightingCS , HDShaderIDs . _VBufferSampleOffset , offset ) ;
cmd . SetComputeMatrixParam ( m_VolumetricLightingCS , HDShaderIDs . _VBufferCoordToViewDirWS , transform ) ;
cmd . SetComputeTextureParam ( m_VolumetricLightingCS , kernel , HDShaderIDs . _VBufferLightingIntegral , vBuffer . GetLightingIntegralBuffer ( ) ) ; // Write
if ( enableReprojection )
{