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

Refactored the grab pass and scene depth rendering #4244

Merged
merged 3 commits into from
May 13, 2022

Conversation

mvaligursky
Copy link
Contributor

@mvaligursky mvaligursky commented May 12, 2022

Fixes: #4090
Related: #2953

This PR refactors and improved both grab pass functionality, as well as the scene depth rendering. Files grab-pass.js and scene-depth.js were refactored into scene-grab.js. The main motivation is to minimize number of resolves and buffer copies taking place, and keeping to more formal render pass implementation required for webGPU.

Shared changes

  • previously, if the depth texture was used, a depth layer was enabled, and all cameras that had the depth layer would capture the depth, wasting performance for cameras other than the main one. This is now controlled by camera (details below)
  • there are now new and consistent textures names for these two textures. Note that even though the engine uses new names, old names are still supported:
uDepthMap -> uSceneDepthMap
texture_grabPass -> uSceneColorMap

Changes to grab-pass

  • previously, when a shader referenced grab pass texture, a rendering would be interrupted in the middle of draw call, a framebuffer copied to texture and then the texture used for the draw call. This gets very expensive when multiple materials use the texture. The commonly used solution is to do a single framebuffer copy after opaque meshes are rendered, making it available for the transparent meshes / post-processing. In our case, this executed during the depth layer, giving used the control over the time inside the frame.
  • There is new public API to request a camera to capture the scene:
CameraComponent.requestSceneColorMap

Changes to depth pass

  • There is new public API to request a camera to capture the scene. This is automatically requested by post-effects, but needs to be manually requested for other uses (for example Soft-Particles).
CameraComponent.requestSceneDepthMap

@mvaligursky mvaligursky self-assigned this May 12, 2022
@mvaligursky mvaligursky added enhancement performance Relating to load times or frame rate area: graphics Graphics related issue labels May 12, 2022
@mvaligursky mvaligursky marked this pull request as draft May 12, 2022 16:47
@NewboO
Copy link
Contributor

NewboO commented Jun 20, 2022

Hello,

How to get the old behaviour for the color buffer? In some of my projects, I'm using shaders to blend UI sprites with custom functions (similar to photoshop blend modes) so I need the current color buffer when rendering the sprite, not one captured some time before because as those sprites can overlap they're now cancelling each other instead of stacking.

@mvaligursky
Copy link
Contributor Author

@NewboO - Unfortunately we don't have a support for this anymore. For multiple reason, this has been removed for now. We will consider having this as an option in the future, but most likely not very immediately.

@yaustar
Copy link
Contributor

yaustar commented Jun 21, 2022

@NewboO, would you be able to share an example shader that no longer works? Perhaps we can provide an alternative path?

@NewboO
Copy link
Contributor

NewboO commented Jun 24, 2022

Here's a sample project: https://playcanvas.com/project/950042/overview/color-buffer

And here's how it looks with previous engine version: https://launch.playcanvas.com/1456173?debug=true&version=1.53.4
image

Now with current engine it gives this: https://launch.playcanvas.com/1456173?debug=true
image

This is a very basic example with only a difference blending on a single layer but I'd like to be able to do this kind of thing with more complex blending formulas on any layer.

@mvaligursky
Copy link
Contributor Author

I think a possible way to do something like this would be to create multiple render targets .. and swap rendering between them, so that you can use what was already rendered to as a texture for following rendering. Not as convenient, especially if this is in 3D with dynamically changing orders unfortunately, so more of a limited case solution I'd say.

@NewboO
Copy link
Contributor

NewboO commented Jun 30, 2022

An update if anyone else than me is interested in getting the old behaviour: the best workaround I found was to duplicate the SceneGrab code I need and call it in a custom Layer.onDrawCall function. It's not perfect but good enough for my use cases and it doesn't require juggling with render targets.

My sample project is updated with a dirty PoC showing both behaviours.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: graphics Graphics related issue performance Relating to load times or frame rate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create simple API to give users access to depth buffer
5 participants