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 3D Particles Documentation #5535

Merged
merged 2 commits into from
Apr 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tutorials/3d/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Rendering
lights_and_shadows
using_decals
physical_light_and_camera_units
particles/index
high_dynamic_range
global_illumination/index
environment_and_post_processing
Expand Down
171 changes: 171 additions & 0 deletions tutorials/3d/particles/attractors.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
.. _doc_3d_particles_attractors:

3D Particle attractors
----------------------

.. figure:: img/particle_attractor.webp
:alt: Particle attractors

Particle attractors are nodes that apply a force to all particles within their reach. They pull
particles closer or push them away based on the direction of that force. There are three types
of attractors: :ref:`class_GPUParticlesAttractorBox3D`, :ref:`class_GPUParticlesAttractorSphere3D`,
and :ref:`class_GPUParticlesAttractorVectorField3D`. You can instantiate them at runtime and
change their properties from gameplay code; you can even animate and combine them for complex
attraction effects.

.. note::

Particle attractors are not yet implemented for 2D particle systems.

The first thing you have to do if you want to use attractors is enable the ``Attractor Interaction``
property on the ParticleProcessMaterial. Do this for every particle system that needs to react to attractors.
Like most properties in Godot, you can also change this at runtime.

Common properties
~~~~~~~~~~~~~~~~~

.. figure:: img/particle_attractor_common.webp
:alt: Common particle attractor properties
:align: right

Common attractor properties

There are some properties that you can find on all attractors. They're located in the
``GPUParticlesAttractor3D`` section in the inspector.

``Strength`` controls how strong the attractor force is. A positive value pulls particles
closer to the attractor's center, while a negative value pushes them away.

``Attenuation`` controls the strength falloff within the attractor's influence region. Every
particle attractor has a boundary. Its strength is weakest at the border of this boundary
and strongest at its center. Particles outside of the boundary are not affected by the attractor
at all. The attenuation curve controls how the strength weakens over that distance. A straight
line means that the strength is proportional to the distance: if a particle is halfway
between the boundary and the center, the attractor strength will be half of what it is
at the center. Different curve shapes change how fast particles accelerate towards the
attractor.

.. figure:: img/particle_attractor_curve.webp
:alt: Different attractor attenuation curves

Strength increase variations: constantly over the distance to the attractor (left), fast
at the boundary border and slowly at the center (middle), slowly at the boundary and
fast at the center (right).

The ``Directionality`` property changes the direction towards which particles are pulled.
At a value of ``0.0``, there is no directionality, which means that particles are pulled towards
the attractor's center. At ``1.0``, the attractor is fully directional, which means particles
will be pulled along the attractor's local ``-Z``-axis. You can change the global direction
by rotating the attractor. If ``Strength`` is negative, particles are instead pulled along
the ``+Z``-axis.

.. figure:: img/particle_attractor_direction.webp
:alt: Different attractor directionality values

No directionality (left) vs. full directionality (right). Notice how the particles move along
the attractor's local Z-axis.

The ``Cull Mask`` property controls which particle systems are affected by an attractor based
on each system's :ref:`visibility layers <class_VisualInstance3D>`. A particle system is only
affected by an attractor if at least one of the system's visibility layers is enabled in the
attractor's cull mask.

.. warning::

There is a `known issue <https://github.com/godotengine/godot/issues/61014>`_ with
GPU particle attractors that prevent the cull mask from working properly in Godot 4.0. We will
update the documentation as soon as it is fixed.

Box attractors
~~~~~~~~~~~~~~

.. figure:: img/particle_attractor_box_entry.webp
:alt: Particle attractor box
:align: right

Box attractor in the node list

Box attractors have a box-shaped influence region. You control their size with the ``Extents``
property. Box extents always measure half of the sides of its bounds, so a value of
``(X=1.0,Y=1.0,Z=1.0)`` creates a box with an influence region that is 2 meters wide on each side.

To create a box attractor, add a new child node to your scene and select ``GPUParticlesAttractorBox3D``
from the list of available nodes. You can animate the box position or attach it to a
moving node for more dynamic effects.

.. figure:: img/particle_attractor_box.webp
:alt: Box attractor parts particle field

A box attractor with a negative strength value parts a particle field as it moves through it.

Sphere attractors
~~~~~~~~~~~~~~~~~

.. figure:: img/particle_attractor_sphere_entry.webp
:alt: Particle attractor sphere
:align: right

Sphere attractor in the node list

Sphere attractors have a spherical influence region. You control their size with the ``Radius``
property. While box attractors don't have to be perfect cubes, sphere attractors will always be
spheres: You can't set width independently from height. If you want to use a sphere attractor for
elongated shapes, you have to change its ``Scale`` in the attractor's ``Node3D`` section.

To create a sphere attractor, add a new child node to your scene and select ``GPUParticlesAttractorSphere3D``
from the list of available nodes. You can animate the sphere position or attach it to a
moving node for more dynamic effects.

.. figure:: img/particle_attractor_sphere.webp
:alt: Sphere attractor parts particle field

