Well, now to the gory details.
Resizing down is always being done by 4x so the easiest thing to employ here is to use linear interpolated downsampling. For 4x downsizing case (each 4 pix quad translated into 1 target pixel) it boils down to a dumb simple mean value (in case we don't have an alpha channel to worry about) or to a - still simple - weighted average with alpha channel values acting as weights. Trouble is that this is world of CG and sprites are raster bitmaps so we have to deal with the aliasing and all other kinds of rounding errors & problems to get this right. Size of the tile sprite at 32x zoom out level is 8x4 so a cost of a rounding error here is extremely high. Existing sprites had been created keeping in mind the specifics of the original downsampling algo. Shapes of the land tiles had been formed in a way so downsized versions would opaquely cover the entire area they're expected to cover when laid out in grid by the engine. This property of opaquely covering the area is one of the extremely important to held as failing to do so would end up with random garbage/glitches appearing on the screen due to the way screen updating works.
Due to reason detailed above it is impossible to simply linear downsize sprites and hope that resulting picture would be correct - it won't. Special techniques must be employed to warrant that resized picture would opaquely cover exactly the same area that would had been covered if the sprite had been resized down using the original algorithm. This problem is not a new one - I had covered it in 32bpp-blitter-aa thread and proposed a possible solution that results in not-so-visually-bad results for tile sprites in case they only have fully transparent<=>fully opaque pixels transition on shape edges. This solution was given a name "FORCE_XXX_HACK" (initially it was "force opaque hack", but as later hack had been extended to either force pixel into opaque of into fully transparent - the name had been changed) and it had been proven to work pretty well for existing 8bpp basesets (original Dos, original Windows and OpenGFX) and older and not officially "existing" 32bpp megapack.
Enough intro talks, let me cover what's all the buzz about.
"Resizing done properly" patch:
- would improve visual appearance of the zoomed-out viewports for any baseset and/or NewGRFs in use;
- would work with any 32bpp blitter which is descendant of the Blitter_32bppBase - all existing 32bpp blitters are (including my 32bpp-anim-aa);
- wouldn't improve visual appearance of areas covered by remapped and/or palette-animated pixels (water + 32bpp-anim blitter = looks bad, just the same as without the patch);
- would improve visual appearance of the water (and rest palette-animated) areas in case non-palette-animated blitter is being used (like 32bpp-simple or 32bpp-optimized);
- would work best for 32bpp basesets and GRFs which have as low amount of masked 32bpp sprites as possible;
- would uncover flaws/bugs in existing basesets and GRFs and could made these glitches more noticeable than they were with original downsampling (it's easier to spot one wrongly coloured pixel on the smooth clean surface rather than on "the pixelated piece of garbage"-like surface that you'd get with nearest neighbour like resizing);
- would hurt the performance a tiny bit but not nearly as much as 32bpp-anim-aa blitter would;
- could serve as a complement to the 32bpp-anim-aa blitter allowing to use low level AA (2x) to get output quality level that's comparable to (or is even the same as with) higher levels of AA (4x-16x).
Thus the best effect you'd get if couple this blitter with the 32bpp baseset and "my 32bpp set of choice" is the self-cooked version of the famous 32bpp "megapack".
zBase might seem to be a good choice here but unfortunately that's not the case due to the fundamental flaw it has (as of r123) for all tile sprites with "shape edges" having some pixels semi-transparent instead of one-step jumps between alpha == 0 and 255. I've been reporting about this problem
here but it isn't known so far if would it be ever addressed or not. It's not that hard to fix though and I had even manually done it (as a matter of experiment) for some part of the zBase r123 but the "Right Way (TM)" to address this issue is not a decode-edit-reencode sequence but rather a change in the render/build sequence of the zBase build system itself. On screenshots posted later "Semi-fixed zBase" reffers to the my modification of the zBase r123 (decode -> manually processe some sprites in GIMP -> re-encode back). "Unmodified zBase r123" stays for "zBase as it was downloaded from openttdcoop repo".
Due to zBase being flawed with producing "accumulating garbage at tile seams on redraw" glitches even with original blitters & downsizing it was desirable to try to "address" this issue by making viewport updates deterministic. So I've created yet another patch that forces the engine to fill each viewport area it's going to update with the neutral grey colour and only then proceed with sprites output. It helps a bit ("seams between tiles" glitch became always visible but it mostly fades into surrounding pixels for majority of temperate terrain tiles) but is not perfect and drains performance a bit more (negligible amount really in case you're on PC which is non older than 4 years from now). You could find this patch in the "downsampling done properly" tarball in the attachments section of the first message in the thread. I highly recommend using it for general gameplay.
It seems that now it just the right time for some fancy pics.
Here is 1x1 comparison of the old algo vs. new one (scaled up 2x so differences could be noticed more easily):
What to look at:
- Original algo is crap. Aliasing artefacts on water and fields are eyes-hurting. Ignoring that and comparing visual appearance between original and "semi-fixed" zBase some differences could be noticed proving that flaws in this baseset affect the original blitters & downsampling too but it's just pretty hard to notice glitches on a "grainy s*** picture" like that.
- New algo with FORCE_XX_HACK active produces smooth and clean picture when coupled with "semi-fixed" zBase. With stock unmodified zBase there are some "visible seams between tiles" glitches. The result isn't perfect though as some sprites end up being not anti-aliased like field fences or power station smoke clouds.
- Turning FORCE_XX_HACK off makes all sprites anti-aliased as expected (compare field fences and power station smoke clouds on the pictures above) but it "brights up" the entire viewport noticeably, especially for 32x zoom out. What actually happens is that 8x4 tile sprites end up being semi-transparent for the most part and neutral gray (#7f7f7f) viewport-filling colour starting to "shine through". It could be easily spotted looking at the "green glass" tiles looking like "4x2 green rects surrounded by washed-out green". IMO it looks really bad for 32x and somewhat bad for 16x level.
- For 8x zoom out level it looks like linear downsampling without FORCE_XX_HACK produces a bit better result comparing to the new algo with FORCE_XX_HACK on. It's hard to spot the difference but it is right there: look at the edge of the factory wall to the right, it is "sharp" with FORCE_XX_HACK and "transparently blended" without it.
- zBase-related "seams between tiles" could be seen for 8x zoom out also (for "unmodified zBase") but for this zoom level they are not so severe (because the cost of 1 pixel error for 32x16 sprite is minor comparing to same 1 pixel vs. 8x4 sprite).
In attachments you could find two more fullsize (~1.5-2MB each) comparison screenshots for old algo vs. new one for 8x zoom out mode.
You could find original fullsize screenshots here (as long as my server is up and functional):
https://lexa2.ru/lx2/OpenTTD/2012-08-14/