mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 06:34:10 +00:00
Fixed TAA bug where the frameIndex was a mismatch in renderer frontend/backend. Backported from VR branch
This commit is contained in:
parent
b9669d3788
commit
d6dabb6869
9 changed files with 106 additions and 96 deletions
|
@ -411,67 +411,7 @@ idCVar r_centerX( "r_centerX", "0", CVAR_FLOAT, "projection matrix center adjust
|
|||
idCVar r_centerY( "r_centerY", "0", CVAR_FLOAT, "projection matrix center adjust" );
|
||||
idCVar r_centerScale( "r_centerScale", "1", CVAR_FLOAT, "projection matrix center adjust" );
|
||||
|
||||
inline float sgn( float a )
|
||||
{
|
||||
if( a > 0.0f )
|
||||
{
|
||||
return ( 1.0f );
|
||||
}
|
||||
if( a < 0.0f )
|
||||
{
|
||||
return ( -1.0f );
|
||||
}
|
||||
return ( 0.0f );
|
||||
}
|
||||
|
||||
// clipPlane is a plane in camera space.
|
||||
void ModifyProjectionMatrix( viewDef_t* viewDef, const idPlane& clipPlane )
|
||||
{
|
||||
static float s_flipMatrix[16] =
|
||||
{
|
||||
// convert from our coordinate system (looking down X)
|
||||
// to OpenGL's coordinate system (looking down -Z)
|
||||
0, 0, -1, 0,
|
||||
-1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
idMat4 flipMatrix;
|
||||
memcpy( &flipMatrix, &( s_flipMatrix[0] ), sizeof( float ) * 16 );
|
||||
|
||||
idVec4 vec = clipPlane.ToVec4();// * flipMatrix;
|
||||
idPlane newPlane( vec[0], vec[1], vec[2], vec[3] );
|
||||
|
||||
// Calculate the clip-space corner point opposite the clipping plane
|
||||
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
|
||||
// transform it into camera space by multiplying it
|
||||
// by the inverse of the projection matrix
|
||||
|
||||
//idVec4 q;
|
||||
//q.x = (sgn(newPlane[0]) + viewDef->projectionMatrix[8]) / viewDef->projectionMatrix[0];
|
||||
//q.y = (sgn(newPlane[1]) + viewDef->projectionMatrix[9]) / viewDef->projectionMatrix[5];
|
||||
//q.z = -1.0F;
|
||||
//q.w = (1.0F + viewDef->projectionMatrix[10]) / viewDef->projectionMatrix[14];
|
||||
|
||||
idMat4 unprojection;
|
||||
R_MatrixFullInverse( viewDef->projectionMatrix, ( float* )&unprojection );
|
||||
idVec4 q = unprojection * idVec4( sgn( newPlane[0] ), sgn( newPlane[1] ), 1.0f, 1.0f );
|
||||
|
||||
// Calculate the scaled plane vector
|
||||
idVec4 c = newPlane.ToVec4() * ( 2.0f / ( q * newPlane.ToVec4() ) );
|
||||
|
||||
float matrix[16];
|
||||
std::memcpy( matrix, viewDef->projectionMatrix, sizeof( float ) * 16 );
|
||||
|
||||
// Replace the third row of the projection matrix
|
||||
matrix[2] = c[0];
|
||||
matrix[6] = c[1];
|
||||
matrix[10] = c[2] + 1.0f;
|
||||
matrix[14] = c[3];
|
||||
|
||||
memcpy( viewDef->projectionMatrix, matrix, sizeof( float ) * 16 );
|
||||
}
|
||||
|
||||
#if !defined( DMAP )
|
||||
|
||||
|
@ -484,7 +424,7 @@ void R_SetupProjectionMatrix( viewDef_t* viewDef, bool doJitter )
|
|||
|
||||
if( R_UseTemporalAA() && doJitter && !( viewDef->renderView.rdflags & RDF_IRRADIANCE ) )
|
||||
{
|
||||
idVec2 jitter = tr.backend.GetCurrentPixelOffset();
|
||||
idVec2 jitter = tr.backend.GetCurrentPixelOffset( viewDef->taaFrameCount );
|
||||
jitterx = jitter.x;
|
||||
jittery = jitter.y;
|
||||
}
|
||||
|
@ -717,6 +657,68 @@ void R_MatrixFullInverse( const float a[16], float r[16] )
|
|||
// RB end
|
||||
|
||||
// SP begin
|
||||
inline float sgn( float a )
|
||||
{
|
||||
if( a > 0.0f )
|
||||
{
|
||||
return ( 1.0f );
|
||||
}
|
||||
if( a < 0.0f )
|
||||
{
|
||||
return ( -1.0f );
|
||||
}
|
||||
return ( 0.0f );
|
||||
}
|
||||
|
||||
// clipPlane is a plane in camera space.
|
||||
void ModifyProjectionMatrix( viewDef_t* viewDef, const idPlane& clipPlane )
|
||||
{
|
||||
static float s_flipMatrix[16] =
|
||||
{
|
||||
// convert from our coordinate system (looking down X)
|
||||
// to OpenGL's coordinate system (looking down -Z)
|
||||
0, 0, -1, 0,
|
||||
-1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
idMat4 flipMatrix;
|
||||
memcpy( &flipMatrix, &( s_flipMatrix[0] ), sizeof( float ) * 16 );
|
||||
|
||||
idVec4 vec = clipPlane.ToVec4();// * flipMatrix;
|
||||
idPlane newPlane( vec[0], vec[1], vec[2], vec[3] );
|
||||
|
||||
// Calculate the clip-space corner point opposite the clipping plane
|
||||
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
|
||||
// transform it into camera space by multiplying it
|
||||
// by the inverse of the projection matrix
|
||||
|
||||
//idVec4 q;
|
||||
//q.x = (sgn(newPlane[0]) + viewDef->projectionMatrix[8]) / viewDef->projectionMatrix[0];
|
||||
//q.y = (sgn(newPlane[1]) + viewDef->projectionMatrix[9]) / viewDef->projectionMatrix[5];
|
||||
//q.z = -1.0F;
|
||||
//q.w = (1.0F + viewDef->projectionMatrix[10]) / viewDef->projectionMatrix[14];
|
||||
|
||||
idMat4 unprojection;
|
||||
R_MatrixFullInverse( viewDef->projectionMatrix, ( float* )&unprojection );
|
||||
idVec4 q = unprojection * idVec4( sgn( newPlane[0] ), sgn( newPlane[1] ), 1.0f, 1.0f );
|
||||
|
||||
// Calculate the scaled plane vector
|
||||
idVec4 c = newPlane.ToVec4() * ( 2.0f / ( q * newPlane.ToVec4() ) );
|
||||
|
||||
float matrix[16];
|
||||
std::memcpy( matrix, viewDef->projectionMatrix, sizeof( float ) * 16 );
|
||||
|
||||
// Replace the third row of the projection matrix
|
||||
matrix[2] = c[0];
|
||||
matrix[6] = c[1];
|
||||
matrix[10] = c[2] + 1.0f;
|
||||
matrix[14] = c[3];
|
||||
|
||||
memcpy( viewDef->projectionMatrix, matrix, sizeof( float ) * 16 );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
R_ObliqueProjection - adjust near plane of previously set projection matrix to perform an oblique projection
|
||||
|
|
|
@ -261,7 +261,7 @@ void SsaoPass::Render(
|
|||
SsaoConstants ssaoConstants = {};
|
||||
ssaoConstants.viewportOrigin = idVec2( viewDef->viewport.x1, viewDef->viewport.y1 );
|
||||
ssaoConstants.viewportSize = idVec2( viewDef->viewport.GetWidth(), viewDef->viewport.GetHeight() );
|
||||
ssaoConstants.pixelOffset = tr.backend.GetCurrentPixelOffset();
|
||||
ssaoConstants.pixelOffset = tr.backend.GetCurrentPixelOffset( viewDef->taaFrameCount );
|
||||
|
||||
// RB: this actually should work but it only works with the old SSAO method ...
|
||||
//ssaoConstants.matClipToView = viewDef->unprojectionToCameraRenderMatrix;
|
||||
|
|
|
@ -84,18 +84,9 @@ void TemporalAntiAliasingPass::Init(
|
|||
}
|
||||
}
|
||||
|
||||
//std::vector<ShaderMacro> MotionVectorMacros;
|
||||
//MotionVectorMacros.push_back( ShaderMacro( "USE_STENCIL", useStencil ? "1" : "0" ) );
|
||||
//m_MotionVectorPS = shaderFactory->CreateShader( "donut/passes/motion_vectors_ps.hlsl", "main", &MotionVectorMacros, nvrhi::ShaderType::Pixel );
|
||||
|
||||
auto taaMotionVectorsShaderInfo = renderProgManager.GetProgramInfo( BUILTIN_TAA_MOTION_VECTORS );
|
||||
m_MotionVectorPS = taaMotionVectorsShaderInfo.ps;
|
||||
|
||||
//std::vector<ShaderMacro> ResolveMacros;
|
||||
//ResolveMacros.push_back( ShaderMacro( "SAMPLE_COUNT", std::to_string( unresolvedColorDesc.sampleCount ) ) );
|
||||
//ResolveMacros.push_back( ShaderMacro( "USE_CATMULL_ROM_FILTER", params.useCatmullRomFilter ? "1" : "0" ) );
|
||||
//m_TemporalAntiAliasingCS = shaderFactory->CreateShader( "donut/passes/taa_cs.hlsl", "main", &ResolveMacros, nvrhi::ShaderType::Compute );
|
||||
|
||||
switch( r_antiAliasing.GetInteger() )
|
||||
{
|
||||
#if ID_MSAA
|
||||
|
@ -221,12 +212,12 @@ void TemporalAntiAliasingPass::TemporalResolve(
|
|||
taaConstants.inputViewSize = idVec2( viewportInput.width() + 1, viewportInput.height() + 1 );
|
||||
taaConstants.outputViewOrigin = idVec2( viewportOutput.minX, viewportOutput.minY );
|
||||
taaConstants.outputViewSize = idVec2( viewportOutput.width() + 1, viewportOutput.height() + 1 );
|
||||
taaConstants.inputPixelOffset = GetCurrentPixelOffset();
|
||||
taaConstants.inputPixelOffset = GetCurrentPixelOffset( viewDef->taaFrameCount );
|
||||
taaConstants.outputTextureSizeInv = idVec2( 1.0f, 1.0f ) / idVec2( float( renderSystem->GetWidth() ), float( renderSystem->GetHeight() ) );
|
||||
taaConstants.inputOverOutputViewSize = taaConstants.inputViewSize / taaConstants.outputViewSize;
|
||||
taaConstants.outputOverInputViewSize = taaConstants.outputViewSize / taaConstants.inputViewSize;
|
||||
taaConstants.clampingFactor = params.enableHistoryClamping ? params.clampingFactor : -1.f;
|
||||
taaConstants.newFrameWeight = feedbackIsValid ? params.newFrameWeight : 1.f;
|
||||
taaConstants.clampingFactor = params.enableHistoryClamping ? params.clampingFactor : -1.0f;
|
||||
taaConstants.newFrameWeight = feedbackIsValid ? params.newFrameWeight : 1.0f;
|
||||
taaConstants.pqC = idMath::ClampFloat( 1e-4f, 1e8f, params.maxRadiance );
|
||||
taaConstants.invPqC = 1.f / taaConstants.pqC;
|
||||
commandList->writeBuffer( m_TemporalAntiAliasingCB, &taaConstants, sizeof( taaConstants ) );
|
||||
|
@ -275,7 +266,7 @@ static float VanDerCorput( size_t base, size_t index )
|
|||
return ret;
|
||||
}
|
||||
|
||||
idVec2 TemporalAntiAliasingPass::GetCurrentPixelOffset()
|
||||
idVec2 TemporalAntiAliasingPass::GetCurrentPixelOffset( int frameIndex )
|
||||
{
|
||||
switch( r_taaJitter.GetInteger() )
|
||||
{
|
||||
|
@ -288,11 +279,11 @@ idVec2 TemporalAntiAliasingPass::GetCurrentPixelOffset()
|
|||
idVec2( -0.3125f, 0.3125f ), idVec2( -0.4375f, 0.0625f ), idVec2( 0.1875f, 0.4375f ), idVec2( 0.4375f, -0.4375f )
|
||||
};
|
||||
|
||||
return offsets[m_FrameIndex % 8];
|
||||
return offsets[frameIndex % 8];
|
||||
}
|
||||
case( int )TemporalAntiAliasingJitter::Halton:
|
||||
{
|
||||
uint32_t index = ( m_FrameIndex % 16 ) + 1;
|
||||
uint32_t index = ( frameIndex % 16 ) + 1;
|
||||
return idVec2{ VanDerCorput( 2, index ), VanDerCorput( 3, index ) } - idVec2( 0.5f, 0.5f );
|
||||
}
|
||||
case( int )TemporalAntiAliasingJitter::R2:
|
||||
|
@ -301,7 +292,7 @@ idVec2 TemporalAntiAliasingPass::GetCurrentPixelOffset()
|
|||
}
|
||||
case( int )TemporalAntiAliasingJitter::WhiteNoise:
|
||||
{
|
||||
std::mt19937 rng( m_FrameIndex );
|
||||
std::mt19937 rng( frameIndex );
|
||||
std::uniform_real_distribution<float> dist( -0.5f, 0.5f );
|
||||
return idVec2{ dist( rng ), dist( rng ) };
|
||||
}
|
||||
|
|
|
@ -116,12 +116,6 @@ public:
|
|||
const viewDef_t* viewDef,
|
||||
const CreateParameters& params );
|
||||
|
||||
void RenderMotionVectors(
|
||||
nvrhi::ICommandList* commandList,
|
||||
const viewDef_t* viewDef,
|
||||
const viewDef_t* viewDefPrevious,
|
||||
idVec3 preViewTranslationDifference = vec3_zero );
|
||||
|
||||
void TemporalResolve(
|
||||
nvrhi::ICommandList* commandList,
|
||||
const TemporalAntiAliasingParameters& params,
|
||||
|
@ -129,7 +123,7 @@ public:
|
|||
const viewDef_t* viewDef );
|
||||
|
||||
void AdvanceFrame();
|
||||
idVec2 GetCurrentPixelOffset();
|
||||
idVec2 GetCurrentPixelOffset( int frameIndex );
|
||||
|
||||
uint32_t GetFrameIndex() const
|
||||
{
|
||||
|
|
|
@ -4865,11 +4865,11 @@ void idRenderBackend::TemporalAAPass( const viewDef_t* _viewDef )
|
|||
renderLog.CloseMainBlock();
|
||||
}
|
||||
|
||||
idVec2 idRenderBackend::GetCurrentPixelOffset() const
|
||||
idVec2 idRenderBackend::GetCurrentPixelOffset( int frameIndex ) const
|
||||
{
|
||||
if( taaPass )
|
||||
{
|
||||
return taaPass->GetCurrentPixelOffset();
|
||||
return taaPass->GetCurrentPixelOffset( frameIndex );
|
||||
}
|
||||
|
||||
return idVec2( 0, 0 );
|
||||
|
@ -5309,6 +5309,8 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
|
|||
|
||||
resolutionScale.SetCurrentGPUFrameTime( commonLocal.GetRendererGPUMicroseconds() );
|
||||
|
||||
// make sure the swapchains and rendertargets have the size requested
|
||||
// by the window system
|
||||
ResizeImages();
|
||||
|
||||
if( cmds->commandId == RC_NOP && !cmds->next )
|
||||
|
@ -5319,7 +5321,6 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
|
|||
if( renderSystem->GetStereo3DMode() != STEREO3D_OFF )
|
||||
{
|
||||
StereoRenderExecuteBackEndCommands( cmds );
|
||||
//renderLog.EndFrame();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5440,7 +5441,7 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
|
|||
break;
|
||||
|
||||
default:
|
||||
common->Error( "RB_ExecuteBackEndCommands: bad commandId" );
|
||||
common->Error( "ExecuteBackEndCommands: bad commandId" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5459,8 +5460,6 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
|
|||
common->Printf( "3d: %i, 2d: %i, SetBuf: %i, CpyRenders: %i, CpyFrameBuf: %i\n", c_draw3d, c_draw2d, c_setBuffers, c_copyRenders, pc.c_copyFrameBuffer );
|
||||
pc.c_copyFrameBuffer = 0;
|
||||
}
|
||||
|
||||
//renderLog.EndFrame();
|
||||
}
|
||||
|
||||
|
||||
|
@ -5482,7 +5481,23 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
|
|||
OPTICK_GPU_CONTEXT( ( void* ) commandList->getNativeObject( commandObject ) );
|
||||
//OPTICK_GPU_EVENT( "DrawView" ); // SRS - now in DrawView() for 3D vs. GUI
|
||||
|
||||
renderLog.OpenBlock( "Render_DrawViewInternal", colorRed );
|
||||
// ugly but still faster than building the string
|
||||
if( !_viewDef->viewEntitys || _viewDef->is2Dgui )
|
||||
{
|
||||
renderLog.OpenBlock( "Render_DrawView2D", colorRed );
|
||||
}
|
||||
else if( stereoEye == -1 )
|
||||
{
|
||||
renderLog.OpenBlock( "Render_DrawView3D_LeftEye", colorRed );
|
||||
}
|
||||
else if( stereoEye == 1 )
|
||||
{
|
||||
renderLog.OpenBlock( "Render_DrawView3D_RightEye", colorRed );
|
||||
}
|
||||
else if( stereoEye == 0 )
|
||||
{
|
||||
renderLog.OpenBlock( "Render_DrawView3D", colorRed );
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// guis can wind up referencing purged images that need to be loaded.
|
||||
|
@ -5860,6 +5875,7 @@ Experimental feature
|
|||
*/
|
||||
void idRenderBackend::MotionBlur()
|
||||
{
|
||||
#if 0
|
||||
if( !viewDef->viewEntitys )
|
||||
{
|
||||
// 3D views only
|
||||
|
@ -5958,6 +5974,7 @@ void idRenderBackend::MotionBlur()
|
|||
globalImages->currentDepthImage->Bind();
|
||||
|
||||
DrawElementsWithCounters( &unitSquareSurface );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -218,7 +218,7 @@ private:
|
|||
|
||||
public:
|
||||
uint64 GL_GetCurrentState() const;
|
||||
idVec2 GetCurrentPixelOffset() const;
|
||||
idVec2 GetCurrentPixelOffset( int frameIndex ) const;
|
||||
|
||||
nvrhi::ICommandList* GL_GetCommandList() const
|
||||
{
|
||||
|
|
|
@ -481,7 +481,7 @@ struct calcEnvprobeParms_t
|
|||
idStr filename;
|
||||
|
||||
// output
|
||||
halfFloat_t* outBuffer; // HDR R11G11B11F packed octahedron atlas
|
||||
halfFloat_t* outBuffer; // HDR RGB16F packed octahedron atlas
|
||||
int time; // execution time in milliseconds
|
||||
};
|
||||
|
||||
|
@ -505,7 +505,7 @@ struct calcLightGridPointParms_t
|
|||
SphericalHarmonicsT<idVec3, 4> shRadiance; // L4 Spherical Harmonics
|
||||
#endif
|
||||
|
||||
halfFloat_t* outBuffer; // HDR R11G11B11F octahedron LIGHTGRID_IRRADIANCE_SIZE^2
|
||||
halfFloat_t* outBuffer; // HDR RGB16F octahedron LIGHTGRID_IRRADIANCE_SIZE^2
|
||||
int time; // execution time in milliseconds
|
||||
};
|
||||
// RB end
|
||||
|
@ -631,6 +631,8 @@ struct viewDef_t
|
|||
idVec4 radianceImageBlends; // blending weights
|
||||
|
||||
Framebuffer* targetRender; // SP: The framebuffer to render to
|
||||
|
||||
int taaFrameCount; // RB: so we have the same frame index in frontend and backend
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ idCVar r_useLightGrid( "r_useLightGrid", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_N
|
|||
idCVar r_exposure( "r_exposure", "0.5", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "HDR exposure or LDR brightness [-4.0 .. 4.0]", -4.0f, 4.0f );
|
||||
|
||||
idCVar r_useTemporalAA( "r_useTemporalAA", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_NEW, "only disable for debugging" );
|
||||
idCVar r_taaJitter( "r_taaJitter", "3", CVAR_RENDERER | CVAR_INTEGER | CVAR_NEW, "0: None, 1: MSAA, 2: Halton, 3: R2 Sequence, 4: White Noise" );
|
||||
idCVar r_taaJitter( "r_taaJitter", "1", CVAR_RENDERER | CVAR_INTEGER | CVAR_NEW, "0: None, 1: MSAA, 2: Halton, 3: R2 Sequence, 4: White Noise" );
|
||||
idCVar r_taaEnableHistoryClamping( "r_taaEnableHistoryClamping", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_NEW, "" );
|
||||
idCVar r_taaClampingFactor( "r_taaClampingFactor", "1.0", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" );
|
||||
idCVar r_taaNewFrameWeight( "r_taaNewFrameWeight", "0.1", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" );
|
||||
|
@ -2584,6 +2584,7 @@ int idRenderSystemLocal::GetWidth() const
|
|||
{
|
||||
return glConfig.nativeScreenWidth >> 1;
|
||||
}
|
||||
|
||||
return glConfig.nativeScreenWidth;
|
||||
}
|
||||
|
||||
|
|
|
@ -680,6 +680,9 @@ void R_RenderView( viewDef_t* parms )
|
|||
|
||||
tr.viewDef = parms;
|
||||
|
||||
// use this same frame index for the projection matrix jittering here and in the backend!
|
||||
tr.viewDef->taaFrameCount = tr.frameCount;
|
||||
|
||||
// setup the matrix for world space to eye space
|
||||
R_SetupViewMatrix( tr.viewDef );
|
||||
|
||||
|
|
Loading…
Reference in a new issue