Skip to content

Commit

Permalink
Particle internal refactor and additions for more artistic control
Browse files Browse the repository at this point in the history
Co-authored-by: Hugo Locurcio <[email protected]>
Co-authored-by: A Thousand Ships <[email protected]>
Co-authored-by: Raul Santos <[email protected]>
Co-authored-by: Mew Pur Pur <[email protected]>
Co-authored-by: ClayJohn <[email protected]>

Apply suggestions from code review

Co-authored-by: Clay John <[email protected]>
  • Loading branch information
QbieShay and clayjohn committed Oct 9, 2023
1 parent 6916349 commit 19574c7
Show file tree
Hide file tree
Showing 24 changed files with 1,197 additions and 481 deletions.
8 changes: 8 additions & 0 deletions doc/classes/GPUParticles2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
<member name="amount" type="int" setter="set_amount" getter="get_amount" default="8">
Number of particles emitted in one emission cycle.
</member>
<member name="amount_ratio" type="float" setter="set_amount_ratio" getter="get_amount_ratio" default="1.0">
The ratio of particles that should actually be emitted. If set to a value lower than [code]1.0[/code], this will set the amount of emitted particles throughout the lifetime to [code]amount * amount_ratio[/code]. Unlike changing [member amount], changing [member amount_ratio] while emitting does not affect already-emitted particles and doesn't cause the particle system to restart. [member amount_ratio] can be used to create effects that make the number of emitted particles vary over time.
[b]Note:[/b] Reducing the [member amount_ratio] has no performance benefit, since resources need to be allocated and processed for the total [member amount] of particles regardless of the [member amount_ratio].
</member>
<member name="collision_base_size" type="float" setter="set_collision_base_size" getter="get_collision_base_size" default="1.0">
Multiplier for particle's collision radius. [code]1.0[/code] corresponds to the size of the sprite.
</member>
Expand All @@ -68,6 +72,10 @@
<member name="fract_delta" type="bool" setter="set_fractional_delta" getter="get_fractional_delta" default="true">
If [code]true[/code], results in fractional delta calculation which has a smoother particles display effect.
</member>
<member name="interp_to_end" type="float" setter="set_interp_to_end" getter="get_interp_to_end" default="0.0">
Causes all the particles in this node to interpolate towards the end of their lifetime.
[b]Note[/b]: This only works when used with a [ParticleProcessMaterial]. It needs to be manually implemented for custom process shaders.
</member>
<member name="interpolate" type="bool" setter="set_interpolate" getter="get_interpolate" default="true">
Enables particle interpolation, which makes the particle movement smoother when their [member fixed_fps] is lower than the screen refresh rate.
</member>
Expand Down
8 changes: 8 additions & 0 deletions doc/classes/GPUParticles3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@
<member name="amount" type="int" setter="set_amount" getter="get_amount" default="8">
Number of particles to emit.
</member>
<member name="amount_ratio" type="float" setter="set_amount_ratio" getter="get_amount_ratio" default="1.0">
The ratio of particles that should actually be emitted. If set to a value lower than [code]1.0[/code], this will set the amount of emitted particles throughout the lifetime to [code]amount * amount_ratio[/code]. Unlike changing [member amount], changing [member amount_ratio] while emitting does not affect already-emitted particles and doesn't cause the particle system to restart. [member amount_ratio] can be used to create effects that make the number of emitted particles vary over time.
[b]Note:[/b] Reducing the [member amount_ratio] has no performance benefit, since resources need to be allocated and processed for the total [member amount] of particles regardless of the [member amount_ratio].
</member>
<member name="collision_base_size" type="float" setter="set_collision_base_size" getter="get_collision_base_size" default="0.01">
</member>
<member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" enum="GPUParticles3D.DrawOrder" default="0">
Expand Down Expand Up @@ -98,6 +102,10 @@
<member name="fract_delta" type="bool" setter="set_fractional_delta" getter="get_fractional_delta" default="true">
If [code]true[/code], results in fractional delta calculation which has a smoother particles display effect.
</member>
<member name="interp_to_end" type="float" setter="set_interp_to_end" getter="get_interp_to_end" default="0.0">
Causes all the particles in this node to interpolate towards the end of their lifetime.
[b]Note[/b]: This only works when used with a [ParticleProcessMaterial]. It needs to be manually implemented for custom process shaders.
</member>
<member name="interpolate" type="bool" setter="set_interpolate" getter="get_interpolate" default="true">
Enables particle interpolation, which makes the particle movement smoother when their [member fixed_fps] is lower than the screen refresh rate.
</member>
Expand Down
83 changes: 78 additions & 5 deletions doc/classes/ParticleProcessMaterial.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
</method>
</methods>
<members>
<member name="alpha_curve" type="Texture2D" setter="set_alpha_curve" getter="get_alpha_curve">
The alpha value of each particle's color will be multiplied by this [CurveTexture] over its lifetime.
</member>
<member name="angle_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's rotation will be animated along this [CurveTexture].
</member>
Expand Down Expand Up @@ -151,13 +154,29 @@
<member name="direction" type="Vector3" setter="set_direction" getter="get_direction" default="Vector3(1, 0, 0)">
Unit vector specifying the particles' emission direction.
</member>
<member name="directional_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
A curve that specifies the velocity along each of the axes of the particle system along its lifetime.
[b]Note:[/b] Animated velocities will not be affected by damping, use [member velocity_limit_curve] instead.
</member>
<member name="directional_velocity_max" type="float" setter="set_param_max" getter="get_param_max">
Maximum directional velocity value, which is multiplied by [member directional_velocity_curve].
[b]Note:[/b] Animated velocities will not be affected by damping, use [member velocity_limit_curve] instead.
</member>
<member name="directional_velocity_min" type="float" setter="set_param_min" getter="get_param_min">
Minimum directional velocity value, which is multiplied by [member directional_velocity_curve].
[b]Note:[/b] Animated velocities will not be affected by damping, use [member velocity_limit_curve] instead.
</member>
<member name="emission_box_extents" type="Vector3" setter="set_emission_box_extents" getter="get_emission_box_extents">
The box's extents if [member emission_shape] is set to [constant EMISSION_SHAPE_BOX].
</member>
<member name="emission_color_texture" type="Texture2D" setter="set_emission_color_texture" getter="get_emission_color_texture">
Particle color will be modulated by color determined by sampling this texture at the same point as the [member emission_point_texture].
[b]Note:[/b] [member emission_color_texture] multiplies the particle mesh's vertex colors. To have a visible effect on a [BaseMaterial3D], [member BaseMaterial3D.vertex_color_use_as_albedo] [i]must[/i] be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. Otherwise, [member emission_color_texture] will have no visible effect.
</member>
<member name="emission_curve" type="Texture2D" setter="set_emission_curve" getter="get_emission_curve">
Each particle's color will be multiplied by this [CurveTexture] over its lifetime.
[b]Note:[/b] This property won't have a visible effect unless the render material is marked as unshaded.
</member>
<member name="emission_normal_texture" type="Texture2D" setter="set_emission_normal_texture" getter="get_emission_normal_texture">
Particle velocity and rotation will be set by sampling this texture at the same point as the [member emission_point_texture]. Used only in [constant EMISSION_SHAPE_DIRECTED_POINTS]. Can be created automatically from mesh or node by selecting "Create Emission Points from Mesh/Node" under the "Particles" tool in the toolbar.
</member>
Expand All @@ -182,6 +201,12 @@
<member name="emission_shape" type="int" setter="set_emission_shape" getter="get_emission_shape" enum="ParticleProcessMaterial.EmissionShape" default="0">
Particles will be emitted inside this region. Use [enum EmissionShape] constants for values.
</member>
<member name="emission_shape_offset" type="Vector3" setter="set_emission_shape_offset" getter="get_emission_shape_offset" default="Vector3(0, 0, 0)">
The offset for the [member emission_shape], in local space.
</member>
<member name="emission_shape_scale" type="Vector3" setter="set_emission_shape_scale" getter="get_emission_shape_scale" default="Vector3(1, 1, 1)">
The scale of the [member emission_shape], in local space.
</member>
<member name="emission_sphere_radius" type="float" setter="set_emission_sphere_radius" getter="get_emission_sphere_radius">
The sphere's radius if [member emission_shape] is set to [constant EMISSION_SHAPE_SPHERE].
</member>
Expand All @@ -200,6 +225,9 @@
<member name="hue_variation_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
Minimum equivalent of [member hue_variation_max].
</member>
<member name="inherit_velocity_ratio" type="float" setter="set_inherit_velocity_ratio" getter="get_inherit_velocity_ratio" default="0.0">
Percentage of the velocity of the respective [GPUParticles2D] or [GPUParticles3D] inherited by each particle when spawning.
</member>
<member name="initial_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
Maximum initial velocity magnitude for each particle. Direction comes from [member direction] and [member spread].
</member>
Expand All @@ -220,17 +248,23 @@
</member>
<member name="orbit_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's orbital velocity will vary along this [CurveTexture].
[b]Note:[/b] For 3D orbital velocity, use a [CurveXYZTexture].
[b]Note:[/b] Animated velocities will not be affected by damping, use [member velocity_limit_curve] instead.
</member>
<member name="orbit_velocity_max" type="float" setter="set_param_max" getter="get_param_max">
<member name="orbit_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
Maximum orbital velocity applied to each particle. Makes the particles circle around origin. Specified in number of full rotations around origin per second.
Only available when [member particle_flag_disable_z] is [code]true[/code].
[b]Note:[/b] Animated velocities will not be affected by damping, use [member velocity_limit_curve] instead.
</member>
<member name="orbit_velocity_min" type="float" setter="set_param_min" getter="get_param_min">
<member name="orbit_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
Minimum equivalent of [member orbit_velocity_max].
[b]Note:[/b] Animated velocities will not be affected by damping, use [member velocity_limit_curve] instead.
</member>
<member name="particle_flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false">
Align Y axis of particle with the direction of its velocity.
</member>
<member name="particle_flag_damping_as_friction" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false">
Changes the behavior of the damping properties from a linear deceleration to a deceleration based on speed percentage.
</member>
<member name="particle_flag_disable_z" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false">
If [code]true[/code], particles will not move on the z axis.
</member>
Expand All @@ -246,6 +280,18 @@
<member name="radial_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
Minimum equivalent of [member radial_accel_max].
</member>
<member name="radial_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
A [CurveTexture] that defines the velocity over the particle's lifetime away (or toward) the [member velocity_pivot].
[b]Note:[/b] Animated velocities will not be affected by damping, use [member velocity_limit_curve] instead.
</member>
<member name="radial_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
Maximum radial velocity applied to each particle. Makes particles move away from the [member velocity_pivot], or toward it if negative.
[b]Note:[/b] Animated velocities will not be affected by damping, use [member velocity_limit_curve] instead.
</member>
<member name="radial_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
Minimum radial velocity applied to each particle. Makes particles move away from the [member velocity_pivot], or toward it if negative.
[b]Note:[/b] Animated velocities will not be affected by damping, use [member velocity_limit_curve] instead.
</member>
<member name="scale_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's scale will vary along this [CurveTexture]. If a [CurveXYZTexture] is supplied instead, the scale will be separated per-axis.
</member>
Expand All @@ -255,6 +301,17 @@
<member name="scale_min" type="float" setter="set_param_min" getter="get_param_min" default="1.0">
Minimum equivalent of [member scale_max].
</member>
<member name="scale_over_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Either a [CurveTexture] or a [CurveXYZTexture] that scales each particle based on its velocity.
</member>
<member name="scale_over_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
Maximum velocity value reference for [member scale_over_velocity_curve].
[member scale_over_velocity_curve] will be interpolated between [member scale_over_velocity_min] and [member scale_over_velocity_max].
</member>
<member name="scale_over_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
Minimum velocity value reference for [member scale_over_velocity_curve].
[member scale_over_velocity_curve] will be interpolated between [member scale_over_velocity_min] and [member scale_over_velocity_max].
</member>
<member name="spread" type="float" setter="set_spread" getter="get_spread" default="45.0">
Each particle's initial direction range from [code]+spread[/code] to [code]-spread[/code] degrees.
</member>
Expand Down Expand Up @@ -317,6 +374,11 @@
<member name="turbulence_noise_strength" type="float" setter="set_turbulence_noise_strength" getter="get_turbulence_noise_strength" default="1.0">
The turbulence noise strength. Increasing this will result in a stronger, more contrasting, flow pattern.
</member>
<member name="velocity_limit_curve" type="Texture2D" setter="set_velocity_limit_curve" getter="get_velocity_limit_curve">
A [CurveTexture] that defines the maximum velocity of a particle during its lifetime.
</member>
<member name="velocity_pivot" type="Vector3" setter="set_velocity_pivot" getter="get_velocity_pivot" default="Vector3(0, 0, 0)">
</member>
</members>
<constants>
<constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter">
Expand Down Expand Up @@ -355,7 +417,16 @@
<constant name="PARAM_ANIM_OFFSET" value="11" enum="Parameter">
Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set animation offset properties.
</constant>
<constant name="PARAM_MAX" value="15" enum="Parameter">
<constant name="PARAM_RADIAL_VELOCITY" value="15" enum="Parameter">
Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set radial velocity properties.
</constant>
<constant name="PARAM_DIRECTIONAL_VELOCITY" value="16" enum="Parameter">
Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set directional velocity properties.
</constant>
<constant name="PARAM_SCALE_OVER_VELOCITY" value="17" enum="Parameter">
Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set scale over velocity properties.
</constant>
<constant name="PARAM_MAX" value="18" enum="Parameter">
Represents the size of the [enum Parameter] enum.
</constant>
<constant name="PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="ParticleFlags">
Expand All @@ -367,7 +438,9 @@
<constant name="PARTICLE_FLAG_DISABLE_Z" value="2" enum="ParticleFlags">
Use with [method set_particle_flag] to set [member particle_flag_disable_z].
</constant>
<constant name="PARTICLE_FLAG_MAX" value="3" enum="ParticleFlags">
<constant name="PARTICLE_FLAG_DAMPING_AS_FRICTION" value="3" enum="ParticleFlags">
</constant>
<constant name="PARTICLE_FLAG_MAX" value="4" enum="ParticleFlags">
Represents the size of the [enum ParticleFlags] enum.
</constant>
<constant name="EMISSION_SHAPE_POINT" value="0" enum="EmissionShape">
Expand Down
24 changes: 24 additions & 0 deletions doc/classes/RenderingServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2627,6 +2627,14 @@
Sets the number of particles to be drawn and allocates the memory for them. Equivalent to [member GPUParticles3D.amount].
</description>
</method>
<method name="particles_set_amount_ratio">
<return type="void" />
<param index="0" name="particles" type="RID" />
<param index="1" name="ratio" type="float" />
<description>
Sets the amount ratio for particles to be emitted. Equivalent to [member GPUParticles3D.amount_ratio].
</description>
</method>
<method name="particles_set_collision_base_size">
<return type="void" />
<param index="0" name="particles" type="RID" />
Expand Down Expand Up @@ -2675,6 +2683,14 @@
Sets the [Transform3D] that will be used by the particles when they first emit.
</description>
</method>
<method name="particles_set_emitter_velocity">
<return type="void" />
<param index="0" name="particles" type="RID" />
<param index="1" name="velocity" type="Vector3" />
<description>
Sets the velocity of a particle node, that will be used by [member ParticleProcessMaterial.inherit_velocity_ratio].
</description>
</method>
<method name="particles_set_emitting">
<return type="void" />
<param index="0" name="particles" type="RID" />
Expand Down Expand Up @@ -2707,6 +2723,14 @@
If [code]true[/code], uses fractional delta which smooths the movement of the particles. Equivalent to [member GPUParticles3D.fract_delta].
</description>
</method>
<method name="particles_set_interp_to_end">
<return type="void" />
<param index="0" name="particles" type="RID" />
<param index="1" name="factor" type="float" />
<description>
Sets the value that informs a [ParticleProcessMaterial] to rush all particles towards the end of their lifetime.
</description>
</method>
<method name="particles_set_interpolate">
<return type="void" />
<param index="0" name="particles" type="RID" />
Expand Down
5 changes: 4 additions & 1 deletion drivers/gles3/shaders/particles.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ layout(std140) uniform FrameData { //ubo:0
float delta;

float particle_size;
float pad0;
vec3 emitter_velocity;

float amount_ratio;
float interp_to_end;
float pad1;
float pad2;

Expand Down
3 changes: 3 additions & 0 deletions drivers/gles3/storage/material_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1395,6 +1395,7 @@ MaterialStorage::MaterialStorage() {
actions.renames["DELTA"] = "local_delta";
actions.renames["NUMBER"] = "particle_number";
actions.renames["INDEX"] = "index";
actions.renames["AMOUNT_RATIO"] = "amount_ratio";
//actions.renames["GRAVITY"] = "current_gravity";
actions.renames["EMISSION_TRANSFORM"] = "emission_transform";
actions.renames["RANDOM_SEED"] = "random_seed";
Expand All @@ -1407,6 +1408,8 @@ MaterialStorage::MaterialStorage() {
actions.renames["COLLISION_NORMAL"] = "collision_normal";
actions.renames["COLLISION_DEPTH"] = "collision_depth";
actions.renames["ATTRACTOR_FORCE"] = "attractor_force";
actions.renames["EMITTER_VELOCITY"] = "emitter_velocity";
actions.renames["INTERPOLATE_TO_END"] = "interp_to_end";

// These are unsupported, but may be used by users. To avoid compile time overhead, we add the stub only when used.
actions.renames["FLAG_EMIT_POSITION"] = "uint(1)";
Expand Down
Loading

0 comments on commit 19574c7

Please sign in to comment.