Closed Rosalie241 closed 2 years ago
The snow is wrong with and without N64-style mip-mapping, check AL RDP for a correct picture. Snowflake texture has 3 tiles with sizes 128x128, 128x128, 16x16 It is impossible to emulate correctly with old GL mipmaps based emulation method. The new texture atlas based method can handle that case. Unfortunately, it is that rare case, where texture parameters for mip-map tiles differ: tex shift for the last tile is different. It makes texture coordinate wrong, so we have four snow balls instead of one. It probably is fixed in experimental mip-map refactoring started by @standard-two-simplex, because that refactoring addresses such issues.
It probably is fixed in experimental mip-map refactoring started by @standard-two-simplex, because that refactoring addresses such issues.
Yes, it works on the experimental branch.
It should be possible to add a temporary fix.
https://github.com/gonetz/GLideN64/blob/9ebb11f37b1090090e5fb110a6b7b18b7cb82f7f/src/Textures.cpp#L1414
Unless I missed something, tmptex.height
in the packed data is used only to compute this ratio. It should be possible to pack tmptex.mipMapRatio = tile_0_shift - current_tile_shift
instead and compute lod_scale = vec2(pow2(mipMapRatio))
. Note that a bit of care should be taken with the sign.
Edit: Actually, two shifts are needed, s and t go separately :(
It should be possible to add a temporary fix.
@gonetz I managed to write a working example. Feel free to adapt it if you wish to clean it up.
https://github.com/standard-two-simplex/GLideN64/tree/mip_map_shift
Oh, I already wrote a solution: fix_mipmap_scale I came to the same idea with texture scale, but it did not work yesterday because of a mistake. Now it works. I'll check your solution too.
Edit: Your solution is great. It requires no additional texture fetches (my does) but it needs way more shader calculations to get the scale. I'm in doubts.
Oh, I already wrote a solution: fix_mipmap_scale
Yeah looks good. It's probably better like this, the scale is calculated only once per tile.
Yeah looks good. It's probably better like this, the scale is calculated only once per tile.
Your code also calculates the scale once per tile, is not it?
It computes the exponent once per tile, but then has to compute its power of two once per pixel. Also, there are some extra per pixel calculations because I packed it all in one byte.
I guess we again need help from @fzurita Francisco, could you test these two branches
https://github.com/gonetz/GLideN64/tree/fix_mipmap_scale and https://github.com/gonetz/GLideN64/tree/mip_map_shift
on mobile devices, which can handle accurate texture mapping?
Is there any difference in performance between them?
fix_mipmap_scale uses one additional texel fetch in compare with master.
mip_map_shift uses several additional shader calculations, including two pow
.
The branches should be tested on games with heavy mip-map usage, like GE, PD, may be BAR
Yep, I'll try to test sometime today.
I'm not seeing much of a difference at all:
master
golden eye: 108
perfect dark: 93
fix_mipmap_scale
golden eye: 106
perfect dark: 92
mip_map_shift
golden eye: 107
perfect dark: 93
This is on a higher end GLES 3.0 device at 1440x1080. I can test a lower end device later to see if there is much difference there, even thought slower devices would generally only use the fast path. If anything, mip_map_shift is very slightly faster.
If anything, mip_map_shift is very slightly faster.
It a bit surprising for me. It is good that both fixes work nearly as fast as current master. Thanks!
mip_map_shift branch is merged to master. @standard-two-simplex, thanks! The bug is fixed. @Rosalie241 thanks for the bug report!
@standard-two-simplex could you add a GLES2 version for your fix?
Done 6103842468c6439452bdf2769c3460ce91091c8f
@fzurita Please, check for errors with a GLES2 device.
in Paper Mario, snow seems to break when the
Enable N64-style mip-mapping
checkbox is enabled.Enable N64-style mip-mapping
enabled:Enable N64-style mip-mapping
disabled:Save State: Paper_Mario_U.pj.zip