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 Trail3D node to draw smooth lines for VFX #7082

Open
QbieShay opened this issue Jun 14, 2023 · 5 comments
Open

Add a Trail3D node to draw smooth lines for VFX #7082

QbieShay opened this issue Jun 14, 2023 · 5 comments

Comments

@QbieShay
Copy link

QbieShay commented Jun 14, 2023

Describe the project you are working on

VFX

Describe the problem or limitation you are having in your project

Godot has no 3D trail node

Trails are incredibly complicated to get right and require an in-depth understanding of linear algebra and geometry in order to get right. Coupled with that, they also require understanding of how to draw meshes and how to assign UVs.
In addition to all of this, rendering also tends to badly deform UVs if there is no subdivisions, which complicates the code significantly for mesh building, and bridging the gap from the emission transform with the last spawned point of the trail ALSO adds complexity.

This is a hard problem that requires very complicated solutions in order to look good and existing plugins tend to not be kept up to date, or have issues

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

Add a trail node (That possibly builds on top of a Line3D node proposed in #6151, but the two works shouldn't be dependant on each other)

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

Glossary:
Emitter: the (moving) point the trail is emitted from
Width: the overall width of the trail
Midpoints: points at which the trail is sampled, used as a base to generate geometry
Segments: Geometry that is generated between midpoints

image

Curve glossary:
image

Line3D node properties:

  • emitting: wheter or not the trail is emitting
  • lifetime: how long does the trail live (when turning emitting off, it should take lifetime to not see the trail anymore
  • profile curve: a multiplier for the trail width along its length.
  • color gradient: a gradient that describes how the color of each midpoint changes over its lifetime.
  • transform align (Y_NORMAL, BILLBOARD): how trail segments are oriented. Y up will cause the trail to treat the emission Y axis as normal and X axis as binormal and Z as tangent. billboard will orient the trail to always face the camera.
  • minimum point distance: minimum distance between points before sampling the next midpoint. prevents artifacts.
  • maximum point distance: maximum distance between points before sampling the next midpoint.
  • UV mode (TRAVEL_DISTANCE, UNIT_RANGE): how UVs are assigned to the generated mesh. travel distance will create UVs that are in world space, while unit range will ensure that the UVs are always in range 0-1 along the visible part of the trail. note that there shouldn't be a jump when a segment is deleted because it exceeded its lifetime

Stretch goals:

  • Bezier interpolation on/off
  • Pause: pause the trail lifetimes from running out. useful if debugging stuff in engine.

NOTE: UV.x should be the length of the trail, while UV.y should be the width, in compliance with how blender organizes UVs on curve meshes by default.

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

It can be worked around with a lot of lines of script that probably will be buggy and not work under all conditions, or that will not look as good as a skilled tech artist can make them look.

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

Because trails add an incredible value to any moving object and not having a well designed Godot plugin means that only projects with skilled tech artists will have the expertise to create good looking ones. This is a very hard problem to solve.

@Calinou Calinou changed the title Add trail node Add a Trail3D node to draw smooth lines for VFX Jun 14, 2023
@Calinou
Copy link
Member

Calinou commented Jun 14, 2023

Putting the cumbersome setup issue aside: If I'm understanding right, the issue is that the current particle trail implementation doesn't allow you to move a node and have the trails follow the moved node. If Local Coords is disabled (default), nothing happens until the next particle is emitted. If Local Coords is enabled, the trail moves along the moved node, but both the start and end points are moved (we only want the end point to move).

I think that if we can figure out a way to have the particle trail connect to the node's origin when it's moved in real-time, this would make the existing trail system much more useful already. It still wouldn't cover all use cases (such as linking two objects together with a persistent line), but some people are only looking for a way to have a projectile emit a trail as it moves.

See this project which features a trail setup, with a GPUParticles3D node that emits a single particle with no velocity or gravity: test_particle_trail_move_node.zip

note that there shouldn't be a jump when a segment is deleted because it exceeded its lifetime

Adding support for particles with infinite lifetime seems like a good way to avoid this issue.

Either way, there's a more general discussion to be had about whether it's a good idea to rely on GPUParticles for general-purpose trails, since it has notable performance issues on certain configurations. For instance, on macOS, transform feedback is implemented on the CPU there (instead of the GPU as done on all other platforms). This makes any use of GPUParticles slower than CPUParticles on macOS.

While I don't think the mesh should be generated 100% on the CPU (as it'd make updating it slow, and require hacks for split screen), a good middle ground would be to generate the mesh's points on the CPU and billboard them on the GPU using a vertex shader.

Lastly, one issue is exposing a user-friendly way for the user to preconfigure points (like in Line2D). This is useful when you want to place ropes or telephone lines in a scene, for instance. We currently have an issue with the various 2D/3D polygon editors, as they require a lot of code duplication and work in slightly different ways. The 3D path/polygon editors also currently don't make use of the subgizmos system that was added in 4.0.

RedefineGamedev's Line3D add-on for Godot 3.x avoids this issue by inheriting from Path3D, which means it automatically gets the Path3D editor available. The downside with this approach is that it's inconsistent with other nodes that generate geometry, such as Label3D which inherits from VisualInstance3D. This means that properties to control visual layers, shadow casting and distance fade must be manually created and exposed to override those properties on the internal node. We should aim to have built-in trail utilities inherit from VisualInstance3D, so that they get all the relevant properties available out of the box in a standard way.

@bruvzg Since you've worked on Label3D, I'd be curious to know if you have any input on the best way to implement 3D trails that are independent of a particle system 🙂

@QbieShay
Copy link
Author

Thank you @Calinou ! That's an extensive comment and a good direction to discuss. Note that I think that the particle trails do suffer from that jumping issue that I mentioned when a segment runs out of its lifetime. I think it's okay for particles because trails are smaller, but for bigger trails (sword, dash, projectile, etc.) then the issue would be way more prominent.

The steps to implement that option through particles are a good step lost, but unfortunately this work (especially the infinite lifetime one) has been blocked on lack of consensus and I am not very confident it will move forward. The second Element should be just being able to tell Godot to calculate trails in world space even if the particle simulation is in local space, but I don't know if it's very complicated. I know I had a thought about that in the past but I don't know if I ever finalized it as a proposal. I remember checking out the code for the trail compute and not understanding anything at all :D
Lastly I'm not sure how those world space UV would be implemented in particle trails. Those are uvs that depend on the distance traveled and are very important to make projectiles that have good motion in their trail( if you use time in your shader to simulate that there will be the moment between when the projectile stops moving and the trail disappears where your trail will scroll while not moving on world space and it looks really bad. There can be solutions to mitigate this but they're all way more complicated than a configuration on a node)

