Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(question) how to composite multiple children using blendFunc #127

Open
transitive-bullshit opened this issue Jun 27, 2017 · 9 comments
Open

Comments

@transitive-bullshit
Copy link

question

library version

3.6.0

npm ls gl-react gl-react-dom gl-react-native gl-react-expo
[email protected] 
└── [email protected]

This should be a relatively simple question, but I'm not seeing an easy way to composite multiple nodes together while being able to take advantage of the parent node's blendFunc.

The only way I can currently see of implementing this is to re-implement the blendFunc in the parent node's shader and have the multiple children passed in as textures, but this seems really backwards, so I'm guessing I'm missing something. None of the examples really use blendFunc or composite multiple children together.

Here's a jsfiddle with a DOM example of what I'm trying to accomplish.

Also, I absolutely love using gl-react -- keep up the great work!! :)

@gre
Copy link
Owner

gre commented Jun 27, 2017

Hi,

Currently gl-react assumes there is only root node that gets drawn to the canvas / framebuffer.
there is no way to draw one child and then another child in the same "draw frame" – BUT this is a great feature request to keep for the next iteration.
at the moment, as you said I'm afraid you would have to use a shader that mix 2 input textures..
later, maybe there should be a way to just pass many children to Surface (and/or something like a <Blend> that would accept many children and perform underlying draw chain)

@transitive-bullshit
Copy link
Author

Thank you for the quick response @gre. For anyone else wanting this type of functionality without constantly blending in shaders, here is a composite component I wrote that composites all children simulating gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA).

@gre
Copy link
Owner

gre commented Jul 18, 2017

one more thought on this:
since Node not always have guarantee to have its own framebuffer (currently only happen for the root node), basically there could be something like a Group that hold a fbo and that can be given children nodes that would all draw directly to that same Group's fbo.

technically, I imagine Node can detect to use the Group's fbo if this.context.glParent instanceof Group (kinda the same way it already branch on glParent === glSurface for the surface case, so the root node knows that it should draw directly on the canvas instead of a fbo).

I need to give more thoughts on many impl details, but basically maybe Group should act like Node in that it's part of the dependent draw system. e.g. Group#_draw() probably needs to delegate the draw calls sequentially in order to all the Node children. I probably should do a PoC to see if all these can work out :)

@gre
Copy link
Owner

gre commented Jul 18, 2017

The name Group is probably not appropriate here. needs to think a better name.
the idea is it draw all its children in sequence one on top of the other so it probably works in combination of using blendFunc and clear (otherwise you just get the latest drawn, since clearing is on by default).

some names idea: Group, Layer, Blend, Chain, NodeGroup, Sequence, All, Combine, Compose, Composite,...

@gre
Copy link
Owner

gre commented Jul 18, 2017

it's kinda like layers in photoshop/Gimp I guess? any existing vocabulary?

I think maybe Layer is on top of the list. except it's more a container of layers. <Layers> ?

@transitive-bullshit
Copy link
Author

I agree this should be a gl-react primitive. I'd go with Layer singular as it's one fbo surface with multiple child nodes.

There's a precedent we can learn from in every retained scenegraph. The only other option I could see is that we don't introduce a new Node type, and instead, Node recognizes if it has multiple children and uses its blendFunc to blend them on top of each other in this specific case. This is what I thought would happen, for instance, the first time I tried using gl-react. That being said, I'd prefer to stick with the explicit Layer container for now.

@gre gre self-assigned this Jul 19, 2017
@gre
Copy link
Owner

gre commented Jul 19, 2017

good thoughts!
TL;DR: yeah using Node children is kinda interesting, but I'll probably stick to a dedicated Layer as it's more explicit and I try to not add even more complexity to Node.

so actually Node supports children, but it's currently only to have an alternative syntax to compose things:

 <Node
        shader={shaders.pixelEditor}
        uniformsOptions={{
          t: { interpolation: "nearest" },
        }}
        uniforms={{
          size,
          gridBorder,
          brushRadius,
          mouse,
          color,
        }}
      >
        <Bus uniform="t">
          <Paint {...rest} />
        </Bus>
      </Node>

(from https://gl-react-cookbook.surge.sh/pixeleditor )

A "Bus" don't render anything but is a way to "connect" something (from the rendered children to the contextual parent) (in this case, it connects Paint to uniform t). now, if you directly give <Paint> in children, i'm not sure what would happen but probably that tree would be ignored as no-one depends on its rendering.
in such case, it would technically be possible to make Paint draw to the parent Node fbo. but it's more a conceptual/design problem: I'm not sure what it means for that parent Node shader (does it even make sense to have a shader on the parent?), and also about the ordering of the draws (should the children render before or after it?). So yeah, probably having a dedicated Layer that also don't render anything on its own is a less complex idea to introduce.

@weepy
Copy link

weepy commented Jul 31, 2017

this would be absolutely amazing!

@gre gre mentioned this issue Aug 3, 2017
Closed
@gre gre removed their assignment Oct 27, 2017
@quaos
Copy link

quaos commented Nov 2, 2021

Hi,
Any progress on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants