mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-24 02:32:18 +00:00
Improved TAA jittering
This commit is contained in:
parent
a7623165b5
commit
39227f1559
6 changed files with 67 additions and 38 deletions
|
@ -470,14 +470,14 @@ void ModifyProjectionMatrix( viewDef_t* viewDef, const idPlane& clipPlane )
|
|||
memcpy( viewDef->projectionMatrix, matrix, sizeof( float ) * 16 );
|
||||
}
|
||||
|
||||
void R_SetupProjectionMatrix( viewDef_t* viewDef )
|
||||
void R_SetupProjectionMatrix( viewDef_t* viewDef, bool doJitter )
|
||||
{
|
||||
// random jittering is usefull when multiple
|
||||
// frames are going to be blended together
|
||||
// for motion blurred anti-aliasing
|
||||
float jitterx, jittery;
|
||||
|
||||
if( R_UseTemporalAA() )
|
||||
if( R_UseTemporalAA() && doJitter )
|
||||
{
|
||||
idVec2 jitter = tr.backend.GetCurrentPixelOffset();
|
||||
jitterx = jitter.x;
|
||||
|
@ -521,54 +521,56 @@ void R_SetupProjectionMatrix( viewDef_t* viewDef )
|
|||
const float yoffset = ( ymax + ymin ) / height;
|
||||
|
||||
#else
|
||||
// according to https://www.elopezr.com/temporal-aa-and-the-quest-for-the-holy-trail/
|
||||
const float xoffset = jitterx / ( 2.0f * viewWidth );
|
||||
const float yoffset = jittery / ( 2.0f * viewHeight );
|
||||
// this mimics the logic in the Donut / Feature Demo
|
||||
const float xoffset = -2.0f * jitterx / ( 1.0f * viewWidth );
|
||||
const float yoffset = -2.0f * jittery / ( 1.0f * viewHeight );
|
||||
#endif
|
||||
|
||||
// RB: IMPORTANT - the projectionMatrix has a few changes to make it work with Vulkan
|
||||
// for a detailed explanation see https://matthewwellings.com/blog/the-new-vulkan-coordinate-system/
|
||||
|
||||
viewDef->projectionMatrix[0 * 4 + 0] = 2.0f * zNear / width;
|
||||
viewDef->projectionMatrix[1 * 4 + 0] = 0.0f;
|
||||
viewDef->projectionMatrix[2 * 4 + 0] = xoffset;
|
||||
viewDef->projectionMatrix[3 * 4 + 0] = 0.0f;
|
||||
float* projectionMatrix = doJitter ? viewDef->projectionMatrix : viewDef->unjitteredProjectionMatrix;
|
||||
|
||||
viewDef->projectionMatrix[0 * 4 + 1] = 0.0f;
|
||||
projectionMatrix[0 * 4 + 0] = 2.0f * zNear / width;
|
||||
projectionMatrix[1 * 4 + 0] = 0.0f;
|
||||
projectionMatrix[2 * 4 + 0] = xoffset;
|
||||
projectionMatrix[3 * 4 + 0] = 0.0f;
|
||||
|
||||
projectionMatrix[0 * 4 + 1] = 0.0f;
|
||||
|
||||
// RB: Y axis now points down the screen
|
||||
#if defined(USE_VULKAN)
|
||||
viewDef->projectionMatrix[1 * 4 + 1] = -2.0f * zNear / height;
|
||||
projectionMatrix[1 * 4 + 1] = -2.0f * zNear / height;
|
||||
#else
|
||||
viewDef->projectionMatrix[1 * 4 + 1] = 2.0f * zNear / height;
|
||||
projectionMatrix[1 * 4 + 1] = 2.0f * zNear / height;
|
||||
#endif
|
||||
viewDef->projectionMatrix[2 * 4 + 1] = yoffset;
|
||||
viewDef->projectionMatrix[3 * 4 + 1] = 0.0f;
|
||||
projectionMatrix[2 * 4 + 1] = yoffset;
|
||||
projectionMatrix[3 * 4 + 1] = 0.0f;
|
||||
|
||||
// this is the far-plane-at-infinity formulation, and
|
||||
// crunches the Z range slightly so w=0 vertexes do not
|
||||
// rasterize right at the wraparound point
|
||||
viewDef->projectionMatrix[0 * 4 + 2] = 0.0f;
|
||||
viewDef->projectionMatrix[1 * 4 + 2] = 0.0f;
|
||||
viewDef->projectionMatrix[2 * 4 + 2] = -0.999f; // adjust value to prevent imprecision issues
|
||||
projectionMatrix[0 * 4 + 2] = 0.0f;
|
||||
projectionMatrix[1 * 4 + 2] = 0.0f;
|
||||
projectionMatrix[2 * 4 + 2] = -0.999f; // adjust value to prevent imprecision issues
|
||||
|
||||
// RB: was -2.0f * zNear
|
||||
// the transformation into window space has changed from [-1 .. -1] to [0 .. -1]
|
||||
viewDef->projectionMatrix[3 * 4 + 2] = -1.0f * zNear;
|
||||
projectionMatrix[3 * 4 + 2] = -1.0f * zNear;
|
||||
|
||||
viewDef->projectionMatrix[0 * 4 + 3] = 0.0f;
|
||||
viewDef->projectionMatrix[1 * 4 + 3] = 0.0f;
|
||||
viewDef->projectionMatrix[2 * 4 + 3] = -1.0f;
|
||||
viewDef->projectionMatrix[3 * 4 + 3] = 0.0f;
|
||||
projectionMatrix[0 * 4 + 3] = 0.0f;
|
||||
projectionMatrix[1 * 4 + 3] = 0.0f;
|
||||
projectionMatrix[2 * 4 + 3] = -1.0f;
|
||||
projectionMatrix[3 * 4 + 3] = 0.0f;
|
||||
|
||||
if( viewDef->renderView.flipProjection )
|
||||
{
|
||||
viewDef->projectionMatrix[1 * 4 + 1] = -viewDef->projectionMatrix[1 * 4 + 1];
|
||||
viewDef->projectionMatrix[1 * 4 + 3] = -viewDef->projectionMatrix[1 * 4 + 3];
|
||||
projectionMatrix[1 * 4 + 1] = -projectionMatrix[1 * 4 + 1];
|
||||
projectionMatrix[1 * 4 + 3] = -projectionMatrix[1 * 4 + 3];
|
||||
}
|
||||
|
||||
// SP Begin
|
||||
if( viewDef->isObliqueProjection )
|
||||
if( viewDef->isObliqueProjection && doJitter )
|
||||
{
|
||||
R_ObliqueProjection( viewDef );
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ void R_GlobalPlaneToLocal( const float modelMatrix[16], const idPlane& in, idPla
|
|||
void R_LocalPlaneToGlobal( const float modelMatrix[16], const idPlane& in, idPlane& out );
|
||||
|
||||
void R_SetupViewMatrix( viewDef_t* viewDef );
|
||||
void R_SetupProjectionMatrix( viewDef_t* viewDef );
|
||||
void R_SetupProjectionMatrix( viewDef_t* viewDef, bool doJitter );
|
||||
|
||||
// RB begin
|
||||
void R_SetupUnprojection( viewDef_t* viewDef );
|
||||
|
|
|
@ -5529,26 +5529,43 @@ void idRenderBackend::DrawMotionVectors()
|
|||
|
||||
// derive the matrix to go from current pixels to previous frame pixels
|
||||
idRenderMatrix inverseMVP;
|
||||
idRenderMatrix::Inverse( viewDef->worldSpace.mvp, inverseMVP );
|
||||
idRenderMatrix::Inverse( viewDef->worldSpace.unjitteredMVP, inverseMVP );
|
||||
|
||||
idRenderMatrix motionMatrix;
|
||||
idRenderMatrix::Multiply( prevMVP[mvpIndex], inverseMVP, motionMatrix );
|
||||
|
||||
prevMVP[mvpIndex] = viewDef->worldSpace.mvp;
|
||||
prevMVP[mvpIndex] = viewDef->worldSpace.unjitteredMVP;
|
||||
|
||||
RB_SetMVP( motionMatrix );
|
||||
// make sure rpWindowCoord is set even without post processing surfaces in the view
|
||||
int x = viewDef->viewport.x1;
|
||||
int y = viewDef->viewport.y1;
|
||||
int w = viewDef->viewport.x2 - viewDef->viewport.x1 + 1;
|
||||
int h = viewDef->viewport.y2 - viewDef->viewport.y1 + 1;
|
||||
|
||||
GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_DEPTHMASK | GLS_CULL_TWOSIDED );
|
||||
// window coord to 0.0 to 1.0 conversion
|
||||
float windowCoordParm[4];
|
||||
windowCoordParm[0] = 1.0f / w;
|
||||
windowCoordParm[1] = 1.0f / h;
|
||||
windowCoordParm[2] = w;
|
||||
windowCoordParm[3] = h;
|
||||
SetFragmentParm( RENDERPARM_WINDOWCOORD, windowCoordParm ); // rpWindowCoord
|
||||
|
||||
renderProgManager.BindShader_MotionVectors();
|
||||
if( r_taaMotionVectors.GetBool() && prevViewsValid )
|
||||
{
|
||||
RB_SetMVP( motionMatrix );
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
globalImages->currentRenderHDRImage->Bind();
|
||||
GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_DEPTHMASK | GLS_CULL_TWOSIDED );
|
||||
|
||||
GL_SelectTexture( 1 );
|
||||
globalImages->currentDepthImage->Bind();
|
||||
renderProgManager.BindShader_MotionVectors();
|
||||
|
||||
DrawElementsWithCounters( &unitSquareSurface );
|
||||
GL_SelectTexture( 0 );
|
||||
globalImages->currentRenderHDRImage->Bind();
|
||||
|
||||
GL_SelectTexture( 1 );
|
||||
globalImages->currentDepthImage->Bind();
|
||||
|
||||
DrawElementsWithCounters( &unitSquareSurface );
|
||||
}
|
||||
|
||||
renderLog.CloseBlock();
|
||||
}
|
||||
|
|
|
@ -472,6 +472,7 @@ struct viewEntity_t
|
|||
float modelViewMatrix[16]; // local coords to eye coords
|
||||
|
||||
idRenderMatrix mvp;
|
||||
idRenderMatrix unjitteredMVP; // no TAA subpixel jittering
|
||||
|
||||
// parallelAddModels will build a chain of surfaces here that will need to
|
||||
// be linked to the lights or added to the drawsurf list in a serial code section
|
||||
|
@ -607,6 +608,9 @@ struct viewDef_t
|
|||
idRenderMatrix projectionRenderMatrix; // tech5 version of projectionMatrix
|
||||
|
||||
// RB begin
|
||||
float unjitteredProjectionMatrix[16]; // second version without TAA subpixel jittering
|
||||
idRenderMatrix unjitteredProjectionRenderMatrix;
|
||||
|
||||
float unprojectionToCameraMatrix[16];
|
||||
idRenderMatrix unprojectionToCameraRenderMatrix;
|
||||
|
||||
|
@ -1292,6 +1296,7 @@ extern idCVar r_taaEnableHistoryClamping;
|
|||
extern idCVar r_taaClampingFactor;
|
||||
extern idCVar r_taaNewFrameWeight;
|
||||
extern idCVar r_taaMaxRadiance;
|
||||
extern idCVar r_taaMotionVectors;
|
||||
// RB end
|
||||
|
||||
/*
|
||||
|
|
|
@ -334,11 +334,12 @@ idCVar r_useLightGrid( "r_useLightGrid", "1", CVAR_RENDERER | CVAR_BOOL, "" );
|
|||
idCVar r_exposure( "r_exposure", "0.5", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_FLOAT, "HDR exposure or LDR brightness [-4.0 .. 4.0]", -4.0f, 4.0f );
|
||||
|
||||
idCVar r_useTemporalAA( "r_useTemporalAA", "1", CVAR_RENDERER | CVAR_BOOL, "only disable for debugging" );
|
||||
idCVar r_taaJitter( "r_taaJitter", "2", CVAR_RENDERER | CVAR_INTEGER, "0: None, 1: MSAA, 2: Halton, 3: R2 Sequence, 4: White Noise" );
|
||||
idCVar r_taaJitter( "r_taaJitter", "3", CVAR_RENDERER | CVAR_INTEGER, "0: None, 1: MSAA, 2: Halton, 3: R2 Sequence, 4: White Noise" );
|
||||
idCVar r_taaEnableHistoryClamping( "r_taaEnableHistoryClamping", "1", CVAR_RENDERER | CVAR_BOOL, "" );
|
||||
idCVar r_taaClampingFactor( "r_taaClampingFactor", "1.0", CVAR_RENDERER | CVAR_FLOAT, "" );
|
||||
idCVar r_taaNewFrameWeight( "r_taaNewFrameWeight", "0.1", CVAR_RENDERER | CVAR_FLOAT, "" );
|
||||
idCVar r_taaMaxRadiance( "r_taaMaxRadiance", "10000", CVAR_RENDERER | CVAR_FLOAT, "" );
|
||||
idCVar r_taaMotionVectors( "r_taaMotionVectors", "1", CVAR_RENDERER | CVAR_BOOL, "" );
|
||||
// RB end
|
||||
|
||||
const char* fileExten[4] = { "tga", "png", "jpg", "exr" };
|
||||
|
|
|
@ -606,7 +606,8 @@ void R_RenderView( viewDef_t* parms )
|
|||
|
||||
// we need to set the projection matrix before doing
|
||||
// portal-to-screen scissor calculations
|
||||
R_SetupProjectionMatrix( tr.viewDef );
|
||||
R_SetupProjectionMatrix( tr.viewDef, true );
|
||||
R_SetupProjectionMatrix( tr.viewDef, false );
|
||||
|
||||
// RB: we need a unprojection matrix to calculate the vertex position based on the depth image value
|
||||
// for some post process shaders
|
||||
|
@ -619,6 +620,9 @@ void R_RenderView( viewDef_t* parms )
|
|||
idRenderMatrix::Transpose( *( idRenderMatrix* )tr.viewDef->worldSpace.modelViewMatrix, viewRenderMatrix );
|
||||
idRenderMatrix::Multiply( tr.viewDef->projectionRenderMatrix, viewRenderMatrix, tr.viewDef->worldSpace.mvp );
|
||||
|
||||
idRenderMatrix::Transpose( *( idRenderMatrix* )tr.viewDef->unjitteredProjectionMatrix, tr.viewDef->unjitteredProjectionRenderMatrix );
|
||||
idRenderMatrix::Multiply( tr.viewDef->unjitteredProjectionRenderMatrix, viewRenderMatrix, tr.viewDef->worldSpace.unjitteredMVP );
|
||||
|
||||
// the planes of the view frustum are needed for portal visibility culling
|
||||
idRenderMatrix::GetFrustumPlanes( tr.viewDef->frustums[FRUSTUM_PRIMARY], tr.viewDef->worldSpace.mvp, false, true );
|
||||
|
||||
|
|
Loading…
Reference in a new issue