A sphere attractor with a negative strength value parts a particle field as it moves through it.

Vector field attractors
~~~~~~~~~~~~~~~~~~~~~~~

.. figure:: img/particle_attractor_vector_entry.webp
:alt: Particle attractor vector field
:align: right

Vector field attractor in the node list

A vector field is a 3D area that contains vectors positioned on a grid. The grid density controls
how many vectors there are and how far they're spread apart. Each vector in a vector field points
in a specific direction. This can be completely random or aligned in a way that forms distinct
patterns and paths.

When particles interact with a vector field, their movement direction changes to match the nearest vector
in the field. As a particle moves closer to the next vector in the field, it changes
direction to match that vector's direction. The particle's speed depends on the vector's length.

Like box attractors, vector field attractors have a box-shaped influence region. You control their size with the ``Extents``
property, where a value of ``(X=1.0,Y=1.0,Z=1.0)`` creates a box with an influence region that is
2 meters wide on each side. The ``Texture`` property takes a :ref:`3D texture <class_Texture3D>`
where every pixel represents a vector with the pixel's color interpreted as the vector's direction and size.

.. note::

When a texture is used as a vector field, there are two types of conversion you need to be aware of:

1. The texture coordinates map to the attractor bounds. The image below shows which part of the texture
corresponds to which part of the vector field volume. For example, the bottom half of the texture
affects the top half of the vector field attractor because ``+Y`` points down in the texture UV space,
but up in Godot's world space.
2. The pixel color values map to direction vectors in space. The image below provides an overview. Since
particles can move in two directions along each axis, the lower half of the color range represents
negative direction values while the upper half represents positive direction values. So a yellow pixel
``(R=1,G=1,B=0)`` maps to the vector ``(X=1,Y=1,Z=-1)`` while a neutral gray ``(R=0.5,G=0.5,B=0.5)``
results in no movement at all.

.. figure:: img/particle_attractor_vector_mapping.webp
:alt: Mapping from texture to vector field

To create a vector field attractor, add a new child node to your scene and select ``GPUParticlesAttractorVectorField3D``
from the list of available nodes. You can animate the attractor's position or attach it to a
moving node for more dynamic effects.

.. figure:: img/particle_attractor_vector.webp
:alt: Vector field attractor in a field of particles

Two particle systems are affected by the same vector field attractor. :download:`Click here to download the 3D texture <img/particle_vector_field_16x16x16.bmp>`.
177 changes: 177 additions & 0 deletions tutorials/3d/particles/collision.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
.. _doc_3d_particles_collision:

3D Particle collisions
----------------------

.. figure:: img/particle_collision.webp
:alt: Particle collisions

Since GPU particles are processed entirely on the GPU, they don't have access to the game's physical
world. If you need particles to collide with the environment, you have to set up particle collision nodes.
There are four of them: :ref:`class_GPUParticlesCollisionBox3D`, :ref:`class_GPUParticlesCollisionSphere3D`,
:ref:`class_GPUParticlesCollisionSDF3D`, and :ref:`class_GPUParticlesCollisionHeightField3D`.

.. note::

GPU Particle collision is not yet implemented for 2D particle systems.

Common properties
~~~~~~~~~~~~~~~~~

.. figure:: img/particle_collision_common.webp
:alt: Common particle collision properties
:align: right

Common collision properties

There are some properties that you can find on all collision nodes. They're located in the
``GPUParticlesCollision3D`` section in the inspector.

The ``Cull Mask`` property controls which particle systems are affected by a collision node based
on each system's :ref:`visibility layers <class_VisualInstance3D>`. A particle system collides with a
collision node only if at least one of the system's visibility layers is enabled in the
collider's cull mask.

.. warning::

There is a `known issue <https://github.com/godotengine/godot/issues/61014>`_ with
GPU particle collision that prevent the cull mask from working properly in Godot 4.0. We will
update the documentation as soon as it is fixed.

Box collision
~~~~~~~~~~~~~

.. figure:: img/particle_collision_box_entry.webp
:alt: Particle collision box
:align: right

Box collision in the node list

Box collision nodes are shaped like a solid, rectangular box. You control their size with the ``Extents``
property. Box extents always measure half of the sides of its bounds, so a value of ``(X=1.0,Y=1.0,Z=1.0)``
creates a box that is 2 meters wide on each side. Box collision nodes are useful for simulating floor
and wall geometry that particles should collide against.

To create a box collision node, add a new child node to your scene and select ``GPUParticlesCollisionBox3D``
from the list of available nodes. You can animate the box position or attach it to a
moving node for more dynamic effects.

.. figure:: img/particle_collision_box.webp
:alt: Box collision with particle systems

Two particle systems collide with a box collision node

Sphere collision
~~~~~~~~~~~~~~~~

.. figure:: img/particle_collision_sphere_entry.webp
:alt: Particle collision sphere
:align: right

Sphere collision in the node list

