mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 00:01:49 +02:00
Fixes for static movement and RR.
This commit is contained in:
@@ -660,6 +660,7 @@ enum PipelineMode
|
||||
static void QD3D12_FlushQueuedBatches();
|
||||
static PipelineMode PickPipeline(bool useTex0, bool useTex1);
|
||||
static Mat4 CurrentMVP();
|
||||
static Mat4 QD3D12_ProjectionWithoutAutomaticJitter(const Mat4& projection);
|
||||
|
||||
struct RetiredResource
|
||||
{
|
||||
@@ -2189,7 +2190,9 @@ static bool QD3D12_UpdateCameraInfoFromCurrentMatrices()
|
||||
if (g_gl.projStack.empty() || g_gl.modelStack.empty())
|
||||
return false;
|
||||
|
||||
const float* glProjection = g_gl.projStack.back().m;
|
||||
const Mat4 unjitteredProjection = QD3D12_ProjectionWithoutAutomaticJitter(g_gl.projStack.back());
|
||||
const float* glProjection = unjitteredProjection.m;
|
||||
const float* rasterProjection = g_gl.projStack.back().m;
|
||||
const float* modelView = g_gl.modelStack.back().m;
|
||||
const float* modelToWorld = g_gl.modelMatrix.m;
|
||||
const UINT renderWidth = g_currentWindow ? g_currentWindow->renderWidth : 0;
|
||||
@@ -2201,7 +2204,7 @@ static bool QD3D12_UpdateCameraInfoFromCurrentMatrices()
|
||||
g_qd3d12AutoCamera.cachedRenderWidth == renderWidth &&
|
||||
g_qd3d12AutoCamera.cachedRenderHeight == renderHeight &&
|
||||
g_gl.cameraState.valid &&
|
||||
memcmp(g_qd3d12AutoCamera.cachedProjection, glProjection, sizeof(g_qd3d12AutoCamera.cachedProjection)) == 0 &&
|
||||
memcmp(g_qd3d12AutoCamera.cachedProjection, rasterProjection, sizeof(g_qd3d12AutoCamera.cachedProjection)) == 0 &&
|
||||
memcmp(g_qd3d12AutoCamera.cachedModelView, modelView, sizeof(g_qd3d12AutoCamera.cachedModelView)) == 0 &&
|
||||
memcmp(g_qd3d12AutoCamera.cachedModelToWorld, modelToWorld, sizeof(g_qd3d12AutoCamera.cachedModelToWorld)) == 0)
|
||||
{
|
||||
@@ -2331,7 +2334,7 @@ static bool QD3D12_UpdateCameraInfoFromCurrentMatrices()
|
||||
g_qd3d12AutoCamera.cachedMotionHistoryReset = g_gl.motionHistoryReset;
|
||||
g_qd3d12AutoCamera.cachedRenderWidth = renderWidth;
|
||||
g_qd3d12AutoCamera.cachedRenderHeight = renderHeight;
|
||||
QD3D12_MatrixCopy(g_qd3d12AutoCamera.cachedProjection, glProjection);
|
||||
QD3D12_MatrixCopy(g_qd3d12AutoCamera.cachedProjection, rasterProjection);
|
||||
QD3D12_MatrixCopy(g_qd3d12AutoCamera.cachedModelView, modelView);
|
||||
QD3D12_MatrixCopy(g_qd3d12AutoCamera.cachedModelToWorld, modelToWorld);
|
||||
return true;
|
||||
@@ -8586,7 +8589,7 @@ static sl::Result QD3D12_SetStreamlineCommonConstants(sl::FrameToken& frameToken
|
||||
memcpy(&consts.clipToCameraView, g_gl.cameraState.clipToView.m, sizeof(float) * 16);
|
||||
memcpy(&consts.clipToPrevClip, g_gl.cameraState.clipToPrevClip.m, sizeof(float) * 16);
|
||||
memcpy(&consts.prevClipToClip, g_gl.cameraState.prevClipToClip.m, sizeof(float) * 16);
|
||||
consts.jitterOffset = { g_gl.jitterX, g_gl.jitterY };
|
||||
consts.jitterOffset = { -g_gl.jitterX, -g_gl.jitterY };
|
||||
// The G-buffer stores motion as previous UV minus current UV after removing
|
||||
// projection jitter, so it is already in normalized screen space.
|
||||
consts.mvecScale = { 1.0f, 1.0f };
|
||||
@@ -8959,6 +8962,74 @@ static void QD3D12_ConfigureDLSSFrameGeneration(QD3D12Window&, void*) {}
|
||||
static void QD3D12_LogDLSSFrameGenerationPresentResult() {}
|
||||
#endif
|
||||
|
||||
static float QD3D12_Halton(uint32_t index, uint32_t base)
|
||||
{
|
||||
float result = 0.0f;
|
||||
float fraction = 1.0f / (float)base;
|
||||
while (index > 0u)
|
||||
{
|
||||
result += (float)(index % base) * fraction;
|
||||
index /= base;
|
||||
fraction /= (float)base;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool QD3D12_ShouldUseAutomaticProjectionJitter(const QD3D12Window& w)
|
||||
{
|
||||
return !w.isPbuffer &&
|
||||
QD3D12_AllowsGamePresentationFeatures(w) &&
|
||||
g_gl.upscalerBackend == QD3D12_UPSCALER_DLSS &&
|
||||
QD3D12_WantsDLSSRayReconstruction();
|
||||
}
|
||||
|
||||
static void QD3D12_UpdateAutomaticProjectionJitter(QD3D12Window& w)
|
||||
{
|
||||
if (!QD3D12_ShouldUseAutomaticProjectionJitter(w))
|
||||
{
|
||||
g_gl.jitterX = 0.0f;
|
||||
g_gl.jitterY = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t jitterIndex = (uint32_t)(g_gl.frameSerial % 8u) + 1u;
|
||||
constexpr float kRRMicroJitterPixels = 0.18f;
|
||||
g_gl.jitterX = (QD3D12_Halton(jitterIndex, 2u) - 0.5f) * kRRMicroJitterPixels;
|
||||
g_gl.jitterY = (QD3D12_Halton(jitterIndex, 3u) - 0.5f) * kRRMicroJitterPixels;
|
||||
}
|
||||
|
||||
static void QD3D12_ApplyAutomaticProjectionJitter(Mat4& projection)
|
||||
{
|
||||
if (!g_currentWindow || g_gl.matrixMode != GL_PROJECTION)
|
||||
return;
|
||||
if (fabsf(g_gl.jitterX) <= 1.0e-6f && fabsf(g_gl.jitterY) <= 1.0e-6f)
|
||||
return;
|
||||
if (!QD3D12_IsPerspectiveProjectionCM(projection.m))
|
||||
return;
|
||||
|
||||
const float renderWidth = (float)std::max<UINT>(1u, g_currentWindow->renderWidth);
|
||||
const float renderHeight = (float)std::max<UINT>(1u, g_currentWindow->renderHeight);
|
||||
projection.m[8] += (2.0f * g_gl.jitterX) / renderWidth;
|
||||
projection.m[9] += (2.0f * g_gl.jitterY) / renderHeight;
|
||||
}
|
||||
|
||||
static Mat4 QD3D12_ProjectionWithoutAutomaticJitter(const Mat4& projection)
|
||||
{
|
||||
Mat4 unjittered = projection;
|
||||
if (!g_currentWindow)
|
||||
return unjittered;
|
||||
if (fabsf(g_gl.jitterX) <= 1.0e-6f && fabsf(g_gl.jitterY) <= 1.0e-6f)
|
||||
return unjittered;
|
||||
if (!QD3D12_IsPerspectiveProjectionCM(unjittered.m))
|
||||
return unjittered;
|
||||
|
||||
const float renderWidth = (float)std::max<UINT>(1u, g_currentWindow->renderWidth);
|
||||
const float renderHeight = (float)std::max<UINT>(1u, g_currentWindow->renderHeight);
|
||||
unjittered.m[8] -= (2.0f * g_gl.jitterX) / renderWidth;
|
||||
unjittered.m[9] -= (2.0f * g_gl.jitterY) / renderHeight;
|
||||
return unjittered;
|
||||
}
|
||||
|
||||
#if defined(QD3D12_ENABLE_FFX)
|
||||
struct QD3D12FfxState
|
||||
{
|
||||
@@ -12348,6 +12419,7 @@ void QD3D12_BeginFrame()
|
||||
g_gl.deferScreenSpaceParticlesToEndFrame = false;
|
||||
g_gl.deferredScreenSpaceParticleTlas.Reset();
|
||||
QD3D12_UpdateViewportState();
|
||||
QD3D12_UpdateAutomaticProjectionJitter(w);
|
||||
|
||||
FrameResources& fr = w.frames[w.frameIndex];
|
||||
QD3D12_CHECK(fr.cmdAlloc->Reset());
|
||||
@@ -15656,6 +15728,7 @@ void APIENTRY glLoadMatrixf(const GLfloat* m)
|
||||
|
||||
auto& top = QD3D12_CurrentMatrixStack().back();
|
||||
memcpy(top.m, m, sizeof(top.m));
|
||||
QD3D12_ApplyAutomaticProjectionJitter(top);
|
||||
}
|
||||
|
||||
void APIENTRY glGetIntegerv(GLenum pname, GLint* params)
|
||||
@@ -15970,6 +16043,7 @@ void APIENTRY glFrustum(GLdouble left, GLdouble right,
|
||||
|
||||
auto& topMat = QD3D12_CurrentMatrixStack().back();
|
||||
topMat = Mat4::Multiply(topMat, proj);
|
||||
QD3D12_ApplyAutomaticProjectionJitter(topMat);
|
||||
}
|
||||
|
||||
void APIENTRY glDepthFunc(GLenum func)
|
||||
|
||||
@@ -3689,6 +3689,12 @@ float2 Rand2(inout uint rng)
|
||||
return float2(Rand(rng), Rand(rng));
|
||||
}
|
||||
|
||||
float2 RayReconstructionTemporalDisk(uint2 pixel, uint sampleIndex, float radius)
|
||||
{
|
||||
uint rng = InitRng(pixel, gFrameIndex, sampleIndex);
|
||||
return ConcentricSampleDisk(Rand2(rng)) * radius;
|
||||
}
|
||||
|
||||
float3 SampleCosineWorld(float3 N, inout uint rng)
|
||||
{
|
||||
float3 tangent, bitangent;
|
||||
@@ -3953,6 +3959,8 @@ float3 PathTraceDirectPointLight(uint2 pixel, float3 worldPos, float3 N, float3
|
||||
// Use a deterministic low-discrepancy pattern instead. With a single sample,
|
||||
// use the light center so default point lights are hard-shadowed and stable.
|
||||
float areaRadius = (sampleCount > 1u && Lgt.samples > 1u) ? max(GetPointLightMaxRadius(Lgt) * 0.03, 0.12) : 0.0;
|
||||
if (gEnableDenoiser == 0u && Lgt.samples != 0u)
|
||||
areaRadius = max(areaRadius, min(max(GetPointLightMaxRadius(Lgt) * 0.006, 0.04), 1.25));
|
||||
float rand = Hash12((float2)pixel + worldPos.xy + float2(worldPos.z, centerDist));
|
||||
|
||||
float3 diffuseAccum = 0.0;
|
||||
@@ -3962,7 +3970,9 @@ float3 PathTraceDirectPointLight(uint2 pixel, float3 worldPos, float3 N, float3
|
||||
for (uint s = 0u; s < sampleCount; ++s)
|
||||
{
|
||||
float2 disk = float2(0.0, 0.0);
|
||||
if (areaRadius > 0.0)
|
||||
if (areaRadius > 0.0 && gEnableDenoiser == 0u)
|
||||
disk = RayReconstructionTemporalDisk(pixel, 0xA11E00u + s, areaRadius);
|
||||
else if (areaRadius > 0.0)
|
||||
disk = ConcentricSampleDisk(Hammersley2D(s, sampleCount, rand)) * areaRadius;
|
||||
|
||||
float3 sampleLightPos = Lgt.position + tangent * disk.x + bitangent * disk.y;
|
||||
@@ -4039,6 +4049,8 @@ float3 PathTraceDirectRectLight(uint2 pixel, float3 worldPos, float3 N, float3 V
|
||||
for (uint s = 0u; s < sampleCount; ++s)
|
||||
{
|
||||
float2 uv = StableRectLightSampleUV(s, sampleCount);
|
||||
if (gEnableDenoiser == 0u)
|
||||
uv = clamp(uv + RayReconstructionTemporalDisk(pixel, 0xEC7000u + s, 0.18), -0.85, 0.85);
|
||||
|
||||
float3 sampleLightPos =
|
||||
Lgt.position +
|
||||
@@ -4178,10 +4190,12 @@ float3 EstimateSingleLightVolumetricScattering(uint2 pixel, float3 cameraPos, fl
|
||||
stepCount = min(max(stepCount, 8u), 32u);
|
||||
float stepLen = viewDist / (float)stepCount;
|
||||
|
||||
// Do not frame-jitter the march. This renderer has no temporal GI history,
|
||||
// so varying the volume sample positions every frame creates visible sparkle.
|
||||
// A centered deterministic slice is stable and the spatial denoiser can smooth it.
|
||||
float jitter = 0.5;
|
||||
if (gEnableDenoiser == 0u)
|
||||
{
|
||||
uint jitterRng = InitRng(pixel, gFrameIndex, 0x701u);
|
||||
jitter = lerp(0.42, 0.58, Rand(jitterRng));
|
||||
}
|
||||
|
||||
float density = EstimateVolumeDensityFromLight(Lgt);
|
||||
float anisotropy = (Lgt.type == GL_RAYTRACING_LIGHT_TYPE_SPOT) ? 0.55 : 0.35;
|
||||
|
||||
Reference in New Issue
Block a user