diff options
Diffstat (limited to 'servers/rendering/renderer_rd')
27 files changed, 277 insertions, 59 deletions
diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index a41552cd5c..3390e9cf64 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -122,8 +122,6 @@ AABB Fog::fog_volume_get_aabb(RID p_fog_volume) const { return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); } } - - return AABB(); } Vector3 Fog::fog_volume_get_extents(RID p_fog_volume) const { diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 63fd10886d..3a9c695653 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -276,7 +276,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p SceneState::PushConstant push_constant; - if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL) { + if constexpr (p_pass_mode == PASS_MODE_DEPTH_MATERIAL) { push_constant.uv_offset = Math::make_half_float(p_params->uv_offset.y) << 16; push_constant.uv_offset |= Math::make_half_float(p_params->uv_offset.x); } else { @@ -355,7 +355,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p uint32_t pipeline_color_pass_flags = 0; uint32_t pipeline_specialization = 0; - if (p_pass_mode == PASS_MODE_COLOR) { + if constexpr (p_pass_mode == PASS_MODE_COLOR) { if (element_info.uses_softshadow) { pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_SOFT_SHADOWS; } @@ -479,6 +479,9 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p if ((surf->owner->base_flags & (INSTANCE_DATA_FLAG_MULTIMESH | INSTANCE_DATA_FLAG_PARTICLES)) == INSTANCE_DATA_FLAG_MULTIMESH) { mesh_storage->_multimesh_get_motion_vectors_offsets(surf->owner->data->base, push_constant.multimesh_motion_vectors_current_offset, push_constant.multimesh_motion_vectors_previous_offset); + } else { + push_constant.multimesh_motion_vectors_current_offset = 0; + push_constant.multimesh_motion_vectors_previous_offset = 0; } RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SceneState::PushConstant)); @@ -711,6 +714,14 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i instance_data.lightmap_uv_scale[2] = inst->lightmap_uv_scale.size.x; instance_data.lightmap_uv_scale[3] = inst->lightmap_uv_scale.size.y; +#ifdef REAL_T_IS_DOUBLE + // Split the origin into two components, the float approximation and the missing precision + // In the shader we will combine these back together to restore the lost precision. + RendererRD::MaterialStorage::split_double(inst->transform.origin.x, &instance_data.transform[12], &instance_data.transform[3]); + RendererRD::MaterialStorage::split_double(inst->transform.origin.y, &instance_data.transform[13], &instance_data.transform[7]); + RendererRD::MaterialStorage::split_double(inst->transform.origin.z, &instance_data.transform[14], &instance_data.transform[11]); +#endif + bool cant_repeat = instance_data.flags & INSTANCE_DATA_FLAG_MULTIMESH || inst->mesh_instance.is_valid(); if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2 && repeats < RenderElementInfo::MAX_REPEATS) { @@ -3036,6 +3047,11 @@ RenderForwardClustered::RenderForwardClustered() { { defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n"; } +#ifdef REAL_T_IS_DOUBLE + { + defines += "\n#define USE_DOUBLE_PRECISION \n"; + } +#endif scene_shader.init(defines); } diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index cde241f231..1e70f6880c 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -230,6 +230,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { float sh[9 * 4]; }; + // When changing any of these enums, remember to change the corresponding enums in the shader files as well. enum { INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4, INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5, diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 75ccf1add5..1987577464 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -621,10 +621,10 @@ void SceneShaderForwardClustered::init(const String p_defines) { //shader compiler ShaderCompiler::DefaultIdentifierActions actions; - actions.renames["MODEL_MATRIX"] = "model_matrix"; + actions.renames["MODEL_MATRIX"] = "read_model_matrix"; actions.renames["MODEL_NORMAL_MATRIX"] = "model_normal_matrix"; actions.renames["VIEW_MATRIX"] = "scene_data.view_matrix"; - actions.renames["INV_VIEW_MATRIX"] = "scene_data.inv_view_matrix"; + actions.renames["INV_VIEW_MATRIX"] = "inv_view_matrix"; actions.renames["PROJECTION_MATRIX"] = "projection_matrix"; actions.renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix"; actions.renames["MODELVIEW_MATRIX"] = "modelview"; @@ -757,6 +757,8 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.usage_defines["RADIANCE"] = "#define CUSTOM_RADIANCE_USED\n"; actions.usage_defines["IRRADIANCE"] = "#define CUSTOM_IRRADIANCE_USED\n"; + actions.usage_defines["MODEL_MATRIX"] = "#define MODEL_MATRIX_USED\n"; + actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; actions.render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; actions.render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n"; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 6c1b69148c..f458063aea 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -1757,6 +1757,14 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr RendererRD::MaterialStorage::store_transform(Transform3D(), push_constant.transform); } +#ifdef REAL_T_IS_DOUBLE + // Split the origin into two components, the float approximation and the missing precision + // In the shader we will combine these back together to restore the lost precision. + RendererRD::MaterialStorage::split_double(inst->transform.origin.x, &push_constant.transform[12], &push_constant.transform[3]); + RendererRD::MaterialStorage::split_double(inst->transform.origin.y, &push_constant.transform[13], &push_constant.transform[7]); + RendererRD::MaterialStorage::split_double(inst->transform.origin.z, &push_constant.transform[14], &push_constant.transform[11]); +#endif + push_constant.flags = inst->flags_cache; push_constant.gi_offset = inst->gi_offset_cache; push_constant.layer_mask = inst->layer_mask; @@ -2472,6 +2480,11 @@ RenderForwardMobile::RenderForwardMobile() { { defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n"; } +#ifdef REAL_T_IS_DOUBLE + { + defines += "\n#define USE_DOUBLE_PRECISION \n"; + } +#endif scene_shader.init(defines); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index 1b31d2749d..a53872fc88 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -371,7 +371,7 @@ protected: /* Geometry instance */ - // check which ones of these apply, probably all except GI and SDFGI + // When changing any of these enums, remember to change the corresponding enums in the shader files as well. enum { INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4, INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5, diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 383ed9247d..691d431b82 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -521,10 +521,10 @@ void SceneShaderForwardMobile::init(const String p_defines) { //shader compiler ShaderCompiler::DefaultIdentifierActions actions; - actions.renames["MODEL_MATRIX"] = "model_matrix"; + actions.renames["MODEL_MATRIX"] = "read_model_matrix"; actions.renames["MODEL_NORMAL_MATRIX"] = "model_normal_matrix"; actions.renames["VIEW_MATRIX"] = "scene_data.view_matrix"; - actions.renames["INV_VIEW_MATRIX"] = "scene_data.inv_view_matrix"; + actions.renames["INV_VIEW_MATRIX"] = "inv_view_matrix"; actions.renames["PROJECTION_MATRIX"] = "projection_matrix"; actions.renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix"; actions.renames["MODELVIEW_MATRIX"] = "modelview"; @@ -657,6 +657,8 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.usage_defines["RADIANCE"] = "#define CUSTOM_RADIANCE_USED\n"; actions.usage_defines["IRRADIANCE"] = "#define CUSTOM_IRRADIANCE_USED\n"; + actions.usage_defines["MODEL_MATRIX"] = "#define MODEL_MATRIX_USED\n"; + actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; actions.render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; actions.render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n"; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 0210151420..bbb53f7b97 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2512,6 +2512,8 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() { actions.renames["VERTEX_ID"] = "gl_VertexIndex"; actions.renames["LIGHT_POSITION"] = "light_position"; + actions.renames["LIGHT_DIRECTION"] = "light_direction"; + actions.renames["LIGHT_IS_DIRECTIONAL"] = "is_directional"; actions.renames["LIGHT_COLOR"] = "light_color"; actions.renames["LIGHT_ENERGY"] = "light_energy"; actions.renames["LIGHT"] = "light"; diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index f169692ea0..a50742f91a 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -170,6 +170,10 @@ void RendererCompositorRD::finalize() { } void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) { + if (p_image.is_null() || p_image->is_empty()) { + return; + } + RD::get_singleton()->prepare_screen_for_drawing(); RID texture = texture_storage->texture_allocate(); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 2190f41603..74b8f0890f 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -282,8 +282,6 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba panorama->fill(panorama_color); return panorama; } - - return Ref<Image>(); } //////////////////////////////////////////////////////////// @@ -3302,7 +3300,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, ERR_FAIL_COND(!light_instance); Rect2i atlas_rect; - uint32_t atlas_size; + uint32_t atlas_size = 1; RID atlas_fb; bool using_dual_paraboloid = false; @@ -3623,6 +3621,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Typed //RID sampled_light; RenderGeometryInstance *gi = geometry_instance_create(p_base); + ERR_FAIL_NULL_V(gi, TypedArray<Image>()); uint32_t sc = RSG::mesh_storage->mesh_get_surface_count(p_base); Vector<RID> materials; diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index 459d798a80..45dc63aa17 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -313,6 +313,14 @@ vec4 light_compute( vec2 uv, vec4 color, bool is_directional) { vec4 light = vec4(0.0); + vec3 light_direction = vec3(0.0); + + if (is_directional) { + light_direction = normalize(mix(vec3(light_position.xy, 0.0), vec3(0, 0, 1), light_position.z)); + light_position = vec3(0.0); + } else { + light_direction = normalize(light_position - light_vertex); + } #CODE : LIGHT @@ -595,9 +603,11 @@ void main() { color = vec4(0.0); //invisible by default due to using light mask } + vec4 original_color = color; + #ifdef MODE_LIGHT_ONLY color = vec4(0.0); -#else +#elif !defined(MODE_UNSHADED) color *= canvas_data.canvas_modulation; #endif @@ -636,6 +646,8 @@ void main() { ); } + light_color.rgb *= original_color.rgb; + light_blend_compute(light_base, light_color, color.rgb); } @@ -682,7 +694,6 @@ void main() { vec3 light_pos = vec3(light_array.data[light_base].position, light_array.data[light_base].height); vec3 pos = light_vertex; vec3 light_vec = normalize(light_pos - pos); - float cNdotL = max(0.0, dot(normal, light_vec)); light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); } @@ -732,6 +743,8 @@ void main() { ); } + light_color.rgb *= original_color.rgb; + light_blend_compute(light_base, light_color, color.rgb); } #endif diff --git a/servers/rendering/renderer_rd/shaders/effects/SCsub b/servers/rendering/renderer_rd/shaders/effects/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/effects/SCsub +++ b/servers/rendering/renderer_rd/shaders/effects/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl index e459756c6a..52aee8b648 100644 --- a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl @@ -360,15 +360,15 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) { const float FXAA_SPAN_MAX = 8.0; #ifdef MULTIVIEW - vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; - vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; - vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; - vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; + vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-0.5, -0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; + vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(0.5, -0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; + vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-0.5, 0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; + vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(0.5, 0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; #else - vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; - vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; - vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; - vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; + vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-0.5, -0.5) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; + vec3 rgbNE = textureLod(source_color, uv_interp + vec2(0.5, -0.5) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; + vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-0.5, 0.5) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; + vec3 rgbSE = textureLod(source_color, uv_interp + vec2(0.5, 0.5) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; #endif vec3 rgbM = color; vec3 luma = vec3(0.299, 0.587, 0.114); @@ -462,12 +462,6 @@ void main() { } #endif - if (params.use_debanding) { - // For best results, debanding should be done before tonemapping. - // Otherwise, we're adding noise to an already-quantized image. - color.rgb += screen_space_dither(gl_FragCoord.xy); - } - color.rgb = apply_tonemapping(color.rgb, params.white); color.rgb = linear_to_srgb(color.rgb); // regular linear -> SRGB conversion @@ -498,5 +492,11 @@ void main() { color.rgb = apply_color_correction(color.rgb); } + if (params.use_debanding) { + // Debanding should be done at the end of tonemapping, but before writing to the LDR buffer. + // Otherwise, we're adding noise to an already-quantized image. + color.rgb += screen_space_dither(gl_FragCoord.xy); + } + frag_color = color; } diff --git a/servers/rendering/renderer_rd/shaders/environment/SCsub b/servers/rendering/renderer_rd/shaders/environment/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/environment/SCsub +++ b/servers/rendering/renderer_rd/shaders/environment/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub b/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index d41474118d..1a8a1f3aa3 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -129,12 +129,52 @@ invariant gl_Position; #GLOBALS +#ifdef USE_DOUBLE_PRECISION +// Helper functions for emulating double precision when adding floats. +vec3 quick_two_sum(vec3 a, vec3 b, out vec3 out_p) { + vec3 s = a + b; + out_p = b - (s - a); + return s; +} + +vec3 two_sum(vec3 a, vec3 b, out vec3 out_p) { + vec3 s = a + b; + vec3 v = s - a; + out_p = (a - (s - v)) + (b - v); + return s; +} + +vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec3 out_precision) { + vec3 s, t, se, te; + s = two_sum(base_a, base_b, se); + t = two_sum(prec_a, prec_b, te); + se += t; + s = quick_two_sum(s, se, se); + se += te; + s = quick_two_sum(s, se, out_precision); + return s; +} +#endif + void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) color_interp = color_attrib; #endif + mat4 inv_view_matrix = scene_data.inv_view_matrix; + +#ifdef USE_DOUBLE_PRECISION + vec3 model_precision = vec3(model_matrix[0][3], model_matrix[1][3], model_matrix[2][3]); + model_matrix[0][3] = 0.0; + model_matrix[1][3] = 0.0; + model_matrix[2][3] = 0.0; + vec3 view_precision = vec3(inv_view_matrix[0][3], inv_view_matrix[1][3], inv_view_matrix[2][3]); + inv_view_matrix[0][3] = 0.0; + inv_view_matrix[1][3] = 0.0; + inv_view_matrix[2][3] = 0.0; +#endif + mat3 model_normal_matrix; if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) { model_normal_matrix = transpose(inverse(mat3(model_matrix))); @@ -142,11 +182,12 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime model_normal_matrix = mat3(model_matrix); } + mat4 matrix; + mat4 read_model_matrix = model_matrix; + if (is_multimesh) { //multimesh, instances are for it - mat4 matrix; - #ifdef USE_PARTICLE_TRAILS uint trail_size = (instances.data[instance_index].flags >> INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT) & INSTANCE_FLAGS_PARTICLE_TRAIL_MASK; uint stride = 3 + 1 + 1; //particles always uses this format @@ -232,7 +273,14 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime #endif //transpose matrix = transpose(matrix); - model_matrix = model_matrix * matrix; +#if !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) || defined(MODEL_MATRIX_USED) + // Normally we can bake the multimesh transform into the model matrix, but when using double precision + // we avoid baking it in so we can emulate high precision. + read_model_matrix = model_matrix * matrix; +#if !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) + model_matrix = read_model_matrix; +#endif // !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) +#endif // !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) || defined(MODEL_MATRIX_USED) model_normal_matrix = model_normal_matrix * mat3(matrix); } @@ -297,7 +345,22 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime // using local coordinates (default) #if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED) +#ifdef USE_DOUBLE_PRECISION + // We separate the basis from the origin because the basis is fine with single point precision. + // Then we combine the translations from the model matrix and the view matrix using emulated doubles. + // We add the result to the vertex and ignore the final lost precision. + vec3 model_origin = model_matrix[3].xyz; + if (is_multimesh) { + vertex = mat3(matrix) * vertex; + model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision); + } + vertex = mat3(model_matrix) * vertex; + vec3 temp_precision; // Will be ignored. + vertex += double_add_vec3(model_origin, model_precision, scene_data.inv_view_matrix[3].xyz, view_precision, temp_precision); + vertex = mat3(scene_data.view_matrix) * vertex; +#else vertex = (modelview * vec4(vertex, 1.0)).xyz; +#endif #ifdef NORMAL_USED normal = modelview_normal * normal; #endif @@ -490,7 +553,6 @@ layout(location = 10) in flat uint instance_index_interp; //defines to keep compatibility with vertex -#define model_matrix instances.data[draw_call.instance_index].transform #ifdef USE_MULTIVIEW #define projection_matrix scene_data.projection_matrix_view[ViewIndex] #define inv_projection_matrix scene_data.inv_projection_matrix_view[ViewIndex] @@ -737,6 +799,17 @@ void fragment_shader(in SceneData scene_data) { vec2 alpha_texture_coordinate = vec2(0.0, 0.0); #endif // ALPHA_ANTIALIASING_EDGE_USED + mat4 inv_view_matrix = scene_data.inv_view_matrix; + mat4 read_model_matrix = instances.data[instance_index].transform; +#ifdef USE_DOUBLE_PRECISION + read_model_matrix[0][3] = 0.0; + read_model_matrix[1][3] = 0.0; + read_model_matrix[2][3] = 0.0; + inv_view_matrix[0][3] = 0.0; + inv_view_matrix[1][3] = 0.0; + inv_view_matrix[2][3] = 0.0; +#endif + { #CODE : FRAGMENT } diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl index e8e2dce990..0d36b98645 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl @@ -62,13 +62,14 @@ layout(set = 0, binding = 3) uniform sampler decal_sampler; layout(set = 0, binding = 4) uniform sampler light_projector_sampler; -#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 5) -#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6) -#define INSTANCE_FLAGS_USE_SDFGI (1 << 7) -#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8) -#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9) -#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10) -#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 11) +#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 4) +#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 5) +#define INSTANCE_FLAGS_USE_SDFGI (1 << 6) +#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 7) +#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 8) +#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9) +#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10) +#define INSTANCE_FLAGS_PARTICLES (1 << 11) #define INSTANCE_FLAGS_MULTIMESH (1 << 12) #define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) #define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub b/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index a109fd4d75..33fd4c35b1 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -123,6 +123,33 @@ invariant gl_Position; #define scene_data scene_data_block.data +#ifdef USE_DOUBLE_PRECISION +// Helper functions for emulating double precision when adding floats. +vec3 quick_two_sum(vec3 a, vec3 b, out vec3 out_p) { + vec3 s = a + b; + out_p = b - (s - a); + return s; +} + +vec3 two_sum(vec3 a, vec3 b, out vec3 out_p) { + vec3 s = a + b; + vec3 v = s - a; + out_p = (a - (s - v)) + (b - v); + return s; +} + +vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec3 out_precision) { + vec3 s, t, se, te; + s = two_sum(base_a, base_b, se); + t = two_sum(prec_a, prec_b, te); + se += t; + s = quick_two_sum(s, se, se); + se += te; + s = quick_two_sum(s, se, out_precision); + return s; +} +#endif + void main() { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) @@ -132,6 +159,17 @@ void main() { bool is_multimesh = bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH); mat4 model_matrix = draw_call.transform; + mat4 inv_view_matrix = scene_data.inv_view_matrix; +#ifdef USE_DOUBLE_PRECISION + vec3 model_precision = vec3(model_matrix[0][3], model_matrix[1][3], model_matrix[2][3]); + model_matrix[0][3] = 0.0; + model_matrix[1][3] = 0.0; + model_matrix[2][3] = 0.0; + vec3 view_precision = vec3(inv_view_matrix[0][3], inv_view_matrix[1][3], inv_view_matrix[2][3]); + inv_view_matrix[0][3] = 0.0; + inv_view_matrix[1][3] = 0.0; + inv_view_matrix[2][3] = 0.0; +#endif mat3 model_normal_matrix; if (bool(draw_call.flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) { @@ -140,11 +178,12 @@ void main() { model_normal_matrix = mat3(model_matrix); } + mat4 matrix; + mat4 read_model_matrix = model_matrix; + if (is_multimesh) { //multimesh, instances are for it - mat4 matrix; - #ifdef USE_PARTICLE_TRAILS uint trail_size = (draw_call.flags >> INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT) & INSTANCE_FLAGS_PARTICLE_TRAIL_MASK; uint stride = 3 + 1 + 1; //particles always uses this format @@ -230,7 +269,15 @@ void main() { #endif //transpose matrix = transpose(matrix); - model_matrix = model_matrix * matrix; + +#if !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) || defined(MODEL_MATRIX_USED) + // Normally we can bake the multimesh transform into the model matrix, but when using double precision + // we avoid baking it in so we can emulate high precision. + read_model_matrix = model_matrix * matrix; +#if !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) + model_matrix = read_model_matrix; +#endif // !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) +#endif // !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) || defined(MODEL_MATRIX_USED) model_normal_matrix = model_normal_matrix * mat3(matrix); } @@ -297,7 +344,22 @@ void main() { // using local coordinates (default) #if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED) +#ifdef USE_DOUBLE_PRECISION + // We separate the basis from the origin because the basis is fine with single point precision. + // Then we combine the translations from the model matrix and the view matrix using emulated doubles. + // We add the result to the vertex and ignore the final lost precision. + vec3 model_origin = model_matrix[3].xyz; + if (is_multimesh) { + vertex = mat3(matrix) * vertex; + model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision); + } + vertex = mat3(model_matrix) * vertex; + vec3 temp_precision; + vertex += double_add_vec3(model_origin, model_precision, scene_data.inv_view_matrix[3].xyz, view_precision, temp_precision); + vertex = mat3(scene_data.view_matrix) * vertex; +#else vertex = (modelview * vec4(vertex, 1.0)).xyz; +#endif #ifdef NORMAL_USED normal = modelview_normal * normal; #endif @@ -468,7 +530,6 @@ layout(location = 9) highp in float dp_clip; //defines to keep compatibility with vertex -#define model_matrix draw_call.transform #ifdef USE_MULTIVIEW #define projection_matrix scene_data.projection_matrix_view[ViewIndex] #define inv_projection_matrix scene_data.inv_projection_matrix_view[ViewIndex] @@ -685,6 +746,17 @@ void main() { vec2 alpha_texture_coordinate = vec2(0.0, 0.0); #endif // ALPHA_ANTIALIASING_EDGE_USED + mat4 inv_view_matrix = scene_data.inv_view_matrix; + mat4 read_model_matrix = draw_call.transform; +#ifdef USE_DOUBLE_PRECISION + read_model_matrix[0][3] = 0.0; + read_model_matrix[1][3] = 0.0; + read_model_matrix[2][3] = 0.0; + inv_view_matrix[0][3] = 0.0; + inv_view_matrix[1][3] = 0.0; + inv_view_matrix[2][3] = 0.0; +#endif + { #CODE : FRAGMENT } diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl index 5e4999fa0f..631ff0575b 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl @@ -55,13 +55,14 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler; layout(set = 0, binding = 3) uniform sampler decal_sampler; layout(set = 0, binding = 4) uniform sampler light_projector_sampler; -#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 5) -#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6) -#define INSTANCE_FLAGS_USE_SDFGI (1 << 7) -#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8) -#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9) -#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10) -#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 11) +#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 4) +#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 5) +#define INSTANCE_FLAGS_USE_SDFGI (1 << 6) +#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 7) +#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 8) +#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9) +#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10) +#define INSTANCE_FLAGS_PARTICLES (1 << 11) #define INSTANCE_FLAGS_MULTIMESH (1 << 12) #define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) #define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index fb5759bc17..3a6dd579b9 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -475,7 +475,7 @@ void main() { float particle_size = FRAME.particle_size; -#ifdef USE_COLLISON_SCALE +#ifdef USE_COLLISION_SCALE particle_size *= dot(vec3(length(PARTICLE.xform[0].xyz), length(PARTICLE.xform[1].xyz), length(PARTICLE.xform[2].xyz)), vec3(0.33333333333)); diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index b36a028f04..70243a9275 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -2526,7 +2526,7 @@ void MaterialStorage::_update_queued_materials() { material_update_list.remove(&material->update_element); if (uniforms_changed) { - //some implementations such as 3D renderer cache the matreial uniform set, so update is required + //some implementations such as 3D renderer cache the material uniform set, so update is required material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL); } } diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index db2e4cfa2a..2ce6550cc1 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -311,6 +311,18 @@ public: } } + // http://andrewthall.org/papers/df64_qf128.pdf +#ifdef REAL_T_IS_DOUBLE + static _FORCE_INLINE_ void split_double(double a, float *ahi, float *alo) { + const double SPLITTER = (1 << 29) + 1; + double t = a * SPLITTER; + double thi = t - (t - a); + double tlo = a - thi; + *ahi = (float)thi; + *alo = (float)tlo; + } +#endif + /* Samplers */ _FORCE_INLINE_ RID sampler_rd_get_default(RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat) { diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 1827b73507..b089b96101 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -2021,6 +2021,7 @@ Transform2D MeshStorage::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bo void MeshStorage::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) { Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); + ERR_FAIL_NULL(skeleton); ERR_FAIL_COND(!skeleton->use_2d); skeleton->base_transform_2d = p_base_transform; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 424d2d3c7a..4dca2233fe 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -102,7 +102,7 @@ ParticlesStorage::ParticlesStorage() { actions.render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n"; actions.render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n"; actions.render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n"; - actions.render_mode_defines["collision_use_scale"] = "#define USE_COLLISON_SCALE\n"; + actions.render_mode_defines["collision_use_scale"] = "#define USE_COLLISION_SCALE\n"; actions.sampler_array_name = "material_samplers"; actions.base_texture_binding_index = 1; @@ -1874,8 +1874,6 @@ AABB ParticlesStorage::particles_collision_get_aabb(RID p_particles_collision) c return aabb; } } - - return AABB(); } Vector3 ParticlesStorage::particles_collision_get_extents(RID p_particles_collision) const { diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp index f925f87cbe..7dd790d1da 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp @@ -59,6 +59,12 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p RendererRD::MaterialStorage::store_transform(cam_transform, ubo.inv_view_matrix); RendererRD::MaterialStorage::store_transform(cam_transform.affine_inverse(), ubo.view_matrix); +#ifdef REAL_T_IS_DOUBLE + RendererRD::MaterialStorage::split_double(-cam_transform.origin.x, &ubo.inv_view_matrix[12], &ubo.inv_view_matrix[3]); + RendererRD::MaterialStorage::split_double(-cam_transform.origin.y, &ubo.inv_view_matrix[13], &ubo.inv_view_matrix[7]); + RendererRD::MaterialStorage::split_double(-cam_transform.origin.z, &ubo.inv_view_matrix[14], &ubo.inv_view_matrix[11]); +#endif + for (uint32_t v = 0; v < view_count; v++) { projection = correction * view_projection[v]; RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix_view[v]); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index b87b4d4a0f..21811068cd 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -673,6 +673,8 @@ void TextureStorage::texture_free(RID p_texture) { } void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) { + ERR_FAIL_COND(p_image.is_null()); + TextureToRDFormat ret_format; Ref<Image> image = _validate_texture_format(p_image, ret_format); @@ -795,6 +797,8 @@ void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<R case RS::TEXTURE_LAYERED_CUBEMAP_ARRAY: { texture.rd_type = RD::TEXTURE_TYPE_CUBE_ARRAY; } break; + default: + ERR_FAIL(); // Shouldn't happen, silence warnings. } texture.rd_format = ret_format.format; |