Skip to content
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

Add option to force texture filtering off #8645

Open
wants to merge 3 commits into
base: master
from

Conversation

@leo60228
Copy link

leo60228 commented Feb 23, 2020

I saw this requested on Reddit. I thought it would look horrible, but I think I might actually prefer it to bilinear filtering.
Menu (ignore the titlebar, that's a bug with my screenshot tool):
Menu
Default:
Default
Force:
Force
None:
None

@Tilka

This comment has been minimized.

Copy link
Member

Tilka commented Feb 24, 2020

What happens with existing configs? Do we translate true/false to 1/0?

@leo60228

This comment has been minimized.

Copy link
Author

leo60228 commented Feb 24, 2020

I wasn't sure how to implement (as in program, not design) that. That would be the best way of doing it, but for now it resets to Default.

… converting checkboxes to dropdowns
@MayImilae

This comment has been minimized.

Copy link
Contributor

MayImilae commented Feb 26, 2020

I can't really agree with the UI and UX approach in this PR. By placing it in the enhancements tab, changing Force Texture Filtering to off is being elevated to the same level as extremely important options like internal resolution, anisotropic filtering, antialiasing, etc etc. This does not belong on that level. Setting texture filtering to force nearest neighbor (more on that later) is an extremely niche option that does not belong on the same level as things users will want to keep configured and accessible.

Now you probably put it here because this is where Force Texture Filtering was. But that was a tiny checkmark button that took up very little real estate on the screen, in the midst of lots of other little buttons. Even though it is location in a prime location, it's mindshare impact is relatively minimal. However, this PR turns it into a dropdown, which takes up WAY more space and promotes is puts it right up in the same level as the critical options like internal resolution. This is really inappropriate for a niche feature.

Also I don't really think Force Texture Filtering belonged here in the first place. Outside of a handful of games where it genuinely improves things (New Super Mario Bros Wii, Skyward Sword, to name two), it basically does nothing but cause minor visual bugs. But it was small, in the midst of a number of other misc options, and had been there forever, so I never bothered to complain.

Anyway, I believe this should be moved to advanced, if we decide to include it at all.


As for the naming of the options, that gets a little messy, as texture filtering is more or less a made up term from marketing that's stuck. Ok so, "texture filtering" the term is defined as the remapping algorithm the GPU uses to remap the texture's pixels to the screen's pixels during rendering. Unless a texture is 1:1 pixel tied to screen space (which you can do btw, screenspace huds are a thing!), its pixels HAVE to be remapped by something, and thus, filtered. That includes anything in 3D; scaling and rotation of textured polygons absolutely require texture filtering. Bilinear, Trilinear, etc etc are all algorithms to handle that remapping, but nearest neighbor is also a way to handle that remapping, it's just a more basic way of doing it. It sounds weird, but nearest neighbor is also texture filtering. The only time you get no texture filtering whatsoever is when the texture lives in screen space and is not scaled or manipulated in any way; but that is not nearest neighbor, that's a texture in screen space.

The confusion comes from marketing of very very early 3D technologies, where "texture filtering" was used as a marketing name for bilinear. Once trilinear came out they just called it the real name, trilinear filtering, but for a while marketing tried to posit that bilinear is "texture filtering", and nearest neighbor was not. But that's basically never the case, and we're kind of stuck with this not great name for it and that confusion to this day.

So, to that end, I believed the naming scheme used here is not correct. You currently have it set to:

  • Default
  • Force
  • None

What that actually is, laid out accurately is:

  • Texture Filtering of each texture is either trilinear filtering (or anisotropy if an aniso setting is enabled in Dolphin) or nearest neighbor as controlled by the game.
  • Remove all game texture settings, forcing Bilinear or Trilinear (or anisotropy) for all textures
  • Force Nearest Neighbor for all textures

How you describe those options doesn't anywhere near indicate what is going on. I'd much prefer something like this:

  • Default
  • Force Trilinear for all textures
  • Force Nearest Neighbor for all textures.

With descriptors below in the Description area:

Default: Allows the game to set whatever texture filtering method it wants for each texture. Anisotropy will replace Trilinear if configured.
Force Trilinear for all textures: Ignores game texture settings and forces Trilinear (or anisotropy if set) for all textures.
Forces Nearest Neighbor for all textures: Ignores game texture settings and forces nearest neighbor filtering for all textures. Disables anisotropy.

And of course, this would be in the Advanced tab, ideally.

So about that trilinear there. So the GameCube has Trilinear filtering from what I understand. However I'm not sure whether Bilinear or Trilinear is more common. I want to confirm with @stenzek about all of that and make sure the word(s) used there is correct.

@mbc07

This comment has been minimized.

Copy link
Contributor

mbc07 commented Feb 26, 2020

How you describe those options doesn't anywhere near indicate what is going on. I'd much prefer something like this:

  • Default
  • Force Trilinear for all textures
  • Force Nearest Neighbor for all textures.

I would drop that "for all textures", though. It would just make the drop-down list even larger especially when you account for translations and I think the suggested description text would already explain better what is going on. I think "Default", "Force Trilinear" (or whatever it should be) and "Force Nearest Neighbor" should be enough...

@MayImilae

This comment has been minimized.

Copy link
Contributor

MayImilae commented Feb 26, 2020

That would be fine with me, honestly. The description can carry a bit more of the load in describing how they work, and it's not incorrect, just... simplified I guess.

As for Bilinear vs Trilinear, it's both. According to stenzek, apparently mipmapped things are trilinear, and everything else is bilinear (except for textures explicitly set as nearest neighbor). However, most things are mipmapped so, trilinear is more common, from my understanding at least.

@JMC47

This comment has been minimized.

Copy link
Contributor

JMC47 commented Feb 27, 2020

@JMC47

This comment has been minimized.

Copy link
Contributor

JMC47 commented Feb 27, 2020

So, disabling texture filtering does make a lot of games look nicer at higher resolutions, particularly games that have precision issues with text.

I do think the best solution would have a heuristic to try to detect HUD/UI stuff, and allow users to force it, use the heuristic, or disable it.

@leo60228

This comment has been minimized.

Copy link
Author

leo60228 commented Feb 28, 2020

@JMC47 Do you have any ideas for how such a heuristic would work?

@leo60228

This comment has been minimized.

Copy link
Author

leo60228 commented Feb 28, 2020

I've tried a few different ideas (contrast, attempt to detect a background color, etc.) and my best attempt was based on whether the texture has any transparent pixels, which... shouldn't be great, but using the UI and environment folders from Bighead's Mario Galaxy texture pack (it was the only png textures I had on my computer) it correctly classifies all but a few environment textures and ~90% of UI textures.

@leo60228

This comment has been minimized.

Copy link
Author

leo60228 commented Feb 28, 2020

As it turns out, eyeballing it didn't work that great, so I calculated it properly. It's correct for 89.4% of environment textures and 98.9% of UI textures when treating "transparent" as "any transparency," and 91.0% of environment textures and 90.2% of UI textures when treating "transparent" as "full transparency."

@leo60228

This comment has been minimized.

Copy link
Author

leo60228 commented Feb 28, 2020

I'm not really convinced that a heuristic that works for even 75% of games is possible, especially without machine learning or something similar.

@JMC47

This comment has been minimized.

Copy link
Contributor

JMC47 commented Feb 28, 2020

Yeah, I don't know if a Heuristic would work, but the fact that this removes visual garbage around text (See: Starfox Assault) at higher resolutions makes it kind of interesting to experiment with.

Other ideas for heuristic, even if it isn't promising: Texture Resolution. Maybe projection?

@leo60228

This comment has been minimized.

Copy link
Author

leo60228 commented Feb 28, 2020

So this overall algorithm seems to work very well but needs some tuning:

  1. Count the number of pixels of every brightness
  2. Iterate over all 2-element windows in that count
  3. If the absolute difference of the two elements is over a/b of the larger element, increment a counter
  4. If the counter is between c and d, then use nearest neighbor scaling, otherwise use the standard scaling algorithm

a, b, c, and d need tuning, but currently I'm using 15, 16, 1, and 50. The current values of a and b successfully filter out bell curves (the vast majority of environment textures in my experience), but an approximately equal percentage of environment and UI textures have a single edge, making choosing c difficult. d exists solely because of displacement maps.

@Mizoxman

This comment has been minimized.

Copy link

Mizoxman commented Mar 15, 2020

I recall playing a game years ago that had a "trilinear nearest" option for texture filtering, so it used bilinear/trilinear when the texture was scaled down, but when you got close enough to it for it to be scaled larger than its largest mipmap it would be nearest-neighbor scaled. Maybe something like that would work?

@leoetlino leoetlino added the RFC label Mar 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked issues

Successfully merging this pull request may close these issues.

None yet

8 participants
You can’t perform that action at this time.