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

MGS2/MGS3: add hook/setting for anisotropic filtering #31

Merged
merged 4 commits into from
Nov 1, 2023

Conversation

emoose
Copy link
Contributor

@emoose emoose commented Oct 31, 2023

Game currently doesn't apply any kind of anisotropic filtering, leaving textures get very muddy in the distance, there's some ways to force this in driver settings but not sure how perfect driver forcing is (and a lot of people probably don't know they can force it via drivers)

In D3D11 it seems for anisotropy to be used a D3D11_SAMPLER_DESC has to be setup with both .Filter = D3D11_FILTER_ANISOTROPIC and also .MaxAnisotropy = anisoAmount

Fortunately for us it looks like game already creates D3D11_SAMPLER_DESC instances already, and uses them with CreateSamplerState etc, but it's only applying worse filters like D3D11_FILTER_MIN_MAG_MIP_POINT / D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT, etc...

(in MGS3 0x14004D310 / CRenderBackend::SetTextureFilter chooses one of those filters above, and 0x140055DE0 / CD3DCachedDevice::SetSamplerState then sets it in the D3D11_SAMPLER_DESC struct)

Sadly we can't just patch the ID of those filters being used over to D3D11_FILTER_ANISOTROPIC since we also have to setup the .MaxAnisotropy field of it too, best way I could find for that was a hook inside SetSamplerState when it's setting up the .Filter field, there wasn't really much room there to hook but was able to find a way to get it working, and also keep the small optimization they use in that func so it only applies the filter when it's being changed from previous one.

Anisotropy makes a pretty big difference in MGS3, before:

23-10-30_00-06-41-097_METAL_GEAR_SOLID3

after:

23-10-30_00-08-02-535_METAL_GEAR_SOLID3

The hook seems to apply fine in MGS2 too but I couldn't really notice much difference there, guess the camera maybe makes it harder to see...

This might need more testing before being merged, haven't really got that far in the games yet so only tried it around starting areas, maybe something later on could break with it.

If anyone wants to help test it here's a build with it included, install on top of 0.7 & edit the INI to enable it:
MGSHDFix-aniso-fixed.zip

(E: build should have fixed pattern scan now)

@emoose
Copy link
Contributor Author

emoose commented Oct 31, 2023

Also wasn't too sure where to put it in INI file, didn't really seem like it needed a section to enable & then set value since we can just treat setting it to non-zero as enabling it, putting it under custom resolution seemed the closest fit but idk really, feel free to move if you like.

@KoKlusz
Copy link

KoKlusz commented Oct 31, 2023

Off topic (?) but can MSAA also be enabled? HD Collection used it 2x MSAA on PS3 and X360 but apparently MSAA is disabled in Master Collection.

@emoose
Copy link
Contributor Author

emoose commented Oct 31, 2023

Looks like they added some MSAA support in the CBaseTexture functions, but the main d3d swapchain init just sets it as default (samples = 1, quality = 0), so seems like it does get left disabled.

Not sure how much work it'd be to get it working, maybe better off using something like DSR instead.

E: hm, apparently setting MSAA on the swapchain isn't really recommended, should be set on the render target instead.. looks like the CBaseTexture MSAA stuff I mentioned above could maybe be used for it, render target creation does go through it at least, but seems they use kAA_None for all of them, need to play with it more some time.

@Lyall
Copy link
Owner

Lyall commented Nov 1, 2023

Looks great. Should the anisotropic value maybe be clamped? If a user sets it to a value higher than 16 would it cause any issues?

@ShizCalev
Copy link
Contributor

The hook seems to apply fine in MGS2 too but I couldn't really notice much difference there, guess the camera maybe makes it harder to see...

image

Peeking around corners appears to be the largest problem area with MGS2.

@ShizCalev
Copy link
Contributor

ShizCalev commented Nov 1, 2023

Looks great. Should the anisotropic value maybe be clamped? If a user sets it to a value higher than 16 would it cause any issues?

diminishing returns to the point where (to my knowledge) most hardware doesn't bother supporting anything higher than 16 anyway. might as well just clamp.

@emoose
Copy link
Contributor Author

emoose commented Nov 1, 2023

Ah yeah probably should add a clamp to it, will check if it has to be power-of-2 as well, and write something in log if user put in something invalid.

E: hm, added clamp to 0-16 below, didn't add non-power-of-2 check since what I read sounded like it'd be fine, but looks like that might be breaking AF actually.. will check it in a sec

E2: oh actually I'm getting pattern scan fail on it for some reason now, hm..

@emoose
Copy link
Contributor Author

emoose commented Nov 1, 2023

Added clamp & log message, seems non-power-of-2 values should work fine, 15x looked pretty similar to 16x at least.

(thought 15x might not be working but seems I'd just broke pattern scan in the log output commit, should be fine now 😅)

MGSHDFix.ini Show resolved Hide resolved
@KoKlusz
Copy link

KoKlusz commented Nov 1, 2023

Not sure how much work it'd be to get it working, maybe better off using something like DSR instead.

Yeah, but the problem with DSR is post process scaling, or rather lack of it (I'm not holding my breath that it will be easy to fix, if it was Konami would probably do it). Plus, enabling MSAA could open the door to forcing SGSSAA via Nvidia drivers.

@MarioTainaka
Copy link

Amazing work so far! I can't keep up with all these updates. Wouldn't Forcing AF via the driver be less work compared to implementing it an ini tho?

@Lyall
Copy link
Owner

Lyall commented Nov 1, 2023

Amazing work so far! I can't keep up with all these updates. Wouldn't Forcing AF via the driver be less work compared to implementing it an ini tho?

It has a few benefits doing it this way. It's vendor-agnostic so you can get 16x AF on a Steam Deck, an AMD GPU, an Nvidia GPU or even an Intel one. Also forcing 16x AF through the NVCP on Nvidia cards can cause issues (very rarely to be fair, Starfield is a recent one that I can recall). Also with it defaulting to 16x in the configuration file, it's one less thing for people to think about.

@MarioTainaka
Copy link

Amazing work so far! I can't keep up with all these updates. Wouldn't Forcing AF via the driver be less work compared to implementing it an ini tho?

It has a few benefits doing it this way. It's vendor-agnostic so you can get 16x AF on a Steam Deck, an AMD GPU, an Nvidia GPU or even an Intel one. Also forcing 16x AF through the NVCP on Nvidia cards can cause issues (very rarely to be fair, Starfield is a recent one that I can recall). Also with it defaulting to 16x in the configuration file, it's one less thing for people to think about.

Ah thank you for clarifying. I always assumed AF just worked properly regardless of vendors their drivers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants