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/environment/fog.cpp14
-rw-r--r--servers/rendering/renderer_rd/environment/gi.cpp51
-rw-r--r--servers/rendering/renderer_rd/environment/gi.h7
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp39
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h4
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl6
-rw-r--r--servers/rendering/renderer_rd/shaders/light_data_inc.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl34
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl14
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl32
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.cpp1
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp5
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp5
-rw-r--r--servers/rendering/renderer_rd/storage_rd/utilities.cpp2
14 files changed, 136 insertions, 82 deletions
diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp
index 58f4c855a4..257b67cf04 100644
--- a/servers/rendering/renderer_rd/environment/fog.cpp
+++ b/servers/rendering/renderer_rd/environment/fog.cpp
@@ -500,7 +500,7 @@ Fog::VolumetricFog::VolumetricFog(const Vector3i &fog_size, RID p_sky_shader) {
fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
RD::get_singleton()->set_resource_name(fog_map, "Fog map");
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
Vector<uint8_t> dm;
dm.resize(fog_size.x * fog_size.y * fog_size.z * 4);
dm.fill(0);
@@ -643,7 +643,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -663,7 +663,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -675,7 +675,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -949,7 +949,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
}
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -960,7 +960,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
}
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -972,7 +972,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp
index feafcc42c9..eaef5ba39c 100644
--- a/servers/rendering/renderer_rd/environment/gi.cpp
+++ b/servers/rendering/renderer_rd/environment/gi.cpp
@@ -1140,6 +1140,7 @@ void GI::SDFGI::erase() {
RD::get_singleton()->free(lightprobe_data);
RD::get_singleton()->free(lightprobe_history_scroll);
+ RD::get_singleton()->free(lightprobe_average_scroll);
RD::get_singleton()->free(occlusion_data);
RD::get_singleton()->free(ambient_texture);
@@ -2427,18 +2428,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
if (last_probe_data_version != data_version) {
//need to re-create everything
- if (texture.is_valid()) {
- RD::get_singleton()->free(texture);
- RD::get_singleton()->free(write_buffer);
- mipmaps.clear();
- }
-
- for (int i = 0; i < dynamic_maps.size(); i++) {
- RD::get_singleton()->free(dynamic_maps[i].texture);
- RD::get_singleton()->free(dynamic_maps[i].depth);
- }
-
- dynamic_maps.clear();
+ free_resources();
Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);
@@ -3130,6 +3120,37 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
last_probe_version = gi->voxel_gi_get_version(probe);
}
+void GI::VoxelGIInstance::free_resources() {
+ if (texture.is_valid()) {
+ RD::get_singleton()->free(texture);
+ RD::get_singleton()->free(write_buffer);
+
+ texture = RID();
+ write_buffer = RID();
+ mipmaps.clear();
+ }
+
+ for (int i = 0; i < dynamic_maps.size(); i++) {
+ RD::get_singleton()->free(dynamic_maps[i].texture);
+ RD::get_singleton()->free(dynamic_maps[i].depth);
+
+ // these only exist on the first level...
+ if (dynamic_maps[i].fb_depth.is_valid()) {
+ RD::get_singleton()->free(dynamic_maps[i].fb_depth);
+ }
+ if (dynamic_maps[i].albedo.is_valid()) {
+ RD::get_singleton()->free(dynamic_maps[i].albedo);
+ }
+ if (dynamic_maps[i].normal.is_valid()) {
+ RD::get_singleton()->free(dynamic_maps[i].normal);
+ }
+ if (dynamic_maps[i].orm.is_valid()) {
+ RD::get_singleton()->free(dynamic_maps[i].orm);
+ }
+ }
+ dynamic_maps.clear();
+}
+
void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
@@ -3936,6 +3957,12 @@ RID GI::voxel_gi_instance_create(RID p_base) {
return rid;
}
+void GI::voxel_gi_instance_free(RID p_rid) {
+ GI::VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_rid);
+ voxel_gi->free_resources();
+ voxel_gi_instance_owner.free(p_rid);
+}
+
void GI::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) {
VoxelGIInstance *voxel_gi = get_probe_instance(p_probe);
ERR_FAIL_COND(!voxel_gi);
diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h
index 304df1605b..8860445c3b 100644
--- a/servers/rendering/renderer_rd/environment/gi.h
+++ b/servers/rendering/renderer_rd/environment/gi.h
@@ -469,6 +469,7 @@ public:
void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render);
void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
+ void free_resources();
};
mutable RID_Owner<VoxelGIInstance> voxel_gi_instance_owner;
@@ -483,6 +484,12 @@ public:
return voxel_gi->texture;
};
+ bool voxel_gi_instance_owns(RID p_rid) const {
+ return voxel_gi_instance_owner.owns(p_rid);
+ }
+
+ void voxel_gi_instance_free(RID p_rid);
+
RS::VoxelGIQuality voxel_gi_quality = RS::VOXEL_GI_QUALITY_LOW;
/* SDFGI */
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index c6f38012a6..6c219933b0 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -2459,8 +2459,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
p_internal_width = p_width;
}
- const float texture_mipmap_bias = -log2f(p_width / p_internal_width) + p_texture_mipmap_bias;
- material_storage->sampler_rd_configure_custom(texture_mipmap_bias);
+ material_storage->sampler_rd_configure_custom(p_texture_mipmap_bias);
update_uniform_sets();
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
@@ -2869,7 +2868,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
WARN_PRINT_ONCE("The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet.");
}
- light_data.shadow_enabled = p_using_shadows && light_storage->light_has_shadow(base);
+ light_data.shadow_opacity = p_using_shadows && light_storage->light_has_shadow(base) ? light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY) : 0.0;
float angular_diameter = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
if (angular_diameter > 0.0) {
@@ -2886,7 +2885,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
angular_diameter = 0.0;
}
- if (light_data.shadow_enabled) {
+ if (light_data.shadow_opacity > 0.001) {
RS::LightDirectionalShadowMode smode = light_storage->light_directional_get_shadow_mode(base);
int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);
@@ -3040,19 +3039,26 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
// Reuse fade begin, fade length and distance for shadow LOD determination later.
float fade_begin = 0.0;
+ float fade_shadow = 0.0;
float fade_length = 0.0;
real_t distance = 0.0;
float fade = 1.0;
+ float shadow_opacity_fade = 1.0;
if (light_storage->light_is_distance_fade_enabled(li->light)) {
fade_begin = light_storage->light_get_distance_fade_begin(li->light);
+ fade_shadow = light_storage->light_get_distance_fade_shadow(li->light);
fade_length = light_storage->light_get_distance_fade_length(li->light);
distance = camera_plane.distance_to(li->transform.origin);
+ // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
if (distance > fade_begin) {
- // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length);
}
+
+ if (distance > fade_shadow) {
+ shadow_opacity_fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_shadow) / fade_length);
+ }
}
float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade;
@@ -3120,7 +3126,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
bool in_shadow_range = true;
if (needs_shadow && light_storage->light_is_distance_fade_enabled(li->light)) {
- if (distance > light_storage->light_get_distance_fade_shadow(li->light)) {
+ if (distance > light_storage->light_get_distance_fade_shadow(li->light) + light_storage->light_get_distance_fade_length(li->light)) {
// Out of range, don't draw shadows to improve performance.
in_shadow_range = false;
}
@@ -3129,7 +3135,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
if (needs_shadow && in_shadow_range) {
// fill in the shadow information
- light_data.shadow_enabled = true;
+ light_data.shadow_opacity = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY) * shadow_opacity_fade;
float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas);
light_data.shadow_normal_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0;
@@ -3189,7 +3195,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
}
}
} else {
- light_data.shadow_enabled = false;
+ light_data.shadow_opacity = 0.0;
}
li->cull_mask = light_storage->light_get_cull_mask(base);
@@ -3637,7 +3643,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
if (p_render_data->render_buffers.is_valid()) {
bool directional_shadows = false;
for (uint32_t i = 0; i < directional_light_count; i++) {
- if (cluster.directional_lights[i].shadow_enabled) {
+ if (cluster.directional_lights[i].shadow_opacity > 0.001) {
directional_shadows = true;
break;
}
@@ -4079,19 +4085,8 @@ bool RendererSceneRenderRD::free(RID p_rid) {
decal_instance_owner.free(p_rid);
} else if (lightmap_instance_owner.owns(p_rid)) {
lightmap_instance_owner.free(p_rid);
- } else if (gi.voxel_gi_instance_owner.owns(p_rid)) {
- RendererRD::GI::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.get_or_null(p_rid);
- if (voxel_gi->texture.is_valid()) {
- RD::get_singleton()->free(voxel_gi->texture);
- RD::get_singleton()->free(voxel_gi->write_buffer);
- }
-
- for (int i = 0; i < voxel_gi->dynamic_maps.size(); i++) {
- RD::get_singleton()->free(voxel_gi->dynamic_maps[i].texture);
- RD::get_singleton()->free(voxel_gi->dynamic_maps[i].depth);
- }
-
- gi.voxel_gi_instance_owner.free(p_rid);
+ } else if (gi.voxel_gi_instance_owns(p_rid)) {
+ gi.voxel_gi_instance_free(p_rid);
} else if (sky.sky_owner.owns(p_rid)) {
sky.update_dirty_skys();
sky.free_sky(p_rid);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 09ec2a9efd..22e9ead243 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -608,7 +608,7 @@ private:
float inv_spot_attenuation;
float cos_spot_angle;
float specular_amount;
- uint32_t shadow_enabled;
+ float shadow_opacity;
float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv
float shadow_matrix[16];
@@ -633,7 +633,7 @@ private:
float softshadow_angle;
float soft_shadow_scale;
uint32_t blend_splits;
- uint32_t shadow_enabled;
+ float shadow_opacity;
float fade_from;
float fade_to;
uint32_t pad[2];
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 e74cfad65c..6f79b9e771 100644
--- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl
@@ -377,7 +377,7 @@ void main() {
for (uint i = 0; i < params.directional_light_count; i++) {
vec3 shadow_attenuation = vec3(1.0);
- if (directional_lights.data[i].shadow_enabled) {
+ if (directional_lights.data[i].shadow_opacity > 0.001) {
float depth_z = -view_pos.z;
vec4 pssm_coord;
@@ -486,7 +486,7 @@ void main() {
vec3 light = omni_lights.data[light_index].color;
- if (omni_lights.data[light_index].shadow_enabled) {
+ if (omni_lights.data[light_index].shadow_opacity > 0.001) {
//has shadow
vec4 uv_rect = omni_lights.data[light_index].atlas_rect;
vec2 flip_offset = omni_lights.data[light_index].direction.xy;
@@ -572,7 +572,7 @@ void main() {
vec3 light = spot_lights.data[light_index].color;
- if (spot_lights.data[light_index].shadow_enabled) {
+ if (spot_lights.data[light_index].shadow_opacity > 0.001) {
//has shadow
vec4 uv_rect = spot_lights.data[light_index].atlas_rect;
vec2 flip_offset = spot_lights.data[light_index].direction.xy;
diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl
index 61c8488a05..799f7087b6 100644
--- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl
@@ -15,7 +15,7 @@ struct LightData { //this structure needs to be as packed as possible
mediump float cone_attenuation;
mediump float cone_angle;
mediump float specular_amount;
- bool shadow_enabled;
+ mediump float shadow_opacity;
highp vec4 atlas_rect; // rect in the shadow atlas
highp mat4 shadow_matrix;
@@ -60,7 +60,7 @@ struct DirectionalLightData {
highp float softshadow_angle;
highp float soft_shadow_scale;
bool blend_splits;
- bool shadow_enabled;
+ mediump float shadow_opacity;
highp float fade_from;
highp float fade_to;
uvec2 pad;
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index 22058b3a06..e9515c7670 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -988,8 +988,10 @@ void fragment_shader(in SceneData scene_data) {
vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
vec3 ref_vec = reflect(-view, bent_normal);
+ ref_vec = mix(ref_vec, bent_normal, roughness * roughness);
#else
vec3 ref_vec = reflect(-view, normal);
+ ref_vec = mix(ref_vec, normal, roughness * roughness);
#endif
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
@@ -1046,6 +1048,7 @@ void fragment_shader(in SceneData scene_data) {
ambient_light *= attenuation;
specular_light *= attenuation;
+ ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness);
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD;
@@ -1203,6 +1206,7 @@ void fragment_shader(in SceneData scene_data) {
uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
vec3 ref_vec = normalize(reflect(-view, normal));
+ ref_vec = mix(ref_vec, normal, roughness * roughness);
//find arbitrary tangent and bitangent, then build a matrix
vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
vec3 tangent = normalize(cross(v0, normal));
@@ -1302,6 +1306,18 @@ void fragment_shader(in SceneData scene_data) {
item_to = subgroupBroadcastFirst(subgroupMax(item_to));
#endif
+#ifdef LIGHT_ANISOTROPY_USED
+ // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy
+ vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent;
+ vec3 anisotropic_tangent = cross(anisotropic_direction, view);
+ vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
+ vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
+#else
+ vec3 bent_normal = normal;
+#endif
+ vec3 ref_vec = normalize(reflect(-view, bent_normal));
+ ref_vec = mix(ref_vec, bent_normal, roughness * roughness);
+
for (uint i = item_from; i < item_to; i++) {
uint mask = cluster_buffer.data[cluster_reflection_offset + i];
mask &= cluster_get_range_clip_mask(i, item_min, item_max);
@@ -1324,16 +1340,8 @@ void fragment_shader(in SceneData scene_data) {
if (!bool(reflections.data[reflection_index].mask & instances.data[instance_index].layer_mask)) {
continue; //not masked
}
-#ifdef LIGHT_ANISOTROPY_USED
- // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy
- vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent;
- vec3 anisotropic_tangent = cross(anisotropic_direction, view);
- vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
- vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
-#else
- vec3 bent_normal = normal;
-#endif
- reflection_process(reflection_index, view, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
+
+ reflection_process(reflection_index, vertex, ref_vec, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
}
}
@@ -1417,7 +1425,7 @@ void fragment_shader(in SceneData scene_data) {
float shadow = 1.0;
- if (directional_lights.data[i].shadow_enabled) {
+ if (directional_lights.data[i].shadow_opacity > 0.001) {
float depth_z = -vertex.z;
vec3 light_dir = directional_lights.data[i].direction;
vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp))));
@@ -1626,7 +1634,7 @@ void fragment_shader(in SceneData scene_data) {
#ifdef LIGHT_TRANSMITTANCE_USED
float transmittance_z = transmittance_depth;
- if (directional_lights.data[i].shadow_enabled) {
+ if (directional_lights.data[i].shadow_opacity > 0.001) {
float depth_z = -vertex.z;
if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
@@ -1681,6 +1689,8 @@ void fragment_shader(in SceneData scene_data) {
} else {
shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0;
}
+
+ shadow = shadow * directional_lights.data[i].shadow_opacity + 1.0 - directional_lights.data[i].shadow_opacity;
#endif
blur_shadow(shadow);
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
index e27c81eaea..7299bb0576 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
@@ -395,7 +395,7 @@ float get_omni_attenuation(float distance, float inv_range, float decay) {
float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {
#ifndef SHADOWS_DISABLED
- if (omni_lights.data[idx].shadow_enabled) {
+ if (omni_lights.data[idx].shadow_opacity > 0.001) {
// there is a shadowmap
vec2 texel_size = scene_data_block.data.shadow_atlas_pixel_size;
vec4 base_uv_rect = omni_lights.data[idx].atlas_rect;
@@ -498,6 +498,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {
}
shadow /= float(sc_penumbra_shadow_samples);
+ shadow = mix(1.0, shadow, omni_lights.data[idx].shadow_opacity);
} else {
//no blockers found, so no shadow
@@ -516,7 +517,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {
vec2 pos = shadow_sample.xy / shadow_sample.z;
float depth = shadow_len - omni_lights.data[idx].shadow_bias;
depth *= omni_lights.data[idx].inv_radius;
- shadow = sample_omni_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale / shadow_sample.z, pos, uv_rect, flip_offset, depth);
+ shadow = mix(1.0, sample_omni_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale / shadow_sample.z, pos, uv_rect, flip_offset, depth), omni_lights.data[idx].shadow_opacity);
}
return shadow;
@@ -674,7 +675,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {
#ifndef SHADOWS_DISABLED
- if (spot_lights.data[idx].shadow_enabled) {
+ if (spot_lights.data[idx].shadow_opacity > 0.001) {
vec3 light_rel_vec = spot_lights.data[idx].position - vertex;
float light_length = length(light_rel_vec);
vec3 spot_dir = spot_lights.data[idx].direction;
@@ -735,6 +736,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {
}
shadow /= float(sc_penumbra_shadow_samples);
+ shadow = mix(1.0, shadow, spot_lights.data[idx].shadow_opacity);
} else {
//no blockers found, so no shadow
@@ -743,7 +745,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {
} else {
//hard shadow
vec3 shadow_uv = vec3(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z);
- shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data_block.data.shadow_atlas_pixel_size, shadow_uv);
+ shadow = mix(1.0, sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data_block.data.shadow_atlas_pixel_size, shadow_uv), spot_lights.data[idx].shadow_opacity);
}
return shadow;
@@ -872,7 +874,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
diffuse_light, specular_light);
}
-void reflection_process(uint ref_index, vec3 view, vec3 vertex, vec3 normal, float roughness, vec3 ambient_light, vec3 specular_light, inout vec4 ambient_accum, inout vec4 reflection_accum) {
+void reflection_process(uint ref_index, vec3 vertex, vec3 ref_vec, vec3 normal, float roughness, vec3 ambient_light, vec3 specular_light, inout vec4 ambient_accum, inout vec4 reflection_accum) {
vec3 box_extents = reflections.data[ref_index].box_extents;
vec3 local_pos = (reflections.data[ref_index].local_matrix * vec4(vertex, 1.0)).xyz;
@@ -880,8 +882,6 @@ void reflection_process(uint ref_index, vec3 view, vec3 vertex, vec3 normal, flo
return;
}
- vec3 ref_vec = normalize(reflect(-view, normal));
-
vec3 inner_pos = abs(local_pos / box_extents);
float blend = max(inner_pos.x, max(inner_pos.y, inner_pos.z));
//make blend more rounded
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
index 26d0de46c2..6548793bee 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
@@ -889,8 +889,10 @@ void main() {
vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
vec3 ref_vec = reflect(-view, bent_normal);
+ ref_vec = mix(ref_vec, bent_normal, roughness * roughness);
#else
vec3 ref_vec = reflect(-view, normal);
+ ref_vec = mix(ref_vec, normal, roughness * roughness);
#endif
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
@@ -940,6 +942,7 @@ void main() {
vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map
float NoV = max(dot(n, view), 0.0001);
vec3 ref_vec = reflect(-view, n);
+ ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness);
// The clear coat layer assumes an IOR of 1.5 (4% reflectance)
float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV));
float attenuation = 1.0 - Fc;
@@ -1036,6 +1039,19 @@ void main() {
vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0);
uint reflection_indices = draw_call.reflection_probes.x;
+
+#ifdef LIGHT_ANISOTROPY_USED
+ // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy
+ vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent;
+ vec3 anisotropic_tangent = cross(anisotropic_direction, view);
+ vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
+ vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
+#else
+ vec3 bent_normal = normal;
+#endif
+ vec3 ref_vec = normalize(reflect(-view, bent_normal));
+ ref_vec = mix(ref_vec, bent_normal, roughness * roughness);
+
for (uint i = 0; i < 8; i++) {
uint reflection_index = reflection_indices & 0xFF;
if (i == 4) {
@@ -1047,16 +1063,8 @@ void main() {
if (reflection_index == 0xFF) {
break;
}
-#ifdef LIGHT_ANISOTROPY_USED
- // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy
- vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent;
- vec3 anisotropic_tangent = cross(anisotropic_direction, view);
- vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
- vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
-#else
- vec3 bent_normal = normal;
-#endif
- reflection_process(reflection_index, view, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
+
+ reflection_process(reflection_index, vertex, ref_vec, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
}
if (reflection_accum.a > 0.0) {
@@ -1134,7 +1142,7 @@ void main() {
#ifdef USE_SOFT_SHADOWS
//version with soft shadows, more expensive
- if (directional_lights.data[i].shadow_enabled) {
+ if (directional_lights.data[i].shadow_opacity > 0.001) {
float depth_z = -vertex.z;
vec4 pssm_coord;
@@ -1286,7 +1294,7 @@ void main() {
#else
// Soft shadow disabled version
- if (directional_lights.data[i].shadow_enabled) {
+ if (directional_lights.data[i].shadow_opacity > 0.001) {
float depth_z = -vertex.z;
vec4 pssm_coord;
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
index d3831b4618..882afdfa54 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
@@ -88,6 +88,7 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) {
light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
+ 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;
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
index dc3f35f942..585c42b2d8 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
@@ -416,7 +416,10 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
mesh->bone_aabbs.resize(p_surface.bone_aabbs.size());
}
for (int i = 0; i < p_surface.bone_aabbs.size(); i++) {
- mesh->bone_aabbs.write[i].merge_with(p_surface.bone_aabbs[i]);
+ const AABB &bone = p_surface.bone_aabbs[i];
+ if (!bone.has_no_volume()) {
+ mesh->bone_aabbs.write[i].merge_with(bone);
+ }
}
mesh->aabb.merge_with(p_surface.aabb);
}
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index e20a04ff2a..84427e1c93 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -416,7 +416,10 @@ TextureStorage::TextureStorage() {
tformat.format = RD::DATA_FORMAT_R8_UINT;
tformat.width = 4;
tformat.height = 4;
- tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ if (RD::get_singleton()->has_feature(RD::SUPPORTS_ATTACHMENT_VRS)) {
+ tformat.usage_bits |= RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT;
+ }
tformat.texture_type = RD::TEXTURE_TYPE_2D;
Vector<uint8_t> pv;
diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.cpp b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
index ae1f22be3b..fcef2f24bf 100644
--- a/servers/rendering/renderer_rd/storage_rd/utilities.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
@@ -290,7 +290,7 @@ bool Utilities::has_os_feature(const String &p_feature) const {
return true;
}
-#if !defined(ANDROID_ENABLED) && !defined(IPHONE_ENABLED)
+#if !defined(ANDROID_ENABLED) && !defined(IOS_ENABLED)
// Some Android devices report support for S3TC but we don't expect that and don't export the textures.
// This could be fixed but so few devices support it that it doesn't seem useful (and makes bigger APKs).
// For good measure we do the same hack for iOS, just in case.