Sprite Scaler

Brainstorm ideas of possible additions to the game. Read this before posting!

Moderators: Forum Moderators, Developers

Forum rules
Before posting a new idea, you must read the following:
User avatar
iceiceice
Developer
Posts: 1056
Joined: August 23rd, 2013, 2:10 am

Sprite Scaler

Post by iceiceice » October 21st, 2014, 5:08 am

One of the things that can be improved on in the game is what happens when you zoom in the view. In current versions of wesnoth, the only image scaling routine we have does a kind of blending called "bilinear interpolation". This is appropriate for many things, like maps / terrain, portraits when they need to be scaled, but it doesn't have such nice results with sprites, because it blurs and destroys their features. This was pointed out by a user in this thread: http://forums.wesnoth.org/viewtopic.php?f=4&t=40987

In that thread I gave a patch to disable the "bluring" and just use "nearest neighbor scaling", which expands each pixel to a block.

Today I made an experiment to see how a different and more sophisticated scaling technique works, which is meant to give better results specifically for pixel art. I imported the published code of the xBRZ algorithm, and hacked it into the help pages in order to see what it does with our unit sprites. (Each sprite is repeated in original, then the 2x, 3x, 4x, 5x xBRZ scaling output.) It's intended to do a better job with small features, and with angles, than a nearest neighbor scaling would.

Many screenshots here: http://imgur.com/a/zeou4#0
[edit: there are much better screenshots later]
git branch here: https://github.com/wesnoth/wesnoth/pull/309

My impression: It needs some fine tuning, it seems to want to put pencil thin black lines around regions in many cases, which looks fine for orcs / undead / other "dark" units but isn't so good for elves and some humans. It's really good however for Cavalry and armored units, and in particular it makes Khalifate units look bad ass. It's generally pretty good at preserving faces somehow. It's sometimes really good with weapons (slurbow, many orcish swords, boneshooter), but sometimes they end up looking like a wet noodle imo.

Any crits or feedback welcome. Especially I would like to know if people want to see something like this in the game.

optimother
Posts: 76
Joined: July 12th, 2014, 4:09 am

Re: Sprite Scaler

Post by optimother » October 21st, 2014, 6:49 am

5x looks awesome, while 2x and 4x are less so. I suppose because of the black outline around same-colored regions, is it possible to try side-by-side comparison with vs without it? Or maybe add outline only for darker colors? It's really nice for some, but duelist and rogue look really scary with it :)

User avatar
tekelili
Posts: 1038
Joined: August 19th, 2009, 9:28 pm

Re: Sprite Scaler

Post by tekelili » October 21st, 2014, 8:54 am

A first glance this looks a "must have" for BfW, even more for units with no portraits (like most khalifate units). If one of those scaled sprites were displayed instead current, ridicolous small, unit image for dialogues, I think would be awesome.

Btw: I never noticed assasin is a "ninja turtle" before see it scaled :lol:
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II

User avatar
shadowm
Site Administrator
Posts: 6479
Joined: November 14th, 2006, 5:54 pm
Location: Chile
Contact:

Re: Sprite Scaler

Post by shadowm » October 21st, 2014, 9:05 am

This is a nice addition that might be useful to others with more specific needs, but it certainly doesn’t make up for missing portraits in character conversations — especially not if real portraits are also involved.
Author of the unofficial UtBS sequels Invasion from the Unknown and After the Storm.
Elsewhere: shadowmBlogFollow me on Twitter

User avatar
tekelili
Posts: 1038
Joined: August 19th, 2009, 9:28 pm

Re: Sprite Scaler

Post by tekelili » October 21st, 2014, 9:19 am

