fix(theme): centre the nudge that recovers the screen size - #25
Merged
Conversation
Every marker sits at floor(screen / 2) + offset, and screen is not known but recovered: the shader divides 2 by the projection matrix's first term and takes a ceiling, minus a nudge for the round trip through float. Get that nudge wrong and every themed screen is a pixel out at some resolutions and correct at others, which is a bug found by a player rather than by us. The bound turns out to be two-sided, and that is what makes the value non-obvious. A round trip that comes back high needs the nudge to exceed the error, or the ceiling jumps a whole pixel. One that comes back low needs the nudge to stay a pixel clear of 1.0, or a real width is rounded away. So the safe range is [error, 1 - error], and the value that survives the widest displays is the middle of it. It was 0.001. Legal, but sitting against the floor: the measured error peaks at 4.9e-4 near width 5837 and grows with the width, so it held a factor of two and would have failed on a display twice as wide. Half holds a factor of a thousand and costs nothing. This came out of trying to falsify the new test. Perturbing the nudge to 0.5 did not make it fail — because 0.5 was also correct, which is what a one-sided assertion could not tell me. The test asserts both ends now, and 0.0001 and 0.999 each break it. The arithmetic is checked without a GPU because it is the one part of a shader that is not GPU-specific: GLSL's highp float and the JVM's Float are both binary32, so the recovery is replayed over every width the client can produce, and the epsilon is read out of the shipped shader rather than repeated so a change there cannot pass by being invisible.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every marker sits at
floor(screen / 2) + offset, andscreenis recovered from the projection matrix rather than known. Wrong by one, and every themed screen is a pixel out at some resolutions and fine at others — found by a player, not by us. This was the one Phase 2 item from the architecture plan still untouched.The bound is two-sided, which is what makes the value non-obvious:
Safe range is
[error, 1 - error]; the value that survives the widest displays is the middle of it.It was
0.001— legal, but against the floor. Measured, the error peaks at 4.9e-4 near width 5837 and grows with width, so it held a factor of two and would have failed on a display twice as wide.0.5holds a factor of a thousand and costs nothing.This came out of failing to falsify the test. Perturbing the nudge to 0.5 did not break it, because 0.5 was also correct — which a one-sided assertion could not tell me. Both ends are asserted now;
0.0001and0.999each break it.Checked without a GPU because this is the one part of a shader that is not GPU-specific: GLSL
highp floatand JVMFloatare both binary32. The recovery is replayed over every width 1..8192, and the epsilon is read out of the shipped shader so a change there cannot pass by being invisible to the test.143 tests, 0 failures.