diff options
Diffstat (limited to 'servers/rendering/renderer_rd')
11 files changed, 160 insertions, 94 deletions
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index 967b725b9e..e7abcf5674 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -267,7 +267,7 @@ RendererCompositorRD::RendererCompositorRD() { if (err != OK) { ERR_PRINT("Can't create shader cache folder, no shader caching will happen: " + shader_cache_dir); } else { - shader_cache_dir = shader_cache_dir.plus_file("shader_cache"); + shader_cache_dir = shader_cache_dir.path_join("shader_cache"); bool shader_cache_enabled = GLOBAL_GET("rendering/shader_compiler/shader_cache/enabled"); if (!Engine::get_singleton()->is_editor_hint() && !shader_cache_enabled) { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 7adc36c57c..fa83428367 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -2484,7 +2484,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p rb->height = p_height; rb->fsr_sharpness = p_fsr_sharpness; rb->render_target = p_render_target; - rb->msaa = p_msaa; + rb->msaa_3d = p_msaa; rb->screen_space_aa = p_screen_space_aa; rb->use_taa = p_use_taa; rb->use_debanding = p_use_debanding; @@ -2509,7 +2509,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p tf.height = rb->internal_height; // If set to rb->width, msaa won't crash tf.array_layers = rb->view_count; // create a layer for every view tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | (_render_buffers_can_be_storage() ? RD::TEXTURE_USAGE_STORAGE_BIT : 0) | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; - if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { + if (rb->msaa_3d != RS::VIEWPORT_MSAA_DISABLED) { tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; } tf.usage_bits |= RD::TEXTURE_USAGE_INPUT_ATTACHMENT_BIT; // only needed when using subpasses in the mobile renderer @@ -2532,7 +2532,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p if (rb->view_count > 1) { tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; } - if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) { + if (rb->msaa_3d == RS::VIEWPORT_MSAA_DISABLED) { tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, (RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT)) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT; } else { tf.format = RD::DATA_FORMAT_R32_SFLOAT; @@ -2543,7 +2543,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT; tf.array_layers = rb->view_count; // create a layer for every view - if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { + if (rb->msaa_3d != RS::VIEWPORT_MSAA_DISABLED) { tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; } else { tf.usage_bits |= RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; @@ -2871,6 +2871,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.color[2] = linear_col.b; light_data.specular = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR); + light_data.volumetric_fog_energy = light_storage->light_get_param(base, RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY); light_data.mask = light_storage->light_get_cull_mask(base); float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); @@ -2952,7 +2953,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const float fade_start = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START); light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep light_data.fade_to = -light_data.shadow_split_offsets[3]; - light_data.shadow_volumetric_fog_fade = 1.0 / light_storage->light_get_shadow_volumetric_fog_fade(base); light_data.soft_shadow_scale = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); light_data.softshadow_angle = angular_diameter; @@ -3082,6 +3082,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.color[1] = linear_col.g * energy; light_data.color[2] = linear_col.b * energy; light_data.specular_amount = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0; + light_data.volumetric_fog_energy = light_storage->light_get_param(base, RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY); light_data.bake_mode = light_storage->light_get_bake_mode(base); float radius = MAX(0.001, light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE)); @@ -3176,7 +3177,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.atlas_rect[3] = rect.size.height; light_data.soft_shadow_scale = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); - light_data.shadow_volumetric_fog_fade = 1.0 / light_storage->light_get_shadow_volumetric_fog_fade(base); if (type == RS::LIGHT_OMNI) { Transform3D proj = (inverse_transform * light_transform).inverse(); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 22e9ead243..3867fd8605 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -456,7 +456,7 @@ private: int width = 0; int height = 0; float fsr_sharpness = 0.2f; - RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; + RS::ViewportMSAA msaa_3d = RS::VIEWPORT_MSAA_DISABLED; RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED; bool use_taa = false; bool use_debanding = false; @@ -618,7 +618,7 @@ private: float soft_shadow_size; float soft_shadow_scale; uint32_t mask; - float shadow_volumetric_fog_fade; + float volumetric_fog_energy; uint32_t bake_mode; float projector_rect[4]; }; @@ -638,7 +638,7 @@ private: float fade_to; uint32_t pad[2]; uint32_t bake_mode; - float shadow_volumetric_fog_fade; + float volumetric_fog_energy; float shadow_bias[4]; float shadow_normal_bias[4]; float shadow_transmittance_bias[4]; @@ -1167,23 +1167,51 @@ public: virtual void decals_set_filter(RS::DecalFilter p_filter) override; virtual void light_projectors_set_filter(RS::LightProjectorFilter p_filter) override; - _FORCE_INLINE_ RS::ShadowQuality shadows_quality_get() const { return shadows_quality; } - _FORCE_INLINE_ RS::ShadowQuality directional_shadow_quality_get() const { return directional_shadow_quality; } - _FORCE_INLINE_ float shadows_quality_radius_get() const { return shadows_quality_radius; } - _FORCE_INLINE_ float directional_shadow_quality_radius_get() const { return directional_shadow_quality_radius; } + _FORCE_INLINE_ RS::ShadowQuality shadows_quality_get() const { + return shadows_quality; + } + _FORCE_INLINE_ RS::ShadowQuality directional_shadow_quality_get() const { + return directional_shadow_quality; + } + _FORCE_INLINE_ float shadows_quality_radius_get() const { + return shadows_quality_radius; + } + _FORCE_INLINE_ float directional_shadow_quality_radius_get() const { + return directional_shadow_quality_radius; + } - _FORCE_INLINE_ float *directional_penumbra_shadow_kernel_get() { return directional_penumbra_shadow_kernel; } - _FORCE_INLINE_ float *directional_soft_shadow_kernel_get() { return directional_soft_shadow_kernel; } - _FORCE_INLINE_ float *penumbra_shadow_kernel_get() { return penumbra_shadow_kernel; } - _FORCE_INLINE_ float *soft_shadow_kernel_get() { return soft_shadow_kernel; } + _FORCE_INLINE_ float *directional_penumbra_shadow_kernel_get() { + return directional_penumbra_shadow_kernel; + } + _FORCE_INLINE_ float *directional_soft_shadow_kernel_get() { + return directional_soft_shadow_kernel; + } + _FORCE_INLINE_ float *penumbra_shadow_kernel_get() { + return penumbra_shadow_kernel; + } + _FORCE_INLINE_ float *soft_shadow_kernel_get() { + return soft_shadow_kernel; + } - _FORCE_INLINE_ int directional_penumbra_shadow_samples_get() const { return directional_penumbra_shadow_samples; } - _FORCE_INLINE_ int directional_soft_shadow_samples_get() const { return directional_soft_shadow_samples; } - _FORCE_INLINE_ int penumbra_shadow_samples_get() const { return penumbra_shadow_samples; } - _FORCE_INLINE_ int soft_shadow_samples_get() const { return soft_shadow_samples; } + _FORCE_INLINE_ int directional_penumbra_shadow_samples_get() const { + return directional_penumbra_shadow_samples; + } + _FORCE_INLINE_ int directional_soft_shadow_samples_get() const { + return directional_soft_shadow_samples; + } + _FORCE_INLINE_ int penumbra_shadow_samples_get() const { + return penumbra_shadow_samples; + } + _FORCE_INLINE_ int soft_shadow_samples_get() const { + return soft_shadow_samples; + } - _FORCE_INLINE_ RS::LightProjectorFilter light_projectors_get_filter() const { return light_projectors_filter; } - _FORCE_INLINE_ RS::DecalFilter decals_get_filter() const { return decals_filter; } + _FORCE_INLINE_ RS::LightProjectorFilter light_projectors_get_filter() const { + return light_projectors_filter; + } + _FORCE_INLINE_ RS::DecalFilter decals_get_filter() const { + return decals_filter; + } int get_roughness_layers() const; bool is_using_radiance_cubemap_array() const; diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index c9b6d09d4c..0f2dea6fe9 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -380,7 +380,7 @@ static const uint32_t cache_file_version = 2; bool ShaderRD::_load_from_cache(Version *p_version) { String sha1 = _version_get_sha1(p_version); - String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; + String path = shader_cache_dir.path_join(name).path_join(base_sha256).path_join(sha1) + ".cache"; Ref<FileAccess> f = FileAccess::open(path, FileAccess::READ); if (f.is_null()) { @@ -443,7 +443,7 @@ bool ShaderRD::_load_from_cache(Version *p_version) { void ShaderRD::_save_to_cache(Version *p_version) { String sha1 = _version_get_sha1(p_version); - String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; + String path = shader_cache_dir.path_join(name).path_join(base_sha256).path_join(sha1) + ".cache"; Ref<FileAccess> f = FileAccess::open(path, FileAccess::WRITE); ERR_FAIL_COND(f.is_null()); diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index 6f79b9e771..07d5223472 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -270,6 +270,9 @@ const vec3 halton_map[TEMPORAL_FRAMES] = vec3[]( vec3(0.9375, 0.25925926, 0.12), vec3(0.03125, 0.59259259, 0.32)); +// Higher values will make light in volumetric fog fade out sooner when it's occluded by shadow. +const float INV_FOG_FADE = 10.0; + void main() { vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size); @@ -375,46 +378,48 @@ void main() { if (total_density > 0.001) { for (uint i = 0; i < params.directional_light_count; i++) { - vec3 shadow_attenuation = vec3(1.0); - - if (directional_lights.data[i].shadow_opacity > 0.001) { - float depth_z = -view_pos.z; - - vec4 pssm_coord; - vec3 light_dir = directional_lights.data[i].direction; - vec4 v = vec4(view_pos, 1.0); - float z_range; - - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.x; - - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.y; - - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.z; - - } else { - pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.w; - } + if (directional_lights.data[i].volumetric_fog_energy > 0.001) { + vec3 shadow_attenuation = vec3(1.0); + + if (directional_lights.data[i].shadow_opacity > 0.001) { + float depth_z = -view_pos.z; + + vec4 pssm_coord; + vec3 light_dir = directional_lights.data[i].direction; + vec4 v = vec4(view_pos, 1.0); + float z_range; + + if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.x; + + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.y; + + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.z; + + } else { + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.w; + } - float depth = texture(sampler2D(directional_shadow_atlas, linear_sampler), pssm_coord.xy).r; - float shadow = exp(min(0.0, (depth - pssm_coord.z)) * z_range * directional_lights.data[i].shadow_volumetric_fog_fade); + float depth = texture(sampler2D(directional_shadow_atlas, linear_sampler), pssm_coord.xy).r; + float shadow = exp(min(0.0, (depth - pssm_coord.z)) * z_range * INV_FOG_FADE); - shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance + shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance - shadow_attenuation = mix(vec3(0.0), vec3(1.0), shadow); - } + shadow_attenuation = mix(vec3(1.0 - directional_lights.data[i].shadow_opacity), vec3(1.0), shadow); + } - total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g); + total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g) * directional_lights.data[i].volumetric_fog_energy; + } } // Compute light from sky @@ -481,7 +486,7 @@ void main() { float d = distance(omni_lights.data[light_index].position, view_pos); float shadow_attenuation = 1.0; - if (d * omni_lights.data[light_index].inv_radius < 1.0) { + if (omni_lights.data[light_index].volumetric_fog_energy > 0.001 && d * omni_lights.data[light_index].inv_radius < 1.0) { float attenuation = get_omni_attenuation(d, omni_lights.data[light_index].inv_radius, omni_lights.data[light_index].attenuation); vec3 light = omni_lights.data[light_index].color; @@ -509,9 +514,9 @@ void main() { float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; - shadow_attenuation = exp(min(0.0, (depth - pos.z)) / omni_lights.data[light_index].inv_radius * omni_lights.data[light_index].shadow_volumetric_fog_fade); + shadow_attenuation = mix(1.0 - omni_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / omni_lights.data[light_index].inv_radius * INV_FOG_FADE)); } - total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_pos - view_pos), normalize(view_pos)), params.phase_g); + total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_pos - view_pos), normalize(view_pos)), params.phase_g) * omni_lights.data[light_index].volumetric_fog_energy; } } } @@ -562,7 +567,7 @@ void main() { float d = length(light_rel_vec); float shadow_attenuation = 1.0; - if (d * spot_lights.data[light_index].inv_radius < 1.0) { + if (spot_lights.data[light_index].volumetric_fog_energy > 0.001 && d * spot_lights.data[light_index].inv_radius < 1.0) { float attenuation = get_omni_attenuation(d, spot_lights.data[light_index].inv_radius, spot_lights.data[light_index].attenuation); vec3 spot_dir = spot_lights.data[light_index].direction; @@ -595,9 +600,9 @@ void main() { float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; - shadow_attenuation = exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade); + shadow_attenuation = mix(1.0 - spot_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * INV_FOG_FADE)); } - total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g); + total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g) * spot_lights.data[light_index].volumetric_fog_energy; } } } diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 799f7087b6..a7fca25a6b 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -25,7 +25,7 @@ struct LightData { //this structure needs to be as packed as possible highp float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle highp float soft_shadow_scale; // scales the shadow kernel for blurrier shadows uint mask; - mediump float shadow_volumetric_fog_fade; + mediump float volumetric_fog_energy; uint bake_mode; highp vec4 projector_rect; //projector rect in srgb decal atlas }; @@ -65,7 +65,7 @@ struct DirectionalLightData { highp float fade_to; uvec2 pad; uint bake_mode; - mediump float shadow_volumetric_fog_fade; + mediump float volumetric_fog_energy; highp vec4 shadow_bias; highp vec4 shadow_normal_bias; highp vec4 shadow_transmittance_bias; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 0960533917..0ffc72f78f 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -240,7 +240,7 @@ void main() { #endif #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) - vec3 signed_tangent_attrib = tangent_attrib * 2.0 - 1.0; + vec2 signed_tangent_attrib = tangent_attrib * 2.0 - 1.0; vec3 tangent = oct_to_vec3(vec2(signed_tangent_attrib.x, abs(signed_tangent_attrib.y) * 2.0 - 1.0)); float binormalf = sign(signed_tangent_attrib.y); vec3 binormal = normalize(cross(normal, tangent) * binormalf); diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 7b58cc08dd..b845c1155e 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -75,6 +75,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; @@ -91,7 +92,6 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_OPACITY] = 1.0; 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); diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 3e3246e8e9..7e98a3cb8e 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -250,13 +250,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; virtual uint64_t light_get_version(RID p_light) const override; diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 84427e1c93..ce19187071 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -2121,6 +2121,10 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) { RD::get_singleton()->free(rt->color); } + if (rt->color_multisample.is_valid()) { + RD::get_singleton()->free(rt->color_multisample); + } + if (rt->backbuffer.is_valid()) { RD::get_singleton()->free(rt->backbuffer); rt->backbuffer = RID(); @@ -2132,6 +2136,7 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) { rt->framebuffer = RID(); rt->color = RID(); + rt->color_multisample = RID(); } void TextureStorage::_update_render_target(RenderTarget *rt) { @@ -2153,30 +2158,50 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { rt->color_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; rt->image_format = rt->is_transparent ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8; - RD::TextureFormat rd_format; + RD::TextureFormat rd_color_attachment_format; RD::TextureView rd_view; { //attempt register - rd_format.format = rt->color_format; - rd_format.width = rt->size.width; - rd_format.height = rt->size.height; - rd_format.depth = 1; - rd_format.array_layers = rt->view_count; // for stereo we create two (or more) layers, need to see if we can make fallback work like this too if we don't have multiview - rd_format.mipmaps = 1; - if (rd_format.array_layers > 1) { // why are we not using rt->texture_type ?? - rd_format.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + rd_color_attachment_format.format = rt->color_format; + rd_color_attachment_format.width = rt->size.width; + rd_color_attachment_format.height = rt->size.height; + rd_color_attachment_format.depth = 1; + rd_color_attachment_format.array_layers = rt->view_count; // for stereo we create two (or more) layers, need to see if we can make fallback work like this too if we don't have multiview + rd_color_attachment_format.mipmaps = 1; + if (rd_color_attachment_format.array_layers > 1) { // why are we not using rt->texture_type ?? + rd_color_attachment_format.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; } else { - rd_format.texture_type = RD::TEXTURE_TYPE_2D; + rd_color_attachment_format.texture_type = RD::TEXTURE_TYPE_2D; + } + rd_color_attachment_format.samples = RD::TEXTURE_SAMPLES_1; + rd_color_attachment_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + rd_color_attachment_format.shareable_formats.push_back(rt->color_format); + rd_color_attachment_format.shareable_formats.push_back(rt->color_format_srgb); + if (rt->msaa != RS::VIEWPORT_MSAA_DISABLED) { + rd_color_attachment_format.is_resolve_buffer = true; } - rd_format.samples = RD::TEXTURE_SAMPLES_1; - rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; - rd_format.shareable_formats.push_back(rt->color_format); - rd_format.shareable_formats.push_back(rt->color_format_srgb); } - rt->color = RD::get_singleton()->texture_create(rd_format, rd_view); + rt->color = RD::get_singleton()->texture_create(rd_color_attachment_format, rd_view); ERR_FAIL_COND(rt->color.is_null()); Vector<RID> fb_textures; + + if (rt->msaa != RS::VIEWPORT_MSAA_DISABLED) { + // Use the texture format of the color attachment for the multisample color attachment. + RD::TextureFormat rd_color_multisample_format = rd_color_attachment_format; + const RD::TextureSamples texture_samples[RS::VIEWPORT_MSAA_MAX] = { + RD::TEXTURE_SAMPLES_1, + RD::TEXTURE_SAMPLES_2, + RD::TEXTURE_SAMPLES_4, + RD::TEXTURE_SAMPLES_8, + }; + rd_color_multisample_format.samples = texture_samples[rt->msaa]; + RD::TextureView rd_view_multisample; + rd_color_multisample_format.is_resolve_buffer = false; + rt->color_multisample = RD::get_singleton()->texture_create(rd_color_multisample_format, rd_view_multisample); + fb_textures.push_back(rt->color_multisample); + ERR_FAIL_COND(rt->color_multisample.is_null()); + } fb_textures.push_back(rt->color); rt->framebuffer = RD::get_singleton()->framebuffer_create(fb_textures, RenderingDevice::INVALID_ID, rt->view_count); if (rt->framebuffer.is_null()) { @@ -2335,6 +2360,17 @@ void TextureStorage::render_target_set_as_unused(RID p_render_target) { rt->was_used = 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; + } + + rt->msaa = p_msaa; + _update_render_target(rt); +} + Size2 TextureStorage::render_target_get_size(RID p_render_target) { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, Size2()); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 682c951f63..25d355d878 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -254,6 +254,9 @@ private: uint32_t view_count; RID framebuffer; RID color; + RID color_multisample; // Needed when MSAA is enabled. + + RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; //used for retrieving from CPU RD::DataFormat color_format = RD::DATA_FORMAT_R4G4_UNORM_PACK8; @@ -556,6 +559,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; virtual void render_target_set_as_unused(RID p_render_target) override; + virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) override; void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps); void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color); |