New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Convert NaN to 1 when generating texture coordinates #9928
Convert NaN to 1 when generating texture coordinates #9928
Conversation
961125f
to
3e41bd3
Compare
|
In testing this, I found that using So, currently, this doesn't work when using ubershaders with either D3D11 or D3D12, but all other backends-ubershader combinations work fine. |
|
I'm not convinced this is entirely correct. Compare the upper-left part of the affected eyelid, where it meets the red part of the eye. On console there's a noticeable bit of black before the reflection starts, but in the current replace-NaN-with-1 it starts immediately. The lower-right part is also more point-y on console than with this PR. Definitely an improvement over the current situation, mind, but I suspect there's more going on here in hardware... |
|
The other eyelid also has some oddness going on with it: Both of these are OGL with specialized shaders. This eyelid isn't visible normally, and there isn't any way to move the camera with the hardware fifoplayer, so it may just be messed up like this normally and you can't see it. |
Hmm, surprised your flag didn't work (did you purge your shader cache?). Alternatively to having this in the vertex shader, could we just correct this when processing the texture coordinates before we send it down. It concerns me a bit to have the backends be broken for some apis (even if this is a niche issue).
Using a normal for a tex coord seems a bit odd too. Is there a different issue at play here? Kinda makes me think of some game bug that just so happens to work right on console (that we've seen many times this year) |
Yep, I deleted the folder each time. Possibly I did testing wrong still, but I'm pretty sure it wasn't a shader cache thing.
XF lets you use a lot of different inputs for texture coordinates (so-called texgens), including positions and normals. (#9876 and its write-up is an example of a good use of positions for texture coordinates.) That said, I don't know why they're doing it here, as I don't think they use the normals as actual normals, so they could just have specified two texture coordinates instead.
The problem is that things other than texture coordinates can be converted to texture coordinates, so NaN would also need to be converted for positions and normals in all places they can be used (instead of just for when they're changed to texture coordinates, since that happens in the shader). It could be done, but it would require more hardware testing to determine exactly what should happen in all cases. |
This fixes eyelids in Shadow the Hedgehog during cutscenes (https://bugs.dolphin-emu.org/issues/11458)
3e41bd3
to
3a4d837
Compare
|
I tested and approve of this change. Maybe needs to be checked on Android to make sure it doesn't break their shaders? |
|
Seems fine on my Adreno phone. (I don't have Shadow the Hedgehog, so I just tested some random game to check that nothing had broken.) |
|
Is a hardware test possible in this case? |
|
Is there a reason to expect that all NaN's of this type can be approximated as 1? For example, a divide by zero NaN should be a clamped max value, no? |
Sure, it's just drawing a triangle with the appropriate data (NaN at one or more vertices) and seeing what happens.
Division by 0 (other than There's no guarantee that all NaNs will become 1. All that I know for sure is that NaN encoded as ffc00000 appears to become 1 based on the hardware fifoplayer. |
Ahh, I didn't know the 'Hardware FIFO player' was the same thing. |
|
The hardware FIFO player is a different thing (it's this repo, which takes a bit of work to get running). It lets you run fifologs on hardware (in the screenshots above, I used test2-obj37.zip from issue 11458). That's how I've been testing things so far. It would be possible to test further by writing something to intentionally draw a triangle like that and see what happens, but I haven't done that yet. |
Have the results ever differed? |
I don't understand what you mean by that. If you mean the results of the hardware fifoplayer differing when run on hardware versus using Dolphin's built-in fifoplayer, yes, sometimes the results do differ (you can get vertex explosions with the hardware fifoplayer in some cases; I haven't investigated why). But that can be resolved by using the hardware fifoplayer in Dolphin, which generally gives the same results as on console (other than the actual graphical issues being investigated). If you mean testing by using the fifoplayer giving different results compared to writing a smaller, self-contained test, that can also sometimes happen (the debug cubes in Super Mario Sunshine are an example of this; they don't show up with the fifoplayer but writing a simpler test that does what they do does result in things showing up, though it is complicated). |
|
@Pokechu22 - is this ready to go? I thought you said |
|
The D3D |
Dang, not sure how I feel about merging this personally. Not because this in itself is very bad but because if we start having little differences in how backends perform or render, then the whole point of What do you mean when you say "don't render correctly"? Does this effect games outside of Shadow the Hedgehog? (I'd assume so since it's always writing this code to be parsed in the shader) |
Nope, it's just that on D3D11/D3D12 with ubershaders, it acts as if the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code LGTM. Untested
|
@Pokechu22 - can we open an issue for ubershaders (assuming this gets merged without a fix to resolve this)? |
|
Yeah, I'll open an issue for it when it gets merged. |
|
I did a basic test where I hex-edited the fifolog to have various values by replacing ffc00000 with other values. The results with this PR and on console can be seen below. (The modified files can be found in shadoweyes.tar.gz.)
I also tried a few where I set the y and z components set to 0 and only changed x:
At least to me, the color seems to be correct, but the positioning is indeed wrong. Using -1 instead of +1 gives closer results, but the size is too big. The behavior with a normal of |
This adjusts the NaN replacement introduced in dolphin-emu#9928 to work around the HLSL compiler optimizing away calls to isnan, which caused that functionality to not work with ubershaders on D3D11 and D3D12 (it did work with specialized shaders, despite a warning being logged for both; that warning is also now gone). Note that the `D3DCOMPILE_IEEE_STRICTNESS` flag did not solve this issue, despite the warning suggesting that it might. Suggested by @kayru and @jamiehayes.
This adjusts the NaN replacement logic introduced in dolphin-emu#9928 to work around the HLSL compiler optimizing away calls to isnan, which caused that functionality to not work with ubershaders on D3D11 and D3D12 (it did work with specialized shaders, despite a warning being logged for both; that warning is also now gone). Note that the `D3DCOMPILE_IEEE_STRICTNESS` flag did not solve this issue, despite the warning suggesting that it might. Suggested by @kayru and @jamiehayes.
This adjusts the NaN replacement logic introduced in dolphin-emu#9928 to work around the HLSL compiler optimizing away calls to isnan, which caused that functionality to not work with ubershaders on D3D11 and D3D12 (it did work with specialized shaders, despite a warning being logged for both; that warning is also now gone). Note that the `D3DCOMPILE_IEEE_STRICTNESS` flag did not solve this issue, despite the warning suggesting that it might. Suggested by @kayru and @jamiehayes.
This adjusts the NaN replacement logic introduced in dolphin-emu#9928 to work around the HLSL compiler optimizing away calls to isnan, which caused that functionality to not work with ubershaders on D3D11 and D3D12 (it did work with specialized shaders, despite a warning being logged for both; that warning is also now gone). Note that the `D3DCOMPILE_IEEE_STRICTNESS` flag did not solve this issue, despite the warning suggesting that it might. Suggested by @kayru and @jamiehayes.















































This fixes eyelids in Shadow the Hedgehog during cutscenes (https://bugs.dolphin-emu.org/issues/11458).
The eyelids (objects 36 and 37) draw on the same data, but object 36 uses texture coord 0 for its texture coordinate while object 37 uses the normal for its texture coordinate. The normal coordinates come from 00793400 (80793400 virtual), and some of them are NaN (specifically encoded as ffc00000). This specifically affects the center of the white part of the eye and the top left part of it, but because of how NaN behaves, the result of trying to interpolate anything with those vertices is NaN.
I used the hardware fifoplayer with the fifolog from that issue, and things rendered correctly, so this isn't a case of bad emulation creating NaNs:
My fix is to convert NaN to 1 before doing any math with it, which seems to give correct results. (Remember that if
xisNaN,x != xis true.)