Added code for debugging Donut's SSAO pass

This commit is contained in:
Robert Beckebans 2023-02-07 15:06:40 +01:00
parent 050c766f9d
commit 846cf265fb
11 changed files with 106 additions and 190 deletions

View file

@ -4,6 +4,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -537,13 +538,7 @@ void R_SetupProjectionMatrix( viewDef_t* viewDef, bool doJitter )
projectionMatrix[3 * 4 + 0] = 0.0f;
projectionMatrix[0 * 4 + 1] = 0.0f;
// RB: Y axis now points down the screen
#if defined(USE_VULKAN)
projectionMatrix[1 * 4 + 1] = -2.0f * zNear / height;
#else
projectionMatrix[1 * 4 + 1] = 2.0f * zNear / height;
#endif
projectionMatrix[2 * 4 + 1] = yoffset;
projectionMatrix[3 * 4 + 1] = 0.0f;

View file

@ -1749,10 +1749,6 @@ void idRenderBackend::GL_Clear( bool color, bool depth, bool stencil, byte stenc
if( depth || stencil )
{
nvrhi::utils::ClearDepthStencilAttachment( commandList, framebuffer, 1.0f, stencilValue );
//nvrhi::ITexture* depthTexture = ( nvrhi::ITexture* )( globalImages->currentDepthImage->GetTextureID() );
//const nvrhi::FormatInfo& depthFormatInfo = nvrhi::getFormatInfo( depthTexture->getDesc().format );
//commandList->clearDepthStencilTexture( depthTexture, nvrhi::AllSubresources, depth, 1.f, depthFormatInfo.hasStencil, stencilValue );
}
}

View file

@ -1,29 +1,23 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <precompiled.h>
#pragma hdrstop
@ -32,11 +26,19 @@ If you have questions concerning this license or the applicable additional terms
#include "SsaoPass.h"
static idCVar r_ssaoBackgroundViewDepth( "r_ssaoBackgroundViewDepth", "100", CVAR_RENDERER | CVAR_FLOAT, "" );
static idCVar r_ssaoRadiusWorld( "r_ssaoRadiusWorld", "0.5", CVAR_RENDERER | CVAR_FLOAT, "" );
static idCVar r_ssaoSurfaceBias( "r_ssaoSurfaceBias", "0.1", CVAR_RENDERER | CVAR_FLOAT, "" );
static idCVar r_ssaoPowerExponent( "r_ssaoSurfaceBias", "2", CVAR_RENDERER | CVAR_FLOAT, "" );
static idCVar r_ssaoBlurSharpness( "r_ssaoBlurSharpness", "16", CVAR_RENDERER | CVAR_FLOAT, "" );
static idCVar r_ssaoAmount( "r_ssaoAmount", "2", CVAR_RENDERER | CVAR_FLOAT, "" );
struct SsaoConstants
{
idVec2 viewportOrigin;
idVec2 viewportSize;
idRenderMatrix matClipToView;
idRenderMatrix matWorldToView;
idRenderMatrix matViewToWorld;
@ -230,7 +232,6 @@ void SsaoPass::CreateBindingSet(
void SsaoPass::Render(
nvrhi::ICommandList* commandList,
const SsaoParameters& params,
const viewDef_t* viewDef,
int bindingSetIndex )
{
@ -238,41 +239,45 @@ void SsaoPass::Render(
assert( m_Compute.BindingSets[bindingSetIndex] );
assert( m_Blur.BindingSets[bindingSetIndex] );
commandList->beginMarker( "SSAO" );
nvrhi::Rect viewExtent( viewDef->viewport.x1, viewDef->viewport.x2, viewDef->viewport.y1, viewDef->viewport.y2 );
nvrhi::Rect quarterResExtent = viewExtent;
quarterResExtent.minX /= 4;
quarterResExtent.minY /= 4;
quarterResExtent.maxX = ( quarterResExtent.maxX + 3 ) / 4;
quarterResExtent.maxY = ( quarterResExtent.maxY + 3 ) / 4;
SsaoConstants ssaoConstants = {};
ssaoConstants.viewportOrigin = idVec2( viewDef->viewport.x1, viewDef->viewport.y1 );
ssaoConstants.viewportSize = idVec2( viewDef->viewport.GetWidth(), viewDef->viewport.GetHeight() );
// SRS - FIXME: These transformations need to be verified
ssaoConstants.matClipToView = viewDef->unprojectionToCameraRenderMatrix;
ssaoConstants.matViewToWorld = viewDef->unprojectionToWorldRenderMatrix;
idRenderMatrix::Inverse( ssaoConstants.matViewToWorld, ssaoConstants.matWorldToView );
// SRS end
ssaoConstants.clipToView = idVec2(
viewDef->projectionMatrix[2 * 4 + 3] / viewDef->projectionMatrix[0 * 4 + 0],
viewDef->projectionMatrix[2 * 4 + 3] / viewDef->projectionMatrix[1 * 4 + 1] );
ssaoConstants.invQuantizedGbufferSize = 1.f / m_QuantizedGbufferTextureSize;
ssaoConstants.quantizedViewportOrigin = idVec2i( quarterResExtent.minX, quarterResExtent.minY ) * 4;
ssaoConstants.amount = params.amount;
ssaoConstants.invBackgroundViewDepth = ( params.backgroundViewDepth > 0.f ) ? 1.f / params.backgroundViewDepth : 0.f;
ssaoConstants.radiusWorld = params.radiusWorld;
ssaoConstants.surfaceBias = params.surfaceBias;
ssaoConstants.radiusToScreen = 0.5f * viewDef->viewport.GetHeight() * abs( viewDef->projectionMatrix[1 * 4 + 1] );
ssaoConstants.powerExponent = params.powerExponent;
commandList->writeBuffer( m_ConstantBuffer, &ssaoConstants, sizeof( ssaoConstants ) );
// SRS - after writing constant buffer, compute ssao for 3d views only
if( viewDef->viewEntitys && !viewDef->is2Dgui )
{
nvrhi::Rect viewExtent( viewDef->viewport.x1, viewDef->viewport.x2, viewDef->viewport.y1, viewDef->viewport.y2 );
nvrhi::Rect quarterResExtent = viewExtent;
quarterResExtent.minX /= 4;
quarterResExtent.minY /= 4;
quarterResExtent.maxX = ( quarterResExtent.maxX + 3 ) / 4;
quarterResExtent.maxY = ( quarterResExtent.maxY + 3 ) / 4;
SsaoConstants ssaoConstants = {};
ssaoConstants.viewportOrigin = idVec2( viewDef->viewport.x1, viewDef->viewport.y1 );
ssaoConstants.viewportSize = idVec2( viewDef->viewport.GetWidth(), viewDef->viewport.GetHeight() );
ssaoConstants.matClipToView = viewDef->unprojectionToCameraRenderMatrix;
// SRS - FIXME: These transformations need to be verified
// RB: TODO: only need for DIRECTIONAL_OCCLUSION
//ssaoConstants.matViewToWorld = viewDef->worldSpace;
//idRenderMatrix::Inverse( ssaoConstants.matViewToWorld, ssaoConstants.matWorldToView );
// SRS end
float projectionMatrix[16];
//R_MatrixTranspose( viewDef->projectionMatrix, projectionMatrix );
memcpy( projectionMatrix, viewDef->projectionMatrix, 16 * 4 );
ssaoConstants.clipToView = idVec2(
projectionMatrix[2 * 4 + 3] / projectionMatrix[0 * 4 + 0],
projectionMatrix[2 * 4 + 3] / projectionMatrix[1 * 4 + 1] );
ssaoConstants.invQuantizedGbufferSize = 1.f / m_QuantizedGbufferTextureSize;
ssaoConstants.quantizedViewportOrigin = idVec2i( quarterResExtent.minX, quarterResExtent.minY ) * 4;
ssaoConstants.amount = r_ssaoAmount.GetFloat();
ssaoConstants.invBackgroundViewDepth = ( r_ssaoBackgroundViewDepth.GetFloat() > 0.f ) ? 1.f / r_ssaoBackgroundViewDepth.GetFloat() : 0.f;
ssaoConstants.radiusWorld = r_ssaoRadiusWorld.GetFloat();
ssaoConstants.surfaceBias = r_ssaoSurfaceBias.GetFloat();
ssaoConstants.powerExponent = r_ssaoPowerExponent.GetFloat();
ssaoConstants.radiusToScreen = 0.5f * viewDef->viewport.GetHeight() * abs( viewDef->projectionMatrix[1 * 4 + 1] );
commandList->writeBuffer( m_ConstantBuffer, &ssaoConstants, sizeof( ssaoConstants ) );
uint32_t dispatchWidth = ( quarterResExtent.width() + 7 ) / 8;
uint32_t dispatchHeight = ( quarterResExtent.height() + 7 ) / 8;
@ -295,6 +300,4 @@ void SsaoPass::Render(
commandList->setComputeState( state );
commandList->dispatch( dispatchWidth, dispatchHeight, 1 );
}
commandList->endMarker();
}

View file

@ -1,33 +1,28 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef RENDERER_PASSES_SSAOPASS_H_
#define RENDERER_PASSES_SSAOPASS_H_
/*
struct SsaoParameters
{
float amount = 2.f;
@ -38,6 +33,7 @@ struct SsaoParameters
bool enableBlur = true;
float blurSharpness = 16.f;
};
*/
class SsaoPass
{
@ -92,7 +88,6 @@ public:
void Render(
nvrhi::ICommandList* commandList,
const SsaoParameters& params,
const viewDef_t* viewDef,
int bindingSetIndex = 0 );
};

View file

@ -6148,7 +6148,7 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef
if( r_ssaoFiltering.GetBool() )
{
float jitterTexScale[4];
#if defined( USE_NVRHI )
commandList->clearTextureFloat( globalImages->ambientOcclusionImage[1]->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 1.f ) );
#endif
@ -6240,15 +6240,14 @@ NVRHI SSAO using compute shaders.
*/
void idRenderBackend::DrawScreenSpaceAmbientOcclusion2( const viewDef_t* _viewDef, bool downModulateScreen )
{
// SRS - run ssao pass on 3d + 2d overlay views to avoid flickering, skip for 2d-only views (menu & pda)
if( ( !_viewDef->viewEntitys || _viewDef->is2Dgui ) && !drawView3D )
if( !r_useSSAO.GetBool() )
{
// 3D views only
return;
}
if( !r_useSSAO.GetBool() )
if( !_viewDef->viewEntitys || _viewDef->is2Dgui )
{
// 3D views only
return;
}
@ -6264,12 +6263,11 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion2( const viewDef_t* _viewDe
}
renderLog.OpenMainBlock( MRB_SSAO_PASS );
renderLog.OpenBlock( "Render_NewSSAO", colorBlue );
renderLog.OpenBlock( "Render_SSAO2", colorBlue );
commandList->clearTextureFloat( globalImages->ambientOcclusionImage[0]->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 1.f ) );
SsaoParameters ssaoParams = {};
ssaoPass->Render( commandList, ssaoParams, _viewDef, 0 );
ssaoPass->Render( commandList, _viewDef, 0 );
renderLog.CloseBlock();
renderLog.CloseMainBlock();

View file

@ -57,8 +57,7 @@
#define MIN_MIP_LEVEL 0
static const float DOOM_TO_METERS = 0.0254; // doom to meters
static const float METERS_TO_DOOM = ( 1.0 / DOOM_TO_METERS ); // meters to doom
/** Used for preventing AO computation on the sky (at infinite depth) and defining the CS Z to bilateral depth key scaling.
This need not match the real far plane but should not be much more than it.*/

View file

@ -177,7 +177,7 @@ void main( uint2 groupId : SV_GroupID, uint2 threadId : SV_GroupThreadID, uint2
int2 storePos = int2( globalId.xy ) + g_Ssao.quantizedViewportOrigin;
float2 storePosF = float2( storePos );
if (all(storePosF >= g_Ssao.viewportOrigin.xy) && all(storePosF < g_Ssao.viewportOrigin.xy + g_Ssao.viewportSize.xy))
if( all( storePosF >= g_Ssao.viewportOrigin.xy ) && all( storePosF < g_Ssao.viewportOrigin.xy + g_Ssao.viewportSize.xy ) )
{
u_RenderTarget[storePos] = totalOcclusion;
}

View file

@ -182,6 +182,7 @@ float2 WindowToClip( float2 windowPos )
float2 windowToClipScale = 1.f / clipToWindowScale;
float2 windowToClipBias = -clipToWindowBias * windowToClipScale;
// TODO add pixelOffset for TAA
return windowPos.xy * windowToClipScale + windowToClipBias;
}
@ -206,7 +207,8 @@ void main( uint3 globalId : SV_DispatchThreadID )
float3 pixelNormal = t_Normals[pixelPos].xyz;
#endif
pixelNormal = normalize(mul(float4(pixelNormal, 0), g_Ssao.matWorldToView).xyz);
// RB: pixelNormal is already in view space
//pixelNormal = normalize( mul( float4( pixelNormal, 0 ), g_Ssao.matWorldToView ).xyz );
float2 pixelClipPos = WindowToClip( pixelPos );
float3 pixelViewPos = ViewDepthToViewPos( pixelClipPos.xy, pixelViewDepth );
@ -269,7 +271,7 @@ void main( uint3 globalId : SV_DispatchThreadID )
float directionalLength = length( result.xyz );
if( directionalLength > 0 )
{
result.xyz = mul(float4(normalize(result.xyz), 0), g_Ssao.matViewToWorld).xyz * directionalLength;
result.xyz = mul( float4( normalize( result.xyz ), 0 ), g_Ssao.matViewToWorld ).xyz * directionalLength;
}
#endif

View file

@ -75,7 +75,8 @@ void main( uint3 globalId : SV_DispatchThreadID )
float linearDepth = depth;
#else
float4 clipPos = float4( 0, 0, depth, 1 );
float4 viewPos = mul(clipPos, g_Ssao.matClipToView);
//float4 clipPos = float4( 0, 0, depth * 2.0 - 1.0, 1 );
float4 viewPos = mul( clipPos, g_Ssao.matClipToView );
float linearDepth = viewPos.z / viewPos.w;
#endif

View file

@ -43,9 +43,6 @@
#define MIN_MIP_LEVEL 0
static const float DOOM_TO_METERS = 0.0254; // doom to meters
static const float METERS_TO_DOOM = ( 1.0 / DOOM_TO_METERS ); // meters to doom
/** Used for preventing AO computation on the sky (at infinite depth) and defining the CS Z to bilateral depth key scaling.
This need not match the real far plane but should not be much more than it.*/
static const float FAR_PLANE_Z = -4000.0;

View file

@ -165,6 +165,9 @@ static float dot4( float2 a, float4 b )
// RB: the golden ratio is useful to animate Blue noise
#define c_goldenRatioConjugate 0.61803398875
static const float DOOM_TO_METERS = 0.0254; // doom to meters
static const float METERS_TO_DOOM = ( 1.0 / DOOM_TO_METERS ); // meters to doom
// ----------------------
// sRGB <-> Linear RGB Color Conversion
// ----------------------
@ -495,77 +498,4 @@ float3 Hash33( float3 p3 )
return frac( ( p3.xxy + p3.yxx ) * p3.zyx );
}
/*
static float3 DitherRGB( float3 color, float2 uvSeed, float quantSteps )
{
// uniform noise
//float3 noise = Hash33( float3( uvSeed, rpJitterTexOffset.w ) );
//float3 noise = float3( InterleavedGradientNoise( uvSeed ) );
float3 noise = _float3( InterleavedGradientNoiseAnim( uvSeed, rpJitterTexOffset.w ) );
// triangular noise [-0.5;1.5[
#if 1
noise.x = RemapNoiseTriErp( noise.x );
noise = noise * 2.0 - 0.5;
#endif
noise = _float3( noise.x );
// quantize/truncate color and dither the result
//float scale = exp2( float( TARGET_BITS ) ) - 1.0;
// lets assume 2^3 bits = 8
//float scale = 7.0;
//const float quantSteps = 8.0;
float scale = quantSteps - 1.0;
// apply dither
color += noise / ( quantSteps );
color = floor( color * scale ) / scale;
//float3 color = c + whiteNoise / 255.0;
return color;
}
*/
/*
static float3 DitherChromaticBlueNoise( float3 color, float2 n, SamplerState blueTex )
{
// uniform noise
//float3 noise = Hash33( float3( n, rpJitterTexOffset.w ) );
//float3 noise = float3( InterleavedGradientNoise( n ) );
//float3 noise = float3( InterleavedGradientNoiseAnim( n, rpJitterTexOffset.w ) );
// uv is screen position / sizeof blue noise image
float2 uv = n.xy * rpJitterTexOffset.xy;
float3 noise = tex2D( blueTex, uv ).rgb;
// rpJitterTexOffset.w is frameTime % 64
noise = frac( noise + c_goldenRatioConjugate * rpJitterTexOffset.w );
// triangular noise [-0.5;1.5[
noise.x = RemapNoiseTriErp( noise.x );
noise = noise * 2.0 - 0.5;
//noise = float3( noise.x );
// quantize/truncate color and dither the result
//float scale = exp2( float( TARGET_BITS ) ) - 1.0;
// lets assume 2^3 bits = 8
float quantSteps = 255.0;
//float3 color = floor( c * scale + noise ) / scale;
color = floor( 0.5 + color * quantSteps - 0.5 + noise ) * ( 1.0 / ( quantSteps - 1.0 ) );
return color;
}
*/
#define SMAA_RT_METRICS float4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)