xemu icon indicating copy to clipboard operation
xemu copied to clipboard

nv2a: Offset vertices to match HW rounding

Open antangelo opened this issue 2 years ago • 9 comments

This is a continuation of the work done in #735 . Hardware will round vertices at 0.5625 instead of OpenGL's 0.5.

The approach taken in this PR shifts each vertex up and to the left by 0.0625, so that the HW rounding point 0.5625 is mapped to 0.5. A small bias is then added based on whether the subpixel was above or below the boundary, to correct for precision errors. This passes all but one of the test cases that abaire made (specifically, the projected adjacent geometry test with a bias of 0.5625 is not entirely matching HW), which is why I'm leaving it in draft for now.

This approach does not work at resolution scales higher than 1x. I'm not sure that there is a general solution that both works above 1x and does not introduce z-fighting or flickering.

Known Issues:

  • [ ] Morrowind Water

antangelo avatar Jan 22 '23 09:01 antangelo

tested on these titles at 1x, there are also no issues with the shadows being cut/clipped based on the camera angle:

SC:DA immagine

SC: immagine

Fabxx avatar Jan 22 '23 10:01 Fabxx

As an FYI, the place where I eventually got stuck was in Tiger Woods where a single screen uses a mix of the fixed function and programmable pipelines. The difference in the way that vertexes are unprojected leads to twinkling seams between polys that were rendered via dissimilar paths. I think my test cases were SC:DA (and/or Spongebob) and Tiger Woods 2005 during the course flyover sequence.

I think the ProjAdjacentGeometry test is the important one: https://github.com/abaire/nxdk_pgraph_tests/blob/main/src/tests/vertex_shader_rounding_tests.cpp#L710

abaire avatar Feb 25 '23 15:02 abaire

As an FYI, the place where I eventually got stuck was in Tiger Woods where a single screen uses a mix of the fixed function and programmable pipelines. The difference in the way that vertexes are unprojected leads to twinkling seams between polys that were rendered via dissimilar paths. I think my test cases were SC:DA (and/or Spongebob) and Tiger Woods 2005 during the course flyover sequence.

I think the ProjAdjacentGeometry test is the important one: https://github.com/abaire/nxdk_pgraph_tests/blob/main/src/tests/vertex_shader_rounding_tests.cpp#L710

Thanks for the context, I'll see about picking up Tiger Woods as another test case. The only ProjAdjacentGeometry test case that this code fails is the one with 0.5625 bias. What's interesting is that HW rounds the leftmost dark square off one pixel to the right, but not the other three. The behavior in this PR rounds all four of them off to the right.

xemuProjAdjacentGeometry_0 5625

antangelo avatar Feb 25 '23 21:02 antangelo

Hopefully it'll turn out that your fix is sufficient and I created the problem in Tiger Woods while chasing down other issues :)

I believe @Triticum0 found the issue w/ TW while testing my PR and can probably say definitively which version is problematic (though I suspect they used the same engine year after year so it might not matter). I'm away from my HW for an indeterminate amount of time and unfortunately I don't appear to have left a comment tracking the specific version I was testing, sorry!

abaire avatar Feb 26 '23 04:02 abaire

Can confirm this works with Splinter Cell: Double Agent, removing the blue/green lines at the top and left.

ajalberd avatar Feb 28 '23 23:02 ajalberd

There seem to be a few small artifacts with this PR vs master in tiger woods 2005 in the form of white dots that flash in and out.

https://user-images.githubusercontent.com/25046221/222288797-c8733fb8-1d6e-4a23-8ac9-cca5feb1a828.mp4

antangelo avatar Mar 01 '23 23:03 antangelo

There seem to be a few small artifacts with this PR vs master in tiger woods 2005 in the form of white dots that flash in and out.

Exactly, I believe that's the background color showing through the gaps caused by (presumably numerical precision induced) differences between the fixed and programmable pipelines.

Before I had to step back from this, I was beginning to consider simply merging the fixed and programmable paths by defining one or more static nv2a shaders to reproduce the fixed pipeline behavior. I hoped that would eliminate this issue and would reduce/remove the potential for other cases where behavior unintentionally ends up differing between the two paths.

abaire avatar Mar 02 '23 04:03 abaire

FWIW I get different results on HW than the gold results. Screenshot with only change being printing out the top-left x coordinate: ProjAdjacentGeometry_0 5625

If you're comparing to golden results, did you check your build of the xbe behaves the same on HW?

Also, games tend to add 0.03125 (1/32) to positions e.g. when Fable TLC draws bloom over the screen it generates positions like this:

v0 IN: (-1, -1), (1, -1), (-1, 1), ...
v0 after xbox VS program: (0.53125, 480.53125), (640.53125,  480.53125), (0.53125,  0.53125), ...

exactly halfway between 0.5 and the threshold 0.5625 (1/16). If they are meant to be at the pixel centre 0.5, maybe coordinates get floored to the nearest 1/16, rather than needing 1/16 subtracted?

NZJenkins avatar Apr 05 '24 12:04 NZJenkins

That's odd, the hardware I had been testing on matches the golden results. Your output is interesting because at a glance, the upper programmable pipeline squares round up along the y-axis and all fixed squares round down, but there are no gaps in between the programmable and fixed squares like would be expected.

Flooring to the nearest 1/16 is an interesting idea, it's worth trying. Doing that alone doesn't fully address the issue though, because we would still need to handle differing rounding behavior at 8/16. I'm not sure what exactly adding 1/32 to the positions is doing, as far as I understand 0.5 and 0.53125 would both round down on HW. If I recall right, Spongebob offsets positions similarly. Given that your HW and mine differ, there might be something more to it.

antangelo avatar Apr 06 '24 00:04 antangelo

Can this be rebased

Triticum0 avatar Mar 11 '25 11:03 Triticum0

Closing in favor of #2183

antangelo avatar May 20 '25 05:05 antangelo