summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_rd')
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp12
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h62
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl89
-rw-r--r--servers/rendering/renderer_rd/shaders/light_data_inc.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.cpp2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.h7
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp66
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h4
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);