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

Add a material-based post processing pass #7849

Open
BastiaanOlij opened this issue Sep 25, 2023 · 6 comments
Open

Add a material-based post processing pass #7849

BastiaanOlij opened this issue Sep 25, 2023 · 6 comments

Comments

@BastiaanOlij
Copy link

Describe the project you are working on

Implementing RenderingEffects post processing support using the new godotengine/godot#80214

Describe the problem or limitation you are having in your project

The new rendering effects implementation is a low level API exposed to users. They allow you to string together a number of additional passes and creating features such as customised post processing. A good example of a more complex use case is: https://github.com/BastiaanOlij/RERadialSunRays

In many situations however a single pass post process is all that is needed to obtain the desired effect and this could be achieved without exposing the user to the low level complexity of the current implementation. This would help more users make use of this system.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The idea is to introduce a build in subclass of RenderingEffects called MaterialRenderingEffect or something to that sorts. This is always going to be a post transparency rendering effect.

We introduce a new shader type "rendering_effect" and a new material type for this. The rendering effect can then be configured with the material. By using hints we can control from which buffers we want to read and write, the build in code will obtain the correct buffers from our RenderSceneBuffersRD object. We should add on special optional pong buffer the effect can use.
This will allow the effect to be added to the effect stack twice, the first time it reads from color and outputs to pong, the second it reads from pong and outputs back to color (or maybe these can be 3 modes: color -> color, color -> pong, pong -> color).

While only offering a subset of features made possible by the new rendering effects system, it would be usable in the majority of use cases and greatly simplify its usage.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

I made a prototype of this implementation shown in this comment:
godotengine/godot#80214 (comment)

That example was build on stream with much of the motivation explained:
https://youtube.com/live/KLmahauWeV4

If this enhancement will not be used often, can it be worked around with a few lines of script?

As the prototype shows, a lot can be written in GDScript and could be offered as a plugin however the one part that can't be done is making this use Godots material system. That is important so that godot build in shader editor can be used, and that even visual shaders would be a possibility. Both would greatly improve usablity

Is there a reason why this should be core and not an add-on in the asset library?

As stated above, it is possible but it would greatly hinder usability.

@TokisanGames
Copy link

@clayjohn Helped me set up multiple post processing passes with BackBufferCopy, where I use a ColorRect with a material shader on it. How is this different? And is it better?

image

@jhony-spocket
Copy link

@TokisanGames, can you please explain how this works in more detail? Does this approach have any performance issues?

@TokisanGames
Copy link

My 3D game scene is attached to $SceneLoader/SubViewportContainer/SubViewport/Scenes The CanvasLayers provide my UI and Scene Loader (SL), which layer over the 3D viewport. The backbuffercopy nodes are set to viewport and filter the 3D viewport and not the canvas layers. The colorrect material shaders are screen space canvas_item shaders.

Here's a shot with none enabled.

image

Here's a shot with all four enabled: tilt shift, desaturation, blur, vignette

image

Running post processing shaders does cost performance no matter how they are done. The question for @BastiaanOlij is the proposed method better, or did I misunderstand the purpose of this proposal and am off topic? Each backbuffercopy makes a copy of the screen buffer, so will this proposed method eliminate copies?

@Calinou Calinou changed the title Material based post processing pass Add a material-based post processing pass Sep 25, 2023
@kebabskal
Copy link

@TokisanGames
I had some problems with the techniques for making post processing from the docs. I havn't tried BackBufferCopy, but I think it shares some of the problems:

https://docs.godotengine.org/en/stable/tutorials/shaders/custom_postprocessing.html
The method of adding a canvas item with a shader that accesses the screen buffer via hint_screen_texture doesn't allow me to read the depth buffer, which I need for an outline effect.
Another severe issue with this is that you can't preview the effect in the 3D view in editor, which is a major hindrance when you are tweaking the look of things.

https://docs.godotengine.org/en/stable/tutorials/shaders/advanced_postprocessing.html
In the other method we place a MeshInstance3D in front of the camera. This enables depth buffer access but the screen texture is now captured BEFORE transparent objects which is very limiting and not to mention confusing.

The method I currently use is leveraging @BastiaanOlij 's PR for RenderingEffects, which add hooks into the renderer where you can customize how rendering is done.
godotengine/godot#80214
This is cool and gives you a ton of options, however, it requires quite a bit more technical knowledge. I had to learn compute shaders and dig through a bunch of example code to just learn how to pass textures/buffers to the shader.

It also integrates with the Environment settings. Enabling me to preview the effect in any scene by just adding my effect to the Default Environment and toggling it on and off using the already existing button in the 3D viewport.

This proposal would be to create a pre-made RenderingEffect that allows you to just plop a material in a slot and have it render as a post effect.
Use existing shader coding knowledge and leverage the material editor to supply and edit settings in real time.
It should be simpler, faster, more capable and more familiar than both the examples from the docs and the method you proposed above.

@BastiaanOlij
Copy link
Author

BastiaanOlij commented Sep 26, 2023

@TokisanGames backbuffer copy requires an extra copy that happens before transparency is run and you can't do successive effects.

RenderingEffects itself allows far more complex post processing after rendering is finished, this proposal just introduces a slightly easier to use implementation ontop of this.

@BastiaanOlij
Copy link
Author

Owh misread, you're doing post in canvas shaders, still requires the copy that RenderingEffects potentially prevents, and you have access to more of the render buffers such as motion vectors

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

5 participants