Game/src/main.cpp
// Compute the view frustums for the light clipping grid.

Compute the view frustums for the light clipping grid.
Compute the view frustums for the light clipping grid .
void ComputeGridFrustums()
{
    auto commandQueue = g_RenderDevice->GetComputeQueue();
    auto commandBuffer = commandQueue->GetComputeCommandBuffer();
    uint32_t screenWidth = std::max( g_WindowWidth, 1u );
    uint32_t screenHeight = std::max( g_WindowHeight, 1u );
    glm::uvec3 numThreads = glm::ceil( glm::vec3( screenWidth / (float)g_LightGridBlockSize, screenHeight / (float)g_LightGridBlockSize, 1 ) );
    glm::uvec3 numThreadGroups = glm::ceil( glm::vec3( numThreads.x / (float)g_LightGridBlockSize, numThreads.y / (float)g_LightGridBlockSize, 1 ) );
    TextureFormat lightGridTextureFormat( TextureComponents::RG,
                                          TextureType::UnsignedInteger,
                                          1,
                                          32, 32, 0, 0, 0, 0 );
    for ( uint32_t i = 0; i < 2; ++i )
    {
        g_PointLightIndexList[i] = g_RenderDevice->CreateStructuredBuffer( commandBuffer, numThreads.x * numThreads.y * numThreads.z * AVERAGE_OVERLAPPING_LIGHTS_PER_TILE, sizeof( uint32_t ) );
        g_PointLightIndexList[i]->SetName( std::wstring( L"Point Light Index List " ) + ( ( i == 0 ) ? L"(Opaque)" : L"(Transparent)" ) );
        g_SpotLightIndexList[i] = g_RenderDevice->CreateStructuredBuffer( commandBuffer, numThreads.x * numThreads.y * numThreads.z * AVERAGE_OVERLAPPING_LIGHTS_PER_TILE, sizeof( uint32_t ) );
        g_SpotLightIndexList[i]->SetName( std::wstring( L"Spot Light Index List " ) + ( ( i == 0 ) ? L"(Opaque)" : L"(Transparent)" ) );
        g_PointLightGrid[i] = g_RenderDevice->CreateTexture2D( numThreads.x, numThreads.y, numThreads.z, lightGridTextureFormat );
        g_PointLightGrid[i]->SetName( std::wstring( L"Point Light Grid " ) + ( ( i == 0 ) ? L"(Opaque)" : L"(Transparent)" ) );
        g_SpotLightGrid[i] = g_RenderDevice->CreateTexture2D( numThreads.x, numThreads.y, numThreads.z, lightGridTextureFormat );
        g_SpotLightGrid[i]->SetName( std::wstring( L"Spot Light Grid " ) + ( ( i == 0 ) ? L"(Opaque)" : L"(Transparent)" ) );
    }
    CameraParamsCB cameraParams;
    cameraParams.Projection = g_Camera->GetProjectionMatrix();
    cameraParams.InverseProjection = glm::inverse( cameraParams.Projection );
    cameraParams.ScreenDimensions = glm::vec2( screenWidth, screenHeight );
    DispatchParamsCB dispatchParams;
    dispatchParams.NumThreadGroups = numThreadGroups;
    dispatchParams.NumThreads = numThreads;
    g_GridFrustums = g_RenderDevice->CreateStructuredBuffer( commandBuffer, numThreads.x * numThreads.y * numThreads.z, sizeof( Frustum ) );
    g_GridFrustums->SetName( L"Grid Frustums" );
    commandBuffer->BindComputePipelineState( g_ComputeGridFrustumsPSO );
    commandBuffer->BindComputeDynamicConstantBuffer( 0, cameraParams );
    commandBuffer->BindCompute32BitConstants( 1, dispatchParams );
    commandBuffer->BindComputeShaderArgument( 2, g_GridFrustums );
    commandBuffer->Dispatch( numThreadGroups );
    commandQueue->Submit( commandBuffer );
}
void ComputeGridFrustums ( ) { auto commandQueue = g_RenderDevice -> GetComputeQueue ( ) ; auto commandBuffer = commandQueue -> GetComputeCommandBuffer ( ) ; uint32_t screenWidth = std :: max ( g_WindowWidth , 1u ) ; uint32_t screenHeight = std :: max ( g_WindowHeight , 1u ) ; glm :: uvec3 numThreads = glm :: ceil ( glm :: vec3 ( screenWidth / ( float ) g_LightGridBlockSize , screenHeight / ( float ) g_LightGridBlockSize , 1 ) ) ; glm :: uvec3 numThreadGroups = glm :: ceil ( glm :: vec3 ( numThreads . x / ( float ) g_LightGridBlockSize , numThreads . y / ( float ) g_LightGridBlockSize , 1 ) ) ; TextureFormat lightGridTextureFormat ( TextureComponents :: RG , TextureType :: UnsignedInteger , 1 , 32 , 32 , 0 , 0 , 0 , 0 ) ; for ( uint32_t i = 0 ; i < 2 ; ++ i ) { g_PointLightIndexList [ i ] = g_RenderDevice -> CreateStructuredBuffer ( commandBuffer , numThreads . x * numThreads . y * numThreads . z * AVERAGE_OVERLAPPING_LIGHTS_PER_TILE , sizeof ( uint32_t ) ) ; g_PointLightIndexList [ i ] -> SetName ( std :: wstring ( L" " ) + ( ( i == 0 ) ? L" " : L" " ) ) ; g_SpotLightIndexList [ i ] = g_RenderDevice -> CreateStructuredBuffer ( commandBuffer , numThreads . x * numThreads . y * numThreads . z * AVERAGE_OVERLAPPING_LIGHTS_PER_TILE , sizeof ( uint32_t ) ) ; g_SpotLightIndexList [ i ] -> SetName ( std :: wstring ( L" " ) + ( ( i == 0 ) ? L" " : L" " ) ) ; g_PointLightGrid [ i ] = g_RenderDevice -> CreateTexture2D ( numThreads . x , numThreads . y , numThreads . z , lightGridTextureFormat ) ; g_PointLightGrid [ i ] -> SetName ( std :: wstring ( L" " ) + ( ( i == 0 ) ? L" " : L" " ) ) ; g_SpotLightGrid [ i ] = g_RenderDevice -> CreateTexture2D ( numThreads . x , numThreads . y , numThreads . z , lightGridTextureFormat ) ; g_SpotLightGrid [ i ] -> SetName ( std :: wstring ( L" " ) + ( ( i == 0 ) ? L" " : L" " ) ) ; } CameraParamsCB cameraParams ; cameraParams . Projection = g_Camera -> GetProjectionMatrix ( ) ; cameraParams . InverseProjection = glm :: inverse ( cameraParams . Projection ) ; cameraParams . ScreenDimensions = glm :: vec2 ( screenWidth , screenHeight ) ; DispatchParamsCB dispatchParams ; dispatchParams . NumThreadGroups = numThreadGroups ; dispatchParams . NumThreads = numThreads ; g_GridFrustums = g_RenderDevice -> CreateStructuredBuffer ( commandBuffer , numThreads . x * numThreads . y * numThreads . z , sizeof ( Frustum ) ) ; g_GridFrustums -> SetName ( L" " ) ; commandBuffer -> BindComputePipelineState ( g_ComputeGridFrustumsPSO ) ; commandBuffer -> BindComputeDynamicConstantBuffer ( 0 , cameraParams ) ; commandBuffer -> BindCompute32BitConstants ( 1 , dispatchParams ) ; commandBuffer -> BindComputeShaderArgument ( 2 , g_GridFrustums ) ; commandBuffer -> Dispatch ( numThreadGroups ) ; commandQueue -> Submit ( commandBuffer ) ; }
Compute the view frustums for the light clipping grid.
Compute the view frustums for the light clipping grid .
// Make sure we can create at least 1 thread (even if the window is minimized)
 // To compute the frustums for the grid tiles, each thread will compute a single 
 // frustum for the tile.
 // Create a light index list and light grid that matches the number of tiles 
 // for the Forward+ light culling compute shader.
 // 2 resources are created for each light type. 1 for the opaque pass, 1 for the 
 // transparent pass.
 // Update the number of thread groups for the compute frustums compute shader.
 // Create a new RWStructuredBuffer for storing the grid frustums.
 // We need 1 frustum for each grid cell.
 // For 1280x720 screen resolution and 16x16 tile size, results in 80x45 grid 
 // for a total of 3,600 frustums.
