瀏覽代碼

-Fix for multiple reflection probes causing issues.
-Fix for positional sound corruption to avoid making people deaf.

Juan Linietsky 8 年之前
父節點
當前提交
741145febd

+ 19 - 0
core/self_list.h

@@ -51,6 +51,25 @@ public:
 				_first->_prev = p_elem;
 			_first = p_elem;
 		}
+		void add_last(SelfList<T> *p_elem) {
+
+			ERR_FAIL_COND(p_elem->_root);
+
+			if (!_first) {
+				add(p_elem);
+				return;
+			}
+
+			SelfList<T> *e = _first;
+
+			while (e->next()) {
+				e = e->next();
+			}
+
+			e->_next = p_elem;
+			p_elem->_prev = e->_next;
+			p_elem->_root = this;
+		}
 
 		void remove(SelfList<T> *p_elem) {
 

+ 5 - 5
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -761,7 +761,7 @@ bool RasterizerSceneGLES3::reflection_probe_instance_postprocess_step(RID p_inst
 	storage->shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, rpi->probe_ptr->update_mode == VS::REFLECTION_PROBE_UPDATE_ALWAYS);
 	for (int i = 0; i < 2; i++) {
 
-		storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0);
+		storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i == 0);
 		storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, rpi->render_step / 5.0);
 
 		uint32_t local_width = width, local_height = height;
@@ -2889,7 +2889,7 @@ void RasterizerSceneGLES3::_setup_reflections(RID *p_reflection_probe_cull_resul
 		reflection_ubo.atlas_clamp[0] = float(x) / reflection_atlas->size;
 		reflection_ubo.atlas_clamp[1] = float(y) / reflection_atlas->size;
 		reflection_ubo.atlas_clamp[2] = float(width) / reflection_atlas->size;
-		reflection_ubo.atlas_clamp[3] = float(height / 2) / reflection_atlas->size;
+		reflection_ubo.atlas_clamp[3] = float(height) / reflection_atlas->size;
 
 		Transform proj = (p_camera_inverse_transform * rpi->transform).inverse();
 		store_transform(proj, reflection_ubo.local_matrix);
@@ -4156,7 +4156,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
 		glDrawBuffers(1, &gldb);
 	}
 
