News: Portal
Our Simutrans site. You can find everything about Simutrans from here.

Support for PNG Alphachannel for tree graphics

Started by NNW, March 07, 2016, 08:53:06 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


I though the following:
makeobj defines image as the area which does not contain 255,255,231 and have a transparency less than 224.
If the transparency level is >0 then the base color will be chose from the player color palette, and the the special color will be 32768+256+256*base_color_index+transparency_level and the latter is transparency/96
That way the images cannot get out of sync and transparency can be added directly from a render.


Makeobj can reads alpha from png alpha channel and store this in pak.
Simutrans can display alpha for smoke, fields, trees and buildings (other objects can be added in due course)

There's no changes needed to dat files.

Makeobj had to be a bit more clever about determining what is a valid alpha channel and what isn't though.

I also had to make a bit of a judgement call as to how low in the code alpha display should be implemented. The level I've chosen means objects need to implement routines to return alpha image numbers, which will then be automatically displayed. A lower level would be possible but this would require fairly radical changes to simgraph and the way images are stored...

Please test!


Hmm, I think it will be still easier to integrate the transparency into one image. I will give a patch hopefully tomorrow to compare. Having two bitmaps certainly would save on non-transparent bitmaps

However, I would still have every image possible with transparency and not so much efforts for each object, and it would be just ignored, if not there. I am curious how high the impact on the low level routines would be.


We can see... the makeobj part can be reused regardless of implementation in Simutrans. My worry was having to duplicate the rescaling routines which having separate images avoids...


May I kindly ask for a compiled windows version for testing purposes?


I would wait until the makeobj format is settled. Also the visual result of both implementation would be different.


Alternative implementation here at a slightly lower level which means all objects drawn as part of simobj can have alpha...

To do this I added alpha_nr to images which can then be used to call the alpha display routines. alpha_nr is set to IMG_LEER if the image has alpha, or the image is alpha itself....


OK, here is my take. If an image has alpha it will be drawn using the slow routines. Otherwise it will all be the same. I added a tree. Screenshot too, not too spectacular. (THus marked by red lines.)


Hmmmm. I guess question is are we wanting to allow shadows (for which 2 bit transparency is fine) or allow a range of effects. The difference is quite noticeable on the smoke graphics I made:

Smoke images as displayed with my patch.

Using same images with prissi's patch.

Incidentally whichever way we implement alpha we should probably commit the code tidying parts of both patches (e.g. moving special colours from tab to bildbesch in prissi's and the long standing incorrect alpha colour channel names fixed in mine).


Wonderful!  This is very exciting.  I have a bunch of alpha tree images that I can offer for testing purposes, but it will have to wait a few days until I return back to my main computer with all of my Simutrans development projects.  I also have vehicles and buildings available with alphas, if this patch is intended to be able to support those as well.
Current projects: Pak128 Trees, blender graphics


Both patches support alphas for everything in the game play area (mine doesn't for menus, window tool icons etc though, I suspect prissi's does although behaviour might be a little odd if a window background has alpha as objects in the game play area behind large windows might not get updated automatically).

I would caution against putting alpha in images just because you can though. With both patches there is a slowdown on image plotting for alpha images, maybe not that much, but if there's a lot of objects on the screen all with alpha images it could be significant.


Absolutely.  For those of us with high-end computers, the performance hit may be worth it for the enhanced graphics capabilities.  The only way to know for sure is to test it with various degrees of alpha images enabled (trees, vehicles, buildings, etc).

Given that for my purposes, performance is less important than appearance, I'd be happy to make the trade off.  It'll also make my Blender-->Simutrans transition process faster as I won't have to spend the time carefully selecting an alpha channel threshold level each time I make an import.
Current projects: Pak128 Trees, blender graphics


Quote from: prissi on March 26, 2016, 09:37:12 PM
I would wait until the makeobj format is settled. Also the visual result of both implementation would be different.

As I said, testing purposes. This is a patch to enhance visuals, so it seems appropriate that graphic artists play around with it to see how it works, especially with two versions around. While programmers will know best which method is more efficient in which scenarioes, the most efficient method would always be not to have alpha channel. Efficiency can't be the only consideration. So if you are willing to exchange performance for appearence, you need to know which method ultimately looks better and by how much. Additionally, I think working with a restricted "alpha palette" is similar to working with a restricted color palette. You can create graphics for the limited palette that look great, but if you try to downsample from a bigger palette, you might be disappointed. Therefore, prissis patch might bring results just as good as kierongreens if proper alpha is carefully chosen - but harder to do and inconveniant to use. Convenience in use should therefore be another factor, which again is probably best decided by graphic artists who will make use of alphachannels.

It's especially important considering without direct access just from screenshots, many questions remain open. For example, what happens if something transparent is in front of a special color, either nightcolor or player color? Can you have transparent special colors? Can you use 25% transparency in both front- and backimage to get 44% transparency in sum? How does zooming handle transparencies? Are any of these different for the two methods?
Or do you only want feedback from the "general public" once stuff is already accepted and in the nightly? That would seem odd.


Regarding limited palette for alpha - yes, this does make life more complicated as to get acceptable results dithering would be needed - with the artist applying this separately for both alpha and colour components. This isn't the easiest things to do and does remind me of displaying images in 256 colour modes back in the mid 1990s...

Unfortunately I'm not in a position to make Windows builds at present as mingw stopped working for me a while back.

A few brief comments on your questions though - each patch keeps most image routines as at present. Hence zooming and overwriting pixels (whether player colour or special day/night etc) on screen already work as expected for both patches. They also work fine with the day/night cycle for normal colours. However prissi's patch supports special colours in images with alphas whereas mine does not (for mine if an image has special colours then alpha doesn't display).

