GNOME Bugzilla – Bug 604715
Layer groups need a pass-through mode
Last modified: 2017-08-08 19:48:24 UTC
Created attachment 149829 [details] xcf file hi, changing the layermode of a layer which is in a layer group (overlay, for example) doesn't really work. But when the layer is outside of a layergroup, it works. seems that the layergroup can't access the pixeldata below it i attached a xcf file which should explain it
I think that's the intended behavior. The whole point of layer groups is that the layers inside don't interact with the layers underneath.
I can reproduce this and I'd say we need to fix this for 2.8.
We will clearly not fix this because it is precisely how it is supposed to work. Layer trees are a hierarchical composition, so in order to do "overlay" on the tree below, the only way of doing this is setting the group layer itself to overlay. Layer modes inside the group of course have no effect on the pixels outside the group.
i don't think that the current way is useful. its useless that you only can set the whole group to layermode XYZ and not single layers. i personally use layergroups to get a better ordering and not creating completely "new objects" that can't affect the rest stuff.
You can use layer modes inside a group, and they will affect the layers below *inside* the group. Groups in GIMP are true "sub-images", not just a means to organize and partly hide away a large list of layers.
I must have done something weird the first time, things work as I expect them to when I try again. So I agree with the resolution as NOTABUG. Ihave, it would be interesting though if you could show a composition where this feature would make sense to have.
(In reply to Michael Natterer from comment #5) > You can use layer modes inside a group, and they will affect the layers > below *inside* the group. > > Groups in GIMP are true "sub-images", not just a means to organize and > partly hide away a large list of layers. (And also to previous flow of the discussion) This is true, but... Imagine situation You are using Gimp for creating multilayered image. Lets say We do have the texture of female face(s) so beside several base textures of different faces (with normal filter, 100% opacity), You also need aditional alyers for diferent haircolours, makeups, facepaints/tattoos and so on. In case I would like to maintain variability to some kind, it is rather necessary to have option to stack various layers with different (pieces of) makeups, haircolours, facepaints. In that manner it is possible to create different versions of same base face with different makeup and or hairstyles, and also to reuse (if applicable) one on different face. In this manner it will be good to have not only stacking in the group, but also standard stacking from bellow. I am still able to nest groups one into another, but this is... Well what Should I do in case I need to turn off one type of layers (e.g. tattoos) to this particulary face texture? With the ability to stack both I jusm mannage to switch off the tattos layer, but in case of nested I do not only switch off the tattoos layer but also any other nested layers!!! So either I have to have everything on the heap (which is poorly managealable for layercount 20+) or use several xcf files and stack the semi-results (flattened or exported) into additional file (which is more or less the same - poorly manageable).
Reopening, it seems we should have this after all.
*** Bug 760859 has been marked as a duplicate of this bug. ***
Bug 604715 has a workaround patch that makes PSDs with such groups display properly.
Er, Bug 604715 is this very bug report you are commenting on, mitch :) Did you mean https://bugzilla.gnome.org/attachment.cgi?id=319437&action=diff from Bug 760859? That said, we probably want a real solution. Would adding the pass-through mode break API/ABI?
I think I need that too ! If I understand right, it's the ability to have in one layer group, different blend mode for each layer. My use case is → expected result → http://hpics.li/0078c1e But if drop-shadow is kept inside its layer group → http://hpics.li/67b4cb4 ( I use this drop-shadow filter → http://hpics.li/712ef41 and this stroke filter → http://hpics.li/31b5ab2 ) So I have to re-arrange layers and delete emptied layer groups to get expected result. Text layer has grain fusion mode, drop-shadow has multiply mode and stroke has normal mode. If those 3 layers were in one layer group, I'd get this → http://hpics.li/c04bb61 where text loses its mode ( why ? ).
I have no idea what these 3rd-party scripts are doing. Please create a *simple* XCF demonstrating the problem, without using any of these additional menu entries.
Well just try to add a drop-shadow and a stroke to a text, put these 3 layers with 3 different modes in a layer group and the result will be the same. It's not related to filters, it's related to layer modes + layer group.
Filters I use come from http://registry.gimp.org/node/186 & http://registry.gimp.org/node/25961 They have the great advantage to let chose if effect is merged with original layer or drawn to a new layer. Such option is a must have with text layers. And they provide "classic" filters but with many options, missing from "basic" default filters in the Gimp ( basic default filters destroy text attribute ).
Created attachment 345128 [details] passthrough compositing example Looks like passthrough groups in photoshop are more than just UI sugar. Take a look at this composition: Layer Mode Opacity + (group) Passthough 50% |- B Normal 100% |- G Lighten 100% R Normal 50% The blue layer blocks the green layer, while the green layer is still blended with the red layer.
*** Bug 783933 has been marked as a duplicate of this bug. ***
Pass through groups are now supported in master: commit 440d8d685582c1702fa36bc53546c437ef1f0ef0 Author: Ell <ell_se@yahoo.com> Date: Fri Apr 21 13:38:22 2017 -0400 app: add pass-through layer mode Only add the enum-value/mode-info for now. Pass-through mode appears above normal mode, in the default group, for layer groups only. app/core/gimpimage.c | 1 + app/operations/layer-modes/gimp-layer-modes.c | 19 +++++++++++++++++++ app/operations/layer-modes/gimpoperationlayermode.c | 1 + app/operations/operations-enums.c | 2 ++ app/operations/operations-enums.h | 1 + libgimp/gimpenums.h | 3 ++- tools/pdbgen/enums.pl | 6 ++++-- 7 files changed, 30 insertions(+), 3 deletions(-) commit 785a0834a24bbcb3ee1e654ea4ff16f4bbf81ea0 Author: Ell <ell_se@yahoo.com> Date: Fri Apr 21 15:21:10 2017 -0400 app: add GimpDrawable::get_source_node() vfunc For pass-through groups, we want to use the group's layer-stack graph directly in its filter node, in place of the drawable's buffer-source node. Add a get_source_node() vfunc to GimpDrawable, which defaults to returning the buffer-source node, and use it in gimp_drawable_get_source_node() instead of using the buffer-source node directly. We'll later override this function for GimpGroupLayer. app/core/gimpdrawable.c | 32 +++++++++++++++++++++++++------- app/core/gimpdrawable.h | 1 + 2 files changed, 26 insertions(+), 7 deletions(-) commit ac3190215b61e0b1b55778788db9442bce1c65c7 Author: Ell <ell_se@yahoo.com> Date: Fri Apr 21 15:38:57 2017 -0400 app: connect layer backdrop to source node's input Make sure the input of the layer's filter node is connected to its source node (when it has an input pad), so that, once we implement pass-though mode, the group's source node can see the backdrop. app/core/gimpdrawable.c | 9 +++++++++ app/core/gimplayer.c | 6 ++++++ 2 files changed, 15 insertions(+) commit 10371ec22f13ee0888f59870ac827d9009b6c0ec Author: Ell <ell_se@yahoo.com> Date: Fri Apr 21 18:04:49 2017 -0400 app: implement pass-through mode in GimpGroupLayer Override GimpDrawable::get_source_node() for GimpGroupLayer. Use a node that contains both the drawable's buffer-source node, and the layer stack's graph node. Choose which one of these to connect to the source node's output based on the group's layer mode: the stack graph for pass-through mode, and the buffer-source node for all the rest. When in pass-through mode, connect the source node's input (which receives the backdrop) to the stack graph's input. Keep maintaining the projection in pass-through mode. ATM, the projection uses the same graph as the source node, so it's rendered against the group's backdrop -- we don't want that. The next few commits fix it. Update the group's drawable directly upon filter stack update in pass-though mode, because the group's graph doesn't go through the projection. TODO: if any of the group's children (or a child of a nested pass- through group, etc.) uses dst-atop/src-in, this needs special attention. app/core/gimpgrouplayer.c | 118 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 7 deletions(-) commit dc1d61ff91831a2a17ba7a6179072571cf756497 Author: Ell <ell_se@yahoo.com> Date: Mon May 8 15:06:00 2017 -0400 app: handle excludes_backdrop in GimpGroupLayer When any of the children of a pass-through group excludes its backdrop, the group itself should exclude the backdrop too. Override get_excludes_backdrop() to follow this logic, and call update_excludes_backdrop() when this condition might change. Note that we always composite pass-through groups using src-over mode, so to actually hide the backdrop, we need to disconnect it from the group's mode node's input pad (and reconnect it, when the backdrop is no longer hidden). app/core/gimpdrawable.c | 12 ++-- app/core/gimpgrouplayer.c | 180 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 148 insertions(+), 44 deletions(-) commit f0aec02dff5b61e68b1ac92569249b1e4974933a Author: Ell <ell_se@yahoo.com> Date: Sat Apr 22 14:12:20 2017 -0400 app: add gimp_projectable_{begin,end}_render() In pass-through mode, the group layer-stack's input is connected to the backdrop. However, when rendering the group's projection, we want to render the stack independently of the backdrop. Unfortunately, we can't use the stack's graph as a subgraph of two different graphs. To work around that, the next few commits add a mechanism for a projectable to be notified before and after its graph is being rendered. We use this mechanism to disconnect the stack's graph from the backdrop before rendering the projection, and reconnect it afterwards. Yep, it's ugly, but it's better than having to maintain n copies of (each node of) the graph (each nesting level requires an extra copy.) This commit adds {begin,end}_render() functions to GimpProjectable. These functions should be called right before/after rendering the projectable's graph. app/core/gimpprojectable.c | 26 ++++++++++++++++++++++++++ app/core/gimpprojectable.h | 4 ++++ 2 files changed, 30 insertions(+) commit 426bc371cdbc62db53fc679c170c1308f0fee10a Author: Ell <ell_se@yahoo.com> Date: Sat Apr 22 14:13:07 2017 -0400 app: add GimpTileHandlerProjectable GimpTileHandlerProjectable is similar to GimpTileHandlerValidate, except that it calls {begin,end}_render() on its associated projectable before validating. app/core/Makefile.am | 2 + app/core/gimptilehandlerprojectable.c | 91 +++++++++++++++++++++++++++++++++++ app/core/gimptilehandlerprojectable.h | 64 ++++++++++++++++++++++++ 3 files changed, 157 insertions(+) commit 1c6861730225b22f42890bc1c0fb39a95e2116d8 Author: Ell <ell_se@yahoo.com> Date: Sat Apr 22 14:22:06 2017 -0400 app: use {begin,end}_render() and GimpTileHandlerProjectable ... ... in GimpProjection and gimp_display_shell_render() (the latter is not really necessary, but whatever.) app/core/gimpprojection.c | 19 +++++++++++++++---- app/display/gimpdisplayshell-render.c | 6 ++++++ 2 files changed, 21 insertions(+), 4 deletions(-) commit 1ca1e15dd0ca0dec6d50d0d915f7bfb1f7b5aa86 Author: Ell <ell_se@yahoo.com> Date: Sat Apr 22 14:28:54 2017 -0400 app: implement {begin,end}_render() for GimpGroupLayer Use them to connect/disconnect the stack graph when the group is in pass-through mode. app/core/gimpgrouplayer.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) commit 3635cf04ab69bafb76d7583da804f580f2d5fbf3 Author: Ell <ell_se@yahoo.com> Date: Fri Apr 21 19:42:04 2017 -0400 app: move bottom-layer special casing to GimpOperationLayerMode GimpFilter's is_last_node field only reflects the item's position within the parent stack. When a layer is contained in a pass- through group, it can be the last layer of the group, while not being the last layer in the graph as a whole (paticularly, if there are visible layers below the group). In fact, when we have nested pass-through groups, whether or not a layer is the last node depends on which group we're considering as the root (since we exclude the backdrop from the group's projection, resulting in different graphs for different groups). Instead of rolling our own graph traversal, just move the relevant logic to GimpOperationLayerMode, and let GEGL do the work for us. At processing time, we can tell if we're the last node by checking if we have any input. For this to work, GimpOperationLayerMode's process() function needs to have control over what's going on. Replace the derived op classes, which override process(), with a call to the layer mode's function (as per gimp_layer_mode_get_function()) in GimpOperationLayerMode's process() function. (Well, actually, this commit keeps the ops around, and just hacks around them in gimp_layer_mode_get_operation(), because laziness :P) Keep using the layer's is_last_node property to do the invalidation. app/core/gimplayer.c | 22 +-- app/operations/layer-modes/gimp-layer-modes.c | 46 +++--- app/operations/layer-modes/gimp-layer-modes.h | 2 + .../layer-modes/gimpoperationlayermode.c | 162 ++++++++++++++++++--- .../layer-modes/gimpoperationlayermode.h | 3 +- 5 files changed, 178 insertions(+), 57 deletions(-) commit 67fc418c3c1cf63e5cd0fcdd33c79541332a851e Author: Ell <ell_se@yahoo.com> Date: Sun Apr 23 17:47:59 2017 -0400 app: adapt gimp_image_merge_layers() to handle pass-through groups ... ... and fix flatten-image along the way. *And* do some cleanup. Currently, gimp_image_merge_layers() combines the layers on its own, one by one. This is incompatible with pass-through groups, because the group's buffer is rendered independently of its backdrop, while we need to take the backdrop into account when mergeing the group. Instead, render the subgraph of the parent graph, corresponding to the set of merged layers, directly into the new layer. Since the layers we merge are always visible and continuous, all we need is a minor massage to the parent graph to make it work. This takes care of pass-through groups intrinsicly. This commit also changes the behavior of flatten-image: Currently, the flattened layers are rendered directly on top of the opaque background, which can make previously-hidden areas (due to layers using composite modes other than src-over, or legacy layer modes) visible. This is almost certainly not desirable. Instead, construct the graph such that the flattened layers are combined with the background only after being merged with one another. app/core/gimpimage-merge.c | 215 ++++++++++++++++++--------------------------- 1 file changed, 85 insertions(+), 130 deletions(-)