diff options
Diffstat (limited to 'drivers')
32 files changed, 611 insertions, 665 deletions
diff --git a/drivers/gles3/environment/gi.cpp b/drivers/gles3/environment/gi.cpp index 84cdb81d35..5b16d3539f 100644 --- a/drivers/gles3/environment/gi.cpp +++ b/drivers/gles3/environment/gi.cpp @@ -98,6 +98,13 @@ float GI::voxel_gi_get_energy(RID p_voxel_gi) const { return 0.0; } +void GI::voxel_gi_set_baked_exposure_normalization(RID p_voxel_gi, float p_baked_exposure) { +} + +float GI::voxel_gi_get_baked_exposure_normalization(RID p_voxel_gi) const { + return 1.0; +} + void GI::voxel_gi_set_bias(RID p_voxel_gi, float p_range) { } diff --git a/drivers/gles3/environment/gi.h b/drivers/gles3/environment/gi.h index 7a0634f22b..5b0aad380e 100644 --- a/drivers/gles3/environment/gi.h +++ b/drivers/gles3/environment/gi.h @@ -74,6 +74,9 @@ public: virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_range) override; virtual float voxel_gi_get_energy(RID p_voxel_gi) const override; + virtual void voxel_gi_set_baked_exposure_normalization(RID p_voxel_gi, float p_baked_exposure) override; + virtual float voxel_gi_get_baked_exposure_normalization(RID p_voxel_gi) const override; + virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_range) override; virtual float voxel_gi_get_bias(RID p_voxel_gi) const override; diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index a960fced1f..0ffede0992 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -183,7 +183,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_state_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW); - GLuint global_buffer = material_storage->global_shader_uniforms_get_uniform_buffer(); + GLuint global_buffer = material_storage->global_shader_parameters_get_uniform_buffer(); glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_LOCATION, global_buffer); glBindBuffer(GL_UNIFORM_BUFFER, 0); @@ -198,7 +198,8 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ int item_count = 0; bool backbuffer_cleared = false; bool time_used = false; - bool material_screen_texture_found = false; + bool material_screen_texture_cached = false; + bool material_screen_texture_mipmaps_cached = false; Rect2 back_buffer_rect; bool backbuffer_copy = false; bool backbuffer_gen_mipmaps = false; @@ -223,10 +224,12 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ GLES3::CanvasMaterialData *md = static_cast<GLES3::CanvasMaterialData *>(material_storage->material_get_data(material, RS::SHADER_CANVAS_ITEM)); if (md && md->shader_data->valid) { if (md->shader_data->uses_screen_texture && canvas_group_owner == nullptr) { - if (!material_screen_texture_found) { + if (!material_screen_texture_cached) { backbuffer_copy = true; back_buffer_rect = Rect2(); backbuffer_gen_mipmaps = md->shader_data->uses_screen_texture_mipmaps; + } else if (!material_screen_texture_mipmaps_cached) { + backbuffer_gen_mipmaps = md->shader_data->uses_screen_texture_mipmaps; } } @@ -287,7 +290,16 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps); backbuffer_copy = false; - material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies + backbuffer_gen_mipmaps = false; + material_screen_texture_cached = true; // After a backbuffer copy, screen texture makes no further copies. + material_screen_texture_mipmaps_cached = backbuffer_gen_mipmaps; + } + + if (backbuffer_gen_mipmaps) { + texture_storage->render_target_gen_back_buffer_mipmaps(p_to_render_target, back_buffer_rect); + + backbuffer_gen_mipmaps = false; + material_screen_texture_mipmaps_cached = true; } // just add all items for now @@ -1023,8 +1035,8 @@ void RasterizerCanvasGLES3::_bind_instance_data_buffer(uint32_t p_max_index) { glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_buffer]); #ifdef WEB_ENABLED - //WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead - glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * p_max_index, state.instance_data_array, GL_DYNAMIC_DRAW); + //WebGL 2.0 does not support mapping buffers, so use slow glBufferSubData instead + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(InstanceData) * p_max_index, state.instance_data_array); #else void *ubo = glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(InstanceData) * p_max_index, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); memcpy(ubo, state.instance_data_array, sizeof(InstanceData) * p_max_index); diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 7537636356..3575837794 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -108,19 +108,6 @@ void RasterizerGLES3::begin_frame(double frame_step) { } void RasterizerGLES3::end_frame(bool p_swap_buffers) { - // if (OS::get_singleton()->is_layered_allowed()) { - // if (!OS::get_singleton()->get_window_per_pixel_transparency_enabled()) { - //clear alpha - // glColorMask(false, false, false, true); - // glClearColor(0.5, 0, 0, 1); - // glClear(GL_COLOR_BUFFER_BIT); - // glColorMask(true, true, true, true); - // } - // } - - // glClearColor(1, 0, 0, 1); - // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - if (p_swap_buffers) { DisplayServer::get_singleton()->swap_buffers(); } else { @@ -293,11 +280,6 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target); ERR_FAIL_COND(!rt); - // TODO: do we need a keep 3d linear option? - - // Make sure we are drawing to the right context. - DisplayServer::get_singleton()->gl_window_make_current(p_screen); - if (rt->external.fbo != 0) { glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->external.fbo); } else { @@ -311,9 +293,6 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display // is this p_screen useless in a multi window environment? void RasterizerGLES3::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { - // All blits are going to the system framebuffer, so just bind once. - glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); - for (int i = 0; i < p_amount; i++) { const BlitToScreen &blit = p_render_targets[i]; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index cb479dda39..85b35639ec 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -483,6 +483,13 @@ void RasterizerSceneGLES3::sky_set_material(RID p_sky, RID p_material) { _invalidate_sky(sky); } +float RasterizerSceneGLES3::sky_get_baked_exposure(RID p_sky) const { + Sky *sky = sky_owner.get_or_null(p_sky); + ERR_FAIL_COND_V(!sky, 1.0); + + return sky->baked_exposure; +} + void RasterizerSceneGLES3::_invalidate_sky(Sky *p_sky) { if (!p_sky->dirty) { p_sky->dirty = true; @@ -561,13 +568,13 @@ void RasterizerSceneGLES3::_update_dirty_skys() { dirty_sky_list = nullptr; } -void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { +void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - ERR_FAIL_COND(p_env.is_null()); + ERR_FAIL_COND(p_render_data->environment.is_null()); GLES3::SkyMaterialData *material = nullptr; - Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env)); + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment)); RID sky_material; @@ -639,6 +646,14 @@ void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const Pag float sign = light_storage->light_is_negative(base) ? -1 : 1; sky_light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY); + if (is_using_physical_light_units()) { + sky_light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY); + } + + if (p_render_data->camera_attributes.is_valid()) { + sky_light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } + Color linear_col = light_storage->light_get_color(base); sky_light_data.color[0] = linear_col.r; sky_light_data.color[1] = linear_col.g; @@ -668,6 +683,7 @@ void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const Pag light_data_dirty = true; for (uint32_t i = sky_globals.directional_light_count; i < sky_globals.max_directional_lights; i++) { sky_globals.directional_lights[i].enabled = false; + sky_globals.last_frame_directional_lights[i].enabled = false; } } @@ -708,7 +724,7 @@ void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const Pag } } -void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -768,12 +784,13 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.matrix[2][0], camera.matrix[0][0], camera.matrix[2][1], camera.matrix[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); + GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); glBindVertexArray(sky_globals.screen_triangle_array); glDrawArrays(GL_TRIANGLES, 0, 3); } -void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -866,6 +883,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, cm.matrix[2][0], cm.matrix[0][0], cm.matrix[2][1], cm.matrix[1][1], shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); + GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); glBindVertexArray(sky_globals.screen_triangle_array); @@ -887,7 +905,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p _filter_sky_radiance(sky, 0); //Just copy over the first mipmap } sky->processing_layer = 1; - + sky->baked_exposure = p_luminance_multiplier; sky->reflection_dirty = false; } else { if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) { @@ -1061,25 +1079,6 @@ Ref<Image> RasterizerSceneGLES3::environment_bake_panorama(RID p_env, bool p_bak return Ref<Image>(); } -RID RasterizerSceneGLES3::camera_effects_allocate() { - return RID(); -} - -void RasterizerSceneGLES3::camera_effects_initialize(RID p_rid) { -} - -void RasterizerSceneGLES3::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) { -} - -void RasterizerSceneGLES3::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) { -} - -void RasterizerSceneGLES3::camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) { -} - -void RasterizerSceneGLES3::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) { -} - void RasterizerSceneGLES3::positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) { } @@ -1403,8 +1402,9 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); - float bg_energy = environment_get_bg_energy(p_render_data->environment); - scene_state.ubo.ambient_light_color_energy[3] = bg_energy; + float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment); + + scene_state.ubo.ambient_light_color_energy[3] = bg_energy_multiplier; scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment); @@ -1413,9 +1413,9 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); color = color.srgb_to_linear(); - scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy; - scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy; - scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy; + scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier; + scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier; + scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier; scene_state.ubo.use_ambient_light = true; scene_state.ubo.use_ambient_cubemap = false; } else { @@ -1459,6 +1459,25 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da } else { } + if (p_render_data->camera_attributes.is_valid()) { + scene_state.ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + scene_state.ubo.IBL_exposure_normalization = 1.0; + if (is_environment(p_render_data->environment)) { + RID sky_rid = environment_get_sky(p_render_data->environment); + if (sky_rid.is_valid()) { + float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes) * environment_get_bg_intensity(p_render_data->environment); + scene_state.ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, sky_get_baked_exposure(sky_rid)); + } + } + } else if (scene_state.ubo.emissive_exposure_normalization > 0.0) { + // This branch is triggered when using render_material(). + // Emissive is set outside the function, so don't set it. + // IBL isn't used don't set it. + } else { + scene_state.ubo.emissive_exposure_normalization = 1.0; + scene_state.ubo.IBL_exposure_normalization = 1.0; + } + if (scene_state.ubo_buffer == 0) { glGenBuffers(1, &scene_state.ubo_buffer); } @@ -1510,7 +1529,17 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b float sign = light_storage->light_is_negative(base) ? -1 : 1; - light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI; + light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY); + + if (is_using_physical_light_units()) { + light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY); + } else { + light_data.energy *= Math_PI; + } + + if (p_render_data->camera_attributes.is_valid()) { + light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } Color linear_col = light_storage->light_get_color(base).srgb_to_linear(); light_data.color[0] = linear_col.r; @@ -1590,7 +1619,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b for (uint32_t i = 0; i < (r_omni_light_count + r_spot_light_count); i++) { uint32_t index = (i < r_omni_light_count) ? i : i - (r_omni_light_count); LightData &light_data = (i < r_omni_light_count) ? scene_state.omni_lights[index] : scene_state.spot_lights[index]; - //RS::LightType type = (i < omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT; + RS::LightType type = (i < r_omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT; LightInstance *li = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].instance : scene_state.spot_light_sort[index].instance; RID base = li->light; @@ -1634,7 +1663,26 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b } } - float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade; + float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * fade; + + if (is_using_physical_light_units()) { + energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY); + + // Convert from Luminous Power to Luminous Intensity + if (type == RS::LIGHT_OMNI) { + energy *= 1.0 / (Math_PI * 4.0); + } else { + // Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle. + // We make this assumption to keep them easy to control. + energy *= 1.0 / Math_PI; + } + } else { + energy *= Math_PI; + } + + if (p_render_data->camera_attributes.is_valid()) { + energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } light_data.color[0] = linear_col.r * energy; light_data.color[1] = linear_col.g * energy; @@ -1671,23 +1719,23 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b glBindBuffer(GL_UNIFORM_BUFFER, 0); } -void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { +void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::Config *config = GLES3::Config::get_singleton(); RENDER_TIMESTAMP("Setup 3D Scene"); - RenderBuffers *rb = nullptr; + Ref<RenderSceneBuffersGLES3> rb; if (p_render_buffers.is_valid()) { - rb = render_buffers_owner.get_or_null(p_render_buffers); - ERR_FAIL_COND(!rb); + rb = p_render_buffers; + ERR_FAIL_COND(rb.is_null()); } // Assign render data // Use the format from rendererRD RenderDataGLES3 render_data; { - render_data.render_buffers = p_render_buffers; - render_data.transparent_bg = rb->is_transparent; + render_data.render_buffers = rb; + render_data.transparent_bg = rb.is_valid() ? rb->is_transparent : false; // Our first camera is used by default render_data.cam_transform = p_camera_data->main_transform; render_data.inv_cam_transform = render_data.cam_transform.affine_inverse(); @@ -1707,7 +1755,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * render_data.lights = &p_lights; render_data.reflection_probes = &p_reflection_probes; render_data.environment = p_environment; - render_data.camera_effects = p_camera_effects; + render_data.camera_attributes = p_camera_attributes; render_data.reflection_probe = p_reflection_probe; render_data.reflection_probe_pass = p_reflection_probe_pass; @@ -1736,7 +1784,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * // Fill Light lists here ////////// - GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_uniforms_get_uniform_buffer(); + GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer(); glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer); Color clear_color; @@ -1768,6 +1816,8 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW); + scene_state.ubo.emissive_exposure_normalization = -1.0; // Use default exposure normalization. + _setup_lights(&render_data, false, render_data.directional_light_count, render_data.omni_light_count, render_data.spot_light_count); _setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, !render_data.reflection_probe.is_valid(), clear_color, false); @@ -1778,17 +1828,24 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * bool draw_sky = false; bool draw_sky_fog_only = false; bool keep_color = false; + float sky_energy_multiplier = 1.0; if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black } else if (render_data.environment.is_valid()) { RS::EnvironmentBG bg_mode = environment_get_background(render_data.environment); - float bg_energy = environment_get_bg_energy(render_data.environment); + float bg_energy_multiplier = environment_get_bg_energy_multiplier(render_data.environment); + bg_energy_multiplier *= environment_get_bg_intensity(render_data.environment); + + if (render_data.camera_attributes.is_valid()) { + bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(render_data.camera_attributes); + } + switch (bg_mode) { case RS::ENV_BG_CLEAR_COLOR: { - clear_color.r *= bg_energy; - clear_color.g *= bg_energy; - clear_color.b *= bg_energy; + clear_color.r *= bg_energy_multiplier; + clear_color.g *= bg_energy_multiplier; + clear_color.b *= bg_energy_multiplier; if (environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); @@ -1796,9 +1853,9 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * } break; case RS::ENV_BG_COLOR: { clear_color = environment_get_bg_color(render_data.environment); - clear_color.r *= bg_energy; - clear_color.g *= bg_energy; - clear_color.b *= bg_energy; + clear_color.r *= bg_energy_multiplier; + clear_color.g *= bg_energy_multiplier; + clear_color.b *= bg_energy_multiplier; if (environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); @@ -1828,11 +1885,13 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * projection = correction * render_data.cam_projection; } - _setup_sky(render_data.environment, p_render_buffers, *render_data.lights, projection, render_data.cam_transform, screen_size); + sky_energy_multiplier *= bg_energy_multiplier; + + _setup_sky(&render_data, *render_data.lights, projection, render_data.cam_transform, screen_size); if (environment_get_sky(render_data.environment).is_valid()) { if (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY || (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_BG && environment_get_background(render_data.environment) == RS::ENV_BG_SKY)) { - _update_sky_radiance(render_data.environment, projection, render_data.cam_transform); + _update_sky_radiance(render_data.environment, projection, render_data.cam_transform, sky_energy_multiplier); } } else { // do not try to draw sky if invalid @@ -1936,7 +1995,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED; scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK; - _draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform); + _draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform, sky_energy_multiplier); } RENDER_TIMESTAMP("Render 3D Transparent Pass"); @@ -1947,8 +2006,8 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * _render_list_template<PASS_MODE_COLOR_TRANSPARENT>(&render_list_params_alpha, &render_data, 0, render_list[RENDER_LIST_ALPHA].elements.size(), true); - if (p_render_buffers.is_valid()) { - _render_buffers_debug_draw(p_render_buffers, p_shadow_atlas, p_occluder_debug_tex); + if (rb.is_valid()) { + _render_buffers_debug_draw(rb, p_shadow_atlas, p_occluder_debug_tex); } glDisable(GL_BLEND); texture_storage->render_target_disable_clear_request(rb->render_target); @@ -2270,74 +2329,10 @@ void RasterizerSceneGLES3::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_dra debug_draw = p_debug_draw; } -RID RasterizerSceneGLES3::render_buffers_create() { - RenderBuffers rb; - return render_buffers_owner.make_rid(rb); -} - -void RasterizerSceneGLES3::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { - GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); - - RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); - ERR_FAIL_COND(!rb); - - //rb->internal_width = p_internal_width; // ignore for now - //rb->internal_height = p_internal_height; - rb->width = p_width; - rb->height = p_height; - //rb->fsr_sharpness = p_fsr_sharpness; - rb->render_target = p_render_target; - //rb->msaa = p_msaa; - //rb->screen_space_aa = p_screen_space_aa; - //rb->use_debanding = p_use_debanding; - //rb->view_count = p_view_count; - - _free_render_buffer_data(rb); - - GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target); - - rb->is_transparent = rt->is_transparent; - - // framebuffer - glGenFramebuffers(1, &rb->framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, rb->framebuffer); - - glBindTexture(GL_TEXTURE_2D, rt->color); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); - - glGenTextures(1, &rb->depth_texture); - glBindTexture(GL_TEXTURE_2D, rb->depth_texture); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rb->depth_texture, 0); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - glBindTexture(GL_TEXTURE_2D, 0); - glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->system_fbo); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - _free_render_buffer_data(rb); - WARN_PRINT("Could not create 3D renderbuffer, status: " + texture_storage->get_framebuffer_error(status)); - return; - } -} - -void RasterizerSceneGLES3::_free_render_buffer_data(RenderBuffers *rb) { - if (rb->depth_texture) { - glDeleteTextures(1, &rb->depth_texture); - rb->depth_texture = 0; - } - if (rb->framebuffer) { - glDeleteFramebuffers(1, &rb->framebuffer); - rb->framebuffer = 0; - } +Ref<RenderSceneBuffers> RasterizerSceneGLES3::render_buffers_create() { + Ref<RenderSceneBuffersGLES3> rb; + rb.instantiate(); + return rb; } //clear render buffers @@ -2365,7 +2360,7 @@ void RasterizerSceneGLES3::_free_render_buffer_data(RenderBuffers *rb) { } */ -void RasterizerSceneGLES3::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer) { +void RasterizerSceneGLES3::_render_buffers_debug_draw(Ref<RenderSceneBuffersGLES3> p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer) { } void RasterizerSceneGLES3::gi_set_use_half_resolution(bool p_enable) { @@ -2384,7 +2379,7 @@ void RasterizerSceneGLES3::sub_surface_scattering_set_quality(RS::SubSurfaceScat void RasterizerSceneGLES3::sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) { } -TypedArray<Image> RasterizerSceneGLES3::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { +TypedArray<Image> RasterizerSceneGLES3::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) { return TypedArray<Image>(); } @@ -2396,16 +2391,13 @@ bool RasterizerSceneGLES3::free(RID p_rid) { ERR_FAIL_COND_V(!sky, false); _free_sky_data(sky); sky_owner.free(p_rid); - } else if (render_buffers_owner.owns(p_rid)) { - RenderBuffers *rb = render_buffers_owner.get_or_null(p_rid); - ERR_FAIL_COND_V(!rb, false); - _free_render_buffer_data(rb); - render_buffers_owner.free(p_rid); - } else if (light_instance_owner.owns(p_rid)) { LightInstance *light_instance = light_instance_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!light_instance, false); light_instance_owner.free(p_rid); + } else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) { + //not much to delete, just free it + RSG::camera_attributes->camera_attributes_free(p_rid); } else { return false; } @@ -2431,6 +2423,9 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); GLES3::Config *config = GLES3::Config::get_singleton(); + // Quality settings. + use_physical_light_units = GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units"); + { // Setup Lights @@ -2486,7 +2481,7 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { scene_globals.default_shader = material_storage->shader_allocate(); material_storage->shader_initialize(scene_globals.default_shader); material_storage->shader_set_code(scene_globals.default_shader, R"( -// Default 3D material shader (clustered). +// Default 3D material shader. shader_type spatial; diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index a54d87a3a3..f0dc972678 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -45,6 +45,7 @@ #include "shaders/cubemap_filter.glsl.gen.h" #include "shaders/sky.glsl.gen.h" #include "storage/material_storage.h" +#include "storage/render_scene_buffers_gles3.h" #include "storage/utilities.h" enum RenderListType { @@ -91,7 +92,7 @@ enum { }; struct RenderDataGLES3 { - RID render_buffers = RID(); + Ref<RenderSceneBuffersGLES3> render_buffers; bool transparent_bg = false; Transform3D cam_transform = Transform3D(); @@ -111,7 +112,7 @@ struct RenderDataGLES3 { const PagedArray<RID> *lights = nullptr; const PagedArray<RID> *reflection_probes = nullptr; RID environment = RID(); - RID camera_effects = RID(); + RID camera_attributes = RID(); RID reflection_probe = RID(); int reflection_probe_pass = 0; @@ -123,7 +124,7 @@ struct RenderDataGLES3 { uint32_t spot_light_count = 0; uint32_t omni_light_count = 0; - RendererScene::RenderInfo *render_info = nullptr; + RenderingMethod::RenderInfo *render_info = nullptr; }; class RasterizerCanvasGLES3; @@ -303,12 +304,13 @@ private: }; enum { - INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 5, - INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6, - INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8, - INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9, - INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10, - INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 11, + INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4, + INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5, + INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 7, + INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 8, + INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 9, + INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 10, + INSTANCE_DATA_FLAG_PARTICLES = 1 << 11, INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12, INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13, INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14, @@ -344,7 +346,7 @@ private: float ambient_color_sky_mix; uint32_t material_uv2_mode; - float pad2; + float emissive_exposure_normalization; uint32_t use_ambient_light = 0; uint32_t use_ambient_cubemap = 0; @@ -357,7 +359,7 @@ private: uint32_t directional_light_count; float z_far; float z_near; - float pad1; + float IBL_exposure_normalization; uint32_t fog_enabled; float fog_density; @@ -490,52 +492,21 @@ protected: double time; double time_step = 0; - struct RenderBuffers { - int internal_width = 0; - int internal_height = 0; - int width = 0; - int height = 0; - //float fsr_sharpness = 0.2f; - RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; - //RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED; - //bool use_debanding = false; - //uint32_t view_count = 1; - - bool is_transparent = false; - - RID render_target; - GLuint internal_texture = 0; // Used for rendering when post effects are enabled - GLuint depth_texture = 0; // Main depth texture - GLuint framebuffer = 0; // Main framebuffer, contains internal_texture and depth_texture or render_target->color and depth_texture - - //built-in textures used for ping pong image processing and blurring - struct Blur { - RID texture; - - struct Mipmap { - RID texture; - int width; - int height; - GLuint fbo; - }; - - Vector<Mipmap> mipmaps; - }; - - Blur blur[2]; //the second one starts from the first mipmap - }; - bool screen_space_roughness_limiter = false; float screen_space_roughness_limiter_amount = 0.25; float screen_space_roughness_limiter_limit = 0.18; - mutable RID_Owner<RenderBuffers, true> render_buffers_owner; + void _render_buffers_debug_draw(Ref<RenderSceneBuffersGLES3> p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer); + + /* Camera Attributes */ - void _free_render_buffer_data(RenderBuffers *rb); - void _allocate_blur_textures(RenderBuffers *rb); - void _allocate_depth_backbuffer_textures(RenderBuffers *rb); + struct CameraAttributes { + float exposure_multiplier = 1.0; + float exposure_normalization = 1.0; + }; - void _render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer); + bool use_physical_light_units = false; + mutable RID_Owner<CameraAttributes, true> camera_attributes_owner; /* Environment */ @@ -605,6 +576,7 @@ protected: bool dirty = false; int processing_layer = 0; Sky *dirty_list = nullptr; + float baked_exposure = 1.0; //State to track when radiance cubemap needs updating GLES3::SkyMaterialData *prev_material; @@ -615,18 +587,18 @@ protected: Sky *dirty_sky_list = nullptr; mutable RID_Owner<Sky, true> sky_owner; - void _setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); + void _setup_sky(const RenderDataGLES3 *p_render_data, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); void _invalidate_sky(Sky *p_sky); void _update_dirty_skys(); - void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform); + void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier); void _filter_sky_radiance(Sky *p_sky, int p_base_layer); - void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform); + void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier); void _free_sky_data(Sky *p_sky); public: static RasterizerSceneGLES3 *get_singleton() { return singleton; } - RasterizerCanvasGLES3 *canvas; + RasterizerCanvasGLES3 *canvas = nullptr; RenderGeometryInstance *geometry_instance_create(RID p_base) override; void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override; @@ -646,14 +618,14 @@ public: /* SDFGI UPDATE */ - void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {} - int sdfgi_get_pending_region_count(RID p_render_buffers) const override { + void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {} + int sdfgi_get_pending_region_count(const Ref<RenderSceneBuffers> &p_render_buffers) const override { return 0; } - AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override { + AABB sdfgi_get_pending_region_bounds(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override { return AABB(); } - uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override { + uint32_t sdfgi_get_pending_region_cascade(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override { return 0; } @@ -665,6 +637,7 @@ public: void sky_set_mode(RID p_sky, RS::SkyMode p_mode) override; void sky_set_material(RID p_sky, RID p_material) override; Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) override; + float sky_get_baked_exposure(RID p_sky) const; /* ENVIRONMENT API */ @@ -686,13 +659,9 @@ public: Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override; - RID camera_effects_allocate() override; - void camera_effects_initialize(RID p_rid) override; - void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override; - void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) override; - - void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) override; - void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override; + _FORCE_INLINE_ bool is_using_physical_light_units() { + return use_physical_light_units; + } void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override; void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override; @@ -743,7 +712,7 @@ public: void voxel_gi_set_quality(RS::VoxelGIQuality) override; - void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; + void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override; void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override; @@ -761,8 +730,7 @@ public: return debug_draw; } - RID render_buffers_create() override; - void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; + Ref<RenderSceneBuffers> render_buffers_create() override; void gi_set_use_half_resolution(bool p_enable) override; void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override; @@ -771,7 +739,7 @@ public: void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override; void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override; - TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override; + TypedArray<Image> bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) override; bool free(RID p_rid) override; void update() override; diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 5ec25327be..7334100575 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -210,8 +210,8 @@ void main() { #include "canvas_uniforms_inc.glsl" #include "stdlib_inc.glsl" -uniform sampler2D atlas_texture; //texunit:-2 -uniform sampler2D shadow_atlas_texture; //texunit:-3 +//uniform sampler2D atlas_texture; //texunit:-2 +//uniform sampler2D shadow_atlas_texture; //texunit:-3 uniform sampler2D screen_texture; //texunit:-4 uniform sampler2D sdf_texture; //texunit:-5 uniform sampler2D normal_texture; //texunit:-6 @@ -241,54 +241,8 @@ layout(std140) uniform MaterialUniforms{ }; #endif -vec2 screen_uv_to_sdf(vec2 p_uv) { - return screen_to_sdf * p_uv; -} - -float texture_sdf(vec2 p_sdf) { - vec2 uv = p_sdf * sdf_to_tex.xy + sdf_to_tex.zw; - float d = texture(sdf_texture, uv).r; - d *= SDF_MAX_LENGTH; - return d * tex_to_sdf; -} - -vec2 texture_sdf_normal(vec2 p_sdf) { - vec2 uv = p_sdf * sdf_to_tex.xy + sdf_to_tex.zw; - - const float EPSILON = 0.001; - return normalize(vec2( - texture(sdf_texture, uv + vec2(EPSILON, 0.0)).r - texture(sdf_texture, uv - vec2(EPSILON, 0.0)).r, - texture(sdf_texture, uv + vec2(0.0, EPSILON)).r - texture(sdf_texture, uv - vec2(0.0, EPSILON)).r)); -} - -vec2 sdf_to_screen_uv(vec2 p_sdf) { - return p_sdf * sdf_to_screen; -} - #GLOBALS -#ifdef LIGHT_CODE_USED - -vec4 light_compute( - vec3 light_vertex, - vec3 light_position, - vec3 normal, - vec4 light_color, - float light_energy, - vec4 specular_shininess, - inout vec4 shadow_modulate, - vec2 screen_uv, - vec2 uv, - vec4 color, bool is_directional) { - vec4 light = vec4(0.0); - -#CODE : LIGHT - - return light; -} - -#endif - #ifdef USE_NINEPATCH float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) { @@ -332,95 +286,6 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo #endif -vec3 light_normal_compute(vec3 light_vec, vec3 normal, vec3 base_color, vec3 light_color, vec4 specular_shininess, bool specular_shininess_used) { - float cNdotL = max(0.0, dot(normal, light_vec)); - - if (specular_shininess_used) { - //blinn - vec3 view = vec3(0.0, 0.0, 1.0); // not great but good enough - vec3 half_vec = normalize(view + light_vec); - - float cNdotV = max(dot(normal, view), 0.0); - float cNdotH = max(dot(normal, half_vec), 0.0); - float cVdotH = max(dot(view, half_vec), 0.0); - float cLdotH = max(dot(light_vec, half_vec), 0.0); - float shininess = exp2(15.0 * specular_shininess.a + 1.0) * 0.25; - float blinn = pow(cNdotH, shininess); - blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); - float s = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); - - return specular_shininess.rgb * light_color * s + light_color * base_color * cNdotL; - } else { - return light_color * base_color * cNdotL; - } -} - -//float distance = length(shadow_pos); -vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv -#ifdef LIGHT_CODE_USED - , - vec3 shadow_modulate -#endif -) { - float shadow; - uint shadow_mode = light_data[light_base].flags & LIGHT_FLAGS_FILTER_MASK; - - if (shadow_mode == LIGHT_FLAGS_SHADOW_NEAREST) { - shadow = textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x; - } else if (shadow_mode == LIGHT_FLAGS_SHADOW_PCF5) { - vec4 shadow_pixel_size = vec4(light_data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); - shadow = 0.0; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 2.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 2.0, 0.0).x; - shadow /= 5.0; - } else { //PCF13 - vec4 shadow_pixel_size = vec4(light_data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); - shadow = 0.0; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 6.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 5.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 4.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 3.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 2.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 2.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 3.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 4.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 5.0, 0.0).x; - shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 6.0, 0.0).x; - shadow /= 13.0; - } - - vec4 shadow_color = unpackUnorm4x8(light_data[light_base].shadow_color); -#ifdef LIGHT_CODE_USED - shadow_color.rgb *= shadow_modulate; -#endif - - shadow_color.a *= light_color.a; //respect light alpha - - return mix(light_color, shadow_color, shadow); -} - -void light_blend_compute(uint light_base, vec4 light_color, inout vec3 color) { - uint blend_mode = light_data[light_base].flags & LIGHT_FLAGS_BLEND_MASK; - - switch (blend_mode) { - case LIGHT_FLAGS_BLEND_MODE_ADD: { - color.rgb += light_color.rgb * light_color.a; - } break; - case LIGHT_FLAGS_BLEND_MODE_SUB: { - color.rgb -= light_color.rgb * light_color.a; - } break; - case LIGHT_FLAGS_BLEND_MODE_MIX: { - color.rgb = mix(color.rgb, light_color.rgb, light_color.a); - } break; - } -} - float msdf_median(float r, float g, float b, float a) { return min(max(min(r, g), min(max(r, g), b)), a); } @@ -487,8 +352,7 @@ void main() { color *= texture(color_texture, uv); } - uint light_count = (draw_data[draw_data_instance].flags >> FLAGS_LIGHT_COUNT_SHIFT) & uint(0xF); //max 16 lights - bool using_light = light_count > uint(0) || directional_light_count > uint(0); + bool using_light = false; vec3 normal; @@ -547,156 +411,11 @@ void main() { #endif } - if (normal_used) { - //convert by item transform - normal.xy = mat2(normalize(draw_data[draw_data_instance].world_x), normalize(draw_data[draw_data_instance].world_y)) * normal.xy; - //convert by canvas transform - normal = normalize((canvas_normal_transform * vec4(normal, 0.0)).xyz); - } - - vec3 base_color = color.rgb; - if (bool(draw_data[draw_data_instance].flags & FLAGS_USING_LIGHT_MASK)) { - color = vec4(0.0); //invisible by default due to using light mask - } - #ifdef MODE_LIGHT_ONLY color = vec4(0.0); #else color *= canvas_modulation; #endif -#if !defined(DISABLE_LIGHTING) && !defined(MODE_UNSHADED) - - for (uint i = uint(0); i < directional_light_count; i++) { - uint light_base = i; - - vec2 direction = light_data[light_base].position; - vec4 light_color = light_data[light_base].color; - -#ifdef LIGHT_CODE_USED - - vec4 shadow_modulate = vec4(1.0); - light_color = light_compute(light_vertex, vec3(direction, light_data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true); -#else - - if (normal_used) { - vec3 light_vec = normalize(mix(vec3(direction, 0.0), vec3(0, 0, 1), light_data[light_base].height)); - light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); - } -#endif - - if (bool(light_data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) { - vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_data[light_base].shadow_matrix[0], light_data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. - - vec4 shadow_uv = vec4(shadow_pos.x, light_data[light_base].shadow_y_ofs, shadow_pos.y * light_data[light_base].shadow_zfar_inv, 1.0); - - light_color = light_shadow_compute(light_base, light_color, shadow_uv -#ifdef LIGHT_CODE_USED - , - shadow_modulate.rgb -#endif - ); - } - - light_blend_compute(light_base, light_color, color.rgb); - } - - // Positional Lights - - for (uint i = uint(0); i < MAX_LIGHTS_PER_ITEM; i++) { - if (i >= light_count) { - break; - } - uint light_base; - if (i < uint(8)) { - if (i < uint(4)) { - light_base = draw_data[draw_data_instance].lights.x; - } else { - light_base = draw_data[draw_data_instance].lights.y; - } - } else { - if (i < uint(12)) { - light_base = draw_data[draw_data_instance].lights.z; - } else { - light_base = draw_data[draw_data_instance].lights.w; - } - } - light_base >>= (i & uint(3)) * uint(8); - light_base &= uint(0xFF); - - vec2 tex_uv = (vec4(vertex, 0.0, 1.0) * mat4(light_data[light_base].texture_matrix[0], light_data[light_base].texture_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. - vec2 tex_uv_atlas = tex_uv * light_data[light_base].atlas_rect.zw + light_data[light_base].atlas_rect.xy; - vec4 light_color = textureLod(atlas_texture, tex_uv_atlas, 0.0); - vec4 light_base_color = light_data[light_base].color; - -#ifdef LIGHT_CODE_USED - - vec4 shadow_modulate = vec4(1.0); - vec3 light_position = vec3(light_data[light_base].position, light_data[light_base].height); - - light_color.rgb *= light_base_color.rgb; - light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, false); -#else - - light_color.rgb *= light_base_color.rgb * light_base_color.a; - - if (normal_used) { - vec3 light_pos = vec3(light_data[light_base].position, light_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); - } -#endif - if (any(lessThan(tex_uv, vec2(0.0, 0.0))) || any(greaterThanEqual(tex_uv, vec2(1.0, 1.0)))) { - //if outside the light texture, light color is zero - light_color.a = 0.0; - } - - if (bool(light_data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) { - vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_data[light_base].shadow_matrix[0], light_data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. - - vec2 pos_norm = normalize(shadow_pos); - vec2 pos_abs = abs(pos_norm); - vec2 pos_box = pos_norm / max(pos_abs.x, pos_abs.y); - vec2 pos_rot = pos_norm * mat2(vec2(0.7071067811865476, -0.7071067811865476), vec2(0.7071067811865476, 0.7071067811865476)); //is there a faster way to 45 degrees rot? - float tex_ofs; - float distance; - if (pos_rot.y > 0.0) { - if (pos_rot.x > 0.0) { - tex_ofs = pos_box.y * 0.125 + 0.125; - distance = shadow_pos.x; - } else { - tex_ofs = pos_box.x * -0.125 + (0.25 + 0.125); - distance = shadow_pos.y; - } - } else { - if (pos_rot.x < 0.0) { - tex_ofs = pos_box.y * -0.125 + (0.5 + 0.125); - distance = -shadow_pos.x; - } else { - tex_ofs = pos_box.x * 0.125 + (0.75 + 0.125); - distance = -shadow_pos.y; - } - } - - distance *= light_data[light_base].shadow_zfar_inv; - - //float distance = length(shadow_pos); - vec4 shadow_uv = vec4(tex_ofs, light_data[light_base].shadow_y_ofs, distance, 1.0); - - light_color = light_shadow_compute(light_base, light_color, shadow_uv -#ifdef LIGHT_CODE_USED - , - shadow_modulate.rgb -#endif - ); - } - - light_blend_compute(light_base, light_color, color.rgb); - } -#endif // UNSHADED - frag_color = color; } diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl index 6b61fe9375..6b65e09cbf 100644 --- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl +++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl @@ -94,27 +94,6 @@ layout(std140) uniform CanvasData { //ubo:0 #define LIGHT_FLAGS_SHADOW_PCF5 uint(1 << 22) #define LIGHT_FLAGS_SHADOW_PCF13 uint(2 << 22) -struct Light { - mat2x4 texture_matrix; //light to texture coordinate matrix (transposed) - mat2x4 shadow_matrix; //light to shadow coordinate matrix (transposed) - vec4 color; - - uint shadow_color; // packed - uint flags; //index to light texture - float shadow_pixel_size; - float height; - - vec2 position; - float shadow_zfar_inv; - float shadow_y_ofs; - - vec4 atlas_rect; -}; - -layout(std140) uniform LightData { //ubo:2 - Light light_data[MAX_LIGHTS]; -}; - layout(std140) uniform DrawDataInstances { //ubo:3 DrawData draw_data[MAX_DRAW_DATA_INSTANCES]; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index c7fdd6ebd8..efd6036ba9 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -629,11 +629,12 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance #if defined(DIFFUSE_LAMBERT_WRAP) - // energy conserving lambert wrap shader - diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))); + // Energy conserving lambert wrap shader. + // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ + diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); #elif defined(DIFFUSE_TOON) - diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL); + diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL) * (1.0 / M_PI); #elif defined(DIFFUSE_BURLEY) diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl index eb1befe38e..4c0fe47f6b 100644 --- a/drivers/gles3/shaders/sky.glsl +++ b/drivers/gles3/shaders/sky.glsl @@ -92,6 +92,7 @@ uniform mat4 orientation; uniform vec4 projection; uniform vec3 position; uniform float time; +uniform float luminance_multiplier; uniform float fog_aerial_perspective; uniform vec3 fog_light_color; @@ -103,6 +104,15 @@ uniform uint directional_light_count; layout(location = 0) out vec4 frag_color; +#ifdef USE_DEBANDING +// https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare +vec3 interleaved_gradient_noise(vec2 pos) { + const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f); + float res = fract(magic.z * fract(dot(pos, magic.xy))) * 2.0 - 1.0; + return vec3(res, -res, res) / 255.0; +} +#endif + void main() { vec3 cube_normal; cube_normal.z = -1.0; @@ -149,6 +159,8 @@ void main() { } + color *= luminance_multiplier; + // Convert to Linear for tonemapping so color matches scene shader better color = srgb_to_linear(color); color *= exposure; @@ -165,4 +177,8 @@ void main() { frag_color.rgb = color; frag_color.a = alpha; + +#ifdef USE_DEBANDING + frag_color.rgb += interleaved_gradient_noise(gl_FragCoord.xy); +#endif } diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp index e2781bfbc0..6411590aee 100644 --- a/drivers/gles3/storage/light_storage.cpp +++ b/drivers/gles3/storage/light_storage.cpp @@ -58,6 +58,7 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0; + light.param[RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5; light.param[RS::LIGHT_PARAM_RANGE] = 1.0; light.param[RS::LIGHT_PARAM_SIZE] = 0.0; @@ -74,7 +75,6 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0; light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; - light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1; light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; light_owner.initialize_rid(p_light, light); @@ -422,13 +422,17 @@ float LightStorage::reflection_probe_get_mesh_lod_threshold(RID p_probe) const { /* LIGHTMAP CAPTURE */ RID LightStorage::lightmap_allocate() { - return RID(); + return lightmap_owner.allocate_rid(); } void LightStorage::lightmap_initialize(RID p_rid) { + lightmap_owner.initialize_rid(p_rid, Lightmap()); } void LightStorage::lightmap_free(RID p_rid) { + Lightmap *lightmap = lightmap_owner.get_or_null(p_rid); + lightmap->dependency.deleted_notify(p_rid); + lightmap_owner.free(p_rid); } void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { @@ -443,6 +447,9 @@ void LightStorage::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) void LightStorage::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { } +void LightStorage::lightmap_set_baked_exposure_normalization(RID p_lightmap, float p_exposure) { +} + PackedVector3Array LightStorage::lightmap_get_probe_capture_points(RID p_lightmap) const { return PackedVector3Array(); } diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h index 857a0261fa..8b708116ac 100644 --- a/drivers/gles3/storage/light_storage.h +++ b/drivers/gles3/storage/light_storage.h @@ -36,6 +36,7 @@ #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" +#include "drivers/gles3/storage/texture_storage.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/storage/light_storage.h" #include "servers/rendering/storage/utilities.h" @@ -92,6 +93,7 @@ struct ReflectionProbe { bool enable_shadows = false; uint32_t cull_mask = (1 << 20) - 1; float mesh_lod_threshold = 0.01; + float baked_exposure = 1.0; Dependency dependency; }; @@ -103,6 +105,7 @@ struct Lightmap { bool uses_spherical_harmonics = false; bool interior = false; AABB bounds = AABB(Vector3(), Vector3(1, 1, 1)); + float baked_exposure = 1.0; int32_t array_index = -1; //unassigned PackedVector3Array points; PackedColorArray point_sh; @@ -244,7 +247,7 @@ public: const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); - return light_owner.owns(light->projector); + return TextureStorage::get_singleton()->owns_texture(light->projector); } _FORCE_INLINE_ bool light_is_negative(RID p_light) const { @@ -261,13 +264,6 @@ public: return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS]; } - _FORCE_INLINE_ float light_get_shadow_volumetric_fog_fade(RID p_light) const { - const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, 0.0); - - return light->param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE]; - } - virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override; virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; } virtual uint64_t light_get_version(RID p_light) const override; @@ -304,6 +300,9 @@ public: /* LIGHTMAP CAPTURE */ + Lightmap *get_lightmap(RID p_rid) { return lightmap_owner.get_or_null(p_rid); }; + bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); }; + virtual RID lightmap_allocate() override; virtual void lightmap_initialize(RID p_rid) override; virtual void lightmap_free(RID p_rid) override; @@ -312,6 +311,7 @@ public: virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override; virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override; virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override; + virtual void lightmap_set_baked_exposure_normalization(RID p_lightmap, float p_exposure) override; virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override; virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override; virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override; diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index a64c7f7200..687e98ba58 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -978,7 +978,7 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (gv) { index = gv->buffer_index; } else { - WARN_PRINT("Shader uses global uniform '" + E.key + "', but it was removed at some point. Material will not display correctly."); + WARN_PRINT("Shader uses global parameter '" + E.key + "', but it was removed at some point. Material will not display correctly."); } uint32_t offset = p_uniform_offsets[E.value.order]; @@ -1095,7 +1095,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name); if (v) { if (v->buffer_index >= 0) { - WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); + WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); } else { HashMap<StringName, uint64_t>::Iterator E = used_global_textures.find(uniform_name); @@ -1110,7 +1110,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet } } else { - WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly."); + WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly."); } } else { HashMap<StringName, Variant>::ConstIterator V = p_parameters.find(uniform_name); @@ -1379,9 +1379,9 @@ MaterialStorage::MaterialStorage() { actions.renames["POINT_SIZE"] = "gl_PointSize"; actions.renames["MODEL_MATRIX"] = "model_matrix"; - actions.renames["CANVAS_MATRIX"] = "canvas_data.canvas_transform"; - actions.renames["SCREEN_MATRIX"] = "canvas_data.screen_transform"; - actions.renames["TIME"] = "canvas_data.time"; + actions.renames["CANVAS_MATRIX"] = "canvas_transform"; + actions.renames["SCREEN_MATRIX"] = "screen_transform"; + actions.renames["TIME"] = "time"; actions.renames["PI"] = _MKSTR(Math_PI); actions.renames["TAU"] = _MKSTR(Math_TAU); actions.renames["E"] = _MKSTR(Math_E); @@ -1399,7 +1399,7 @@ MaterialStorage::MaterialStorage() { actions.renames["SPECULAR_SHININESS"] = "specular_shininess"; actions.renames["SCREEN_UV"] = "screen_uv"; actions.renames["SCREEN_TEXTURE"] = "screen_texture"; - actions.renames["SCREEN_PIXEL_SIZE"] = "canvas_data.screen_pixel_size"; + actions.renames["SCREEN_PIXEL_SIZE"] = "screen_pixel_size"; actions.renames["FRAGCOORD"] = "gl_FragCoord"; actions.renames["POINT_COORD"] = "gl_PointCoord"; actions.renames["INSTANCE_ID"] = "gl_InstanceIndex"; @@ -1715,6 +1715,7 @@ ShaderCompiler::DefaultIdentifierActions actions; actions.usage_defines["HALF_RES_COLOR"] = "\n#define USES_HALF_RES_COLOR\n"; actions.usage_defines["QUARTER_RES_COLOR"] = "\n#define USES_QUARTER_RES_COLOR\n"; actions.render_mode_defines["disable_fog"] = "#define DISABLE_FOG\n"; + actions.render_mode_defines["use_debanding"] = "#define USE_DEBANDING\n"; actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; @@ -1762,7 +1763,7 @@ int32_t MaterialStorage::_global_shader_uniform_allocate(uint32_t p_elements) { return -1; } -void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value) { +void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderParameterType p_type, const Variant &p_value) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; @@ -2055,7 +2056,7 @@ void MaterialStorage::_global_shader_uniform_mark_buffer_dirty(int32_t p_index, } } -void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) { +void MaterialStorage::global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) { ERR_FAIL_COND(global_shader_uniforms.variables.has(p_name)); GlobalShaderUniforms::Variable gv; gv.type = p_type; @@ -2093,7 +2094,7 @@ void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::Gl global_shader_uniforms.variables[p_name] = gv; } -void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { +void MaterialStorage::global_shader_parameter_remove(const StringName &p_name) { if (!global_shader_uniforms.variables.has(p_name)) { return; } @@ -2109,7 +2110,7 @@ void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { global_shader_uniforms.variables.erase(p_name); } -Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { +Vector<StringName> MaterialStorage::global_shader_parameter_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -2122,7 +2123,7 @@ Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { return names; } -void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const Variant &p_value) { +void MaterialStorage::global_shader_parameter_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND(!global_shader_uniforms.variables.has(p_name)); GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.value = p_value; @@ -2143,7 +2144,7 @@ void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const } } -void MaterialStorage::global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) { +void MaterialStorage::global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) { if (!global_shader_uniforms.variables.has(p_name)) { return; //variable may not exist } @@ -2174,7 +2175,7 @@ void MaterialStorage::global_shader_uniform_set_override(const StringName &p_nam } } -Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) const { +Variant MaterialStorage::global_shader_parameter_get(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -2186,7 +2187,7 @@ Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) con return global_shader_uniforms.variables[p_name].value; } -RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_internal(const StringName &p_name) const { +RS::GlobalShaderParameterType MaterialStorage::global_shader_parameter_get_type_internal(const StringName &p_name) const { if (!global_shader_uniforms.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } @@ -2194,15 +2195,15 @@ RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_inte return global_shader_uniforms.variables[p_name].type; } -RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type(const StringName &p_name) const { +RS::GlobalShaderParameterType MaterialStorage::global_shader_parameter_get_type(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance."); } - return global_shader_uniform_get_type_internal(p_name); + return global_shader_parameter_get_type_internal(p_name); } -void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) { +void MaterialStorage::global_shader_parameters_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -2247,11 +2248,11 @@ void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) "samplerCube", }; - RS::GlobalShaderUniformType gvtype = RS::GLOBAL_VAR_TYPE_MAX; + RS::GlobalShaderParameterType gvtype = RS::GLOBAL_VAR_TYPE_MAX; for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { if (global_var_type_names[i] == type) { - gvtype = RS::GlobalShaderUniformType(i); + gvtype = RS::GlobalShaderParameterType(i); break; } } @@ -2275,23 +2276,23 @@ void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) if (global_shader_uniforms.variables.has(name)) { //has it, update it - global_shader_uniform_set(name, value); + global_shader_parameter_set(name, value); } else { - global_shader_uniform_add(name, gvtype, value); + global_shader_parameter_add(name, gvtype, value); } } } } -void MaterialStorage::global_shader_uniforms_clear() { +void MaterialStorage::global_shader_parameters_clear() { global_shader_uniforms.variables.clear(); } -GLuint MaterialStorage::global_shader_uniforms_get_uniform_buffer() const { +GLuint MaterialStorage::global_shader_parameters_get_uniform_buffer() const { return global_shader_uniforms.buffer; } -int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance) { +int32_t MaterialStorage::global_shader_parameters_instance_allocate(RID p_instance) { ERR_FAIL_COND_V(global_shader_uniforms.instance_buffer_pos.has(p_instance), -1); int32_t pos = _global_shader_uniform_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); global_shader_uniforms.instance_buffer_pos[p_instance] = pos; //save anyway @@ -2300,7 +2301,7 @@ int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance return pos; } -void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { +void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) { ERR_FAIL_COND(!global_shader_uniforms.instance_buffer_pos.has(p_instance)); int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos >= 0) { @@ -2309,7 +2310,7 @@ void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { global_shader_uniforms.instance_buffer_pos.erase(p_instance); } -void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) { +void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) { if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } @@ -2498,7 +2499,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { if (shader->data) { for (const KeyValue<StringName, HashMap<int, RID>> &E : shader->default_texture_parameter) { for (const KeyValue<int, RID> &E2 : E.value) { - shader->data->set_default_texture_param(E.key, E2.value, E2.key); + shader->data->set_default_texture_parameter(E.key, E2.value, E2.key); } } } @@ -2528,7 +2529,7 @@ String MaterialStorage::shader_get_code(RID p_shader) const { return shader->code; } -void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const { +void MaterialStorage::get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const { GLES3::Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); if (shader->data) { @@ -2536,7 +2537,7 @@ void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<Property } } -void MaterialStorage::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) { +void MaterialStorage::shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) { GLES3::Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); @@ -2555,7 +2556,7 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin } } if (shader->data) { - shader->data->set_default_texture_param(p_name, p_texture, p_index); + shader->data->set_default_texture_parameter(p_name, p_texture, p_index); } for (Material *E : shader->owners) { Material *material = E; @@ -2563,7 +2564,7 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin } } -RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const { +RID MaterialStorage::shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const { const GLES3::Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, RID()); if (shader->default_texture_parameter.has(p_name) && shader->default_texture_parameter[p_name].has(p_index)) { @@ -2573,7 +2574,7 @@ RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const String return RID(); } -Variant MaterialStorage::shader_get_param_default(RID p_shader, const StringName &p_param) const { +Variant MaterialStorage::shader_get_parameter_default(RID p_shader, const StringName &p_param) const { Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, Variant()); if (shader->data) { @@ -2693,7 +2694,7 @@ void MaterialStorage::material_set_param(RID p_material, const StringName &p_par } if (material->shader && material->shader->data) { //shader is valid - bool is_texture = material->shader->data->is_param_texture(p_param); + bool is_texture = material->shader->data->is_parameter_texture(p_param); _material_queue_update(material, !is_texture, is_texture); } else { _material_queue_update(material, true, true); @@ -2764,14 +2765,14 @@ bool MaterialStorage::material_casts_shadows(RID p_material) { return true; //by default everything casts shadows } -void MaterialStorage::material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) { +void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { GLES3::Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); if (material->shader && material->shader->data) { material->shader->data->get_instance_param_list(r_parameters); if (material->next_pass.is_valid()) { - material_get_instance_shader_uniforms(material->next_pass, r_parameters); + material_get_instance_shader_parameters(material->next_pass, r_parameters); } } } @@ -2867,7 +2868,7 @@ void CanvasShaderData::set_code(const String &p_code) { valid = true; } -void CanvasShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void CanvasShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -2938,7 +2939,7 @@ void CanvasShaderData::get_instance_param_list(List<RendererMaterialStorage::Ins } } -bool CanvasShaderData::is_param_texture(const StringName &p_param) const { +bool CanvasShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -3111,7 +3112,7 @@ void SkyShaderData::set_code(const String &p_code) { valid = true; } -void SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void SkyShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -3180,7 +3181,7 @@ void SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::Instan } } -bool SkyShaderData::is_param_texture(const StringName &p_param) const { +bool SkyShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -3435,7 +3436,7 @@ void SceneShaderData::set_code(const String &p_code) { valid = true; } -void SceneShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void SceneShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -3507,7 +3508,7 @@ void SceneShaderData::get_instance_param_list(List<RendererMaterialStorage::Inst } } -bool SceneShaderData::is_param_texture(const StringName &p_param) const { +bool SceneShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index a2a7554821..65c46631ed 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -53,11 +53,11 @@ namespace GLES3 { struct ShaderData { virtual void set_code(const String &p_Code) = 0; - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) = 0; + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) = 0; virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const = 0; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0; - virtual bool is_param_texture(const StringName &p_param) const = 0; + virtual bool is_parameter_texture(const StringName &p_param) const = 0; virtual bool is_animated() const = 0; virtual bool casts_shadows() const = 0; virtual Variant get_default_parameter(const StringName &p_parameter) const = 0; @@ -165,11 +165,11 @@ struct CanvasShaderData : public ShaderData { bool uses_time = false; virtual void set_code(const String &p_Code); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; @@ -216,10 +216,10 @@ struct SkyShaderData : public ShaderData { bool uses_light; virtual void set_code(const String &p_Code); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; @@ -337,11 +337,11 @@ struct SceneShaderData : public ShaderData { uint32_t index = 0; virtual void set_code(const String &p_Code); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; @@ -376,7 +376,7 @@ struct GlobalShaderUniforms { struct Variable { HashSet<RID> texture_materials; // materials using this - RS::GlobalShaderUniformType type; + RS::GlobalShaderParameterType type; Variant value; Variant override; int32_t buffer_index; //for vectors @@ -437,7 +437,7 @@ private: GlobalShaderUniforms global_shader_uniforms; int32_t _global_shader_uniform_allocate(uint32_t p_elements); - void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value); + void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderParameterType p_type, const Variant &p_value); void _global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements); /* SHADER API */ @@ -515,24 +515,24 @@ public: void _update_global_shader_uniforms(); - virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override; - virtual void global_shader_uniform_remove(const StringName &p_name) override; - virtual Vector<StringName> global_shader_uniform_get_list() const override; + virtual void global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) override; + virtual void global_shader_parameter_remove(const StringName &p_name) override; + virtual Vector<StringName> global_shader_parameter_get_list() const override; - virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override; - virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override; - virtual Variant global_shader_uniform_get(const StringName &p_name) const override; - virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override; - RS::GlobalShaderUniformType global_shader_uniform_get_type_internal(const StringName &p_name) const; + virtual void global_shader_parameter_set(const StringName &p_name, const Variant &p_value) override; + virtual void global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) override; + virtual Variant global_shader_parameter_get(const StringName &p_name) const override; + virtual RS::GlobalShaderParameterType global_shader_parameter_get_type(const StringName &p_name) const override; + RS::GlobalShaderParameterType global_shader_parameter_get_type_internal(const StringName &p_name) const; - virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override; - virtual void global_shader_uniforms_clear() override; + virtual void global_shader_parameters_load_settings(bool p_load_textures = true) override; + virtual void global_shader_parameters_clear() override; - virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override; - virtual void global_shader_uniforms_instance_free(RID p_instance) override; - virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override; + virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override; + virtual void global_shader_parameters_instance_free(RID p_instance) override; + virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override; - GLuint global_shader_uniforms_get_uniform_buffer() const; + GLuint global_shader_parameters_get_uniform_buffer() const; /* SHADER API */ @@ -548,11 +548,11 @@ public: virtual void shader_set_code(RID p_shader, const String &p_code) override; virtual void shader_set_path_hint(RID p_shader, const String &p_path) override; virtual String shader_get_code(RID p_shader) const override; - virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; + virtual void get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; - virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; - virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override; - virtual Variant shader_get_param_default(RID p_shader, const StringName &p_param) const override; + virtual void shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; + virtual RID shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const override; + virtual Variant shader_get_parameter_default(RID p_shader, const StringName &p_name) const override; virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override; @@ -579,7 +579,7 @@ public: virtual bool material_is_animated(RID p_material) override; virtual bool material_casts_shadows(RID p_material) override; - virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) override; + virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override; virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override; diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index ddf94af5b8..22d84eba93 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -260,7 +260,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) } for (int i = 0; i < p_surface.bone_aabbs.size(); i++) { const AABB &bone = p_surface.bone_aabbs[i]; - if (!bone.has_no_volume()) { + if (bone.has_volume()) { mesh->bone_aabbs.write[i].merge_with(bone); } } @@ -352,6 +352,10 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const { sd.attribute_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.attribute_buffer, s.attribute_buffer_size); } + if (s.skin_buffer != 0) { + sd.skin_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.skin_buffer, s.skin_buffer_size); + } + sd.vertex_count = s.vertex_count; sd.index_count = s.index_count; sd.primitive = s.primitive; @@ -550,6 +554,21 @@ void MeshStorage::mesh_clear(RID p_mesh) { glDeleteBuffers(1, &s.index_buffer); s.index_buffer = 0; } + + if (s.versions) { + memfree(s.versions); //reallocs, so free with memfree. + } + + if (s.lod_count) { + for (uint32_t j = 0; j < s.lod_count; j++) { + if (s.lods[j].index_buffer != 0) { + glDeleteBuffers(1, &s.lods[j].index_buffer); + s.lods[j].index_buffer = 0; + } + } + memdelete_arr(s.lods); + } + memdelete(mesh->surfaces[i]); } if (mesh->surfaces) { diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.cpp b/drivers/gles3/storage/render_scene_buffers_gles3.cpp new file mode 100644 index 0000000000..9123984dc7 --- /dev/null +++ b/drivers/gles3/storage/render_scene_buffers_gles3.cpp @@ -0,0 +1,103 @@ +/*************************************************************************/ +/* render_scene_buffers_gles3.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef GLES3_ENABLED + +#include "render_scene_buffers_gles3.h" +#include "texture_storage.h" + +RenderSceneBuffersGLES3::~RenderSceneBuffersGLES3() { + free_render_buffer_data(); +} + +void RenderSceneBuffersGLES3::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + + //internal_size.x = p_internal_size.x; // ignore for now + //internal_size.y = p_internal_size.y; + width = p_target_size.x; + height = p_target_size.y; + //fsr_sharpness = p_fsr_sharpness; + //texture_mipmap_bias = p_texture_mipmap_bias; + render_target = p_render_target; + //msaa = p_msaa; + //screen_space_aa = p_screen_space_aa; + //use_debanding = p_use_debanding; + //view_count = p_view_count; + + free_render_buffer_data(); + + GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target); + + is_transparent = rt->is_transparent; + + // framebuffer + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + + glBindTexture(GL_TEXTURE_2D, rt->color); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); + + glGenTextures(1, &depth_texture); + glBindTexture(GL_TEXTURE_2D, depth_texture); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + glBindTexture(GL_TEXTURE_2D, 0); + glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->system_fbo); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + free_render_buffer_data(); + WARN_PRINT("Could not create 3D renderbuffer, status: " + texture_storage->get_framebuffer_error(status)); + return; + } +} + +void RenderSceneBuffersGLES3::free_render_buffer_data() { + if (depth_texture) { + glDeleteTextures(1, &depth_texture); + depth_texture = 0; + } + if (framebuffer) { + glDeleteFramebuffers(1, &framebuffer); + framebuffer = 0; + } +} + +#endif // GLES3_ENABLED diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.h b/drivers/gles3/storage/render_scene_buffers_gles3.h new file mode 100644 index 0000000000..ad0d2032b0 --- /dev/null +++ b/drivers/gles3/storage/render_scene_buffers_gles3.h @@ -0,0 +1,98 @@ +/*************************************************************************/ +/* render_scene_buffers_gles3.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RENDER_SCENE_BUFFERS_GLES3_H +#define RENDER_SCENE_BUFFERS_GLES3_H + +#ifdef GLES3_ENABLED + +#include "servers/rendering/storage/render_scene_buffers.h" + +#include "platform_config.h" +#ifndef OPENGL_INCLUDE_H +#include <GLES3/gl3.h> +#else +#include OPENGL_INCLUDE_H +#endif + +class RenderSceneBuffersGLES3 : public RenderSceneBuffers { + GDCLASS(RenderSceneBuffersGLES3, RenderSceneBuffers); + +public: + // Original implementation, need to investigate which ones we'll keep like this and what we'll change... + + int internal_width = 0; + int internal_height = 0; + int width = 0; + int height = 0; + //float fsr_sharpness = 0.2f; + RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; + //RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED; + //bool use_debanding = false; + //uint32_t view_count = 1; + + bool is_transparent = false; + + RID render_target; + GLuint internal_texture = 0; // Used for rendering when post effects are enabled + GLuint depth_texture = 0; // Main depth texture + GLuint framebuffer = 0; // Main framebuffer, contains internal_texture and depth_texture or render_target->color and depth_texture + + //built-in textures used for ping pong image processing and blurring + struct Blur { + RID texture; + + struct Mipmap { + RID texture; + int width; + int height; + GLuint fbo; + }; + + Vector<Mipmap> mipmaps; + }; + + Blur blur[2]; //the second one starts from the first mipmap + +private: +public: + virtual ~RenderSceneBuffersGLES3(); + virtual void configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; + + virtual void set_fsr_sharpness(float p_fsr_sharpness) override{}; + virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override{}; + virtual void set_use_debanding(bool p_use_debanding) override{}; + + void free_render_buffer_data(); +}; + +#endif // GLES3_ENABLED + +#endif // RENDER_SCENE_BUFFERS_GLES3_H diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index 543638e8ff..a801b3285a 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -1199,7 +1199,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { rt->color_internal_format = rt->is_transparent ? GL_RGBA8 : GL_RGB10_A2; rt->color_format = GL_RGBA; - rt->color_type = rt->is_transparent ? GL_BYTE : GL_UNSIGNED_INT_2_10_10_10_REV; + rt->color_type = rt->is_transparent ? GL_UNSIGNED_BYTE : GL_UNSIGNED_INT_2_10_10_10_REV; rt->image_format = Image::FORMAT_RGBA8; glDisable(GL_SCISSOR_TEST); @@ -1564,6 +1564,19 @@ void TextureStorage::render_target_clear_used(RID p_render_target) { rt->used_in_frame = false; } +void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + if (p_msaa == rt->msaa) { + return; + } + + WARN_PRINT("2D MSAA is not yet supported for GLES3."); + _clear_render_target(rt); + rt->msaa = p_msaa; + _update_render_target(rt); +} + void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 71f713bc9f..4f4032723b 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -528,6 +528,7 @@ public: virtual void render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) override; virtual bool render_target_was_used(RID p_render_target) override; void render_target_clear_used(RID p_render_target); + virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) override; // new void render_target_set_as_unused(RID p_render_target) override { diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp index 654104722b..16bacf1829 100644 --- a/drivers/gles3/storage/utilities.cpp +++ b/drivers/gles3/storage/utilities.cpp @@ -82,6 +82,8 @@ RS::InstanceType Utilities::get_base_type(RID p_rid) const { return RS::INSTANCE_MULTIMESH; } else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) { return RS::INSTANCE_LIGHT; + } else if (GLES3::LightStorage::get_singleton()->owns_lightmap(p_rid)) { + return RS::INSTANCE_LIGHTMAP; } return RS::INSTANCE_NONE; } @@ -114,6 +116,9 @@ bool Utilities::free(RID p_rid) { } else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) { GLES3::LightStorage::get_singleton()->light_free(p_rid); return true; + } else if (GLES3::LightStorage::get_singleton()->owns_lightmap(p_rid)) { + GLES3::LightStorage::get_singleton()->lightmap_free(p_rid); + return true; } else { return false; } diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp index 8d2f8a7ed6..165de34c71 100644 --- a/drivers/png/image_loader_png.cpp +++ b/drivers/png/image_loader_png.cpp @@ -36,7 +36,7 @@ #include <string.h> -Error ImageLoaderPNG::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) { +Error ImageLoaderPNG::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) { const uint64_t buffer_size = f->get_length(); Vector<uint8_t> file_buffer; Error err = file_buffer.resize(buffer_size); diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h index 91c3c8925f..a247d77310 100644 --- a/drivers/png/image_loader_png.h +++ b/drivers/png/image_loader_png.h @@ -40,7 +40,7 @@ private: static Ref<Image> load_mem_png(const uint8_t *p_png, int p_size); public: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderPNG(); }; diff --git a/drivers/register_driver_types.cpp b/drivers/register_driver_types.cpp index 504ef9843a..53a7f7aa4f 100644 --- a/drivers/register_driver_types.cpp +++ b/drivers/register_driver_types.cpp @@ -34,11 +34,11 @@ #include "drivers/png/image_loader_png.h" #include "drivers/png/resource_saver_png.h" -static ImageLoaderPNG *image_loader_png; +static Ref<ImageLoaderPNG> image_loader_png; static Ref<ResourceSaverPNG> resource_saver_png; void register_core_driver_types() { - image_loader_png = memnew(ImageLoaderPNG); + image_loader_png.instantiate(); ImageLoader::add_image_format_loader(image_loader_png); resource_saver_png.instantiate(); @@ -46,9 +46,8 @@ void register_core_driver_types() { } void unregister_core_driver_types() { - if (image_loader_png) { - memdelete(image_loader_png); - } + ImageLoader::remove_image_format_loader(image_loader_png); + image_loader_png.unref(); ResourceSaver::remove_resource_format_saver(resource_saver_png); resource_saver_png.unref(); diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 388ad479b9..300fbcdcfd 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -70,7 +70,7 @@ void FileAccessUnix::check_errors() const { } } -Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { +Error FileAccessUnix::open_internal(const String &p_path, int p_mode_flags) { _close(); path_src = p_path; diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 297c34e454..e1311a80f8 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -54,7 +54,7 @@ class FileAccessUnix : public FileAccess { public: static CloseNotificationFunc close_notification_func; - virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file + virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file virtual bool is_open() const override; ///< true when file is open virtual String get_path() const override; /// returns the path for the current open file diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 384f46c8df..c8a42e925e 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -51,7 +51,6 @@ #include <sys/sysctl.h> #endif -#include <assert.h> #include <dlfcn.h> #include <errno.h> #include <poll.h> @@ -104,10 +103,6 @@ static void _setup_clock() { } #endif -void OS_Unix::debug_break() { - assert(false); -} - static void handle_interrupt(int sig) { if (!EngineDebugger::is_active()) { return; @@ -194,13 +189,21 @@ String OS_Unix::get_name() const { return "Unix"; } +String OS_Unix::get_distribution_name() const { + return ""; +} + +String OS_Unix::get_version() const { + return ""; +} + double OS_Unix::get_unix_time() const { struct timeval tv_now; gettimeofday(&tv_now, nullptr); return (double)tv_now.tv_sec + double(tv_now.tv_usec) / 1000000; } -OS::Date OS_Unix::get_date(bool p_utc) const { +OS::DateTime OS_Unix::get_datetime(bool p_utc) const { time_t t = time(nullptr); struct tm lt; if (p_utc) { @@ -208,7 +211,7 @@ OS::Date OS_Unix::get_date(bool p_utc) const { } else { localtime_r(&t, <); } - Date ret; + DateTime ret; ret.year = 1900 + lt.tm_year; // Index starting at 1 to match OS_Unix::get_date // and Windows SYSTEMTIME and tm_mon follows the typical structure @@ -216,24 +219,11 @@ OS::Date OS_Unix::get_date(bool p_utc) const { ret.month = (Month)(lt.tm_mon + 1); ret.day = lt.tm_mday; ret.weekday = (Weekday)lt.tm_wday; - ret.dst = lt.tm_isdst; - - return ret; -} - -OS::Time OS_Unix::get_time(bool p_utc) const { - time_t t = time(nullptr); - struct tm lt; - if (p_utc) { - gmtime_r(&t, <); - } else { - localtime_r(&t, <); - } - Time ret; ret.hour = lt.tm_hour; ret.minute = lt.tm_min; ret.second = lt.tm_sec; - get_time_zone_info(); + ret.dst = lt.tm_isdst; + return ret; } diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index f4609a565b..b35f161524 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -62,9 +62,10 @@ public: virtual Error set_cwd(const String &p_cwd) override; virtual String get_name() const override; + virtual String get_distribution_name() const override; + virtual String get_version() const override; - virtual Date get_date(bool p_utc) const override; - virtual Time get_time(bool p_utc) const override; + virtual DateTime get_datetime(bool p_utc) const override; virtual TimeZoneInfo get_time_zone_info() const override; virtual double get_unix_time() const override; @@ -85,7 +86,6 @@ public: virtual int get_processor_count() const override; - virtual void debug_break() override; virtual void initialize_debugging() override; virtual String get_executable_path() const override; diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index f2d78636d7..53e9146f85 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1733,7 +1733,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T ERR_FAIL_INDEX_V(p_format.samples, TEXTURE_SAMPLES_MAX, RID()); - image_create_info.samples = rasterization_sample_count[p_format.samples]; + image_create_info.samples = _ensure_supported_sample_count(p_format.samples); image_create_info.tiling = (p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; // Usage. @@ -1884,6 +1884,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T texture.mipmaps = image_create_info.mipLevels; texture.base_mipmap = 0; texture.base_layer = 0; + texture.is_resolve_buffer = p_format.is_resolve_buffer; texture.usage_flags = p_format.usage_bits; texture.samples = p_format.samples; texture.allowed_shared_formats = p_format.shareable_formats; @@ -3425,7 +3426,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF description.pNext = nullptr; description.flags = 0; description.format = vulkan_formats[p_attachments[i].format]; - description.samples = rasterization_sample_count[p_attachments[i].samples]; + description.samples = _ensure_supported_sample_count(p_attachments[i].samples); bool is_sampled = p_attachments[i].usage_flags & TEXTURE_USAGE_SAMPLING_BIT; bool is_storage = p_attachments[i].usage_flags & TEXTURE_USAGE_STORAGE_BIT; @@ -3546,7 +3547,8 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF break; } } - } else { + } + if (!used_last) { for (int j = 0; j < p_passes[last_pass].color_attachments.size(); j++) { if (p_passes[last_pass].color_attachments[j] == i) { used_last = true; @@ -4116,7 +4118,11 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac } else if (texture && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) { pass.vrs_attachment = i; } else { - pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED); + if (texture && texture->is_resolve_buffer) { + pass.resolve_attachments.push_back(i); + } else { + pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED); + } } } @@ -6567,7 +6573,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma multisample_state_create_info.pNext = nullptr; multisample_state_create_info.flags = 0; - multisample_state_create_info.rasterizationSamples = rasterization_sample_count[p_multisample_state.sample_count]; + multisample_state_create_info.rasterizationSamples = _ensure_supported_sample_count(p_multisample_state.sample_count); multisample_state_create_info.sampleShadingEnable = p_multisample_state.enable_sample_shading; multisample_state_create_info.minSampleShading = p_multisample_state.min_sample_shading; Vector<VkSampleMask> sample_mask; @@ -7353,7 +7359,9 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu // If it is the first we're likely populating our VRS texture. // Bit dirty but... if (!texture || (!(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(i != 0 && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT))) { - color_count++; + if (!texture || !texture->is_resolve_buffer) { + color_count++; + } } } ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID, "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ")."); @@ -8993,6 +9001,25 @@ void RenderingDeviceVulkan::_begin_frame() { frames[frame].index = Engine::get_singleton()->get_frames_drawn(); } +VkSampleCountFlagBits RenderingDeviceVulkan::_ensure_supported_sample_count(TextureSamples p_requested_sample_count) const { + VkSampleCountFlags sample_count_flags = limits.framebufferColorSampleCounts & limits.framebufferDepthSampleCounts; + + if (sample_count_flags & rasterization_sample_count[p_requested_sample_count]) { + // The requested sample count is supported. + return rasterization_sample_count[p_requested_sample_count]; + } else { + // Find the closest lower supported sample count. + VkSampleCountFlagBits sample_count = rasterization_sample_count[p_requested_sample_count]; + while (sample_count > VK_SAMPLE_COUNT_1_BIT) { + if (sample_count_flags & sample_count) { + return sample_count; + } + sample_count = (VkSampleCountFlagBits)(sample_count >> 1); + } + } + return VK_SAMPLE_COUNT_1_BIT; +} + void RenderingDeviceVulkan::swap_buffers() { ERR_FAIL_COND_MSG(local_device.is_valid(), "Local devices can't swap buffers."); _THREAD_SAFE_METHOD_ @@ -9340,10 +9367,10 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de // NOTE: If adding new project settings here, also duplicate their definition in // rendering_server.cpp for headless doctool. - staging_buffer_block_size = GLOBAL_DEF("rendering/vulkan/staging_buffer/block_size_kb", 256); + staging_buffer_block_size = GLOBAL_DEF("rendering/rendering_device/staging_buffer/block_size_kb", 256); staging_buffer_block_size = MAX(4u, staging_buffer_block_size); staging_buffer_block_size *= 1024; // Kb -> bytes. - staging_buffer_max_size = GLOBAL_DEF("rendering/vulkan/staging_buffer/max_size_mb", 128); + staging_buffer_max_size = GLOBAL_DEF("rendering/rendering_device/staging_buffer/max_size_mb", 128); staging_buffer_max_size = MAX(1u, staging_buffer_max_size); staging_buffer_max_size *= 1024 * 1024; @@ -9351,7 +9378,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de // Validate enough blocks. staging_buffer_max_size = staging_buffer_block_size * 4; } - texture_upload_region_size_px = GLOBAL_DEF("rendering/vulkan/staging_buffer/texture_upload_region_size_px", 64); + texture_upload_region_size_px = GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64); texture_upload_region_size_px = nearest_power_of_2_templated(texture_upload_region_size_px); frames_drawn = frame_count; // Start from frame count, so everything else is immediately old. @@ -9366,7 +9393,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de ERR_CONTINUE(err != OK); } - max_descriptors_per_pool = GLOBAL_DEF("rendering/vulkan/descriptor_pools/max_descriptors_per_pool", 64); + max_descriptors_per_pool = GLOBAL_DEF("rendering/rendering_device/descriptor_pools/max_descriptors_per_pool", 64); // Check to make sure DescriptorPoolKey is good. static_assert(sizeof(uint64_t) * 3 >= UNIFORM_TYPE_MAX * sizeof(uint16_t)); diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 6007e1ab4d..abec1b0e1b 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -150,6 +150,8 @@ class RenderingDeviceVulkan : public RenderingDevice { bool used_in_raster = false; bool used_in_compute = false; + bool is_resolve_buffer = false; + uint32_t read_aspect_mask = 0; uint32_t barrier_aspect_mask = 0; bool bound = false; // Bound to framebffer. @@ -1042,6 +1044,8 @@ class RenderingDeviceVulkan : public RenderingDevice { HashMap<RID, String> resource_names; #endif + VkSampleCountFlagBits _ensure_supported_sample_count(TextureSamples p_requested_sample_count) const; + public: virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>()); virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture); diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index b52179b4f3..99ef57abae 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -1706,10 +1706,10 @@ Error VulkanContext::_update_swap_chain(Window *window) { // Find a supported composite alpha mode - one of these is guaranteed to be set. VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = { - VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR, VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR, + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, }; for (uint32_t i = 0; i < ARRAY_SIZE(compositeAlphaFlags); i++) { if (surfCapabilities.supportedCompositeAlpha & compositeAlphaFlags[i]) { diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 1a66d19373..095d936c78 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -58,7 +58,7 @@ void FileAccessWindows::check_errors() const { } } -Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) { +Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) { _close(); path_src = p_path; diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h index 8629bb936b..d84c400775 100644 --- a/drivers/windows/file_access_windows.h +++ b/drivers/windows/file_access_windows.h @@ -51,7 +51,7 @@ class FileAccessWindows : public FileAccess { void _close(); public: - virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file + virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file virtual bool is_open() const override; ///< true when file is open virtual String get_path() const override; /// returns the path for the current open file |