On another note when I compile pak64 with prissi's version this produces an assert error running simutrans in the bild_besch image rotation routines (I'm guessing somewhere an offset has been set which would cause the assert to fail?). Doesn't happen in pak128.Britain though...


I think some of the visual differences between the two patches come from the fact that I use 0 as opaque while you use 255 as opaque, when I read the patch. The display routines in coth cases only support 25/50/75% transparency (or did I get this wrong?)

Also transparent player color were important to me, as one could have a station with window panel on top in player color (although support of that in my patch is still very limited). I also try an approach which will have way less impact on drawing (i.e. still using assembler for most of the draing without adding much new code).


My patch supports 32 levels (5 bits of transparency). 5 bit alpha has been in Simutrans for years since climates were introduced because it's used in generating landscape tiles. That's one reason I've used the method I did for general alpha, because these routines are already there.

Yes the alpha gets flipped in your patch but it still works as intended - if you look at the smoke you can see the centre is opaque, the outside semi transparent, which is the same as in mine, it's just the boundary between the two is more obvious in yours because of the 2 bit alpha.

It should be fairly easy to add player colours to my implementation I hope. Certainly people would expect this when alpha is added to trunk.


Ups, well 32*256 is also possible. I did overlook that. But supporting this is easy, I just changed colorpixcopy. So also 32 trasnparency levels. I found out that my tree was broken, possibly because my Gimp skills together with the poor GUI.

OK, here is the code which is more flexibel and much faster and supports player colors. It even involves less changing and works now with transparent trees too.


I still favour a full range of colours being able to be used but will see what's possible... Incidentally at present my patch should support player colours just not the special night time ones.


Ok, version of my patch which supports player and special colours and alphas


Ok, here a small correction of mine, no further changes of function. Codewise, I am of course leaning to mine since it does not need extra support for the objects and uses less data for display; but I am biased.

SO let's summarize the two patches:

full support of special colors and player colors

+ full 15 bit color support
+ can control which are transparent an which not
- need code for each object to enable transparency
- pak sizes nearly double when using transparency
- slower since more data used to render twice (need profiling to quantify)

+ almost any image (not for ground tiles) can use transparent colors
+ no extra efforts codewise on the objects
+ paks size stay the same (also in memory)
+ potentially faster code as only transparent bit are using slow routine (need profiling to quantify)
- transparent base colro is limited to one of the 240 base colors
- color will be one of the 224 indexed colors (the ones the player colors are finally choosen from)

Now the important question: Does the finer control with 15 bit colors instead of choosen 8 bit makes a visual difference (especially since blending means mixing with other colors anyway)?


To add - mine now works at low level so any image can have transparency. So really the difference is:

any 15 bit colour, and special/player/index colours can have colour alpha
larger pak size

special/player/index colours only can have alpha
pak size remains same

As you say, profiling could determine which is quicker, I've not noted a slowdown so far with mine even on screens with many objects (smoke), however that might change if people started using also on all object.
indexed colour alpha


Thanks, I overlooked that your last was low level too. So now both would be similar for pak developers. (Honestly, most of the time for this patch  I needed to get the transparency right in Gimp ... )

As currently pak size is not the limit (although some paks nearing 1 GB for graphics alone) the question is really, does 15 bit gives a visual difference than 8 bit base color and how much impact on the drawing. I think we need some screenshots on smoke and more profiling with trees (and maybe more than one too).


Indeed - I suspect for pak64 it wouldn't make too much of a difference with colours but for rendered paks it would be more noticeable.

It really depends what pak authors try to do with this. For shadows and transparent roofs (or even the greyscale smoke) the palette should cope fine. However having a full range of colours allows anti-aliasing around image edges which would look odd with a restricted number of colours. That said, adding alpha to that many images could well slow the game down too much in any case...


I think it may be best to combine the best of both and possibly extend the image system a litte further.

Now we have (in my patch)

(transparent pixels) (either normal pixels or with highest bit set pixel to color transform and transparency) (either zero for end of line or repeat)

maybe we should get introduce two flags

$8xxx for all following pixel transparent followed by alpha (new color alpha new color alpha) with actual length = runlen*2
$4xxx repeat this following color runlen times with actual length = 2
$Cxxx repeat following transparent color with actual length = 4

The values $8000, $4000, $C000 would be then a zero length transparent run, just to switch to transparency (for example).