@QbieShay
Copy link
Author

QbieShay commented Jun 15, 2023

I forgot, but also trail setup is incredibly cumbersome as it is now and i do not see a way this will improve without breaking compat. Trails within particles are using for tertiary elements to add that extra nice look to a VFX. Trails for projectiles (think fireball) are primary elements that compose a VFX. The trail of a fireball is core to the distinct look of it. While I understand that the implementation looks very similar, the artistic usecase is different, and particles trails are just not there, feature wise and UX wise, to take a central role in a VFX.

However

Considering all the usual constraints I think it's worth a shot. I think we can come up with a solution later for a trail in case the particle solution won't be good enough even after trying. I think all the improvements to particle system mentioned here are needed also for other usecases.

To recap

  1. Infinite lifetime
  2. Custom vector exposed in materials
  3. Trails in world space even for local simulation toggle
  4. Better setup UX?

@MajorMcDoom
Copy link

Hi y'all, just wanted to mention some tech I made that might help with this:
#6151 (comment)

@DDarby-Lewis
Copy link

@MajorMcDoom your addition is very welcome and I will definitely be incorporating it into what I am doing - I needed a trail for a fireball - the particle system (good as it is) doesn't have a way to add a trail that is emitted in local space but trailed in global space. I'm taking a look at if it is possible to do it in a particle system with a custom particle system shader but I'm not sure if that will work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Needs consensus
Development

No branches or pull requests

4 participants