CacheAsBitmap / Blendmode Issue


#1

I’ve been trying a few things with masks and lighting effects/shadows and am not having much luck replication what you could do in Flash.

Both the highlight mask and shadow are Sprites which contain bitmaps. Both are cached as bitmap and set to blendmode layer.

The shadow then is set to alpha = 0.5, making a shadow effect, except that where the internal bitmaps are overlapping, I’m getting darker shadow, I was expecting (as per Flash) that that the layer blendmode would prevent this?

My highlite mask sprite works the same way as the shadow sprite (except it masks a graphic gradient, in a sprite with cache as bitmap) but I’m not getting the shape of the opaque parts of the bitmap, I’m getting the full bitmap rect.

I’ve tried publishing the project out as Flash (rather than HTML5) and it’s not working there either, although it does fail differently.

Any ideas as to what I can do to resolve this?


#2

The Flash blend modes work a little differently than the OpenGL or the canvas/Cairo blending modes. Perhaps if you share a screenshot of what effect you want to make, and a little bit of sample code to try and do it, people may be able to experiment?


#3

Thanks @singmajesty,
I had a think about how best to resolve this issue (because like most things there are a number of ways of approaching it.)
If you look at the attached image, this explains what I’d like to be able to do.
MASK

The first part is my bitmap, just a black circle on transparent.

I then want to combine a number of these in a sprite, this is part 2 (bear in mind that the individual bitmaps can move)

Then I’d like to use this sprite as a mask, as per part 3.

I would have expected that the above method would do this, but it doesn (the cacheAsBitmap part for step 2 doesn’t work for me - as mentioned above I just get a mask of the bitmap rect.)

If someone could tell me a way to make this happen, well, that would be amazing!

I just had a quick check, to see if I was using WebGL - because I’ve templated off an older project am using haxedef name=“legacy” which I presume means I’m targeting Canvas. This would be my preference anyway, as I know some of my target platforms work better this way.

Code wise I’m doing something like this:

bmd = Assets.getBitmapData(“img/shape.png”);

var b:Bitmap;
b = new Bitmap(bmd, openfl.display.PixelSnapping.NEVER, true);

this.container = new Sprite();
this.container.addChild(b); // obviously this would be within a loop to create a number of shapes
this.container.cacheAsBitmap = true;

this.shape.cacheAsBitmap = true;
this.shape.mask = this.container;


#4

It’s a workaround, but this works currently on the OpenGL renderer:

package;


import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.Sprite;


class Main extends Sprite {
	
	
	public function new () {
		
		super ();
		
		var stripes = new Sprite ();
		
		for (i in 0...50) {
			
			var even = (i % 2 == 0);
			stripes.graphics.beginFill (even ? 0xFF0000 : 0x00FF00);
			stripes.graphics.drawRect (i * 4, 0, 4, stage.stageHeight);
			
		}
		
		addChild (stripes);
		
		var donut = new Sprite ();
		makeDonut (donut, 40, 40);
		var donutBitmapData = new BitmapData (Std.int (donut.width), Std.int (donut.height), true, 0);
		donutBitmapData.draw (donut);
		var donutBitmap = new Bitmap (donutBitmapData);
		// addChild (donutBitmap);
		
		// stripes.mask = donutBitmap;
		stripes.mask = donut;
		
	}
	
	
	private function makeDonut (sprite:Sprite, x:Float, y:Float):Void {
		
		sprite.graphics.beginFill (0, 1);
		sprite.graphics.drawCircle (x, y, 20);
		sprite.graphics.drawCircle (x, y, 40);
		sprite.graphics.endFill ();
		
	}
	
	
}

The inside is filled on software and on Flash, I think we need to implement the cacheAsBitmap alpha masking behavior from Flash to fully support what you want