Sphere collision nodes are shaped like a solid sphere. The ``Radius`` property controls the size of the sphere.
While box collision nodes don't have to be perfect cubes, sphere collision nodes will always be
spheres. If you want to set width independently from height, you have to change the ``Scale``
property in the ``Node3D`` section.

To create a sphere collision node, add a new child node to your scene and select ``GPUParticlesCollisionSphere3D``
from the list of available nodes. You can animate the sphere's position or attach it to a
moving node for more dynamic effects.

.. figure:: img/particle_collision_sphere.webp
:alt: Sphere collision with particle systems

Two particle systems collide with a sphere collision node

Height field collision
~~~~~~~~~~~~~~~~~~~~~~

.. figure:: img/particle_collision_height.webp
:alt: Particle collision height field
:align: right

Height field collision in the node list

Height field particle collision is very useful for large outdoor areas that need to collide with particles.
At runtime, the node creates a height field from all the meshes within its bounds that match its cull mask.
Particles collide against the mesh that this height field represents. Since the height field generation is
done dynamically, it can follow the player camera around and react to changes in the level. Different
settings for the height field density offer a wide range of performance adjustments.

To create a height field collision node, add a new child node to your scene and select ``GPUParticlesCollisionHeightField3D``
from the list of available nodes.

A height field collision node is shaped like a box. The ``Extents`` property controls its size. Extents
always measure half of the sides of its bounds, so a value of ``(X=1.0,Y=1.0,Z=1.0)`` creates a box that
is 2 meters wide on each side. Anything outside of the node's extents is ignored for height field creation.

The ``Resolution`` property controls how detailed the height field is. A lower resolution performs faster
at the cost of accuracy. If the height field resolution is too low, it may look like particles penetrate level geometry
or get stuck in the air during collision events. They might also ignore some smaller meshes completely.

.. figure:: img/particle_heightfield_res.webp
:alt: Height field resolutions

At low resolutions, height field collision misses some finer details (left)

The ``Update Mode`` property controls when the height field is recreated from the meshes within its
bounds. Set it to ``When Moved`` to make it refresh only when it moves. This performs well and is
suited for static scenes that don't change very often. If you need particles to collide with dynamic objects
that change position frequently, you can select ``Always`` to refresh every frame. This comes with a
cost to performance and should only be used when necessary.

.. note::

It's important to remember that when ``Update Mode`` is set to ``When Moved``, it is the *height field node*
whose movement triggers an update. The height field is not updated when one of the meshes inside it moves.

The ``Follow Camera Enabled`` property makes the height field follow the current camera when enabled. It will
update whenever the camera moves. This property can be used to make sure that there is always particle collision
around the player while not wasting performance on regions that are out of sight or too far away.

SDF collision
~~~~~~~~~~~~~

.. figure:: img/particle_collision_sdf_entry.webp
:alt: Particle collision SDF
:align: right

SDF collision in the node list

SDF collision nodes create a `signed distance field <https://www.reddit.com/r/explainlikeimfive/comments/k2zbos/eli5_what_are_distance_fields_in_graphics>`_
that particles can collide with. SDF collision is similar to height field collision in that it turns multiple
meshes within its bounds into a single collision volume for particles. A major difference is that signed distance
fields can represent holes, tunnels and overhangs, which is impossible to do with height fields alone. The
performance overhead is larger compared to height fields, so they're best suited for small-to-medium-sized environments.

To create an SDF collision node, add a new child node to your scene and select ``GPUParticlesCollisionSDF3D``
from the list of available nodes. SDF collision nodes have to be baked in order to have any effect on particles
in the level. To do that, click the ``Bake SDF`` button in the viewport toolbar
while the SDF collision node is selected and choose a directory to store the baked data. Since SDF collision needs
to be baked in the editor, it's static and cannot change at runtime.

.. figure:: img/particle_collision_sdf.webp
:alt: SDF particle collision

SDF particle collision allows for very detailed 3-dimensional collision shapes

An SDF collision node is shaped like a box. The ``Extents`` property controls its size. Extents
always measure half of the sides of its bounds, so a value of ``(X=1.0,Y=1.0,Z=1.0)`` creates a box that
is 2 meters wide on each side. Anything outside of the node's extents is ignored for collision.

The ``Resolution`` property controls how detailed the distance field is. A lower resolution performs faster
at the cost of accuracy. If the resolution is too low, it may look like particles penetrate level geometry
or get stuck in the air during collision events. They might also ignore some smaller meshes completely.

.. figure:: img/particle_collision_sdf_res.webp
:alt: Resolution comparison

The same area covered by a signed distance field at different resolutions: 16 (left) and 256 (right)

The ``Thickness`` property gives the distance field, which is usually hollow on the inside, a thickness to
prevent particles from penetrating at high speeds. If you find that some particles don't collide with the
level geometry and instead shoot right through it, try setting this property to a higher value.

The ``Bake Mask`` property controls which meshes will be considered when the SDF is baked. Only meshes that
render on the active layers in the bake mask contribute to particle collision.
Loading