OverviewFilesCommitsIssuesDocsReleasesPeers

ifsrenderer-linux / blender / test_viewport_resolution.py

69 lines · python ref:
"""
Proves the viewport overlay actually reaches 1:1.

The internal render resolution is divided down while the camera moves, because every
frame throws its samples away and one dispatch has to cover the whole image. The
comment said full resolution returned once the view settled. It did not: the settled
tier was DIVISOR 2, so the overlay was permanently half resolution per axis - a
quarter of the pixels - scaled up. That was the ceiling on how sharp it could look,
and it coarsened the depth texture too, which is why occlusion edges were blocky.

Nothing caught it because the code was self-consistent and only the comment was
wrong, and a permanently soft overlay looks like a design choice rather than a bug.
So this asserts the property the comment claims, not the constants themselves.

Runs inside Blender (ifs_viewport imports bpy and gpu):
    blender -b --factory-startup -noaudio --python blender/test_viewport_resolution.py
"""

import os
import sys
import unittest

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))


class ViewportResolution(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        try:
            import ifs_viewport
        except ImportError as ex:
            raise unittest.SkipTest(f"needs Blender's bpy/gpu modules ({ex})")
        cls.Session = ifs_viewport.Session

    def test_a_settled_view_eventually_renders_at_full_resolution(self):
        """The whole point: without this the overlay can never be sharper than half."""
        self.assertEqual(1, self.Session.divisor_for(10_000),
                         "a long-settled view still renders below 1:1, so the overlay "
                         "is permanently softer than the screen")

    def test_motion_is_coarser_than_rest(self):
        """The coarse tier is what keeps mouselook readable; losing it is also a bug."""
        moving = self.Session.divisor_for(0)
        settled = self.Session.divisor_for(10_000)
        self.assertGreater(moving, settled)

    def test_resolution_never_gets_coarser_as_the_view_settles(self):
        """
        Monotonic by frame count. A non-monotonic schedule would resize - and so throw
        away the accumulation - repeatedly while the user sits still.
        """
        divisors = [self.Session.divisor_for(n) for n in range(0, 200)]
        for earlier, later in zip(divisors, divisors[1:]):
            self.assertLessEqual(later, earlier,
                                 "the divisor increased as the view settled")

    def test_it_steps_rather_than_jumping_straight_to_full(self):
        """
        The middle tier gives a readable image within a few frames of stopping;
        jumping straight to 1:1 leaves a long noisy period instead.
        """
        seen = {self.Session.divisor_for(n) for n in range(0, 200)}
        self.assertGreaterEqual(len(seen), 3,
                                f"expected a stepped schedule, got tiers {sorted(seen)}")


if __name__ == "__main__":
    unittest.main(argv=sys.argv[:1], exit=False, verbosity=2)