### Godot version

4.0.1.stable

### System information

Manjaro Linux

### Issue description

As the title mentions, setting the property `trail_lifetime` of `GPUParticles3D` below 0.1 will - as defined in `servers/rendering/renderer_rd/storage_rd/particles_storage.cpp:424` - always result in the error message: 

`ERROR: Condition "p_length < 0.1" is true.`

This is true for setting it from the editor and from script. Since this is a hardcoded value, would it not be more user-friendly to limit the `p_length` and warn the user if they try to set it below this threshold? 

### Steps to reproduce

Create a scene with `GPUParticles3D` and set the property `trail_lifetime` below 0.1 from editor or script.

### Minimal reproduction project

Trivial
copy_push_constant.align_mode = particles->transform_align;
	if (do_sort) {
		RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[ParticlesShader::COPY_MODE_FILL_SORT_BUFFER + particles->userdata_count * ParticlesShader::COPY_MODE_MAX]);
		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0);
		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1);
		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->trail_bind_pose_uniform_set, 2);
		RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy_push_constant, sizeof(ParticlesShader::CopyPushConstant));
		RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1);
		RD::get_singleton()->compute_list_end();
		sort_effects->sort_buffer(particles->particles_sort_uniform_set, particles->amount);
	}
	if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) {
		copy_push_constant.total_particles *= particles->trail_bind_poses.size();
	}
	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
	uint32_t copy_pipeline = do_sort ? ParticlesShader::COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER : ParticlesShader::COPY_MODE_FILL_INSTANCES;
	copy_pipeline += particles->userdata_count * ParticlesShader::COPY_MODE_MAX;
	copy_push_constant.copy_mode_2d = particles->mode == RS::PARTICLES_MODE_2D ? 1 : 0;
	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[copy_pipeline]);
	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0);
	if (do_sort) {
		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1);
	}
	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->trail_bind_pose_uniform_set, 2);
	RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy_push_constant, sizeof(ParticlesShader::CopyPushConstant));
	RD::get_singleton()->compute_list_dispatch_threads(compute_list, copy_push_constant.total_particles, 1, 1);
	RD::get_singleton()->compute_list_end();
}
void ParticlesStorage::_particles_update_buffers(Particles *particles) {