godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.17k stars 98 forks source link

Add a Line3D node #6151

Open ettiSurreal opened 1 year ago

ettiSurreal commented 1 year ago

Related: https://github.com/godotengine/godot-proposals/issues/5196_

Describe the project you are working on

Mainly testing features and making small test games for fun.

Describe the problem or limitation you are having in your project

A lack of a 3D equivalent of Line2D, or any sort of 3D line drawing functionality.

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

A Line3D node, with the same functionality as Line2D, and more to make it truly versatile for 3D, since at heart it's just taking a few points in 3D space and drawing a mesh between them, which can be used for many different things such as:

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

Would be defined by a PackedVector3Array, of course.

Line3D should have feature parity with Line2D, having options for:

Gradient and Texture should be covered by shaders, might need Texture Mode to determine if UVs tile or stretch?

Line3D Specific settings:

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

It's a relatively major feature, and far from beginner friendly to code (very intimidating).

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

Line2D is in core, and no way to do the things it does in 3D out of the box.

Calinou commented 1 year ago
  • Removal of Sections, they are now controlled by the node the resource is assigned to.

A mesh resource can be assigned to several different/unrelated nodes at once. How can you keep track of this within the mesh resource?

  • Possible removal of Section Length, i do not think there are any use cases for that, and it most likely just causes confusion, please let me know of any use cases.

I agree with removing the section count (or section subdivision), as it always felt like a second way to achieve the same thing to me (i.e. changing the detail level).

QbieShay commented 1 year ago

Related to https://github.com/godotengine/godot-proposals/issues/6145

ettiSurreal commented 1 year ago
  • Removal of Sections, they are now controlled by the node the resource is assigned to.

A mesh resource can be assigned to several different/unrelated nodes at once. How can you keep track of this within the mesh resource?

Admittedly my understanding of everything is still very limited, but here's an abstraction of how i imagine it working The sections are the "points" of the mesh and the amount and transform of them is controlled externally by the node it is assigned to, such as Line3D and the GPUParticles3D trails. Everything else like the width and curve is shared across every node that the resource is attached to. I am not sure how doable this is in the engine at the current point in time and i definitely don't know how to implement something like this myself, but sharing the same resource between Line3D lines and particle trails seems more optimal because of how similar they are.

stebulba commented 1 year ago

Line3D ... Trail for me is two different things. CSGPolygon3D on fallow path mode is for me already a 3D line. If the staff merge this PR https://github.com/godotengine/godot/pull/61424 that will be mostly the same thing that what the line2d do, for 3D.

But maybe, We should move the CSGPolygon, including the fallow path mode to a new line3D node. That will be a MeshInstance3D. If we want to use this mesh as CSG, that will be easy. If we don't want break the actual CSGPolygon, we should be able to call from CSGPolygon the line3d and get the mesh to convert it to csg. Simulate the actual path fallow from the line3D class.

After that, I think we should have a new separate node, the Trail3D. Because the purpose is completly different that a Line3D. This trail node, can be inherited from the Line3D fallow path mode.

MajorMcDoom commented 10 months ago

Hi all, just wanted to share this shader I made which might help with achieving the goals of this proposal.

Basically it does all the billboarding math in a vertex shader. The CPU side only has to supply points and tangents (easily calculated). Trails I do not believe any existing feature in Godot has a similar effect. I tried to replicate Unity's behaviour, but it's actually more stable, as you can see here: UnityTrails There are a couple requirements for this to work:

I'd be happy to share more if we feel like this will be useful.

MajorMcDoom commented 10 months ago

Did some additional investigation: In the trail use case, or other use cases with relatively high segmentation, this shader produces better results than Unity. But, in use cases with extremely low segmentation, it looks worse. Screenshot 2024-01-11 195605 Screenshot 2024-01-11 200007 However, this is something we can work around with artificially introduced "corner vertices". Just one extra vertex seems to be enough to mitigate this issue. But of course, there's also the chance the vertex shader can be improved to prevent "twists" in these edge cases.

Zireael07 commented 10 months ago

@MajorMcDoom Can you share the shader on a site such as godotshaders.com ?

MajorMcDoom commented 10 months ago

@MajorMcDoom Can you share the shader on a site such as godotshaders.com ?

Seems like various parts of GodotShaders have been down for a day now, including registration and uploading, so I'm just gonna attach a zip with some files. :)

line_and_trail_stuff.zip

fixed_trails

There are three files:

This was all implemented to just a "good enough" level for my own game, but I'm just providing it here as something we can maybe test and iterate with. The actual implementation I think should support any user material/shader, with the billboarding happening "outside" somehow. I think this can be achieved either as part of the GLSL generation, or as its own base shader type, maybe.

Disclaimer on the provided tech:

ettiSurreal commented 10 months ago

A year later, rewrote most of the proposal to be more to the point, took out the part about combining this with the existing TrailMeshes (the idea behind this was just code reuse since it seemed "close enough").

DDarby-Lewis commented 10 months ago

@MajorMcDoom This is so much appreciated, thank you!

aaronfranke commented 9 months ago

Godot Next provides a Trail3D node type which can be used for 3D lines: https://github.com/godot-extended-libraries/godot-next/blob/master/addons/godot-next/3d/trail_3d.gd

MajorMcDoom commented 4 months ago

Hi all, I added an updated version which fixes some bugs and adds some new features (like texturing). It's in the form of an addon folder this time, in a GitHub repo. Hopefully it'll come in useful for whoever implements this proposal.

https://github.com/CozyCubeGames/godot-lines-and-trails-3d

New features:

It also comes by default with a material assigned now.

fire_trail fishing_rod rope

Just as a reminder: I won't be supporting this add-on. I will only answer questions about it as best as I can if they pertain to the implementation of this proposal.

mrSuave00 commented 1 month ago

Hi all, I added an updated version which fixes some bugs and adds some new features (like texturing). It's in the form of an addon folder this time, in a GitHub repo. Hopefully it'll come in useful for whoever implements this proposal.

https://github.com/CozyCubeGames/godot-lines-and-trails-3d

New features:

  • Texturing support
  • Three possible shaders (solid, transparent mix, transparent additive).

It also comes by default with a material assigned now, and you can also use the MeshInstance3D's surface material override instead of just the GeometryInstance3D's material override.

fire_trail fire_trail fishing_rod fishing_rod rope rope

hey! don't mean to necro the post, but can you tell me how to create new materials for the trails? i tried using your default materials with it, but i cannot use it for more than one type because the textures are not interchangable for some reason. so if i change the texture (while making the shader and material unique), it just applies the default anyways. any workaround for that? making new shaders based on that doesn't work either, always reverts to default

MajorMcDoom commented 1 month ago

hey! don't mean to necro the post, but can you tell me how to create new materials for the trails? i tried using your default materials with it, but i cannot use it for more than one type because the textures are not interchangable for some reason. so if i change the texture (while making the shader and material unique), it just applies the default anyways. any workaround for that? making new shaders based on that doesn't work either, always reverts to default

Hey there,

You actually do still have to use the GeometryInstance3D's material override property, not the per-surface material override of MeshInstance3D. I tried to fix this but it presented issues (like you described).

As mentioned in the README, I won't be providing support for the add-on. And since this is the Godot repo, I would ask that no further questions be asked here about its operation, just to keep things on topic. Unfortunately you'll have to do any further troubleshooting or modification on your own. Thanks for your understanding. :)

I'll edit my earlier posts to reflect this.