News:

Simutrans Wiki Manual
The official on-line manual for Simutrans. Read and contribute.

Darker special color for windows

Started by Zeno, January 29, 2012, 05:07:51 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Zeno

Both of the two available colors for windows look odd in many of pak128's trains because it's a too light grey and a bit more contrast would be required most of the times. I guess that changing a current special color would be crazy, so I hope it's possible to add an additional color for use in vehicle windows. A darker grey such as #262626 would be nice, but before discussing it would be nice to know whether it's possible or not, or which reasons there are in favour or against. Thank you.

PS: An example of what I try to explain can be seen in the two attached vehicles; in the first one the windows are not visible during day, while in the second they are more visible.

The Hood

I've been thinking about this too. Pak128.Britain uses very dark black for windows and at present we don't use night lights. What I'd like to see is a way of choosing special night colours e.g. in a config file, so that I could chose e.g. 010101 as being a night colour for pak128.Britain.

Fabio

I often feel that more special colours would be needed, maybe more than just this one.

In a way, I would like them to be pakset-customizable instead of hardcoded. Paksets could have a tab file or a compiled pak object with three entries per line: png colour, day colour and night colour. Display routines could lookup this table and replace colours accordingly.

Also more player colours would be nice, for better antialiasing.




The Hood preceded me...

Zeno

Well, I would like just a change on the window color, but I understand that is not practical as it would modify/leave useless all existing material.

About player colors, the more colors you use for AA, the less you'll have as "normal" colors. For player colors, instead of adding more colors I'd prefer a system such as OTTD's one, which is far in front of us at that: each object is composed by two images, the normal image and a mask image (#FF8000 IIRC) that only shows the places where player color should be applied. Then when you select a player color, the selected color is antialiased all over the mask zone, following the original image reference to reproduce the same area with a different color. I don't know exactly about the coding of this, but I can have an idea of the concept. Results are simply awful, like comparing 16M colors to a CGA 4 color display. Of course that will be probably expensive in memory and/or cpu terms.

wlindley

How about modifying makeobj's png converter so that:

       
  • Transparent in the source PNG should mean transparent in the pakfile.  That alone should make translation from 3D models easier.
  • Images can have optional mask image, such that all colors in the regular painted PNG are permissible (no special colors) -- and the existing special palette colors would be used in the mask image.  Again, the PNG reader should understand Transparent in the mask image as really meaning transparent.
  • Non-special colors in the mask image would have no effect.  Thus, when makeobj reads an existing DAT, with no masks, would default to using the existing PNG as both the image and the mask, and everything would Just Work.  New DATs actually wanting no mask, would use the new parameter with a blank value.
  • The executable program would likewise regard a missing mask as being the same as the image, to maintain full compatibility with existing PAK files.

In the case of windows and other night-colors, the executable would leave the read-in image colors alone during day, and set to the existing special colors at night.


prissi

#5
What two avialable colors? There are 10 colors for windows, see the attached file.

But actually, what kind of vehicle has black windows during day?

About colors on the fly: This is not possible, the special colors are converted during pak file image conversion. OpenTTD can do this easily, since it has only 8 bit palette. As such trnsparency is just a special color. The 32 bit version use alpha blending indeed, but reduce many graphics effect du to processor load (or rather bus load).

Introducing another special color in makeobj is easy: But it would appear in all previous objects, thus you have to use a new version of shades on any of them ...

Zeno

Quote from: prissi on January 29, 2012, 08:27:25 PM
What two avialable colors? There are 10 colors for windows, see the attached file.
There are two grey window colors candidate for a "dark" window.

Quote from: prissi on January 29, 2012, 08:27:25 PM
But actually, what kind of vehicle has black windows during day?
Dunno in Germany, but in spain most passenger trains have darkened glass windows that look like plain black when seen from 50 or 100 m.

Anyway, I tried all other reasonable colors (green, red, magenta, blue and yellow are not appropiate for a window) and the vehicles keep looking odd for same reason. None of them make contrast enough with the vehicle's body paint. I will try providing a frame for those windows or other workaround :(

Fabio

Could you please consider this requests:


Shadow
Presently shadows (e.g. trees) are painted with a cris-cross pattern of black pixels.
New special color #3A4040 would be painted as a 50% transparent black pixel.


Light
Special color #B9CCCC could be totally transparent in daylight, but turn 50% transparent light at night.
This could be used e.g. for street lamps and other light sources.


The first one is much more important, IMHO.






If special colors are to be compiled by Makeobj, why not include them (well, the non standard ones) in DAT files?
E.g.

NightColor[0]=#FF8000


