Browse Source

Merge pull request #46387 from lawnjelly/gles2_light_ordering

GLES2 fix for consistent light ordering with BVH
Rémi Verschelde 4 years ago
parent
commit
ab3db20db8
2 changed files with 37 additions and 0 deletions
  1. 29 0
      drivers/gles2/rasterizer_scene_gles2.cpp
  2. 8 0
      drivers/gles2/rasterizer_scene_gles2.h

+ 29 - 0
drivers/gles2/rasterizer_scene_gles2.cpp

@@ -899,6 +899,10 @@ RID RasterizerSceneGLES2::light_instance_create(RID p_light) {
 
 	light_instance->light_index = 0xFFFF;
 
+	// an ever increasing counter for each light added,
+	// used for sorting lights for a consistent render
+	light_instance->light_counter = _light_counter++;
+
 	if (!light_instance->light_ptr) {
 		memdelete(light_instance);
 		ERR_FAIL_V_MSG(RID(), "Condition ' !light_instance->light_ptr ' is true.");
@@ -3285,6 +3289,30 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
 			index++;
 		}
 
+		// for fog transmission, we want some kind of consistent ordering of lights
+		// add any more conditions here in which we need consistent light ordering
+		// (perhaps we always should have it, but don't know yet)
+		if (env && env->fog_transmit_enabled) {
+
+			struct _LightSort {
+
+				bool operator()(LightInstance *A, LightInstance *B) const {
+					return A->light_counter > B->light_counter;
+				}
+			};
+
+			int num_lights_to_sort = render_light_instance_count - render_directional_lights;
+
+			if (num_lights_to_sort) {
+				SortArray<LightInstance *, _LightSort> sorter;
+				sorter.sort(&render_light_instances[render_directional_lights], num_lights_to_sort);
+				// rejig indices
+				for (int i = render_directional_lights; i < render_light_instance_count; i++) {
+					render_light_instances[i]->light_index = i;
+				}
+			}
+		}
+
 	} else {
 		render_light_instances = NULL;
 		render_directional_lights = 0;
@@ -4086,4 +4114,5 @@ void RasterizerSceneGLES2::finalize() {
 }
 
 RasterizerSceneGLES2::RasterizerSceneGLES2() {
+	_light_counter = 0;
 }

+ 8 - 0
drivers/gles2/rasterizer_scene_gles2.h

@@ -88,6 +88,10 @@ public:
 	uint32_t current_refprobe_index;
 	uint32_t current_shader_index;
 
+private:
+	uint32_t _light_counter;
+
+public:
 	RasterizerStorageGLES2 *storage;
 	struct State {
 
@@ -528,6 +532,10 @@ public:
 
 		Rect2 directional_rect;
 
+		// an ever increasing counter for each light added,
+		// used for sorting lights for a consistent render
+		uint32_t light_counter;
+
 		Set<RID> shadow_atlases; // atlases where this light is registered
 	};