shadowm wrote:This is a nice addition that might be useful to others with more specific needs, but it certainly doesn’t make up for missing portraits in character conversations — especially not if real portraits are also involved.
Hum... I really dislike how currently looks :(
unit_image_dialogue.png
edit: Note that I am asking for something like scale x3, just something that allows identify image as speaker (in image attached I am unble to identfy naffat as speaker)
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II

User avatar
iceiceice
Developer
Posts: 1056
Joined: August 23rd, 2013, 2:10 am

Re: Sprite Scaler

Post by iceiceice » October 21st, 2014, 6:29 pm

Ok I figured out what the problem was...
Spoiler:
Take two: http://imgur.com/a/VPALw#0

I also added some pics comparing the "~xBRZ" image path function (which is how I hacked it in) vs. the default wesnoth "~SCALE" function (which I'm pretty sure gives the same results for when you zoom in on game map.)

http://imgur.com/a/KgsZS#0

User avatar
Crow_T
Posts: 850
Joined: February 24th, 2011, 4:20 am

Re: Sprite Scaler

Post by Crow_T » October 21st, 2014, 9:24 pm

Getting black lines when scaling images that have an alpha channel is related to/fixed by (it's been a while) something called "premultiply alpha" if that helps any. It's a pretty common graphics issue that has been solved already, some decent code may exist somewhere to use. But your code seems to be handling it pretty well.

Edit: I'm probably off base here, it's been a long day...

Anyhow, some things, like the drakes, look great. Others tend to get kind of rough at times.

Edit AGAIN: haha, actually looking through the new set they look pretty sweet. Would all the in-game gfx, the map tiles and doodads, scale the same way? I'd be cool to see a fully animated unit using this algo for all the frames. :geek:

Just to edit again, I'm pretty impressed at how well that algorithm works, it really keeps the feel of the original art.

optimother
Posts: 76
Joined: July 12th, 2014, 4:09 am

Re: Sprite Scaler

Post by optimother » October 22nd, 2014, 7:24 am

Great! 2x is perfect to me. But 5x is often indeed better with dark outlines.

User avatar
GunChleoc
Translator
Posts: 437
Joined: September 28th, 2012, 7:35 am
Contact:

Re: Sprite Scaler

Post by GunChleoc » October 22nd, 2014, 10:59 am

These look really good :)

User avatar
beetlenaut
Developer
Posts: 2205
Joined: December 8th, 2007, 3:21 am
Location: Washington State
Contact:

Re: Sprite Scaler

Post by beetlenaut » October 22nd, 2014, 2:11 pm

I think we should use this algorithm for the sprites, and the blurring one for terrain. That would make the retina monitor owners very happy I suspect.
Campaigns: Dead Water
The Founding of Borstep
Secrets of the Ancients

User avatar
lipk
Developer
Posts: 631
Joined: July 18th, 2011, 1:42 pm
Location: Here and there and everywhere

Re: Sprite Scaler

Post by lipk » October 22nd, 2014, 5:28 pm

In current versions of wesnoth, the only image scaling routine we have does a kind of blending called "bilinear interpolation".
FWIW, that's not true, we have a nearest neighbor scaler as well (scale_surface_sharp in sdl/utils.cpp) and it's supposed to be used for sprite scaling since ever. Not as if it mattered, xBRZ certainly looks way better than either NN or BI.

User avatar
iceiceice
Developer
Posts: 1056
Joined: August 23rd, 2013, 2:10 am

Re: Sprite Scaler

Post by iceiceice » October 22nd, 2014, 5:53 pm

Crow_T wrote: Would all the in-game gfx, the map tiles and doodads, scale the same way? I'd be cool to see a fully animated unit using this algo for all the frames. :geek:
If you pull my current version of the branch, then yes, you can arrange this, see my screenshot. (Still preliminary at this point, but the dialog at least lets you play around with the various scaling possibilities just so we can evaluate how they look.)

IMO the zoomed animations look best at exactly 2x, 3x zoom values. (In my branch you might also want to give wesnoth --log-info=display on the command line, then it will tell you the exact zoom value on command line when you hit one of the zoom hotkeys. But usually you can tell when you hit 2x or 3x just by looking at it anyways.) Even 4x looks nice also, it's not very practical but maybe suitable for a trailer or something.
lipk wrote:
In current versions of wesnoth, the only image scaling routine we have does a kind of blending called "bilinear interpolation".
FWIW, that's not true, we have a nearest neighbor scaler as well (scale_surface_sharp in sdl/utils.cpp) and it's supposed to be used for sprite scaling since ever.
Ok, but it's not definitely the case in 1.12 or 1.13, we're definitely using scale_surface and not scale_surface_sharp on unit sprites, otherwise the patch I made in this thread wouldn't have worked.
Attachments
adv_graphics.png
advanced graphics options dialog

User avatar
zookeeper
WML Wizard
Posts: 9732
Joined: September 11th, 2004, 10:40 pm
Location: Finland

Re: Sprite Scaler

Post by zookeeper » October 22nd, 2014, 6:46 pm

I don't mind advanced preferences for that sort of thing, but I think it warrants rather careful thinking. There's all the graphics on the map (units, terrain, etc), portraits, and the ~SCALE IPF. Portrait scaling probably should never be affected by any options, whereas units and terrain and such should likely use the same algorithm (whichever it is). Scaling by IPF can be used pretty much for anything, so I guess it needs such an additional argument as well? But what happens when someone uses an IPF-scaled sprite in a unit animation, for example? Which algorithm gets used and when? There's some issues like that which need to be figured out.

User avatar
tekelili
Posts: 1038
Joined: August 19th, 2009, 9:28 pm

Re: Sprite Scaler

Post by tekelili » October 22nd, 2014, 6:47 pm

Thanks a lot for your work, iceiceice. Sorry if I am asking something obvious: Can I already use it for generate custom images outside BfW? Could you provide me a x3 scaled Naffat.png so I can do some test? (Note English in technical language use to be a great barrier to learn do stuff on my own).

Edit: Ignore all above, scaling using current image path function wasnt so bad as I expected.
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II

User avatar
iceiceice
Developer
Posts: 1056
Joined: August 23rd, 2013, 2:10 am

Re: Sprite Scaler

Post by iceiceice » October 22nd, 2014, 11:17 pm

zookeeper wrote:There's some issues like that which need to be figured out.
Okay, here was my take on it:
  1. The main reason to have a preference like this is to allow people to select low or hi graphics settings appropriate for their machine. Allowing customization to taste is good also but its a distant second and it's balanced with, our desire to make the game always look its best / make it easy for it to look its best.

    Therefore, the preference is only really intended to affect the graphics drawn on the map while playing the game, since that's the only time that scaling could be CPU intensive.

    I am exposing more options in this dialog than I would want to have in a release, to help us figure out what the best settings are. It might be that this should ultimately be replaced with a "graphics lo / graphics hi" slider or checkbox. (Or maybe only show the full options in debug mode or something.)
  2. Portraits should ideally never be scaled. If they are, it should be done with whatever method Jetrel & co. thinks looks the best I guess.
  3. IPF's are used by content authors to construct new images from the game resources. If IPF's are sensitive to preferences, then it makes them hard to use since you don't know what you are going to get. So if at all possible I would like for the choice of algorithm to be made by the content author and not by the preference.

    In my branch, ~SCALE is always bilinear interpolation regardless of the preferences. I added a new one, ~xBRZ which selects the xBRZ algorithm always. I guess we might also add a new one, ~SCALE_SHARP or ~SCALE_NN, which always does nearest neighbor scaling. (We don't have one like that right now, do we?)

    The only time that IMO an IPF should be changed by preferences would be in case of ultra low machine specs, i.e. "I'm running wesnoth on a brick, please help me!"
beetlenaut wrote: I think we should use this algorithm for the sprites, and the blurring one for terrain.
zookeeper wrote: ... whereas units and terrain and such should likely use the same algorithm ...
Yeah so I have tested both, beetlenauts suggestion, and the xBRZ for both setting, I think both of these are fine. I think I lean slightly towards xBRZ for both, but I didn't look at that many different maps and terrains. I guess we'll have to discuss which we think is better.

Here's a screenshot with xBRZ for both, at 4x zoom:
http://i.imgur.com/yBtrwKH.png

Here's a screenshot with xBRZ zoom, linear for the terrains, 4x zoom:
http://i.imgur.com/PJnhi8a.png

Here's a screenshot with linear for both (the current default):
http://i.imgur.com/Wo6nMRa.png

(Edit: I add these to an album, for ease of side-by-side viewing: http://imgur.com/a/8ChMl#0)

You can also build my branch if you want to see how the animations look.

Edit: I used xBRZ + nearest neighbor, I didn't take pictures of xBRZ + linear option.
tekelili wrote: Can I already use it for generate custom images outside BfW?
I guess its moot for you, but anyways I looked at this, for some reason I thought there was an external program that already exists for it but I couldn't find it. The closest I found was a request for xBRZ as a filter in the GIMP, but I didn't see that this was fulfilled. Mostly it seems that xBRZ has been ported to a wide variety of different console emulator programs.

Note also that, I didn't find any implementation that properly handles the alpha channel, that's why I had to change the code to do this, and what I did was definitely a hack so far. So your odds to find a third party program are not high.

Nevertheless though, I decided its a good idea anyways to add this feature to wesnoth.

In 1.13.0+dev there is now a feature so that, similarly to how you can take screen shots, you can generate an image file from any wesnoth imagepath, with image path modifiers, by passing this to wesnoth in the command line. So for instance if you do this:

Code: Select all

wesnoth --render-image "units/undead-skeletal/banebow-bow-attack-1.png~SCALE(144,144)" "banebow.bmp"
you get this: http://i.imgur.com/6hJcvFz.png

Edit: Unfortunately though, it seems that SDL does not support writing out the alpha channel for some silly reason. So this might not *really* work in wesnoth for a long time.

Post Reply