Shadow atlas preparations

This commit is contained in:
Robert Beckebans 2022-03-30 11:22:58 +02:00
parent 361c0292ec
commit 52545c8230
8 changed files with 180 additions and 24 deletions

View file

@ -39,6 +39,7 @@ static const int MAX_HIERARCHICAL_ZBUFFERS = 6; // native resolution + 5 MIP LEV
static const int ENVPROBE_CAPTURE_SIZE = 256;
static const int RADIANCE_OCTAHEDRON_SIZE = 512;
static const int IRRADIANCE_OCTAHEDRON_SIZE = 30 + 2;
static const int SHADOW_ATLAS_SIZE = 8192;
#if 1
static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 2048, 1024, 512, 512, 256 };
@ -139,6 +140,7 @@ private:
struct globalFramebuffers_t
{
idList<Framebuffer*> swapFramebuffers;
Framebuffer* shadowAtlasFBO;
Framebuffer* shadowFBO[MAX_SHADOWMAP_RESOLUTIONS][6];
Framebuffer* hdrFBO;
Framebuffer* ldrFBO;

View file

@ -666,6 +666,7 @@ public:
idImage* fogImage; // increasing alpha is denser fog
idImage* fogEnterImage; // adjust fogImage alpha based on terminator plane
// RB begin
idImage* shadowAtlasImage; // 8192 * 8192 for clustered forward shading
idImage* shadowImage[5];
idImage* jitterImage1; // shadow jitter
idImage* jitterImage4;

View file

@ -623,6 +623,11 @@ void R_QuadraticImage( idImage* image, nvrhi::ICommandList* commandList )
}
// RB begin
static void R_CreateShadowMapImage_Atlas( idImage* image, nvrhi::ICommandList* commandList )
{
image->GenerateShadowArray( SHADOW_ATLAS_SIZE, SHADOW_ATLAS_SIZE, TF_LINEAR, TR_CLAMP_TO_ZERO_ALPHA, TD_DEPTH, commandList );
}
static void R_CreateShadowMapImage_Res0( idImage* image, nvrhi::ICommandList* commandList )
{
int size = shadowMapResolutions[0];
@ -1005,6 +1010,7 @@ void idImageManager::CreateIntrinsicImages()
ImageFromFunction( "_quadratic", R_QuadraticImage );
// RB begin
shadowAtlasImage = ImageFromFunction( "_shadowMapAtlas", R_CreateShadowMapImage_Atlas );
shadowImage[0] = ImageFromFunction( va( "_shadowMapArray0_%i", shadowMapResolutions[0] ), R_CreateShadowMapImage_Res0 );
shadowImage[1] = ImageFromFunction( va( "_shadowMapArray1_%i", shadowMapResolutions[1] ), R_CreateShadowMapImage_Res1 );
shadowImage[2] = ImageFromFunction( va( "_shadowMapArray2_%i", shadowMapResolutions[2] ), R_CreateShadowMapImage_Res2 );

View file

@ -120,6 +120,7 @@ void Framebuffer::ResizeFramebuffers()
globalImages->currentNormalsImage->Reload( false, tr.backend.commandList );
globalImages->smaaEdgesImage->Reload( false, tr.backend.commandList );
globalImages->smaaBlendImage->Reload( false, tr.backend.commandList );
globalImages->shadowAtlasImage->Reload( false, tr.backend.commandList );
for( int i = 0; i < MAX_SHADOWMAP_RESOLUTIONS; i++ )
{
globalImages->shadowImage[i]->Reload( false, tr.backend.commandList );
@ -151,6 +152,10 @@ void Framebuffer::ResizeFramebuffers()
}
}
globalFramebuffers.shadowAtlasFBO = new Framebuffer( "_shadowAtlas",
nvrhi::FramebufferDesc()
.setDepthAttachment( globalImages->shadowAtlasImage->texture ) );
globalFramebuffers.ldrFBO = new Framebuffer( "_ldr",
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->currentRenderLDR->texture )

View file

