Famous / engine

MIT License
1.75k stars 250 forks source link

FR: Suggestions for WebGLRenderer refactor #456

Open oldschooljarvis opened 9 years ago

oldschooljarvis commented 9 years ago

Having heard the GL side of things is slated for a major refactor, as well as having seen some of the writing on the wall, I figured now might be a good time to request certain features that might otherwise be untenable if not for an impending refactor.

So without further ado, here's my wish list:

1. Decouple the cutout system from WebGLRenderer

I would argue that the cutout system should not be an intrinsic part of WebGLRenderer. Per issue 313, barring a major leap like rasterization of DOM content (which is a long, long ways off), the only way complex cutouts can be reliably achieved is if the cutout system is exposed to the user, and the user is free to define the cutout representing their DOM content.

2. Eschew vertex-based cutouts in favor of a fragment-based system with blending support

Currently, the cutout system is based on vertex data (geometry). While this might be somewhat more efficient than alternatives, it's also not as capable. DOM images containing alpha opacity are the most glaring argument against the current system.

3. The cutout/blending system should support n layers

Specifically, n GL layers. Imagine the following scenario:

You have DOM content containing alpha opacity, some Famous GL content, as well as foreign (i.e. non-Famous) GL content. All of it needs to play nicely together.

  1. Tell the cutout system about your complex DOM content so it can render a correct cutout.
  2. Create a new layer within this same system, passing in the appropriate color and depth buffers that represent said foreign GL content.

Ideally, the system would first perform fragment depth testing across all layers, followed by a blending pass. The end result is you'd have DOM + n GL layers all coexisting peacefully, all respecting the same cutout state, with a single Canvas element.

4. Ability to specify a custom depth buffer precision for each layer

For my use case, I require a logarithmic depth buffer. Moreover, the aforementioned depth testing is worthless unless the depth value scale is homogenous across all tested layers.

5. Post-processing pipeline

I know this is already planned, so I'll just say I'm really looking forward to it. :-)

Conclusion

If nothing else, having the first item would make it such that those of us wishing to implement our own cutout system wouldn't have to rewrite most of WebGLRenderer to do so.

Thanks for reading! Looking forward to any input.

alexanderGugel commented 9 years ago

Thanks for the detailed "wish list" :smile:

  1. Current system is messed up. Cutouts should be completely decoupled. First step is probably to make them components that send draw commands to the WebGLRenderer (just like Mesh). This allows a more flexible approach towards cutouts.
  2. Maybe. Not sure yet.
  3. I'm not sure if we want to introduce the complexity of having an arbitrary number of canvas layers (or number of WebGLRenderers). I would say it's rather unlikely that we're going to implement this in the near future.
  4. Nothing planed in that direction, but I would welcome any PRs in that direction.
  5. This is a separate feature. I'm unsure about the current priority of the PPP.

Conclusion

The cutout system will be decoupled by making the cutouts components. We're currently refactoring parts of the WebGLRenderer, changes like mentioned above will be implemented during this refactor.

alexanderGugel commented 9 years ago

I'm leaving this open in case anyone wants to add anything....

trusktr commented 9 years ago

the user is free to define the cutout representing their DOM content.

But that's what I love about "mixed mode", is not having to worry about that. That's what makes Engine special. I don't want to think about that. I just want it to work. But if it's as easy as

let el = new DOMElement(node)
let cutout = new DOMElementCutout(node)

then I can live with that.

michaelobriena commented 9 years ago

We are working on an implementation for a node to know the drawn size of the DOM and creating a cutout based on the border-radius so the user doesn't need to self define.

trusktr commented 9 years ago

Eschew vertex-based cutouts

Does not a cutout also have a fragment shader? Farhad was telling me we could put shadows on the cutouts, implying fragment shaders.

trusktr commented 9 years ago

@michaelobriena Awesome.

trusktr commented 9 years ago

having the first item would make it such that those of us wishing to implement our own cutout system wouldn't have to rewrite most of WebGLRenderer to do so.

I could see that being really powerful in cases when a DOM element has a border radius or is clipped into arbitrary shapes using the CSS clip property. I would agree that some control is needed in those scenarios, but at the top level there should be no control required for it to work with normal rectangular DOM elements (the default).

oldschooljarvis commented 9 years ago

@alexanderGugel

  1. Good to know. Any ideas about how user-defined cutouts might work? I intentionally left that part vague since I figured it could probably go many different ways. Perhaps something as low-level as dealing with raw buffers, to as high-level as simply supplying an image.
  2. Not sure how DOM images with alpha opacity would be handled otherwise.
  3. Understandable. Put another way, I was basically looking for a way to have Famous accept foreign color/depth buffers and reconcile them with its cutout system. If this isn't going to happen, then at least the converse would be nice - the ability to retrieve both cutout state and Famous' GL buffers so that they could be integrated into a custom blending/compositing solution. Sounds like the former is going to happen, but for the latter it would probably mean having to support render targets.
  4. This shouldn't be that hard, though I may as well wait until the refactor has shaken out before submitting PRs.

A couple extra thoughts:

Thanks again, appreciate the feedback.