From a22f449ecde800e98249c847aa384bc1a66a0ade Mon Sep 17 00:00:00 2001 From: Wls50 Date: Mon, 24 Nov 2025 21:22:19 +0100 Subject: [PATCH] fix gtao glitches; add timer to measure animation phase --- Timer.h | 1 + betterRenderer/renderer/source/XeGTAO.h | 12 ++--- betterRenderer/renderer/source/nvrenderer.cpp | 2 + betterRenderer/renderer/source/ssao.cpp | 48 ++++++++++++++++--- betterRenderer/renderer/source/ssao.h | 9 +++- .../renderer/source/track_batching.cpp | 3 ++ betterRenderer/shaders/XeGTAO/GTAO.hlsl | 1 + betterRenderer/shaders/XeGTAO/XeGTAO.hlsli | 9 ++-- betterRenderer/shaders/project.manul | 3 +- widgets/perfgraphs.cpp | 2 + widgets/perfgraphs.h | 2 + 11 files changed, 71 insertions(+), 21 deletions(-) diff --git a/Timer.h b/Timer.h index b0f1870d..5ac9cc3c 100644 --- a/Timer.h +++ b/Timer.h @@ -58,6 +58,7 @@ struct subsystem_stopwatches { stopwatch gfx_reflections; stopwatch gfx_swap; stopwatch gfx_gui; + stopwatch gfx_animate; stopwatch sim_total; stopwatch sim_dynamics; stopwatch sim_events; diff --git a/betterRenderer/renderer/source/XeGTAO.h b/betterRenderer/renderer/source/XeGTAO.h index 2abb5347..63caa4f6 100644 --- a/betterRenderer/renderer/source/XeGTAO.h +++ b/betterRenderer/renderer/source/XeGTAO.h @@ -161,21 +161,21 @@ namespace XeGTAO template inline T clamp( T const & v, T const & min, T const & max ) { assert( max >= min ); if( v < min ) return min; if( v > max ) return max; return v; } // If using TAA then set noiseIndex to frameIndex % 64 - otherwise use 0 - inline void GTAOUpdateConstants( XeGTAO::GTAOConstants& consts, int viewportWidth, int viewportHeight, const XeGTAO::GTAOSettings & settings, const float projMatrix[16], bool rowMajor, unsigned int frameCounter ) + inline void GTAOUpdateConstants( XeGTAO::GTAOConstants& consts, int viewportWidth, int viewportHeight, const XeGTAO::GTAOSettings & settings, const glm::mat4& projMatrix, bool rowMajor, unsigned int frameCounter ) { consts.ViewportSize = { viewportWidth, viewportHeight }; consts.ViewportPixelSize = { 1.0f / (float)viewportWidth, 1.0f / (float)viewportHeight }; - float depthLinearizeMul = (rowMajor)?(-projMatrix[3 * 4 + 2]):(-projMatrix[3 + 2 * 4]); // float depthLinearizeMul = ( clipFar * clipNear ) / ( clipFar - clipNear ); - float depthLinearizeAdd = (rowMajor)?( projMatrix[2 * 4 + 2]):( projMatrix[2 + 2 * 4]); // float depthLinearizeAdd = clipFar / ( clipFar - clipNear ); + float depthLinearizeMul = -projMatrix[3][2]; // float depthLinearizeMul = ( clipFar * clipNear ) / ( clipFar - clipNear ); + float depthLinearizeAdd = -projMatrix[2][2]; // float depthLinearizeAdd = clipFar / ( clipFar - clipNear ); // correct the handedness issue. need to make sure this below is correct, but I think it is. if( depthLinearizeMul * depthLinearizeAdd < 0 ) depthLinearizeAdd = -depthLinearizeAdd; - consts.DepthUnpackConsts = { -depthLinearizeMul, depthLinearizeAdd }; + consts.DepthUnpackConsts = { depthLinearizeMul, depthLinearizeAdd }; - float tanHalfFOVY = 1.0f / ((rowMajor)?(projMatrix[1 * 4 + 1]):(projMatrix[1 + 1 * 4])); // = tanf( drawContext.Camera.GetYFOV( ) * 0.5f ); - float tanHalfFOVX = 1.0F / ((rowMajor)?(projMatrix[0 * 4 + 0]):(projMatrix[0 + 0 * 4])); // = tanHalfFOVY * drawContext.Camera.GetAspect( ); + float tanHalfFOVY = 1.0f / projMatrix[1][1]; // = tanf( drawContext.Camera.GetYFOV( ) * 0.5f ); + float tanHalfFOVX = 1.0F / projMatrix[0][0]; // = tanHalfFOVY * drawContext.Camera.GetAspect( ); consts.CameraTanHalfFOV = { tanHalfFOVX, tanHalfFOVY }; consts.NDCToViewMul = { consts.CameraTanHalfFOV.x * 2.0f, consts.CameraTanHalfFOV.y * -2.0f }; diff --git a/betterRenderer/renderer/source/nvrenderer.cpp b/betterRenderer/renderer/source/nvrenderer.cpp index 283f7f4e..a7688b26 100644 --- a/betterRenderer/renderer/source/nvrenderer.cpp +++ b/betterRenderer/renderer/source/nvrenderer.cpp @@ -1321,6 +1321,8 @@ void NvRenderer::DebugUi() { ImGui::SameLine(); if (ImGui::Button("Bloom Config")) m_bloom->ShowGui(); ImGui::SameLine(); + m_ssao->OnGui(ImGui::Button("GTAO Config")); + ImGui::SameLine(); if (ImGui::Button("Take Screenshot")) MakeScreenshot(); } ImGui::End(); diff --git a/betterRenderer/renderer/source/ssao.cpp b/betterRenderer/renderer/source/ssao.cpp index b36db4ec..76c697b3 100644 --- a/betterRenderer/renderer/source/ssao.cpp +++ b/betterRenderer/renderer/source/ssao.cpp @@ -129,6 +129,27 @@ void NvSsao::Init() { .addBindingLayout(blPrefilterDepths)); } + { + BindingLayoutHandle blPrefilterDepths; + BindingSetDesc bsDescPrefilter = + BindingSetDesc() + .addItem(BindingSetItem::ConstantBuffer(0, m_constantBuffer)) + .addItem(BindingSetItem::Texture_SRV(0, m_gbuffer->m_gbuffer_depth)) + .addItem(BindingSetItem::Sampler(0, sampler_point)); + for (int i = 0; i < XE_GTAO_DEPTH_MIP_LEVELS; ++i) { + bsDescPrefilter.addItem( + BindingSetItem::Texture_UAV(i, m_workingDepths, Format::UNKNOWN, + TextureSubresourceSet(i, 1, 0, 1))); + } + utils::CreateBindingSetAndLayout(m_backend->GetDevice(), + ShaderType::Compute, 0, bsDescPrefilter, + blPrefilterDepths, m_BSPrefilterDepths); + m_PSOPrefilterDepths = m_backend->GetDevice()->createComputePipeline( + ComputePipelineDesc() + .setComputeShader(m_CSPrefilterDepths16x16) + .addBindingLayout(blPrefilterDepths)); + } + { BindingLayoutHandle blGTAO; utils::CreateBindingSetAndLayout( @@ -187,12 +208,8 @@ void NvSsao::Render(nvrhi::ICommandList* command_list, command_list->beginMarker("XeGTAO"); XeGTAO::GTAOConstants constants{}; - XeGTAO::GTAOSettings settings{}; - settings.QualityLevel = 2; - settings.Radius = 10.f; - settings.ThinOccluderCompensation = .7f; XeGTAO::GTAOUpdateConstants(constants, m_width, m_height, settings, - glm::value_ptr(projection), false, frame_index); + projection, false, frame_index); command_list->writeBuffer(m_constantBuffer, &constants, sizeof(constants)); { @@ -222,7 +239,7 @@ void NvSsao::Render(nvrhi::ICommandList* command_list, { command_list->beginMarker("Denoise Pass"); - int num_passes = 4; + int num_passes = settings.DenoisePasses; nvrhi::ITexture* ping = m_workingAOTerm; nvrhi::ITexture* pong = m_workingAOTermPong; for (int i = 0; i < num_passes; ++i) { @@ -260,3 +277,22 @@ void NvSsao::Render(nvrhi::ICommandList* command_list, } command_list->endMarker(); } + +void NvSsao::OnGui(bool const open_now) { + static bool open = false; + open |= open_now; + if(open && ImGui::Begin("GTAO Settings", &open)) { + ImGui::InputInt("Quality level", &settings.QualityLevel); + ImGui::InputInt("Denoise passes", &settings.DenoisePasses); + ImGui::InputFloat("Radius", &settings.Radius); + if(ImGui::CollapsingHeader("Advanced")) { + ImGui::InputFloat("Radius multiplier", &settings.RadiusMultiplier); + ImGui::InputFloat("Falloff range", &settings.FalloffRange); + ImGui::InputFloat("Sample distribution power", &settings.SampleDistributionPower); + ImGui::InputFloat("Thin occluder compensation", &settings.ThinOccluderCompensation); + ImGui::InputFloat("Final value power", &settings.FinalValuePower); + ImGui::InputFloat("Depth MIP sampling offset", &settings.DepthMIPSamplingOffset); + } + ImGui::End(); + } +} diff --git a/betterRenderer/renderer/source/ssao.h b/betterRenderer/renderer/source/ssao.h index 2bdd539c..e40460c9 100644 --- a/betterRenderer/renderer/source/ssao.h +++ b/betterRenderer/renderer/source/ssao.h @@ -1,15 +1,18 @@ #pragma once -#include +#include #include +#include -#include +#include "XeGTAO.h" struct NvSsao { NvSsao(class NvRenderer* renderer); void Init(); + XeGTAO::GTAOSettings settings{}; + class NvRendererBackend* m_backend; struct NvGbuffer* m_gbuffer; @@ -52,4 +55,6 @@ struct NvSsao { void Render(nvrhi::ICommandList* command_list, const glm::mat4& projection, size_t frame_index); + + void OnGui(bool open_now); }; \ No newline at end of file diff --git a/betterRenderer/renderer/source/track_batching.cpp b/betterRenderer/renderer/source/track_batching.cpp index f4ff2f02..946e4599 100644 --- a/betterRenderer/renderer/source/track_batching.cpp +++ b/betterRenderer/renderer/source/track_batching.cpp @@ -4,6 +4,7 @@ #include "nvrenderer/nvrenderer.h" #include "nvrendererbackend.h" +#include #include #include @@ -1057,6 +1058,7 @@ void NvRenderer::Render(const Renderable& renderable, const RenderPass& pass, void NvRenderer::Animate(const glm::dvec3& origin, double radius, uint64_t frame) { + Timer::subsystem.gfx_animate.start(); { auto motion_scope = m_motion_cache->SetInstance(nullptr); auto& motion_cache = m_motion_cache->Get(nullptr); @@ -1095,6 +1097,7 @@ void NvRenderer::Animate(const glm::dvec3& origin, double radius, if (!instance.m_animatable && instance.m_was_once_animated) return; Animate(instance, origin, frame); }); + Timer::subsystem.gfx_animate.stop(); } void NvRenderer::GatherSpotLights(const RenderPass& pass) { diff --git a/betterRenderer/shaders/XeGTAO/GTAO.hlsl b/betterRenderer/shaders/XeGTAO/GTAO.hlsl index 9a69f3fd..ffd8c3e4 100644 --- a/betterRenderer/shaders/XeGTAO/GTAO.hlsl +++ b/betterRenderer/shaders/XeGTAO/GTAO.hlsl @@ -54,6 +54,7 @@ SamplerState g_samplerPointClamp : register( s0 ); // Engine-specific normal map loader lpfloat3 LoadNormal( int2 pos ) { + return (float3)0.; #if 0 // special decoding for external normals stored in 11_11_10 unorm - modify appropriately to support your own encoding uint packedInput = g_srcNormalmap.Load( int3(pos, 0) ).x; diff --git a/betterRenderer/shaders/XeGTAO/XeGTAO.hlsli b/betterRenderer/shaders/XeGTAO/XeGTAO.hlsli index cfb9566e..3bea2518 100644 --- a/betterRenderer/shaders/XeGTAO/XeGTAO.hlsli +++ b/betterRenderer/shaders/XeGTAO/XeGTAO.hlsli @@ -111,11 +111,10 @@ float3 XeGTAO_ComputeViewspacePosition( const float2 screenPos, const float view float XeGTAO_ScreenSpaceToViewSpaceDepth( const float screenDepth, const GTAOConstants consts ) { - float depthLinearizeMul = consts.DepthUnpackConsts.x; - float depthLinearizeAdd = consts.DepthUnpackConsts.y; - // Optimised version of "-cameraClipNear / (cameraClipFar - projDepth * (cameraClipFar - cameraClipNear)) * cameraClipFar" - //return 2500. / (.1 - screenDepth * (.1 - 2500.)) * .1; - return depthLinearizeMul / (depthLinearizeAdd - screenDepth); + float depthLinearizeMul = consts.DepthUnpackConsts.x; + float depthLinearizeAdd = consts.DepthUnpackConsts.y; + // Optimised version of "-cameraClipNear / (cameraClipFar - projDepth * (cameraClipFar - cameraClipNear)) * cameraClipFar" + return depthLinearizeMul / (depthLinearizeAdd - screenDepth); } lpfloat4 XeGTAO_CalculateEdges( const lpfloat centerZ, const lpfloat leftZ, const lpfloat rightZ, const lpfloat topZ, const lpfloat bottomZ ) diff --git a/betterRenderer/shaders/project.manul b/betterRenderer/shaders/project.manul index d8964657..2eeae4bd 100644 --- a/betterRenderer/shaders/project.manul +++ b/betterRenderer/shaders/project.manul @@ -1,8 +1,6 @@ templates: # Partially pre-filled containers to avoid excessive copypasta XeGTAO: - # TODO Depth conversion is broken since converting to reversed depth buffer - # after attempting to fix it, it is still broken but with hardcoded values source: XeGTAO/GTAO target: compute definitions: # TODO (mostly) move to shader file I guess @@ -14,6 +12,7 @@ templates: XE_GTAO_USE_HALF_FLOAT_PRECISION: 0 VA_COMPILED_AS_SHADER_CODE: 1 VA_SATURATE: saturate + XE_GTAO_GENERATE_NORMALS_INPLACE: 1 envmap: source: envmap target: compute diff --git a/widgets/perfgraphs.cpp b/widgets/perfgraphs.cpp index 277f93f0..5d37a332 100644 --- a/widgets/perfgraphs.cpp +++ b/widgets/perfgraphs.cpp @@ -33,6 +33,8 @@ void perfgraph_panel::render_contents() { stopwatch = &Timer::subsystem.gfx_swap; else if (current_timer == gfx_gui) stopwatch = &Timer::subsystem.gfx_gui; + else if (current_timer == gfx_animate) + stopwatch = &Timer::subsystem.gfx_animate; else if (current_timer == sim_total) stopwatch = &Timer::subsystem.sim_total; else if (current_timer == sim_dynamics) diff --git a/widgets/perfgraphs.h b/widgets/perfgraphs.h index f00c554a..302a2e12 100644 --- a/widgets/perfgraphs.h +++ b/widgets/perfgraphs.h @@ -12,6 +12,7 @@ class perfgraph_panel : public ui_panel gfx_reflections, gfx_swap, gfx_gui, + gfx_animate, sim_total, sim_dynamics, sim_events, @@ -31,6 +32,7 @@ class perfgraph_panel : public ui_panel "gfx_reflections", "gfx_swap", "gfx_gui", + "gfx_animate", "sim_total", "sim_dynamics", "sim_events",