godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.71k stars 21.12k forks source link

Support for multiple rendertargets #24034

Closed CptPotato closed 4 years ago

CptPotato commented 5 years ago

As far as I can tell, rendering to multiple rendertargets in a Viewport is not supported at the moment.

I might be the odd one out here but this feature is something I could definitely use, specifically for implementing my own rendering and lighting in 2D. Also, please let me know if I'm wrong and this is already possible.

Zylann commented 5 years ago

Aren't Viewports themselves usable as rendertargets? In fact it's the only way to achieve that using the API right now, I think limitations were mentionned in past issues

CptPotato commented 5 years ago

I thought about this workaround but it would mean that I have to render every rendertarget separately which is something I want to avoid 😕

Ideally, allowing a Viewport to have multiple ViewportTextures would be a nice solution. Though, I'm not sure if this is compatible with how the current renderer works. I may have to resort to writing my own VisualServer implementation.

starry-abyss commented 5 years ago

What is the benefit of that? Like, each render-to-texture is a separate operation, isn't it? No matter if it's from same or different viewport (which can share World with other viewport). Or am I missing something?

Also, BTW are those multiple ViewportTextures supposed to have the same content? Because instead one can just use the same single texture to read from everywhere (obviously)...

CptPotato commented 5 years ago

@starry-abyss Multiple Rendertargets (also referred to as "MRT") is a technique which allows you to render your objects to multiple textures simultaneously from the pixel shader. (-> much lower performance impact than rendering multiple times, also easier to set up)

So instead of binding only one rendertarget as output you can bind multiple ones (it should be up to 4 or maybe even higher nowadays). Then all you have to do is write to the different registers from the pixel shader. This way you're not bound by the max. 4 channels RGBA of one texture but instead can output more data to be used later.

This feature has been supported since ancient DirectX 9, it's used by pretty much most engines and I think Godot internally uses it, aswell. I'm sure GLES3 has no issues with it. GLES2 might not support it, though.

Also, BTW are those multiple ViewportTextures supposed to have the same content? Because instead one can just use the same single texture to read from everywhere (obviously)...

Getting multiple textures with the same content is not the aim :smile: (as this would be possible with a simple copy). In my case things like normals, surface color and other material properties are what I want to store in the buffers.

starry-abyss commented 5 years ago

@CptPotato Thanks for explanations! Sounds like sometimes I might want to use (not in Godot project for now though, but for other pixel art 2D game).

reduz commented 5 years ago

I am planning to implement this in the Vulkan renderer. You will be able to configure extra render targets. Not sure if this will be project wide or viewport wide, given shaders need to be compiled specifically toi output this.

CptPotato commented 5 years ago

Great to hear that something like this is planned. With this I could port my 2D deferred / forward hybrid renderer to Godot :smile:

girng commented 5 years ago

you can add another viewport container then just switch between them. if doing a 4 person multiplayer game like diddy kong racing (4 render targets), that is already an edge case imo. several reasons, but not limited to:

cool suggestion however. but it's already doable

CptPotato commented 5 years ago

@girng I think there's a misunderstanding 😕

Rendering the same scene multiple times from different perspectives is not what I want to do - this is also not what MRT does.

The best way I can explain it is that you just output more data per pixel and store it in multiple buffers. Deferred rendering/shading would be one of the use cases for this. This article about deferred shading might be a bit too technical but illustrates the way it can be used quite well.

Chaosus commented 5 years ago

I am planning to implement this in the Vulkan renderer.

Pushed to 4.0 then

samdze commented 4 years ago

I definitely need this feature, having each shader that can target multiple textures using different rendering strategies, hope it gets added with 4.0 as Juan said.

samdze commented 4 years ago

Oh and furthermore, I also need to be able to render from arbitrary sprites/drawables (not contained in a particular viewport) to a selected buffer/texture to store global data for post-processing, custom depth test, or other things.

A solution could be to allow each Viewport (even the root one) to have an ordered (or named) set of ViewportTextures, which can then be reused by assigning them like any other Resource to slots of sub-Viewports instead of creating new ones (so that objects contained in sub-viewports can also render to the same root ViewportTexture directly)

@reduz what do you think?

Calinou commented 4 years ago

Closing in favor of https://github.com/godotengine/godot-proposals/issues/495, as feature proposals are now tracked on the Godot Proposals repository.