@ -3300,7 +3300,7 @@ void idRenderBackend::ShadowMapPassPerforated( const drawSurf_t** drawSurfs, int
idRenderBackend::ShadowMapPassFast
=====================
*/
void idRenderBackend::ShadowMapPassFast( const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side )
void idRenderBackend::ShadowMapPassFast( const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side, bool atlas )
{
if( r_skipShadows.GetBool() )
{
@ -3354,23 +3354,35 @@ void idRenderBackend::ShadowMapPassFast( const drawSurf_t* drawSurfs, const view
SetupShadowMapMatrices( vLight, side, lightProjectionRenderMatrix, lightViewRenderMatrix );
#if defined( USE_NVRHI )
if( side < 0 )
if( atlas )
{
globalFramebuffers.shadowFBO[vLight->shadowLOD][0]->Bind();
//globalFramebuffers.shadowAtlasFBO->Bind();
// TODO light offset in atlas
//GL_ViewportAndScissor( 0, 0, shadowMapResolutions[vLight->shadowLOD], shadowMapResolutions[vLight->shadowLOD] );
}
else
{
globalFramebuffers.shadowFBO[vLight->shadowLOD][side]->Bind();
}
if( side < 0 )
{
globalFramebuffers.shadowFBO[vLight->shadowLOD][0]->Bind();
}
else
{
globalFramebuffers.shadowFBO[vLight->shadowLOD][side]->Bind();
}
GL_ViewportAndScissor( 0, 0, shadowMapResolutions[vLight->shadowLOD], shadowMapResolutions[vLight->shadowLOD] );
GL_ViewportAndScissor( 0, 0, shadowMapResolutions[vLight->shadowLOD], shadowMapResolutions[vLight->shadowLOD] );
const nvrhi::FramebufferAttachment& att = currentFrameBuffer->GetApiObject()->getDesc().depthAttachment;
if( att.texture )
{
int slice = std::max( 0, side );
commandList->clearDepthStencilTexture( att.texture, nvrhi::TextureSubresourceSet().setArraySlices( slice, 1 ), true, 1.f, false, 0x80 );
const nvrhi::FramebufferAttachment& att = currentFrameBuffer->GetApiObject()->getDesc().depthAttachment;
if( att.texture )
{
int slice = std::max( 0, side );
commandList->clearDepthStencilTexture( att.texture, nvrhi::TextureSubresourceSet().setArraySlices( slice, 1 ), true, 1.f, false, 0x80 );
}
}
#elif !defined( USE_VULKAN )
@ -3802,6 +3814,129 @@ void idRenderBackend::ShadowMapPassOld( const drawSurf_t* drawSurfs, const viewL
renderLog.CloseBlock();
}
void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
{
if( r_skipShadows.GetBool() || viewDef->viewLights == NULL )
{
return;
}
renderLog.OpenMainBlock( MRB_SHADOW_ATLAS_PASS );
renderLog.OpenBlock( "Render_ShadowAtlas", colorYellow );
GL_SelectTexture( 0 );
const bool useLightDepthBounds = r_useLightDepthBounds.GetBool() && !r_useShadowMapping.GetBool();
Framebuffer* previousFramebuffer = Framebuffer::GetActiveFramebuffer();
globalFramebuffers.shadowAtlasFBO->Bind();
GL_ViewportAndScissor( 0, 0, SHADOW_ATLAS_SIZE, SHADOW_ATLAS_SIZE );
const nvrhi::FramebufferAttachment& att = currentFrameBuffer->GetApiObject()->getDesc().depthAttachment;
if( att.texture )
{
commandList->clearDepthStencilTexture( att.texture, nvrhi::AllSubresources, true, 1.0f, false, 0x80 );
}
//
// for each light, perform shadowing to a big atlas Framebuffer
//
for( const viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next )
{
if( vLight->lightShader->IsFogLight() )
{
continue;
}
if( vLight->lightShader->IsBlendLight() )
{
continue;
}
if( vLight->localInteractions == NULL && vLight->globalInteractions == NULL && vLight->translucentInteractions == NULL )
{
continue;
}
const idMaterial* lightShader = vLight->lightShader;
renderLog.OpenBlock( lightShader->GetName(), colorMdGrey );
// set the depth bounds for the whole light
if( useLightDepthBounds )
{
GL_DepthBoundsTest( vLight->scissorRect.zmin, vLight->scissorRect.zmax );
}
// RB: shadow mapping
//if( r_useShadowMapping.GetBool() )
int side, sideStop;
if( vLight->parallel )
{
side = 0;
sideStop = r_shadowMapSplits.GetInteger() + 1;
}
else if( vLight->pointLight )
{
if( r_shadowMapSingleSide.GetInteger() != -1 )
{
side = r_shadowMapSingleSide.GetInteger();
sideStop = side + 1;
}
else
{
side = 0;
sideStop = 6;
}
}
else
{
side = -1;
sideStop = 0;
}
for( ; side < sideStop ; side++ )
{
ShadowMapPassFast( vLight->globalShadows, vLight, side, true );
}
renderLog.CloseBlock();
}
// go back to main render target
if( previousFramebuffer != NULL )
{
previousFramebuffer->Bind();
}
else
{
Framebuffer::Unbind();
}
renderProgManager.Unbind();
GL_State( GLS_DEFAULT );
SetFragmentParm( RENDERPARM_ALPHA_TEST, vec4_zero.ToFloatPtr() );
// go back from light view to default camera view
ResetViewportAndScissorToDefaultCamera( _viewDef );
// unbind texture units
GL_SelectTexture( 0 );
// reset depth bounds
if( useLightDepthBounds )
{
GL_DepthBoundsTest( 0.0f, 0.0f );
}
renderLog.CloseBlock();
renderLog.CloseMainBlock();
}
/*
==============================================================================================
@ -3890,7 +4025,7 @@ void idRenderBackend::DrawInteractions( const viewDef_t* _viewDef )
for( ; side < sideStop ; side++ )
{
ShadowMapPassFast( vLight->globalShadows, vLight, side );
ShadowMapPassFast( vLight->globalShadows, vLight, side, false );
}
// go back to main render target
@ -6161,7 +6296,10 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
//-------------------------------------------------
AmbientPass( drawSurfs, numDrawSurfs, false );
//GL_EndRenderPass();
//-------------------------------------------------
// render all light <-> geometry interactions to a depth buffer atlas
//-------------------------------------------------
ShadowAtlasPass( _viewDef );
//-------------------------------------------------
// main light renderer

View file

@ -331,10 +331,12 @@ private:
void AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs, bool fillGbuffer );
void SetupShadowMapMatrices( const viewLight_t* vLight, int side, idRenderMatrix& lightProjectionRenderMatrix, idRenderMatrix& lightViewRenderMatrix );
void ShadowMapPassFast( const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side );
void ShadowMapPassFast( const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side, bool atlas );
void ShadowMapPassPerforated( const drawSurf_t** drawSurfs, int numDrawSurfs, const viewLight_t* vLight, int side, const idRenderMatrix& lightProjectionRenderMatrix, const idRenderMatrix& lightViewRenderMatrix );
void ShadowMapPassOld( const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side );
void ShadowAtlasPass( const viewDef_t* _viewDef );
void StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t* vLight );
void StencilSelectLight( const viewLight_t* vLight );

View file

@ -55,16 +55,17 @@ const char* renderLogMainBlockLabels[] =
ASSERT_ENUM_STRING( MRB_FILL_GEOMETRY_BUFFER, 3 ), // RB
ASSERT_ENUM_STRING( MRB_SSAO_PASS, 4 ), // RB
ASSERT_ENUM_STRING( MRB_AMBIENT_PASS, 5 ), // RB
ASSERT_ENUM_STRING( MRB_DRAW_INTERACTIONS, 6 ),
ASSERT_ENUM_STRING( MRB_DRAW_SHADER_PASSES, 7 ),
ASSERT_ENUM_STRING( MRB_FOG_ALL_LIGHTS, 8 ),
ASSERT_ENUM_STRING( MRB_BLOOM, 9 ),
ASSERT_ENUM_STRING( MRB_DRAW_SHADER_PASSES_POST, 10 ),
ASSERT_ENUM_STRING( MRB_DRAW_DEBUG_TOOLS, 11 ),
ASSERT_ENUM_STRING( MRB_CAPTURE_COLORBUFFER, 12 ),
ASSERT_ENUM_STRING( MRB_POSTPROCESS, 13 ),
ASSERT_ENUM_STRING( MRB_DRAW_GUI, 14 ),
ASSERT_ENUM_STRING( MRB_TOTAL, 15 )
ASSERT_ENUM_STRING( MRB_SHADOW_ATLAS_PASS, 6 ), // RB
ASSERT_ENUM_STRING( MRB_DRAW_INTERACTIONS, 7 ),
ASSERT_ENUM_STRING( MRB_DRAW_SHADER_PASSES, 8 ),
ASSERT_ENUM_STRING( MRB_FOG_ALL_LIGHTS, 9 ),
ASSERT_ENUM_STRING( MRB_BLOOM, 10 ),
ASSERT_ENUM_STRING( MRB_DRAW_SHADER_PASSES_POST, 11 ),
ASSERT_ENUM_STRING( MRB_DRAW_DEBUG_TOOLS, 12 ),
ASSERT_ENUM_STRING( MRB_CAPTURE_COLORBUFFER, 13 ),
ASSERT_ENUM_STRING( MRB_POSTPROCESS, 14 ),
ASSERT_ENUM_STRING( MRB_DRAW_GUI, 15 ),
ASSERT_ENUM_STRING( MRB_TOTAL, 16 )
};
#if defined( USE_VULKAN )

View file

@ -45,6 +45,7 @@ enum renderLogMainBlock_t
MRB_FILL_GEOMETRY_BUFFER,
MRB_SSAO_PASS,
MRB_AMBIENT_PASS,
MRB_SHADOW_ATLAS_PASS,
MRB_DRAW_INTERACTIONS,
MRB_DRAW_SHADER_PASSES,
MRB_FOG_ALL_LIGHTS,