diff options
Diffstat (limited to 'scene/resources/particle_process_material.cpp')
| -rw-r--r-- | scene/resources/particle_process_material.cpp | 99 |
1 files changed, 52 insertions, 47 deletions
diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp index 9ceddbc7b1..6f8df70548 100644 --- a/scene/resources/particle_process_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -31,7 +31,6 @@ #include "particle_process_material.h" #include "core/version.h" -#include "scene/resources/curve_texture.h" Mutex ParticleProcessMaterial::material_mutex; SelfList<ParticleProcessMaterial>::List *ParticleProcessMaterial::dirty_materials = nullptr; @@ -531,10 +530,10 @@ void ParticleProcessMaterial::_update_shader() { code += "\n"; code += "void calculate_initial_physical_params(inout PhysicalParameters params, inout uint alt_seed){\n"; - code += " params.linear_accel = mix(linear_accel_min, linear_accel_min ,rand_from_seed(alt_seed));\n"; - code += " params.radial_accel = mix(radial_accel_min, radial_accel_min,rand_from_seed(alt_seed));\n"; - code += " params.tangent_accel = mix(tangent_accel_min, tangent_accel_max,rand_from_seed(alt_seed));\n"; - code += " params.damping = mix(damping_min, damping_max,rand_from_seed(alt_seed));\n"; + code += " params.linear_accel = mix(linear_accel_min, linear_accel_max, rand_from_seed(alt_seed));\n"; + code += " params.radial_accel = mix(radial_accel_min, radial_accel_max, rand_from_seed(alt_seed));\n"; + code += " params.tangent_accel = mix(tangent_accel_min, tangent_accel_max, rand_from_seed(alt_seed));\n"; + code += " params.damping = mix(damping_min, damping_max, rand_from_seed(alt_seed));\n"; code += "}\n"; code += "\n"; code += "void calculate_initial_dynamics_params(inout DynamicsParameters params,inout uint alt_seed){\n"; @@ -672,13 +671,18 @@ void ParticleProcessMaterial::_update_shader() { code += " float orbit_amount = param.orbit_velocity;\n"; if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { - code += " orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).r;\n"; + CurveTexture *texture = Object::cast_to<CurveTexture>(tex_parameters[PARAM_ORBIT_VELOCITY].ptr()); + if (texture) { + code += " orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).r;\n"; + } else { + code += " orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).b;\n"; + } } code += " if (orbit_amount != 0.0) {\n"; code += " vec3 pos = transform[3].xyz;\n"; code += " vec3 org = emission_transform[3].xyz;\n"; code += " vec3 diff = pos - org;\n"; - code += " float ang = orbit_amount * pi * 2.0;\n"; + code += " float ang = orbit_amount * pi * 2.0 * delta;\n"; code += " mat2 rot = mat2(vec2(cos(ang), -sin(ang)), vec2(sin(ang), cos(ang)));\n"; code += " displacement.xy -= diff.xy;\n"; code += " displacement.xy += rot * diff.xy;\n"; @@ -687,8 +691,8 @@ void ParticleProcessMaterial::_update_shader() { code += " vec3 orbit_velocities = vec3(param.orbit_velocity);\n"; code += " orbit_velocities *= texture(orbit_velocity_curve, vec2(lifetime)).rgb;\n"; - code += " orbit_velocities *= degree_to_rad;\n"; - code += " orbit_velocities *= delta/total_lifetime; // we wanna process those by the delta angle\n"; + code += " orbit_velocities *= pi * 2.0;\n"; + code += " orbit_velocities *= delta; // we wanna process those by the delta angle\n"; code += " //vec3 local_velocity_pivot = ((emission_transform) * vec4(velocity_pivot,1.0)).xyz;\n"; code += " // X axis\n"; code += " vec3 local_pos = (inverse(emission_transform) * transform[3]).xyz;\n"; @@ -719,7 +723,7 @@ void ParticleProcessMaterial::_update_shader() { code += " local_pos -= velocity_pivot;\n"; code += " local_pos.z = 0.;\n"; code += " mat3 z_rotation_mat = mat3(\n"; - code += " vec3(cos(orbit_velocities.z),-sin(orbit_velocities.z),0.0),\n"; + code += " vec3(cos(orbit_velocities.z),sin(orbit_velocities.z),0.0),\n"; code += " vec3(-sin(orbit_velocities.z),cos(orbit_velocities.z), 0.0),\n"; code += " vec3(0.0,0.0,1.0)\n"; code += " );\n"; @@ -958,21 +962,22 @@ void ParticleProcessMaterial::_update_shader() { code += " {\n"; code += " // copied from previous version\n"; code += " if (physics_params.damping > 0.0) {\n"; + code += " float v = length(VELOCITY);\n"; if (!particle_flags[PARTICLE_FLAG_DAMPING_AS_FRICTION]) { - code += " float v = length(VELOCITY);\n"; + code += " v -= physics_params.damping * DELTA;\n"; + } else { + code += " if (v > 0.001) {\n"; code += " // Realistic friction formula. We assume the mass of a particle to be 0.05kg.\n"; code += " float damp = v * v * physics_params.damping * 0.05 * DELTA;\n"; code += " v -= damp;\n"; - code += " if (v < 0.0) {\n"; - code += " VELOCITY = vec3(0.0);\n"; - code += " } else {\n"; - code += " VELOCITY = normalize(VELOCITY) * v;\n"; - code += " }\n"; - } else { - code += " if (length(VELOCITY) > 0.01){\n"; - code += " VELOCITY -= normalize(VELOCITY) * length(VELOCITY) * (physics_params.damping) * DELTA;\n"; - code += " }\n"; + code += " }\n"; } + + code += " if (v < 0.0) {\n"; + code += " VELOCITY = vec3(0.0);\n"; + code += " } else {\n"; + code += " VELOCITY = normalize(VELOCITY) * v;\n"; + code += " }\n"; code += " }\n"; code += " \n"; code += " }\n"; @@ -985,10 +990,6 @@ void ParticleProcessMaterial::_update_shader() { code += " VELOCITY = mix(VELOCITY,vec3(0.0),clamp(collision_friction, 0.0, 1.0));\n"; code += " } else {\n"; code += " VELOCITY = vec3(0.0);\n"; - // If turbulence is enabled, set the noise direction to up so the turbulence color is "neutral" - if (turbulence_enabled) { - code += " noise_direction = vec3(1.0, 0.0, 0.0);\n"; - } code += " }\n"; code += " }\n"; } else if (collision_mode == COLLISION_HIDE_ON_CONTACT) { @@ -996,7 +997,6 @@ void ParticleProcessMaterial::_update_shader() { code += " ACTIVE = false;\n"; code += " }\n"; } - code += " vec3 final_velocity = controlled_displacement + VELOCITY;\n"; code += " \n"; code += " // turbulence before limiting\n"; if (turbulence_enabled) { @@ -1007,17 +1007,22 @@ void ParticleProcessMaterial::_update_shader() { } code += " \n"; code += " vec3 noise_direction = get_noise_direction(TRANSFORM[3].xyz);\n"; - // The following snippet causes massive performance hit. We don't need it as long as collision is disabled. - // Refer to GH-83744 for more info. - if (collision_mode != COLLISION_DISABLED) { + + // Godot detects when the COLLIDED keyword is used. If it's used anywhere in the shader then Godot will generate the screen space SDF for collisions. + // We don't need it as long as collision is disabled. Refer to GH-83744 for more info. + if (collision_mode == COLLISION_RIGID) { code += " if (!COLLIDED) {\n"; - code += " \n"; - code += " float vel_mag = length(final_velocity);\n"; - code += " float vel_infl = clamp(dynamic_params.turb_influence * turbulence_influence, 0.0,1.0);\n"; - code += " final_velocity = mix(final_velocity, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; + } + code += " float vel_mag = length(VELOCITY);\n"; + code += " float vel_infl = clamp(dynamic_params.turb_influence * turbulence_influence, 0.0,1.0);\n"; + code += " VELOCITY = mix(VELOCITY, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; + code += " vel_mag = length(controlled_displacement);\n"; + code += " controlled_displacement = mix(controlled_displacement, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; + if (collision_mode == COLLISION_RIGID) { code += " }\n"; } } + code += " vec3 final_velocity = controlled_displacement + VELOCITY;\n"; code += " \n"; code += " // limit velocity\n"; if (velocity_limit_curve.is_valid()) { @@ -1375,7 +1380,7 @@ void ParticleProcessMaterial::set_param_texture(Parameter p_param, const Ref<Tex tex_parameters[p_param] = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); switch (p_param) { case PARAM_INITIAL_LINEAR_VELOCITY: { @@ -1387,7 +1392,7 @@ void ParticleProcessMaterial::set_param_texture(Parameter p_param, const Ref<Tex } break; case PARAM_ORBIT_VELOCITY: { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, tex_rid); - _adjust_curve_range(p_texture, -500, 500); + _adjust_curve_range(p_texture, -2, 2); notify_property_list_changed(); } break; case PARAM_LINEAR_ACCEL: { @@ -1471,7 +1476,7 @@ Color ParticleProcessMaterial::get_color() const { void ParticleProcessMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) { color_ramp = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1483,7 +1488,7 @@ Ref<Texture2D> ParticleProcessMaterial::get_color_ramp() const { void ParticleProcessMaterial::set_color_initial_ramp(const Ref<Texture2D> &p_texture) { color_initial_ramp = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_initial_ramp, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1504,7 +1509,7 @@ void ParticleProcessMaterial::set_particle_flag(ParticleFlags p_particle_flag, b void ParticleProcessMaterial::set_alpha_curve(const Ref<Texture2D> &p_texture) { alpha_curve = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->alpha_ramp, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1516,7 +1521,7 @@ Ref<Texture2D> ParticleProcessMaterial::get_alpha_curve() const { void ParticleProcessMaterial::set_emission_curve(const Ref<Texture2D> &p_texture) { emission_curve = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_ramp, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1528,7 +1533,7 @@ Ref<Texture2D> ParticleProcessMaterial::get_emission_curve() const { void ParticleProcessMaterial::set_velocity_limit_curve(const Ref<Texture2D> &p_texture) { velocity_limit_curve = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->velocity_limit_curve, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1562,19 +1567,19 @@ void ParticleProcessMaterial::set_emission_box_extents(Vector3 p_extents) { void ParticleProcessMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) { emission_point_texture = p_points; - RID tex_rid = p_points.is_valid() ? p_points->get_rid() : RID(); + Variant tex_rid = p_points.is_valid() ? Variant(p_points->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, tex_rid); } void ParticleProcessMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) { emission_normal_texture = p_normals; - RID tex_rid = p_normals.is_valid() ? p_normals->get_rid() : RID(); + Variant tex_rid = p_normals.is_valid() ? Variant(p_normals->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, tex_rid); } void ParticleProcessMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) { emission_color_texture = p_colors; - RID tex_rid = p_colors.is_valid() ? p_colors->get_rid() : RID(); + Variant tex_rid = p_colors.is_valid() ? Variant(p_colors->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, tex_rid); _queue_shader_change(); } @@ -2100,8 +2105,8 @@ void ParticleProcessMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_DIRECTIONAL_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "directional_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveXYZTexture"), "set_param_texture", "get_param_texture", PARAM_DIRECTIONAL_VELOCITY); ADD_SUBGROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-2,2,0.001,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-2,2,0.001,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture,CurveXYZTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY); ADD_SUBGROUP("Radial Velocity", "radial_"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_VELOCITY); @@ -2162,11 +2167,11 @@ void ParticleProcessMaterial::_bind_methods() { ADD_GROUP("Turbulence", "turbulence_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "turbulence_enabled"), "set_turbulence_enabled", "get_turbulence_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_strength", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_turbulence_noise_strength", "get_turbulence_noise_strength"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_scale", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_turbulence_noise_scale", "get_turbulence_noise_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_scale", PROPERTY_HINT_RANGE, "0,10,0.001,or_greater"), "set_turbulence_noise_scale", "get_turbulence_noise_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "turbulence_noise_speed"), "set_turbulence_noise_speed", "get_turbulence_noise_speed"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_speed_random", PROPERTY_HINT_RANGE, "0,4,0.01"), "set_turbulence_noise_speed_random", "get_turbulence_noise_speed_random"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_TURB_VEL_INFLUENCE); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_TURB_VEL_INFLUENCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_min", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param_min", "get_param_min", PARAM_TURB_VEL_INFLUENCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_max", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param_max", "get_param_max", PARAM_TURB_VEL_INFLUENCE); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_initial_displacement_min", PROPERTY_HINT_RANGE, "-100,100,0.1"), "set_param_min", "get_param_min", PARAM_TURB_INIT_DISPLACEMENT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_initial_displacement_max", PROPERTY_HINT_RANGE, "-100,100,0.1"), "set_param_max", "get_param_max", PARAM_TURB_INIT_DISPLACEMENT); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "turbulence_influence_over_life", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TURB_INFLUENCE_OVER_LIFE); |
