Layers and Blend modes

Discussion and feedback on Construct 2

Post » Thu Feb 07, 2013 1:06 am

Hello! This is my first week with Construct 2 and I'm excited with what I've seen so far and amazed by the length of the FAQ!

My question is regarding the compositing process in general, as I'd like to have a better understanding of how layers, z-order, and blend modes affect the final image.

A specific scenario I have been unable to understand is in regards to "spotlight" effects:

In the Lighting Demo, this is achieved by having a lighting layer with a black, opaque background. The "spotlight" sprites on top are blended as "Destination out" in order to "burn a hole" through the black background. Then, the layer is rendered through "Force own texture" (it's necessary but I don't know why) and blended as Normal onto the layers below.

My initial attempt to do the same effect was like this:

Lighting sprites are blended as Normal onto the lighting layer. The layer is otherwise transparent, and the layer is blended as "Destination in" onto the lower layers, to hide any area that is still transparent on the lighting layer.

This appears to work perfectly in the editor, but when running the game, the area that should be black is actually transparent, and I don't know why or how to fill it in. Choosing "Force own texture" on the layer has no effect. To show the difference, I included both techniques in a project, and coloured the html demo's background purple so the transparency problem in my technique would be obvious.

capx
https://dl.dropbox.com/u/117529592/Construct%202/Forum%20questions/LightingAndBlendModes.capx

html demo
https://dl.dropbox.com/u/117529592/Construct%202/Forum%20questions/LightingAndBlendModes/index.html

(Sorry for not having clickable links, but I'm a new user and the forum disallows it)

If anyone could explain why I end up with a transparent background (and if I can make it black), why it looks right in the editor, how "Force own texture" affects the rendering process (I know it renders the full layer separately, but what are the implications aside from performance), or how layering and blending work in general, it would be greatly appreciated!

Thanks!Cowdozer2013-02-07 01:11:16
B
6
Posts: 26
Reputation: 577

Post » Sun Feb 10, 2013 10:08 am

*bump* Is there anything I can do to make my question more clear, or is everyone else just as confused? :p
B
6
Posts: 26
Reputation: 577

Post » Sun Feb 10, 2013 11:47 am

Without force own texture, imagine that all your objects are gathered in one layer (respecting the their layer repartition for z sorting) and then rendered

If a layer has force own texture on, their object will be kind of baked into one canvas, and then this intermediary rendering will be used instead of the objects (this intermediary rendering is what makes using force own texture slightly slower)

The consequence of that, is that effects are limited to one layer. If you burn hole you can, in a way control which which object you will affect this way.

In your implementation, you put an effect on the entire layer, so it will be applyed to everything underneath.
If an object is in Destination-in, everything underneath its transparent pixels will be erased, else revealed.
Since your layer is mostly transparent except for the few light sprite that are on it, only what's under your light sprites will be revealed, else you'll see the background of the HTML element containing the C2 canvas (gray in the preview)

You see black in the editor, it's because it's the color of nothing (:
destination in totally erased eveything on the viewport.
Try changing the background color of your Lighting or Background layers you'll see nothing will change, the black isn't the color of your Lighting layer (how could it be, it's a transparent layer (: )




Yann2013-02-10 11:52:07
B
60
S
22
G
14
Posts: 1,479
Reputation: 16,346

Post » Sun Feb 10, 2013 10:48 pm

Thanks Yann! It's still a little confusing, but your explanation really helps! That's a very good point about black being the colour of nothing in the editor. But if that is indeed the case, then why is the editor's colour of nothing typically light blue? If you make all layers invisible or make them (semi)transparent, you see that the background colour of the editor is light blue, not black. Do you think that maybe the Destination In effect is burning through the editor's background colour as well? If so, I'd consider that a small bug in the editor view.

Another potential editor view bug is that I found you could set the light blend mode to XOR and get the same effect as Destination Out, but the editor view would show it opaque (as if blend mode were Normal). There seem to be some other weird things with XOR, such as it still having an effect on the overall image even if you make the layer Transparent. Either I am misunderstanding something (quite likely), or it's behaving incorrectly.

I'll try to paraphrase and expand on your overall explanation:
My understanding is that rendering is done starting with the lowest layer, and each layer renders objects using z-order from lowest to highest. Force Own Texture will render a layer on its own, independent of layers above and below it, and the visual effect of this is that blending modes on objects within that layer will only be applied to objects and the background of that layer, and not to anything rendered on lower layers. Once it's rendered to a texture, the layer will be rendered over the output of the layers below using the layer blend mode. This all seems to make sense and agree with my observations, EXCEPT:

I found another way to do this lighting without Force Own Texture! This time, I have the lighting sprites blend mode Destination Out (same as demo), and the Lighting layer is Black, but instead of enabling Force Own Texture, I set Opacity to 99.999%. It seems that layer opacity has an effect as to whether a sprite's blend mode stops at the current layer or applies to all layers below it. If the layer is opaque, sprite blend modes apply to everything below it, but if the layer is semitransparent, sprite blend modes only apply to the current layer. Since Opacity is at 99.999%, it's enough to trigger this different behaviour, but 99.999% is visually opaque (it might indeed be opaque, although I'd have to screenshot and test pixel values).

I wonder, is this method notably more efficient? From what I understand, it should be considerably more efficient. I also wonder if XOR is more or less efficient than Destination Out, because those two blend modes seem to be visually equivalent in this situation.

I've updated the capx and html with a third layout. The third has settings:
Lighting layer: background black and 99.999% opaque, blend Normal.
Lighting sprites: XOR for mouse, Destination out for 8Direction.


capx
https://dl.dropbox.com/u/117529592/Construct%202/Forum%20questions/LightingAndBlendModes.capx

html demo
https://dl.dropbox.com/u/117529592/Construct%202/Forum%20questions/LightingAndBlendModes/index.html

Aside (not really important):
One thing that I could see value in is having a Force Own Texture mode that forces this layer and all above layers to a texture. I think this would allow for implementation of certain effects more easily (or maybe just conceptually more straightforward), but make other effects impossible. I think it's probably fine as it is, and you can probably get whatever effect you want with enough layers and the right settings.

Thanks again for your help!Cowdozer2013-02-10 22:49:44
B
6
Posts: 26
Reputation: 577

Post » Fri Feb 22, 2013 9:32 am

So I did a bit of research and after getting a bit more info from this post (http://www.scirra.com/forum/topic60071_post391987.html#369144), I took a look at the [Construct2 path]\exporters\html5\layout.js file to see how it's done.
Functions Layer.prototype.draw and Layer.prototype.drawGL make it obvious that there are 4 ways that a layer will be rendered to its own texture:
[code]// Needs own texture
this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0
                         || this.active_effect_types.length > 0
                         || this.blend_mode !== 0);[/code]
This also shows that my setting opacity to 99.999% was doing nothing but triggering the layer to be rendered off-screen, so it provides absolutely no performance improvement over enabling the layer's Force Own Texture mode. It also shows that if you have set a Blend Mode for the layer, it will automatically render off-screen, and the Force Own Texture setting will not make a difference. Force Own Texture is only needed when sprites on the layer have a special blend mode that you only want to apply to the current layer.

Aside from that, the description I had in the previous post about the rendering process was pretty correct.Cowdozer2013-02-22 09:33:30
B
6
Posts: 26
Reputation: 577


Return to Construct 2 General

Who is online

Users browsing this forum: gamecorpstudio and 15 guests