Author Topic: How to do dynamic lighting by partially undoing a colorTransform  (Read 393 times)

sano98

  • New Member
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Hi, fellow developers!

For my current project, where I am deploying to flash target, I’m looking for a way to undo the colorTransformation of an FlxSprite or FlxTilemap for those pixels where it overlaps with another object.

Let me explain:
On screen, I have a building with windows and a day and night cycle. I adjust the color of the sky repeatedly during one day.


Obviously, I also needed lighting effects for the interior. The usual way dynamic lighting is suggested in flixel is to layer a black, semitransparent graphic over the screen and then cut out the areas where there is a light source. I didn’t like this solution, as it also darkens areas which wouldn’t need darkening – like the moon shining in from the outside.

Instead, I decided to repeatedly adjust the .color-attribute of each relevant FlxSprite and FlxTilemap.


Code: [Select]
currentColor.adjustToDayTime(); //some function is updating the variable currentColor
Registry.buildingStructureTileMap.color = currentColor;
for (i in 0...Registry.objectGroup.length)
{
Registry.objectGroup.members[i].color = currentColor;
}

This led to some nice light moods with reasonable performance.




Now, in order to create a light source in the building, I am trying to achieve something like this:



Basically, I want the colorTransformation to be undone in those regions that are hit by light (=overlapping with a light-cone FlxSprite)
I haven’t been successful so far, but I have several approaches how to do this:



Write my own blendmode

A blendmode defines how overlapping pixels are represented on the screen. Normally, only the top pixel is shown, but the rules can be modified at will.
So, I was thinking when object A has an intersection with lightsource B, my rule should state that the original, unmodified pixels of A should be shown on screen. As in before the colorTransformation took place. The original bitmap must still linger somewhere in the memory anyways, as repeated changes of the .color-attribute are always applied to the original graphic (coloring an object yellow and then red will leave it red, not orange).
The problem is that I was unable to find the code for the blendmodes in the first place. It seems not to be a part of the haxeFlixel library, and I couldn’t find them in the openfl libs either. It is probably hidden somewhere deep down in lime or even flash itself – I have no clue.


Use Alpha masks

The alphaMask-function from the FlxSpriteUtil-package sound like a very good idea – alpha masks do exactly what I am looking for – they take a source graphic (for me, my uncolored original) , a mask (my light cone) and an output, where the source graphic is being placed into (the colorized version of my object on the screen).
But I couldn’t get this to work, either. The limitation that the mask must be of the same size as the source are a primary obstacle. Furthermore, it doesn’t seem to be working with Tilemaps, and with animated FlxSprites, it loaded the whole spritesheet instead of only the current frame.


Write something from scratch


So, that’s about it. Any suggestions or advice?
Many thanks,
-sano