mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-15 07:00:58 +00:00
Sort and render shadows into shadowmap atlas
This commit is contained in:
parent
52545c8230
commit
63fe4a167a
4 changed files with 101 additions and 20 deletions
|
@ -41,11 +41,9 @@ 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 };
|
||||
#else
|
||||
static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 1024, 1024, 1024, 1024, 1024 };
|
||||
#endif
|
||||
//static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 2048, 1024, 512, 512, 256 };
|
||||
static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 1024, 512, 512, 256, 128 };
|
||||
//static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 1024, 1024, 1024, 1024, 1024 };
|
||||
|
||||
|
||||
class Framebuffer
|
||||
|
|
|
@ -153,8 +153,8 @@ void Framebuffer::ResizeFramebuffers()
|
|||
}
|
||||
|
||||
globalFramebuffers.shadowAtlasFBO = new Framebuffer( "_shadowAtlas",
|
||||
nvrhi::FramebufferDesc()
|
||||
.setDepthAttachment( globalImages->shadowAtlasImage->texture ) );
|
||||
nvrhi::FramebufferDesc()
|
||||
.setDepthAttachment( globalImages->shadowAtlasImage->texture ) );
|
||||
|
||||
globalFramebuffers.ldrFBO = new Framebuffer( "_ldr",
|
||||
nvrhi::FramebufferDesc()
|
||||
|
|
|
@ -3355,32 +3355,25 @@ void idRenderBackend::ShadowMapPassFast( const drawSurf_t* drawSurfs, const view
|
|||
|
||||
#if defined( USE_NVRHI )
|
||||
|
||||
int slice = Max( 0, side );
|
||||
|
||||
if( atlas )
|
||||
{
|
||||
//globalFramebuffers.shadowAtlasFBO->Bind();
|
||||
|
||||
// TODO light offset in atlas
|
||||
|
||||
//GL_ViewportAndScissor( 0, 0, shadowMapResolutions[vLight->shadowLOD], shadowMapResolutions[vLight->shadowLOD] );
|
||||
GL_ViewportAndScissor( vLight->imageAtlasOffset[slice].x, vLight->imageAtlasOffset[slice].y, vLight->imageSize.x, vLight->imageSize.y );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( side < 0 )
|
||||
{
|
||||
globalFramebuffers.shadowFBO[vLight->shadowLOD][0]->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
globalFramebuffers.shadowFBO[vLight->shadowLOD][side]->Bind();
|
||||
}
|
||||
|
||||
globalFramebuffers.shadowFBO[vLight->shadowLOD][slice]->Bind();
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
@ -3814,6 +3807,7 @@ void idRenderBackend::ShadowMapPassOld( const drawSurf_t* drawSurfs, const viewL
|
|||
renderLog.CloseBlock();
|
||||
}
|
||||
|
||||
void RectAllocatorBinPack2D( const idList<idVec2i>& inputSizes, const idStrList& inputNames, idList<idVec2i>& outputPositions, idVec2i& totalSize, const int START_MAX );
|
||||
|
||||
void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
|
||||
{
|
||||
|
@ -3842,15 +3836,86 @@ void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
|
|||
}
|
||||
|
||||
//
|
||||
// for each light, perform shadowing to a big atlas Framebuffer
|
||||
// sort lights into atlas
|
||||
//
|
||||
|
||||
int shadowIndex = 0;
|
||||
idList<idVec2i> inputSizes;
|
||||
idStrList inputNames;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const idMaterial* lightShader = vLight->lightShader;
|
||||
|
||||
for( ; side < sideStop ; side++ )
|
||||
{
|
||||
//ShadowMapPassFast( vLight->globalShadows, vLight, side, true );
|
||||
|
||||
inputSizes.Append( idVec2i( shadowMapResolutions[ vLight->shadowLOD ], shadowMapResolutions[ vLight->shadowLOD ] ) );
|
||||
inputNames.Append( lightShader->GetName() );
|
||||
|
||||
shadowIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
idList<idVec2i> outputPositions;
|
||||
idVec2i totalSize;
|
||||
|
||||
RectAllocatorBinPack2D( inputSizes, inputNames, outputPositions, totalSize, SHADOW_ATLAS_SIZE );
|
||||
|
||||
//
|
||||
// for each light, perform shadowing to a big atlas Framebuffer
|
||||
//
|
||||
shadowIndex = 0;
|
||||
|
||||
for( viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next )
|
||||
{
|
||||
if( vLight->lightShader->IsFogLight() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( vLight->lightShader->IsBlendLight() )
|
||||
{
|
||||
continue;
|
||||
|
@ -3898,8 +3963,24 @@ void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
|
|||
sideStop = 0;
|
||||
}
|
||||
|
||||
vLight->imageSize.x = shadowMapResolutions[ vLight->shadowLOD ];
|
||||
vLight->imageSize.y = shadowMapResolutions[ vLight->shadowLOD ];
|
||||
|
||||
for( ; side < sideStop ; side++ )
|
||||
{
|
||||
int slice = Max( 0, side );
|
||||
|
||||
vLight->imageAtlasOffset[ slice ].x = outputPositions[ shadowIndex ].x;
|
||||
vLight->imageAtlasOffset[ slice ].y = outputPositions[ shadowIndex ].y;
|
||||
|
||||
shadowIndex++;
|
||||
|
||||
if( vLight->imageAtlasOffset[ slice ].x == -1 || vLight->imageAtlasOffset[ slice ].y == -1 )
|
||||
{
|
||||
// didn't fit into atlas anymore
|
||||
continue;
|
||||
}
|
||||
|
||||
ShadowMapPassFast( vLight->globalShadows, vLight, side, true );
|
||||
}
|
||||
|
||||
|
|
|
@ -416,6 +416,8 @@ struct viewLight_t
|
|||
bool parallel; // lightCenter gives the direction to the light at infinity
|
||||
idVec3 lightCenter; // offset the lighting direction for shading and
|
||||
int shadowLOD; // level of detail for shadowmap selection
|
||||
idVec2i imageSize;
|
||||
idVec2i imageAtlasOffset[6];
|
||||
// RB end
|
||||
idRenderMatrix inverseBaseLightProject; // the matrix for deforming the 'zeroOneCubeModel' to exactly cover the light volume in world space
|
||||
const idMaterial* lightShader; // light shader used by backend
|
||||
|
|
Loading…
Reference in a new issue