“Layer grouping for effects, or scene-wide effects”

EDIT: I think Silver-Streak words it better than I can.

Original post: Simply put, I want the ability to apply an effect to a group of layers after they are rendered, as a single container (in a similar manner to how object effects are affected by layer effects). Currently, to have a similar effect to what I am describing you need to render the entire scene into a sprite using the sprite snapshot extension and then apply effects to said sprite, which is inflexible, and very costly, performance wise.

It’d allow for a much greater variety of visual effects, in a manner that theoretically would be much less costly than re-rendering the entire scene into a sprite, and then applying effects to said sprite.

Thank you for your consideration.

Visual examples of using a color map on all layers simultaneously:
TUlSfl1 gHZdr51

Currently, this is possible in-engine, but as mentioned above, it’s highly costly, performance wise, due to having to render the entire scene into a sprite before we can do any kind of post-processing, making it unviable for mobile browser games, and mobile games in general.

Having the ability to globally apply effects to a scene, or to a chosen set of layers, would allow similar effects to the ones displayed above.

2 Likes

The amount of events needed to do this, plus the extension, is probably the same amount of effort as applying the effect to each layer. Applying them to each layer is probably much less performance impacting than your current method.

Is there a reason you’re not just doing that currently instead of rendering the entire scene twice?

The main reason has to do with the fact that I need to add a dither to the entire image, which can only be done through this method. What I am effectively doing is having a tiled sprite in screen blending mode overlay the entire game, and then rendering the contents of the game into the sprite, which then uses the color map to automatically apply dithering to every element, dynamically.

I can’t really put everything on a single layer either, as some layers have outline effects, outlines that would disappear if it were all on a single layer. Ultimately, the reason why I need to have that effect stack is due to the fact that if I didn’t, many effects would become moot.

There’s also the fact that adding such a feature would be a massive QOL improvement for gdevelop users in general, as you could have a single place to adjust all of a scene’s effects, rather than having to do so on every layer individually. so even if you aren’t doing something as specific as me, it’d still improve the engine workflow.

And I know it’s possible, as I’m already doing it the inefficient way.

Another thing I’ll need to mention is how performance draining effects are, especially when you have multiple of them in a single scene. Even having 4 effects on a layer causes performance to take a big hit, let alone having the same redundant effect on each layer being rendered over and over again. I had previously tried applying the effects individually on each layer, but it was so ressource consuming that I had to use the method that I do, AS A RESSOURCE SAVING MEASURE.

For example, the reason why I have outlined objects on one layer, rather than outlining every single object, is that having the effect happen on that one layer SIGNIFICANTLY reduces the hit to performance, as you are only rendering the effect once, rather than multiple times over on each object.

Now, imagine using an effect like CRT or color map (both of which are significantly heavier than outlines) on your main layer, your UI layer, your paralax scrolling layer, your background layer, etc. all at once.You’d be toasting actual powerful computers.

Unfortunately, grouped layers/layer effects won’t solve this need for you. It would still have to apply the effect to each layer in the background, each layer is still a unique layer (and unique camera), so the dithering would move differently per layer, unless you are mirroring the cameras on each layer (or they are static) at which point you are better off putting everything on one layer at that point.

Sadly, None of what you are asking for which change the resources needed. The layers will still have to have the effects applied on each, even if you as the game dev are only applying it once in the IDE. The only other option would be to do a second pass on everything as a merged layer after all events and graphic rendering is done, which would be running a rendering pass twice on the entire game, which would be the same performance impact as what you are doing right now.

To be clear, this would help with a UX change reducing the number of clicks/extensions to set up this method initially, which I agree with. I just want to make clear that it would not be some magic bullet for what you are running into, performance wise.

First of all, the dither pattern is on the top layer, overlaying all of the others. Basically a translucent square that covers the image as a whole.

Secondly, What I’m asking is something that would apply effects on the container that has all of the layers, not something that applies effects on each layer individually. In the same way that a sprite with an effect applied to it will have the end result of the effect be affected by a layer effect, I want a sublayer/group of layers be affected after they rendered by their parent/container’s effect. Which is different from just applying the effect on each layer individually.

It’s something that is entirely possible to do with the PixiJS renderer, as it’s already being done to some level.

Having the option to have something like what I am describing, or even something like a scene effect would erase the need for one to render an entire scene twice, which would nearly halve the rendering performance cost.

This is a bit different than your original request around the layers, would still require a new global container system of some kind to be built, and the effect system itself to be reworked a bit at how it looks at content, but yes it should be technically possible.

It may or may not have a noticeable performance impact (they wouldn’t suddenly need to stop addressing layer logic, so it would be a container of containers and rendering needs would not necessarily be reduced for some things), but would definitely be more impactful than just the ability to group layers.

I did specify that I wanted the effect applied to the group of layers after they were rendered, although I guess I wasn’t necessarily clear.

Should I edit the initial post to clarify?

1 Like

I think the context in the thread here is helpful for the devs when/if they review it.

Just to confirm, super high level summary:

Main asks:

  • Some way to apply an Effect in GDevelop (a PixiJS Filter) to an entire user-defined container, or at bare minimum the entire scene, rather than only on a single layer or an object.
  • This should allow for the entire canvas, but also hopefully with some way to select subsets of layers (such as grouping layers so you can apply all effects to the entire group at once and have it render as one effect)

Reasoning/benefit:

  • There are many layer effects that need to be layer independent to appear as intended (or desired). Currently even if you apply it to each layer they’re going to look incorrect because of layer movement.
    • e.g. Ascii effect, Displacement Map, Dot/halftone, pixelate, etc.
  • While the quantity of objects the effect is being applied to will remain the same, the amount of effect (filter) instances would be reduced. This could potentially help performance.
  • Edit: (forgot one) by having a larger container but maintaining the layers themselves, you can have effects that apply to X layers but still have some effects only applying to one or two within.
  • From a UX perspective, this dramatically reduces the amount of extra setup needed for these type of effects, not just from a adding effect perspective, but from number of events/variables/etc to keep those effects settings in sync if you are changing them dynamically during the game. (moving a displacement map, increasing pixelate for a fade in/out effect, etc)

Notes for devs: Per PixiJS’s API documentation, the preferred method is to apply filters to as large a container as possible, so this may enable getting closer to their recommended use case. PixiJS API Documentation

@sonic507d If the above matches your understanding, feel free to quote it in your OP. I’d also recommend updating the topic title to “Layer grouping for effects, or scene-wide effects” or something similar.

2 Likes