Reject cross-surface temporal motion dilation

This commit is contained in:
Emil
2026-09-24 02:57:25 +03:00
parent 3a4a262750
commit 7c88356fb4
2 changed files with 13 additions and 3 deletions
+7 -3
View File
@@ -86,9 +86,11 @@ TemporalReferenceResult temporal_reference_resolve(const TemporalReferenceFrame&
if (!previous || !valid_motion(center))
continue;
// Dilate the nearest opaque depth's motion at a silhouette, but
// never resurrect a center pixel with no previous transform.
// Dilate from the nearest compatible depth at a silhouette, but
// never borrow foreground motion for newly exposed background or
// resurrect a center pixel with no previous transform.
const TemporalReferencePixel* selected = &center;
const float current_depth_tolerance = .002f + .01f * center.depth;
const auto min_y = y ? y - 1 : y;
const auto min_x = x ? x - 1 : x;
const auto max_y = std::min(y + 1, current.height - 1);
@@ -96,7 +98,9 @@ TemporalReferenceResult temporal_reference_resolve(const TemporalReferenceFrame&
for (auto sy = min_y; sy <= max_y; ++sy)
for (auto sx = min_x; sx <= max_x; ++sx) {
const auto& candidate = current.pixels[std::size_t(sy) * current.width + sx];
if (valid_motion(candidate) && candidate.depth < selected->depth)
if (valid_motion(candidate) &&
std::abs(candidate.depth - center.depth) <=
current_depth_tolerance && candidate.depth < selected->depth)
selected = &candidate;
}
const float u = (static_cast<float>(x) + .5f) / current.width - selected->motion[0];
@@ -142,6 +142,12 @@ void nearest_depth_motion_dilation() {
prior.depth[4] = .1f; // Undilated center motion would fail this depth check.
prior.depth[3] = .2f;
prior.color[3] = {.1f, .1f, .1f, 1};
const auto exposed_background = temporal_reference_resolve(frame, &prior);
require(!exposed_background.accepted[4] &&
exposed_background.history.color[4] == frame.pixels[4].color,
"A newly exposed deep background pixel must not borrow foreground motion");
frame.pixels[4].depth = .203f;
frame.pixels[4].previous_depth = .203f;
const auto dilated = temporal_reference_resolve(frame, &prior);
require(dilated.accepted[4] && dilated.history.color[4][0] < .5f,
"Nearest-depth foreground motion should fill a valid silhouette pixel");