Spike

My arts book says, that in shadows the scattered blue light of the sky is present while the yellow direct light from sun is blocked, and therefore suggests to give shadows a slight blue tint (if blue sky is assumed).

kierongreen

Could just make it so that the current grey indicates window, then it is up to the pak to define what colour this will appear in game in the day and at night. That way we don't end up using any more special colours, and backwards compatibility is retained?

Although I guess fabio and TheHoods suggestions would allow this anyway after rereading!

prissi

Using a pak to overide day and night special colors is easy.

Using transparency to render will take more time and may not get the intended results. But the main problem is than any new special color will require a recoding of all pngs to remove/include it for all paks to be compiled by makeobj. I can here the crys of joy from the pak set authors (including mine).

Fabio

A simple script could change those special colours, and if it becomes pakset-dependent, it will only affect paksets willing to undergo a similar process.

Transparency would enhance shadows dramatically, which are the main drawbacks in your opinion?

Ters

I fear that alpha blending/transparency, without hardware acceleration like in Simutrans3D, will easily cut frame rate in half. It will of course vary with how many shadows or other transparent objects there are on the screen.

kierongreen

Alpha blending is very slow (relatively) compared to just normal plotting. In game I'm running at the moment it's getting to point where I have to turn off station coverage unless I really need to check it or game is unplayable (note - I wrote a lot of the early code for blending!)

Fabio

Well, having shadows in a special colour, couldn't set in display options dialog whether we want it drawn as solid 50% transparency or dark colour - full transparency pattern.

prissi

There is still the issue that a new color require all paksets to treat their images with a new version of shades. Apart from the speed issue.

As kierongreen supports my no on special transparent colors, ill move this to denied, even though pak-set configurable special colors may come.

sdog

kierongreen's suggestion from above would not require pak-sets to re-draw their images:
Quote from: kierongreen on February 02, 2012, 04:13:09 PM
Could just make it so that the current grey indicates window, then it is up to the pak to define what colour this will appear in game in the day and at night. That way we don't end up using any more special colours, and backwards compatibility is retained?

edit:
just realized i'm beating a dead horse here, sorry haven't seen it was already moved to denied patches.

VS

The irony is that the original request (in thread title) is not entirely denied, only what was discussed in the whole thread is denied :P

My projects... Tools for messing with Simutrans graphics. Graphic archive - templates and some other stuff for painters. Development logs for most recent information on what is going on. And of course pak128!

Spike

I haven't checked the alpha blending code yet, but a 50% blend can be cheated very fast

assuming 8 bit per channel RGB:


   int rgb1, rgb2;
   ...
   int blended = ((rgb1 & 0x00FEFEFE) + (rgb2 & 0x00FEFEFE)) >> 1;


That should be quite fast. I used that with good success in other projects.

Edit: If it's already done this way, I'm sorry, didn't want to play Mr. "I know it better", but it's late and I should get some sleep, and don't want to check the code now ... hopefully the snippet will help. Same trick can be done in rgb 555, but I don't have the mask values right available from memory.

kierongreen

I'm pretty sure I did it this way - actually I think 1/4 and 3/4 blends were also hardcoded maybe.

Ters

I wan't so much worried about the math, but the fact that you need an extra read operation. Of course, if Simutrans renders a complete tile at a time (I haven't checked), caching might help somewhat.

kierongreen

Once you get down to machine code there's no such thing as rendering a complete tile at a time. Well, at least unless you are using hardware accelerated graphics. It's not just the extra read operation alone that will slow things down, it'll be the knock on affect on register usage and memory caching. Plotting a tile, with clipping and a simple 1 bit transparency maybe uses 5 registers for each line loop - read address, write address, image pixel, transparent colour and end of line address. If you want to just add one colour for half transparency you need to add two registers to that, the semi transparent colour and background pixel.

Dwachs

Quote from: prissi on February 03, 2012, 02:05:33 PM
even though pak-set configurable special colors may come.
... which is reality since r5187 thanks to prissi.

have fun :)
Parsley, sage, rosemary, and maggikraut.

Fabio

Quote from: Dwachs on February 05, 2012, 09:56:26 AM
... which is reality since r5187 thanks to prissi.

have fun :)

Awesome! Could you please document how should it be coded in dat? Thanks in advance!


Ters

Quote from: kierongreen on February 05, 2012, 09:42:16 AM
Once you get down to machine code there's no such thing as rendering a complete tile at a time. Well, at least unless you are using hardware accelerated graphics. It's not just the extra read operation alone that will slow things down, it'll be the knock on affect on register usage and memory caching.

