Open Laserlicht opened 2 years ago
Hi @Laserlicht , what do you mean by blurry graphics? The game has nothing related to filtering. Did you try 800x600 or 1024x768 resolutions? Do you play in fullscreen? If not why don't you try to resize the window?
Also please specify your OS and what exact resolution and settings you have for your monitor.
Hi @ihhub
Sorry, I was not precise enough.
Yes, full screen experience. But with a lower resolution than that the monitor. So that the gui elements are larger (and therefore also blurrier).
Example: If I use 1600x900 on my 2560x1440 monitor it would look like this (view it in 100%):
If I apply an xBrz filter on it (e.g. this) then it would look like this (view it in 100%):
In my opinion much better.
@Laserlicht Have you tried 1280x720 with integer scaling option (AFAIK it is available for AMD and nVidia graphic cards)?
@afrikansviridovic: The difference is very small.
We could e.g. use the xbrz library from Zenju.
For me, however, this is too much. Using the filter is not that hard, but you have to understand the rendering of fheroes2 first. In principle, we would only have to exchange the image before transferring it to sdl.
Furthermore we should have a parameter to change the scalefactor / deactivate.
@Laserlicht interesting. If you still have the save file to produce exactly the same screenshot, could you try with the following hint changed to "nearest" instead of "linear"? https://github.com/ihhub/fheroes2/blob/bbb68b95e330003a09fa589cb4b4c35b3537994e/src/engine/screen.cpp#L946
See here for possible values: https://wiki.libsdl.org/SDL_HINT_RENDER_SCALE_QUALITY
Yes, another example (this time at 1360x768 on 2560x1440 - in my opinion a good choice for balance between gui size and hi-res):
View it in 100%
Original:
Linear:
Nearest:
XBR x3 (+ linear downscale):
I have a feeling that we're trying to fix an OS issue. If the application generates 800x600 image / frame in full screen mode then the monitor will display the same image. However, the modern OSes have an option of software scaling by using some blurring based algorithms to upscale the image for higher resolution. What the proposed filters do in theory is to do deconvolution which never gives precise results without introducing artifacts.
@Laserlicht if you're using MacOS or Windows please disable OS scaling to verify my explanation.
I have done the tests with Ubuntu. In Ubuntu, the operating system or SDL seems to do the scaling. But this is basically comparable in (scaled) window mode.
I do not see this as an OS issue.
After all, the buttons in the GUI are fixed in size. This means that if you have a high pixel density, you have no choice but to render it in a smaller resolution and scale it up. The only question is how this should be done.
Emulators usually have a large selection of filter options. Of course, the focus is much stronger there, because the difference between the original resolution and the screen resolution is immense.
But of course a filter can only provide a nicer picture, but not more information.
The solution of Heroes 3 HD mod, however, I find very good.
With @a1exsh tip you can at least switch to nearest, which is often better than linear. But in my opinion not up to XBRZ or similar.
@Laserlicht , have you tried 1024x768 resolution in full screen mode? Exactly this resolution, not the higher one. How does it look? Isn't it what you're looking for?
It is blurry too, because 768 is not an even divisor of 1440.
This game obviously should use nearest scaling instead of linear because linear makes it blurry. This game contains pixel art and it is intended to show as it is without any filtering.
There SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "linear" );
it should be changed to "nearest"
and problem is solved. Or at least make it configurable. (I play it in 640x480 and if I resize the window to be larger, it makes everything blurry)
"nearest" is not without issues — I've tried that and could immediately notice that the small font becomes ugly (2px lines mixed with 1px).
This game obviously should use nearest scaling instead of linear because linear makes it blurry. This game contains pixel art and it is intended to show as it is without any filtering. There
SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "linear" );
it should be changed to"nearest"
and problem is solved. Or at least make it configurable. (I play it in 640x480 and if I resize the window to be larger, it makes everything blurry)
Nearest filter is a personal preference. Almost everyone has a different opinion.
I prefer xBRZ or hqx, even if the pixel feeling is lost.
That's why a setting option would be good. Comparable to HoMM3 HD.
HoMM3 HD:
@Laserlicht interesting. If you still have the save file to produce exactly the same screenshot, could you try with the following hint changed to "nearest" instead of "linear"?
See here for possible values: https://wiki.libsdl.org/SDL_HINT_RENDER_SCALE_QUALITY
It was be great to have options in menu for this problem.
As I mentioned in this comment it is good to know what problem are we going to solve. Is it to have a bigger picture preserving the same image quality? Or adding some special effects on the end result frame?
We already have in-game Resize() function which does subpixel scaling with maximum information preservation but the biggest issue is that the game is based on 8-bit images with a limited palette, not on RGBA images like for Heroes 3.
Also all these wrappers are weak solution to solve existing problems just because there are no other ways to modify the original game's image rendering. I recommend to think beyond "let's modify image X1xY1 into image X2xY2 by applying a scaling function Z".
With diferent options in menu must be solves all tasks. preserving the same image quality and adding some special effects. Everyone will decide for themselves how they want to play if they have a choice.
This feature is the lowest priority for now and could be implemented only after 1.0 as the project still has many unsolved issues for 1.0 release.
Оf course :)
I made a quick and dirty proof of concept of what this would look like using xBRZ scaling (and high-DPI awareness). Current scaling: xBrz:
This is simply doing what you said above, "let's modify image X1xY1 into image X2xY2 by applying a scaling function Z", but I (personally) think the results look pretty good and would be a nice quality of life improvement.
Implementation wise, this modifies the surface that the final frame is rendered to by a constant scaling factor
int scaleFactor = 2; ... _surface = SDL_CreateRGBSurface( 0, width_ * scaleFactor, height_ * scaleFactor, isPaletteModeSupported ? 8 : 32, 0, 0, 0, 0 );
The logical size ('SDL_RenderSetLogicalSize') remains the same so that internally, coordinates aren't affected.
Then, when the scene is rendered, the palette transform is applied and the results are stored in a temporary surface of the original, unscaled width and height. xBRZ (or whatever scaling algorithm) is then applied with the scaled surface as the output:
static SDL_Surface * out_surface = SDL_CreateRGBSurface( 0, imageWidth, imageHeight, 32, 0, 0, 0, 0 ); ... xbrz::scale( scale, ( (uint32_t *)out ) + imageWidth * 2, (uint32_t*)surface->pixels, imageWidth, imageHeight - 4, xbrz::ColorFormat::RGB );
This has some issues, notably that it is really slow.
Thinking about it, it might make more sense to render each asset (sprite, tile, etc) upscaled, then simply blit the upscaled versions onto the final surface. This should be much faster, and be slightly higher quality, at the expense of some run-time memory usage.
Also, please have an option for nearest.
Hi @Laserlicht , the latest version of fheroes2 contains a plenty of resolution options including those with integer scaling. Does it solve your original issue?
Hi @ihhub
No not really because:
But:
But I think this can postponed until SDL3 releases. Which should support shaders. xBrz for example can runned as shader: https://github.com/libretro/glsl-shaders/tree/master/xbrz
Can we get a sharp scale option instead of only bilinear filtering? Essentially looking for pixel doubling when you pick 2.0x scale like 960x540 so the pixels look sharp on a 1080p display. Currently the image is quite blurry unless I want to pick a native 1920x1080 image which makes everything too small.
Can we get a sharp scale option instead of only bilinear filtering?
There was a setting to choose between "linear" and "nearest (neighbor)" scaling. The code is still there in the engine, but I don't know if the setting from the cfg file is respected.
Can we get a sharp scale option instead of only bilinear filtering?
There was a setting to choose between "linear" and "nearest (neighbor)" scaling. The code is still there in the engine, but I don't know if the setting from the cfg file is respected.
Oh, you're right, and it does work. I set "screen scaling type = nearest" - was "linear" before. Now it has sharp pixels. Would be nice if this was an option in the UI but this works, thanks.
Preliminary checks
Describe the problem requiring a solution
When playing on a high-resolution monitor in original resolution, everything is very small.
If you play it in a lower resolution, then it can get very blurry.
Describe the possible solution
In the HoMM3 HD mod it is possible to choose a lower resolution and increase it with a filter. xBRZ x4 +Hermite (at 1870x1052 on a 1440p monitor) for example gives a very good, sharp result and is a good compromise. Of course, it costs computing power, that's clear.
Unfortunately I don't have enough experience to implement something like this myself. But perhaps others will also find the idea good.
Additional info
No response