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 a Line3D node #6151

Open
ettiSurreal opened this issue Jan 23, 2023 · 14 comments
Open

Add a Line3D node #6151

ettiSurreal opened this issue Jan 23, 2023 · 14 comments

Comments

@ettiSurreal
Copy link

ettiSurreal commented Jan 23, 2023

Related: #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:

  • Visualizing Path3Ds
  • Trails, Lasers
  • Simple cables/wires/ropes, overall simple procedural geometry.
  • 3D UI

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:

  • Width, and a Curve for it, would separating X and Y be worth it?
  • A Closed property
  • Feasible options from Capping and Border

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

Line3D Specific settings:

  • Mesh Mode:
    • Ribbon: Simple strip, meant for billboarding, but can be used without it
      • Rotation Offset: Rotates the strip, only effective when not billboarded
    • Cross: Two strips intersecting each other at 90 degree angles, meant for when billboarding is not an option for one reason or another.
      • Rotation Offset: Rotates the cross.
    • Tube: A tube/cylinder, meant for cables and large trails where you could see a line is flat with ribbons/crosses.
      • Segments: The resolution of the tube.
  • Direction:
    • Follow: Faces are rotated along the line, equivalent to PathFollow from CSGPolygon3D
    • Custom: all faces face a specific direction, defined by a Vector3.

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
Copy link
Member

Calinou commented Jan 23, 2023

  • 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
Copy link

Related to #6145

@ettiSurreal
Copy link
Author

ettiSurreal commented Jan 23, 2023

  • 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
Copy link

stebulba commented Nov 14, 2023

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 godotengine/godot#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
Copy link

MajorMcDoom commented Jan 11, 2024

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:

  • The line tangent at each point is submitted through the NORMAL. This a trick. Also note that "line tangent" here is not the same "tangent" in shaders.
  • The half-width at each point is submitted through one component of the UV. Note that this still allows for texturing of the line, and even tiling along it, since lateral scrolling or tiling doesn't really make sense for billboarded lines anyway. We can just normalize the half-width UV to become 0 and 1 before the fragment shader. An alternative is to use UV2 for half-widths.

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

@MajorMcDoom
Copy link

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
Copy link

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

@MajorMcDoom
Copy link

MajorMcDoom commented Jan 13, 2024

@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:

  • line_3d.gd: This is the class that lets you manually specify points and connects them. Inherits from MeshInstance3D.
  • trail_3d.gd: This inherits from Line3D and adds trail functionality (related to Add a Trail3D node to draw smooth lines for VFX #7082)
  • line_3d.gdshader: This is the shader that does the billboarding.

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:

  • It doesn't have texturing implemented yet, but it's super easy to add.
  • It has some extra features I needed that y'all might not need (e.g. overall alpha, camera fade, softness, etc.).
  • Currently you MUST set the material of the trail or line through the Material Override of the GeometryInstance3D
  • The material MUST use the provided line_3d shader.

@ettiSurreal ettiSurreal changed the title Add a Line3D node, reworks to Ribbon/TubeTrailMesh and GPUParticles3D trails Add a Line3D node Jan 18, 2024
@ettiSurreal
Copy link
Author

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
Copy link

@MajorMcDoom This is so much appreciated, thank you!

@aaronfranke
Copy link
Member

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
Copy link

MajorMcDoom commented Jul 23, 2024

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.

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
Copy link

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
Copy link

MajorMcDoom commented Sep 30, 2024

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.

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

9 participants