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 support for rendering 2D to a custom output #11696

Open
VoidgirlChloe opened this issue Feb 4, 2025 · 1 comment
Open

Add support for rendering 2D to a custom output #11696

VoidgirlChloe opened this issue Feb 4, 2025 · 1 comment

Comments

@VoidgirlChloe
Copy link

VoidgirlChloe commented Feb 4, 2025

Describe the project you are working on

General 2D VFX, particularly custom lighting and interactive foliage

Describe the problem or limitation you are having in your project

For advanced VFX, being able to render to multiple buffers that hold different information is quite valuable.
The best way to do this currently is to create viewports via RenderingServer.viewport_create() and manually force them to draw before the main viewport, to avoid a 1-frame delay.
This is not the most performance friendly way, and still does not allow you to do things like creating a velocity texture.
The compositor does allow for some more functionality, but this is limited to 3D and still not sufficient.

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

What would solve all of these problems is a way to ask the rendering server to draw a canvas like it usually would, but to a custom output, using a custom shader (the same for all nodes) and with custom data.
For the example of a velocity texture, you would ask the rendering server for the list of canvas items to be drawn, generate a buffer containing a vec2 of each nodes velocity, then ask the rendering server to draw those nodes to a supplied texture, using a supplied shader and the supplied buffer.

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

The basic usage would look something like

var canvas_cull_mask = 2
var target_texture = rd.texture_create(...)
var shader = rd.shader_create_from_spirv(...)

var items_to_draw: Array[CanvasItem] = RenderingServer.cull_canvas(get_canvas(), canvas_cull_mask, get_canvas_transform())

var velocities = PackedFloat32Array()
velocities.resize(items_to_draw.size() * 2)

for i in items_to_draw.size():
    var item = items_to_draw[i]
    if item is RigidBody2D:
       velocities[2*i] = item.linear_velocity.x
       velocities[2*i+1] = item.linear_velocity.y
    elif item is ...
    else:
       velocites[2*i] = 0.0
       velocities[2*i+1] = 0.0

var uniform_buf = rd.uniform_buffer_create(velocities.to_byte_array(), 4 * velocities.size())
var uniform_set = rd.uniform_set_create(...)

RenderingServer.custom_draw(target_texture, items_to_draw, shader, uniform_set)

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

No.
There are hacks to achieve some of this, but they are not good for performance nor are they convenient or able to cover all the necessary use cases.

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

There is no way to implement this via either gdscript or gdextension, because the engine exposes no relevant hooks.
Additionally, this enhances the functionality of the rendering server.
The whole job of the rendering server is to allow culling and sorting of a canvas via the SceneTree, and drawing of all the various types of canvas items, without putting unnecessary work on the user. This would still do exactly that, but allow for more flexibility in how the drawing itself happens.

@VoidgirlChloe
Copy link
Author

I would be happy to contribute to this myself, but the engine render code is rather dense.
So far I believe that RendererCanvasRenderRD::_render_batch_items is probably close to what needs to be exposed from the engine
So any knowledge about the internals of the engine would be appreciated as well and perhaps I could work on this myself

@Calinou Calinou changed the title 2D custom rendering Add support for rendering 2D to a custom output Feb 8, 2025
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

2 participants