engine icon indicating copy to clipboard operation
engine copied to clipboard

Implement a system to describe the custom frame rendering using render passes

Open mvaligursky opened this issue 1 year ago • 3 comments

Current situation:

  • Render of the frame is handled by the forward renderer, which pretty much forces few render passes to render if more of less fixed order, and handles shadows, rendering to camera, grab passes, post effects, main forward pass rendering and not many others.

Goal:

  • Make clearly defined interface to describe a frame / part of the frame using modular render passes. This will be a unified interface, which can be used to describe a post-effect, or a way the camera renders it's content, or even a whole frame. Initially the interface will be internal, to allow the engine ti implement many new features, but when it stabilises, the goal is to expose it as an API to give users controls of their rendering.

High level design (subject to change)

  • each render pass is a class which extends the RenderPass, and implements its callbacks as needed (before, execute, after). It also stores dependent render passes, that execute after (and possibly even before if needed) the render pass itself.
  • this will allow us to write many isolated render passes, that implement some basic functionality, and combine them together to create more complex render passes / post-effects or even whole frames.

Example of few render passes and their combination to a frame: RenderPassForward - renders opaque / transparent meshes to render target as needed RenderPassExtractBright - a render pass which takes source texture, and extracts the bright parts of it to the destination texture (render target). 'RenderPassBlur' - a render pass that blurs source texture into a render target texture. 'RenderPassBloom' - a combined render pass, which first uses RenderPassExtractBright, and after that runs the blur pass(s) to create a bloom effect, stored in a texture (without writing it back to the framebuffer). 'RenderPassDepth' - this is already created, allows the camera to be rendered out to generate depth buffer. 'RenderPassSSAO' - takes source depth texture, generates occlusion buffer, and after that runs multiple RenderPassBlur passes to blur it. The result is ssao buffer that can be used at a later stage. 'RenderPassTestFrame' - an example of putting those things together to create a frame. It would start with RenderPassDepth and RenderPassSSAO to generate occlusion texture, followed by RenderPassForward to render the scene, then RenderPassBloom to generate the bloom buffer, and finally it will run some RenderPassCompose to blend the bloom on top of the output of the RenderPassForward, into the backbuffer.

Many details are not described, but the flexibility of the system should be visible here. The engine will provide many render passes for its build-in rendering, but users can create custom render passes and build the frame / effects as a combination of both.

Related to https://github.com/playcanvas/engine/issues/5686 and https://github.com/playcanvas/engine/issues/4271

mvaligursky avatar Sep 28 '23 13:09 mvaligursky

Out of interest is there anything Multiple Render Targets can help with or are there downsides to this approach? One example could be to write out a bloom mask texture so that only certain materials are affected by bloom. This would be like a sort of simultaneous render pass.

MAG-AdrianMeredith avatar Sep 28 '23 15:09 MAG-AdrianMeredith

Sure, as we / users create render passes, some might use MRT. The initial depth pass I mentioned in the example will most likely be a pass that can render more than just depth, and would use MRT to render depth, velocity, roughness, world normals and similar depending what follow up passes need - SSR for example would need the normals and roughness, in addition to the depth. I'm looking at writing this in a very modular form .. so the users can replace one of the bloom passes for example, while still using the same blur pass it needs internally.

mvaligursky avatar Sep 30 '23 09:09 mvaligursky