Can I manually render a viewport?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By euriherasme

Hello everyone!

What I want to do is render a viewport and use the resulting texture on another viewport. I know the docs have a section on “custom post processing” (custom_post_processing_godot_docs), but it relies on the node hierarchy to work, which would work poorly for what I want to do.

Imagine I am doing a 3x3 blur and I want to apply the same blur multiple times, to get a blurrier image without using a large kernel. In code it would look something like:

create ViewportA //VpA
create ViewportB //VpB
create ViewportArray[] add ViewportA and ViewportB

render Viewport A using SCREEN_TEXTURE and blur

for i 0...k :
    render ViewportArray[(i+1)%2] using ViewportArray[i%2] and blur

In this example k is the number of times to reapply the blur. so if k is equal to 5 for example I would have (imagine they are always using a material that blurs the image it is given)

render VpA using SCREEN_TEXTURE
render VpB using VpA
render VpA using VpB
render VpB using VpA
render VpA using VpB
render VpB using VpA

the result would be VpA having a SCREEN_TEXTURE with a blur 3x3 applied 6 times.

if I wanted to do it with the node structure setup I would need to create 6 viewports instead of 2 (without counting the scene viewport), and nest them accordingly. There is a note on the custom portprocessing page that says:

You can also render your Viewports separately without nesting them like this. You just need to use two Viewports and to render them one after the other.

But I have not found any render, or update functions for a specific viewport. There is a function on the visual server called “force draw” but it draws all the viewports attached to it, but I just want to render a single one.

Any help on this would be really appreciated!
Thank you in advance

:bust_in_silhouette: Reply From: Inces

It sounds complicated. Is it all for blur effect ?
You don’t need to manually override viewport rendering for this, there is a method Viewport.get_texture(). Viewport is constantly drawing this texture every frame but You can freeze it by transforming it into image.
Common practice for cumulative screen effects is creating color rects reaching whole viewports and applying shaders to them, whith backbuffer copies inbetween them.

Sorry if I misunderstood, I only code in GSL

Hey, thanks for answering!

Nop, it is not for a blur effect, it is for a simulation I want to make on the fragment shader and I want to use the results of that simulation on another part of the simulation or render them using another algorithm to the screen. I used the blur example because it explains pretty well why the node structure is not good in certain cases.

The method Viewport.get_texture() does not render the viewport, it just gives you the render texture reference and You can freeze it by transforming it into image but that would require the data to be sent to the CPU which I don’t want to (because it is more unnecessary processing because everything can be done in the GPU)

On the cumulative screen effects side. I don’t need more than 1 back buffer copy, and that would be at the start of the blurring process. After the first one they just render from one to the other:

  1. render VpA using SCREEN_TEXTURE
  2. render VpB using VpA
  3. render VpA using VpB
  4. render VpB using VpA
  5. render VpA using VpB
  6. render VpB using VpA

(this should all happen in the same frame, and give me the ability to render the las one into the screen texture, but this las part is not as important to me right now)

Don’t worry about misunderstanding, I am still thankful that someone decided to answer!

euriherasme | 2021-11-11 12:27