gonetz / GLideN64

A new generation, open-source graphics plugin for N64 emulators.
Other
770 stars 178 forks source link

Paper Mario Snow #2570

Closed Rosalie241 closed 2 years ago

Rosalie241 commented 3 years ago

in Paper Mario, snow seems to break when the Enable N64-style mip-mapping checkbox is enabled.

Enable N64-style mip-mapping enabled: image

Enable N64-style mip-mapping disabled: image

Save State: Paper_Mario_U.pj.zip

gonetz commented 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.

ghost commented 2 years ago

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 :(

ghost commented 2 years ago

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

gonetz commented 2 years ago

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.

ghost commented 2 years ago

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.

gonetz commented 2 years ago

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?

ghost commented 2 years ago

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.

gonetz commented 2 years ago

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

fzurita commented 2 years ago

Yep, I'll try to test sometime today.

fzurita commented 2 years ago

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.

gonetz commented 2 years ago

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!

gonetz commented 2 years ago

mip_map_shift branch is merged to master. @standard-two-simplex, thanks! The bug is fixed. @Rosalie241 thanks for the bug report!

gonetz commented 2 years ago

@standard-two-simplex could you add a GLES2 version for your fix?

ghost commented 2 years ago

Done 6103842468c6439452bdf2769c3460ce91091c8f

@fzurita Please, check for errors with a GLES2 device.

gonetz commented 2 years ago

Done 6103842

Thanks!