From 741145febd2b4fc2db4b076a339ded88dfa3c5e5 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 15 Jul 2017 18:40:47 -0300 Subject: [PATCH] -Fix for multiple reflection probes causing issues. -Fix for positional sound corruption to avoid making people deaf. --- core/self_list.h | 19 ++++++++++++++ drivers/gles3/rasterizer_scene_gles3.cpp | 10 +++---- drivers/gles3/shaders/cubemap_filter.glsl | 2 ++ drivers/gles3/shaders/scene.glsl | 32 ++++++++++------------- scene/3d/audio_stream_player_3d.cpp | 32 ++++++++++++++++++----- scene/3d/audio_stream_player_3d.h | 7 ++++- scene/3d/reflection_probe.cpp | 2 +- servers/visual/visual_server_scene.cpp | 2 +- 8 files changed, 74 insertions(+), 32 deletions(-) diff --git a/core/self_list.h b/core/self_list.h index 9edf735f7b2..e229d5bf8e2 100644 --- a/core/self_list.h +++ b/core/self_list.h @@ -51,6 +51,25 @@ public: _first->_prev = p_elem; _first = p_elem; } + void add_last(SelfList *p_elem) { + + ERR_FAIL_COND(p_elem->_root); + + if (!_first) { + add(p_elem); + return; + } + + SelfList *e = _first; + + while (e->next()) { + e = e->next(); + } + + e->_next = p_elem; + p_elem->_prev = e->_next; + p_elem->_root = this; + } void remove(SelfList *p_elem) { diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 89c4c909ee6..f87b4336fe9 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/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); } diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index 393ef2892a2..ac4e47a4406 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/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; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 6fbfeeff6c7..27bf7d99f82 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/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;i0.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; } diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index cc9470e88d9..87ea0184253 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/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) diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index 549bf67a2f4..8603cab5a4e 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/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]; diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index 86a62bec977..0dc5b58e454 100644 --- a/scene/3d/reflection_probe.cpp +++ b/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 { diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 5009d76d432..13d1c7faa98 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/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;