This might save also a lot of memory on larger comic paks as well (and also for player colored stuff in pak64 and others).


I like kierongreen's approach more as it uses the existing routines and is not bound to special colors. Performance should not be a problem if the screen is not completely filled with transparent objects. One could also disable it on max zoom out.

Kieron, what happens if the png-images of the object and the alpha-map do not match perfectly? Is the run-length encoding taken from the object image anyway?
Parsley, sage, rosemary, and maggikraut.


Dwachs - RLE is shared between alpha and colour images yes. Code writing images enforces this and it is assumed when reading.

It's worth noting that my patch does leave 10bits per pixel unused currently. This may be seen either as a drawback or potential for future uses (e.g. player colour aliasing)


Ok, a proof of concept to have both 15 bit colors with 32 levels of transparency without wasting much space as indicated above. (One could still discuss on how to store them in memory). The zooming is not finished, because I am not sure to continue with it. It would certainly enforce 100% sync, since any transparent pixel cannot be opaque at the same time.

This is still a hack, as there is no compression of identical pixels yet (i.e. a true RLE) and no good zooming, since I am not sure if I should continue.

Thus, seeing how difficult it was to get the desired transparency for a simple tree into GIMP, I highly doubt that there will be many transparency images coming up soon which are not shadow or smoke, and hence blending with one of the 224 nearest colors may do the trick quite well. Moreover, due to the preferred fast calculation (maybe there should be a setting for makeobj to allow on demand only 25/50/75% transparency), there are only 3 bit red and blue and 3 bits green used anyway, thus in total 512 colors. The difference to 224 base colors (about 7.5 bit) is then a 3/4 bit per color and seems minor to me given the double memory footprint and computation effort.


3d rendered images have alpha channels available for no additional cost to the artist (or indeed, as pointed out in some cases a saving). Hence why I said that pak64 might not be representative of other paks in terms of colour usage.

In terms of the wasted space - in pak128 images are around 4KBytes each compressed. We've only just gone beyond the 65k image limit, so even if every single pak has an alpha channel added that would add approximately 250MByte of disc space and memory usage.

Regarding speed of calculation I'm not sure - have we done profiling here? The 32 level alpha is fairly efficient - a separate multiply of red/blue, and green components followed by a bit shift divide of each and writing the combined value (at least in my patch).

Had a quick look through that latest patch - that's a lot of work you've put into changing routines in simgraph. With the amount of extra code in there what's the performance hit (I note you haven't done the red/blue, green optimisations yet or would the compiler do this?).


Will an object (say a vehicle or a three) automatically blend to the ground/to other objects, or does one have to manually add the blending to the edges of every object graphic? Would there be a possibility/desire to blend objects automatically?


Blending objects is something that has to be done by the artist. Also it may not look great in Simutrans, rather unsharp (but that depends on pixel size and object).

For pak64 the memory impact is indeed neglible (although true RLE might even speed up drawing). But the last time I checked pak128 it was 402 MB on my harddisk, pak128.britain 229 MB, pak128.german (which is most likely to received many alphas soon) 161 MB, and pak129.comic 109 MB. Most of this space (about three quarter) is from the images. Ok, some of them are merged on load.

Also only about half of them could get transparency (trees, factories, smoke, buildings with shadows), although vehicles with shadows seems unlikely soon (as they will clash badly with the non-shadowed ones).

Adding 250 MB of main memory has some impact, especially for small VPS networking servers and smartphones and tablets and the likes where we slowly work to support them too. But then I may be too old fashioned ...

Profiling has not been done yet, sorry.


Regarding memory consumption when simutrans is running - it would be trivial in my patch (a couple of lines in and a setting in simuconf or similar) to add a reduced graphics quality setting for lower specification hardware which ignored and did not load the alpha image. You'd still have the graphics stored on disc but storage really is practically meaningless these days (even for older hardware running simutrans an extra 100mb disc space is insignificant).

Regarding adding alphas Ves, as prissi points out this will need to be done manually. Alpha could be used to give soft shadows, smooth image borders and more realistic glass, smoke and fire but this would require significant work from artists (they do like a challenge though!). The point prissi makes about unsharp is also well made - alpha would not be something to be used everywhere and anywhere just for the sake of it as it could just make everything look blurry.


I did some last thing, using 3 4 3 for encoding of the base color (31 transparency levels and 1024 colros just was enough space). That shoudl give in the end the same appearance. But tonight I will try to get some useful profiling out of it. I just want to have some more trees and some made transparent.


I'll be back to my main computer on April 2nd and will upload a bunch of alpha-enabled trees at this time, if that will be useful.  I'll also upload some buildings and vehicles as well, to round out the testing.
Current projects: Pak128 Trees, blender graphics


That would be most helpful. Manually giving trees shadow is very painful.

EDIT: It is really hard to make shadows using this feature, because at the border of a shadow the transparent color is already different, but the transparency is just below the first level. So every shadow has a blueish halo. It may work better, when there is no background at all, i.e. alllayer but the trees are transparent.