I wasn't thinking of some single instruction that draws a tile, but that rendering finishes drawing in a very confined area before moving on to draw somewhere else. That way, (almost) the entire tile could fit in the cache.

Quote from: kierongreen on February 05, 2012, 09:42:16 AM
Plotting a tile, with clipping and a simple 1 bit transparency maybe uses 5 registers for each line loop - read address, write address, image pixel, transparent colour and end of line address. If you want to just add one colour for half transparency you need to add two registers to that, the semi transparent colour and background pixel.

You can't keep the background colour in a register without a to me very exotic way of drawing things, but then you would need multiple read adresses, one for each sprite covering the pixel.
Normal rendering with only 100 % transparency would go as follows:

read pixel from sprite
if pixel is not transparent
    write pixel to render buffer

With blending, it becomes:

read pixel from sprite
read pixel from render buffer
blend the colours
write pixel to render buffer

The second read is what worries me. One could of course move the second read and the blending into an if block, but that would only help where there is no partial transparency. Or is there something I have overlooked?

The Hood

Question (maybe I'm being dumb) - what does 0x01 mean as a colour? I thought they would be specified as six digit hex codes...

jamespetts

Is 0x not just the initialisation string to tell the compiler (or Makeobj in this case) that the following number is hexidecimal? So 0x01 in hex is the same as 1 in decimal (and octal, and binary and just about every other number base that one cares to imagine...).
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Fabio

Quote from: Ters on February 05, 2012, 12:34:53 PM
Normal rendering with only 100 % transparency would go as follows:

read pixel from sprite
if pixel is not transparent
    write pixel to render buffer

With blending, it becomes:

read pixel from sprite
read pixel from render buffer
blend the colours
write pixel to render buffer

The second read is what worries me. One could of course move the second read and the blending into an if block, but that would only help where there is no partial transparency. Or is there something I have overlooked?

Putting the second reading in an if block would help, as this half transparency would be used in a very limited number of pixels. Empirically, for a tree it would be less than 1 quarter of pixels in a tile, but probably quite less.
E.g.

Read from image
If not transparent then
If half_transparent then
Read from buffer
Blend colors
Write to buffer
Else
Write to buffer


Only a heavy use of transparency would impact performance, a limited use (e.g. For shadows) would have minimal impact.

Even a true alpha channel would have a limited impact as it would be mostly used for antialiasing, so limited to edges.

Reading routine could then use a threshold:
0-40% full transparency
41-90% half transparency
91-100% fully opaque

jamespetts

I think that the code for reading hexadecimal values is causing errors here - get_int() seems to be clipping the first digit from a number in a .dat file when it reads non-hexadecimal numbers, so that, for example, 117 becomes 17. I should note that this problem appears in the "111.1 merge" branch of Experimental, so it is not impossible that there is some issue with merging the two, but I think this unlikely, as the get_int() code has always been the same in Standard as Experimental.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Markohs

#30
Maybe a petter aproach is using RGBA 32-bit per pixel objects to give complete flexibility to the PAK creators. Even making the PAK distribution in a a new format, just a .ZIP file with PNG's and .dat .

EDIT: I should have read the entire thread before posting, you already talked about an alpha channel.

Dwachs

Quote from: jamespetts on February 05, 2012, 04:32:53 PM
I think that the code for reading hexadecimal values is causing errors here - get_int() seems to be clipping the first digit from a number in a .dat file when it reads non-hexadecimal numbers, so that, for example, 117 becomes 17. I should note that this problem appears in the "111.1 merge" branch of Experimental, so it is not impossible that there is some issue with merging the two, but I think this unlikely, as the get_int() code has always been the same in Standard as Experimental.
This should be fixed already.
Parsley, sage, rosemary, and maggikraut.

jamespetts

Aha, excellent! I know that the Github version of Standard is sometimes a little behind the SVN version.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Ters

Quote from: fabio on February 05, 2012, 04:22:42 PM
Only a heavy use of transparency would impact performance, a limited use (e.g. For shadows) would have minimal impact.

I wouldn't call shadows a limited use of transparency. As far as I can see, most trees cast one. It is less than the transparency used for hidden trees and buildings, though, but that made my former computer lag when panning around.

The Hood

Quote from: jamespetts on February 05, 2012, 02:57:12 PM
Is 0x not just the initialisation string to tell the compiler (or Makeobj in this case) that the following number is hexidecimal? So 0x01 in hex is the same as 1 in decimal (and octal, and binary and just about every other number base that one cares to imagine...).

I still don't get how 0x01 is supposed to be hex. Surely that leaves just "01"? How would I code #000000 (for example) to be a special colour?

VS

#35
To answer directly what you're asking - in this format it would be: 0x00, 0x00, 0x00

But you must understand that this only changes the appearance of already existing specials. The first three umbers encode day and the next three night colour. But the actual colour in images is still the same as before. When editing simuconf.tab, you "select" the original with the number in brackets, then give how it should look. The current entries just repeat the old table, so that everything looks the same.

You could try changing one of the entries to 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF (might need spaces or lowercase?) and get some unexpected results (one of the specials will now always be saturated red, with any existing pakset). Thus, I fear that this is bordering on useless, since a change in this table would break all backwards compatibility.

edit: It's not useless, but useful only for future paksets that start with clean slate. Either that, or a massive overhaul of already existing pakset.

edit2: I will try to assemble some statistics on actual usage of specials (in near future). Maybe there are some unpopular ones...

My projects... Tools for messing with Simutrans graphics. Graphic archive - templates and some other stuff for painters. Development logs for most recent information on what is going on. And of course pak128!

The Hood

Thanks VS, that's helpful. Backwards compatibility won't be a problem with pak128.Britain as currently there are no night colours whatsoever. If I understand correctly, in order to get night colours I would have to use shades or similar to paint on the special colours where desired (making the windows appear special grey in the image rather than pak128.Britain black in the png file) then use the entries in simuconf.tab to get the program to redraw these as black in daytime (to get the same appearance as now) and whatever I chose for night. Is this right?

Fabio

An extremely simple Imagemagick script could do the trick of replacing e.g. 0x090909 (new special colour) with 0x0a0a0a in all images in a folder in minutes. Just run it locally and commit to svn. If we decide for new colors, I can help with the script.

VS

Hood -> Yes. However, while drawing in Shades or any other program, you will still see just the "original" colours, only their appearance [later] in game will change. Let's say you convert the five greys to other colours. Then, you'll have to paint still with the greys, even though they would be red or white in game.

Fabio -> Sorry, but you're totally out of the loop :P The current specials stay. You can just configure how they look. We got no new colours. We can only change the old ones. This breaks all the images, as the specials are already used.

My projects... Tools for messing with Simutrans graphics. Graphic archive - templates and some other stuff for painters. Development logs for most recent information on what is going on. And of course pak128!

prissi

Pink (was only added for french signals) and blue lights are almost not used.

Spike


Fabio

Sorry, I got it completely wrong this time. I thought it was about mapping new colours and associated problems, not redefining old ones to newer values.

kierongreen

QuoteYou can't keep the background colour in a register without a to me very exotic way of drawing things
What I was meaning was the transparent colour - as in, the value you will test an image pixel against to determine whether the following however many pixels are transparent. I think I used this method in one of my own projects.

Actually the simutrans image code works slightly differently than I remembered (it has been several years since I last looked at it!) - it uses a pixel counter to say how many transparent or opaque pixels follows. This means that adding a special shadow colour is much, much more of a performance hit.

For each line currently when plotting simutrans does:

do
  read number of transparent pixels, and skip over these

  read number of opaque pixels
  for each opaque pixel
    copy from source to destination

until no pixels remaining;


The plot can be a straight copy, or a 25%, 50% or 75% blend of either the image or it's outline with the background - there is no function for an arbitrary % blend. In each of these cases plot or blend is a simple function which is just a loop plotting or blending x number of pixels.

Note that at the moment blends only use image outlines - if I remember correctly this was due to both being faster and producing a better effect in game.

Now, if we were to allow one 50% special colour transparency for shadows this would mean:

do
  read number of transparent pixels, and skip over these

  read number of opaque pixels
  for each opaque pixel
    test to see whether a shadow
      YES: blend black colour
      NO: copy from source to destination
until no pixels remaining;


When plotting an image every pixel will be slower than normal, with shadow pixels slower still. Purely guessing (if anyone is interested they could try to benchmark) I'd say image plotting would be around 5% slower for an image with no shadows, rising to maybe 40% slower for one with lots of shadow pixels.

Also an image with blended shadows will have twice the number of shadow pixels as one using a dithered shadow pattern - for a typical tree this may result in around 10% more pixels being plotted, further contributing to performance loss. However for clipped plotting in particular this is very slightly offset by not having to switch between skipping and plotting pixels.

colonyan

"special_color[0]=0x57, 0x65, 0x6F, 0xD3, 0xC3, 0x80 ,,, "
I can not figure why there are 6 colours assigned for each special colour.
Basically this allows to designate day colour for each night time colour right?
Can someone share how to use these lines?