2
0
Эх сурвалжийг харах

Avoid updating particles during 2D rendering

In 2D the particle uniform set isn't obtained until the render pass. So in 2D just avoid rendering if not updated yet.
clayjohn 2 жил өмнө
parent
commit
41021b07be

+ 4 - 0
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

@@ -3598,6 +3598,10 @@ void RenderForwardClustered::_geometry_instance_update(RenderGeometryInstance *p
 		}
 		ginstance->transforms_uniform_set = particles_storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
 
+		if (particles_storage->particles_get_frame_counter(ginstance->data->base) == 0) {
+			// Particles haven't been cleared or updated, update once now to ensure they are ready to render.
+			particles_storage->update_particles();
+		}
 	} else if (ginstance->data->base_type == RS::INSTANCE_MESH) {
 		if (mesh_storage->skeleton_is_valid(ginstance->data->skeleton)) {
 			ginstance->transforms_uniform_set = mesh_storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);

+ 4 - 0
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

@@ -2626,6 +2626,10 @@ void RenderForwardMobile::_geometry_instance_update(RenderGeometryInstance *p_ge
 		}
 		ginstance->transforms_uniform_set = particles_storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
 
+		if (particles_storage->particles_get_frame_counter(ginstance->data->base) == 0) {
+			// Particles haven't been cleared or updated, update once now to ensure they are ready to render.
+			particles_storage->update_particles();
+		}
 	} else if (ginstance->data->base_type == RS::INSTANCE_MESH) {
 		if (mesh_storage->skeleton_is_valid(ginstance->data->skeleton)) {
 			ginstance->transforms_uniform_set = mesh_storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);

+ 1 - 1
servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp

@@ -790,7 +790,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
 					ERR_BREAK(particles_storage->particles_get_mode(pt->particles) != RS::PARTICLES_MODE_2D);
 					particles_storage->particles_request_process(pt->particles);
 
-					if (particles_storage->particles_is_inactive(pt->particles)) {
+					if (particles_storage->particles_is_inactive(pt->particles) || particles_storage->particles_get_frame_counter(pt->particles) == 0) {
 						break;
 					}
 

+ 6 - 1
servers/rendering/renderer_rd/storage_rd/particles_storage.h

@@ -455,6 +455,12 @@ public:
 		return particles->mode;
 	}
 
+	_FORCE_INLINE_ uint32_t particles_get_frame_counter(RID p_particles) {
+		Particles *particles = particles_owner.get_or_null(p_particles);
+		ERR_FAIL_COND_V(!particles, false);
+		return particles->frame_counter;
+	}
+
 	_FORCE_INLINE_ uint32_t particles_get_amount(RID p_particles, uint32_t &r_trail_divisor) {
 		Particles *particles = particles_owner.get_or_null(p_particles);
 		ERR_FAIL_COND_V(!particles, 0);
@@ -487,7 +493,6 @@ public:
 		ERR_FAIL_COND_V(!particles, RID());
 		if (particles->particles_transforms_buffer_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(particles->particles_transforms_buffer_uniform_set)) {
 			_particles_update_buffers(particles);
-			update_particles();
 			Vector<RD::Uniform> uniforms;
 
 			{