narzoul / DDrawCompat

DirectDraw and Direct3D 1-7 compatibility, performance and visual enhancements for Windows Vista, 7, 8, 10 and 11
BSD Zero Clause License
885 stars 67 forks source link

Add more resolution scaling filters #195

Closed De-M-oN closed 7 months ago

De-M-oN commented 1 year ago

Could you add more scaling interpolators? Bilinear is not a good interpolator. Better would be lanczos, spline or bicubic. What I mean is the way how it goes to the target resolution. e.g. if the game is on 640x480 and you upscale it to your e.g. 2560x1600 monitor.

narzoul commented 1 year ago

What do you mean by spline? And which variant of bicubic, for that matter? I'm not an image processing expert, but even just a little bit of searching leads to many different variations, parameters, etc. I don't want to overcomplicate things. Perhaps I'll just start out with something "simple" like Lanczos, which at least seems to have a well specified single definition (apart from the fact that it also has a customizable parameter), unlike the others you've mentioned. But, I don't know when I'll have time for such luxury stuff anyway, for now there are a lot of more important issues to be fixed.

De-M-oN commented 1 year ago

http://avisynth.nl/index.php/Resize Lanczos 3 (=3 taps) Spline36 you can see in the link too Bicubic can stay at the default values I think. Same for Lanczos if its then 3 taps.

I dont know if it helps, but dgvoodoo2 has these scalers:

Resampling: When scaling is done by the dgVoodoo for the given scaling mode,
;                         you can choose which filter is to be used for resampling the output image
;                         Available filters are: "pointsampled", "bilinear", "bicubic", "lanczos-2", "lanczos-3"
Mitch037 commented 1 year ago

Once I came across an interesting thread on OBS forums related to a recommendation for downscaling filter for gaming-related content. It is said that bicubic is the default recommendation as lanczos is meant for face-cams and real-life videos.

De-M-oN commented 1 year ago

Bicubic can be better if you do extreme upscaling like from 480p to 4k or so. Then the sharper lanczos might produce ringing artifacts around fonts. I mainly speak about upscaling. I doubt there will be much downscaling going on here. Games can have a too low resolution. Never heard of a game where the minimum resolution is too high. The OBS user probably wants to downscale the resolution for his twitch livestream. For downscaling I would also rather use bicubic.

Mitch037 commented 1 year ago

From what I could understand from that thread (correct me if i'm wrong) is that the described filters work this way for both cases - downscaling & upscaling. I realize that in regards to DDrawCompat we have upscaling in mind.

De-M-oN commented 1 year ago

I cant agree on that. I had always good results with Lanczos. Doesnt hurt to offer it anyway, right? Even more I like Spline36.

narzoul commented 1 year ago

DisplayFilter is used for downscaling when the target resolution is larger than the display resolution. This is often the case when ResolutionScale is used, even with a display(1) setting, since it rounds up to integer scale factors. So a 640x480 -> 1920x1080 resolution scale actually upscales with a 3x factor to 1920x1440, and then downscales to 1440x1080.

The way downscaling currently works is that for scale factors less than or equal to 0.5, it repeatedly downscales the image to half size with simple bilinear filtering, until the scale factor is greater than 0.5. Then the last scaling step is performed with the selected DisplayFilter. This should probably work fine with these new filters too.

narzoul commented 7 months ago

I added all requested filters in v0.5.0. I ended up implementing proper downscaling too, using discrete convolution with increased tap count and all that. At least, I hope I got it right, looks good enough to me.

De-M-oN commented 1 hour ago

Wouldnt that have to be at "ResolutonScaleFilter" available then? How I read it here, this would still upscale via nearest neighbor and would just do the downscaling to the monitor resolution via e.g. spline.

narzoul commented 48 minutes ago

I don't know where you got all this info from. The requested filters are in the DisplayFilter setting.

ResolutionScaleFilter is a completely different setting that only affects resolution-scaled render targets, and only if the application ever needs to access them through CPU. In this case, ResolutionScaleFilter is used to temporarily downscale the image, so that the application can read/write some pixels directly through the CPU. Then, only the CPU-modified pixels will be scaled back up again, and these always use nearest neighbor. The unmodified pixels preserve their original (upscaled) resolution.

DisplayFilter is universally applicable in all situations when the final display resolution is different from internally rendered resolution. So it will either downscale to the DisplayResolution (e.g. if a large ResolutionScale setting is used), or upscale from the application's internal resolution to the DisplayResolution (e.g. if ResolutionScale=app is used and the display resolution is larger).