-	if (env && env->bg_mode == VS::ENV_BG_SKY && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
+	if (env && env->bg_mode == VS::ENV_BG_SKY && (!storage->frame.current_rt || (!storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW))) {
 
 		/*
 		if (use_mrt) {
@@ -4175,7 +4175,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
 		_render_mrts(env, p_cam_projection);
 	} else {
 		//FIXME: check that this is possible to use
-		if (state.used_screen_texture) {
+		if (storage->frame.current_rt && state.used_screen_texture) {
 			glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
 			glReadBuffer(GL_COLOR_ATTACHMENT0);
 			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo);
@@ -4189,7 +4189,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
 		}
 	}
 
-	if (state.used_screen_texture) {
+	if (storage->frame.current_rt && state.used_screen_texture) {
 		glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7);
 		glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
 	}

+ 2 - 0
drivers/gles3/shaders/cubemap_filter.glsl

@@ -247,6 +247,7 @@ void main() {
 
 #if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
 
+	N.y=-N.y;
 	frag_color=vec4(texture(N,source_cube).rgb,1.0);
 #endif
 
@@ -277,6 +278,7 @@ void main() {
 #endif
 
 #if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
+			H.y=-H.y;
 			sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl;
 #endif
 			sum.a += ndotl;

+ 14 - 18
drivers/gles3/shaders/scene.glsl

@@ -1093,27 +1093,19 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
 		}
 
 
-
-		vec3 splane=normalize(local_ref_vec);
 		vec4 clamp_rect=reflections[idx].atlas_clamp;
-
-		splane.z*=-1.0;
-		if (splane.z>=0.0) {
-			splane.z+=1.0;
-			clamp_rect.y+=clamp_rect.w;
-		} else {
-			splane.z=1.0 - splane.z;
-			splane.y=-splane.y;
+		vec3 norm = normalize(local_ref_vec);
+		norm.xy/=1.0+abs(norm.z);
+		norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25);
+		if (norm.z>0) {
+			norm.y=0.5-norm.y+0.5;
 		}
 
-		splane.xy/=splane.z;
-		splane.xy=splane.xy * 0.5 + 0.5;
-
-		splane.xy = splane.xy * clamp_rect.zw + clamp_rect.xy;
-		splane.xy = clamp(splane.xy,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw);
+		vec2 atlas_uv =  norm.xy * clamp_rect.zw + clamp_rect.xy;
+		atlas_uv = clamp(atlas_uv,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw);
 
 		highp vec4 reflection;
-		reflection.rgb = textureLod(reflection_atlas,splane.xy,roughness*5.0).rgb;
+		reflection.rgb = textureLod(reflection_atlas,atlas_uv,roughness*5.0).rgb;
 
 		if (reflections[idx].params.z < 0.5) {
 			reflection.rgb = mix(skybox,reflection.rgb,blend);
@@ -1466,6 +1458,7 @@ FRAGMENT_SHADER_CODE
 	vec3 specular_light = vec3(0.0,0.0,0.0);
 	vec3 ambient_light;
 	vec3 diffuse_light = vec3(0.0,0.0,0.0);
+	vec3 env_reflection_light = vec3(0.0,0.0,0.0);
 
 	vec3 eye_vec = -normalize( vertex_interp );
 
@@ -1483,7 +1476,7 @@ FRAGMENT_SHADER_CODE
 				vec3 ref_vec = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n);
 				ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz);
 				vec3 radiance = textureDualParaboloid(radiance_map,ref_vec,roughness) * bg_energy;
-				specular_light = radiance;
+				env_reflection_light = radiance;
 
 			}
 			//no longer a cubemap
@@ -1673,12 +1666,15 @@ FRAGMENT_SHADER_CODE
 	highp vec4 ambient_accum = vec4(0.0,0.0,0.0,0.0);
 
 	for(int i=0;i<reflection_count;i++) {
-		reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,reflection_accum,ambient_accum);
+		reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,env_reflection_light,reflection_accum,ambient_accum);
 	}
 
 	if (reflection_accum.a>0.0) {
 		specular_light+=reflection_accum.rgb/reflection_accum.a;
+	} else {
+		specular_light+=env_reflection_light;
 	}
+
 	if (ambient_accum.a>0.0) {
 		ambient_light+=ambient_accum.rgb/ambient_accum.a;
 	}

+ 26 - 6
scene/3d/audio_stream_player_3d.cpp

@@ -382,6 +382,9 @@ void AudioStreamPlayer3D::_notification(int p_what) {
 					} break;
 				}
 
+				bool filled_reverb = false;
+				int vol_index_max = AudioServer::get_singleton()->get_speaker_mode() + 1;
+
 				if (area) {
 
 					if (area->is_overriding_audio_bus()) {
@@ -391,14 +394,14 @@ void AudioStreamPlayer3D::_notification(int p_what) {
 					}
 
 					if (area->is_using_reverb_bus()) {
+
+						filled_reverb = true;
 						StringName bus_name = area->get_reverb_bus();
 						output.reverb_bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
 
 						float uniformity = area->get_reverb_uniformity();
 						float area_send = area->get_reverb_amount();
 
-						int vol_index_max = AudioServer::get_singleton()->get_speaker_mode() + 1;
-
 						if (uniformity > 0.0) {
 
 							float distance = cam_area_pos.length();
@@ -406,6 +409,9 @@ void AudioStreamPlayer3D::_notification(int p_what) {
 
 							//float dist_att_db = -20 * Math::log(dist + 0.00001); //logarithmic attenuation, like in real life
 
+							float center_val[3] = { 0.5, 0.25, 0.16666 };
+							AudioFrame center_frame(center_val[vol_index_max - 1], center_val[vol_index_max - 1]);
+
 							if (attenuation < 1.0) {
 								//pan the uniform sound
 								Vector3 rev_pos = cam_area_pos;
@@ -448,14 +454,20 @@ void AudioStreamPlayer3D::_notification(int p_what) {
 
 									} break;
 								}
-							}
 
-							float center_val[3] = { 0.5, 0.25, 0.16666 };
-							AudioFrame center_frame(center_val[vol_index_max - 1], center_val[vol_index_max - 1]);
+								for (int i = 0; i < vol_index_max; i++) {
+
+									output.reverb_vol[i] = output.reverb_vol[i].linear_interpolate(center_frame, attenuation);
+								}
+							} else {
+								for (int i = 0; i < vol_index_max; i++) {
+
+									output.reverb_vol[i] = center_frame;
+								}
+							}
 
 							for (int i = 0; i < vol_index_max; i++) {
 
-								output.reverb_vol[i] = output.reverb_vol[i].linear_interpolate(center_frame, attenuation);
 								output.reverb_vol[i] = output.vol[i].linear_interpolate(output.reverb_vol[i] * attenuation, uniformity);
 								output.reverb_vol[i] *= area_send;
 							}
@@ -491,6 +503,14 @@ void AudioStreamPlayer3D::_notification(int p_what) {
 					output.pitch_scale = 1.0;
 				}
 
+				if (!filled_reverb) {
+
+					for (int i = 0; i < vol_index_max; i++) {
+
+						output.reverb_vol[i] = AudioFrame(0, 0);
+					}
+				}
+
 				outputs[new_output_count] = output;
 				new_output_count++;
 				if (new_output_count == MAX_OUTPUTS)

+ 6 - 1
scene/3d/audio_stream_player_3d.h

@@ -48,7 +48,12 @@ private:
 		AudioFrame reverb_vol[3];
 		Viewport *viewport; //pointer only used for reference to previous mix
 
-		Output() { filter_gain = 0; }
+		Output() {
+			filter_gain = 0;
+			viewport = NULL;
+			reverb_bus_index = -1;
+			bus_index = -1;
+		}
 	};
 
 	Output outputs[MAX_OUTPUTS];

+ 1 - 1
scene/3d/reflection_probe.cpp

@@ -162,7 +162,7 @@ bool ReflectionProbe::are_shadows_enabled() const {
 void ReflectionProbe::set_cull_mask(uint32_t p_layers) {
 
 	cull_mask = p_layers;
-	VS::get_singleton()->reflection_probe_set_enable_shadows(probe, p_layers);
+	VS::get_singleton()->reflection_probe_set_cull_mask(probe, p_layers);
 }
 uint32_t ReflectionProbe::get_cull_mask() const {
 

+ 1 - 1
servers/visual/visual_server_scene.cpp

@@ -1849,7 +1849,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
 						if (reflection_probe->reflection_dirty || VSG::scene_render->reflection_probe_instance_needs_redraw(reflection_probe->instance)) {
 							if (!reflection_probe->update_list.in_list()) {
 								reflection_probe->render_step = 0;
-								reflection_probe_render_list.add(&reflection_probe->update_list);
+								reflection_probe_render_list.add_last(&reflection_probe->update_list);
 							}
 
 							reflection_probe->reflection_dirty = false;