godot-polyliner icon indicating copy to clipboard operation
godot-polyliner copied to clipboard

Consider RenderingServer to update meshes

Open Firepal opened this issue 10 months ago • 3 comments

Actual pipedream shit right here, but it could help with editor responsiveness and having lots of Trail3Ds, probably even more if I rewrote stuff in Mono...

In the current code, every time a line gets updated (every curve change for Line3D, every frame for Trail3D), a completely new ArrayMesh is produced. That's an unnecessary new memory allocation we could probably do away with if we could literally update the surface directly. We generally know the vertex count of what we're gonna draw anyway, and Trail3D doesn't change vertex count at all!

This function can apparently do it: https://docs.godotengine.org/en/stable/classes/class_renderingserver.html#class-renderingserver-method-mesh-surface-update-vertex-region

("If you're gonna have it be that complex, why not just write a Godot module directly for ultimate performance and flexibility?" Because I like fancy shaders and I'm scared that I won't be able to reimplement the stuff that makes them work! Also I don't know how to program, I just script...)

Firepal avatar Feb 13 '25 00:02 Firepal

Oh this is a good find. I will probably take a crack at this at some point. I use this line 3d to make a curved UI element that's anchored to a moving object, so avoiding redraws would be great.

On Wed, Feb 12, 2025, 7:20 PM Firepal @.***> wrote:

Actual pipedream shit right here, but it could help with editor responsiveness and having lots of Trail3Ds, probably even more if I rewrote stuff in Mono...

In the current code, every time a line gets updated (every curve change for Line3D, every frame for Trail3D), a completely new ArrayMesh is produced. That's an unnecessary new memory allocation we could probably do away with if we could literally update the surface directly. We generally know the vertex count of what we're gonna draw anyway, and Trail3D doesn't change vertex count at all!

This function can apparently do it: https://docs.godotengine.org/en/stable/classes/class_renderingserver.html#class-renderingserver-method-mesh-surface-update-vertex-region

("If you're gonna have it be that complex, why not just write a Godot module directly for ultimate performance and flexibility?" Because I like fancy shaders and I'm scared that I won't be able to reimplement the stuff that makes them work! Also I don't know how to program, I just script...)

— Reply to this email directly, view it on GitHub https://github.com/Firepal/godot-polyliner/issues/8, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHQKBNAB7HURFQNL7R66PZT2PPQLLAVCNFSM6AAAAABXA4QVR2VHI2DSMVQWIX3LMV43ASLTON2WKOZSHA2DSNRTHE3DIOI . You are receiving this because you are subscribed to this thread.Message ID: @.***>

BluntBSE avatar Feb 13 '25 14:02 BluntBSE

It's particularly about making redraws inexpensive. Right now redraws (regenerating the line mesh on CPU) exclusively happens when changing the Curve3D, moving the node shouldn't itself cause redraws.

The main idea I have to use RenderingServer is to use Meshes like a growable array. i.e. allocate a Mesh with a certain vertex count, then reallocate a bigger one when needed. Regardless of the way the Mesh is laid out, in theory all we have to do is then push just the number of vertices we are actually using. Just uploading things to buffers that already exist!

This of course is going to take a bunch of work; rewriting the mesh generation logic to not use SurfaceTool anymore, instead properly making Packed*Arrays for all our attributes, then turning vertex data into the proper byte format... :rage1:

(There's probably also an optimization to be had with Trail3D and index buffers, but we'll fight that dragon when we get to it... :suspect:)

Firepal avatar Feb 13 '25 16:02 Firepal

Unfortunately, I do need to redraw the mesh to make it stretch between my two nodes as they move, hahah.

I've never worked directly with the rendering server before, but if I start taking a crack at it in my project (I might have to for the sake of FPS), I'll let you know and propose some PRs to this project.

On Thu, Feb 13, 2025 at 11:00 AM Firepal @.***> wrote:

It's particularly about making redraws inexpensive. Right now redraws (regenerating the line mesh on CPU) exclusively happens when changing the Curve3D, moving the node shouldn't itself cause redraws.

The main idea I have to use RenderingServer is to use Meshes like a growable array. i.e. allocate a Mesh with a certain vertex count, then reallocate a bigger one when needed. Regardless of the way the Mesh is laid out, in theory all we have to do is then push just the number of vertices we are actually using.

This of course is going to take a bunch of work; rewriting the mesh generation logic to not use SurfaceTool anymore, instead properly making Packed*Arrays for all our attributes, then turning vertex data into the proper byte format... [image: :rage1:]

(There's probably also an optimization to be had with Trail3D and index buffers, but we'll fight that dragon when we get to it... [image: :suspect:])

— Reply to this email directly, view it on GitHub https://github.com/Firepal/godot-polyliner/issues/8#issuecomment-2657053261, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHQKBNANMTXFFKS3XWTMN2T2PS6RVAVCNFSM6AAAAABXA4QVR2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMNJXGA2TGMRWGE . You are receiving this because you commented.Message ID: @.***> [image: Firepal]Firepal left a comment (Firepal/godot-polyliner#8) https://github.com/Firepal/godot-polyliner/issues/8#issuecomment-2657053261

It's particularly about making redraws inexpensive. Right now redraws (regenerating the line mesh on CPU) exclusively happens when changing the Curve3D, moving the node shouldn't itself cause redraws.

The main idea I have to use RenderingServer is to use Meshes like a growable array. i.e. allocate a Mesh with a certain vertex count, then reallocate a bigger one when needed. Regardless of the way the Mesh is laid out, in theory all we have to do is then push just the number of vertices we are actually using.

This of course is going to take a bunch of work; rewriting the mesh generation logic to not use SurfaceTool anymore, instead properly making Packed*Arrays for all our attributes, then turning vertex data into the proper byte format... [image: :rage1:]

(There's probably also an optimization to be had with Trail3D and index buffers, but we'll fight that dragon when we get to it... [image: :suspect:])

— Reply to this email directly, view it on GitHub https://github.com/Firepal/godot-polyliner/issues/8#issuecomment-2657053261, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHQKBNANMTXFFKS3XWTMN2T2PS6RVAVCNFSM6AAAAABXA4QVR2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMNJXGA2TGMRWGE . You are receiving this because you commented.Message ID: @.***>

BluntBSE avatar Feb 14 '25 15:02 BluntBSE