summaryrefslogtreecommitdiff
path: root/servers/visual
diff options
context:
space:
mode:
Diffstat (limited to 'servers/visual')
-rw-r--r--servers/visual/rasterizer.h4
-rw-r--r--servers/visual/visual_server_scene.cpp75
-rw-r--r--servers/visual/visual_server_scene.h13
3 files changed, 61 insertions, 31 deletions
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index f87f838fd6..15b60594b6 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -120,9 +120,7 @@ public:
Vector<Color> lightmap_capture_data; //in a array (12 values) to avoid wasting space if unused. Alpha is unused, but needed to send to shader
virtual void base_removed() = 0;
- virtual void base_changed() = 0;
- virtual void base_material_changed() = 0;
-
+ virtual void base_changed(bool p_aabb, bool p_materials) = 0;
InstanceBase() :
dependency_item(this) {
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 33fa8d365f..13de92f226 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -612,7 +612,7 @@ void VisualServerScene::instance_set_surface_material(RID p_instance, int p_surf
VSG::storage->material_remove_instance_owner(instance->materials[p_surface], instance);
}
instance->materials.write[p_surface] = p_material;
- instance->base_material_changed();
+ instance->base_changed(false, true);
if (instance->materials[p_surface].is_valid()) {
VSG::storage->material_add_instance_owner(instance->materials[p_surface], instance);
@@ -840,7 +840,7 @@ void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instanc
ERR_FAIL_COND(!instance);
instance->cast_shadows = p_shadow_casting_setting;
- instance->base_material_changed(); // to actually compute if shadows are visible or not
+ instance->base_changed(false, true); // to actually compute if shadows are visible or not
}
void VisualServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) {
@@ -851,7 +851,7 @@ void VisualServerScene::instance_geometry_set_material_override(RID p_instance,
VSG::storage->material_remove_instance_owner(instance->material_override, instance);
}
instance->material_override = p_material;
- instance->base_material_changed();
+ instance->base_changed(false, true);
if (instance->material_override.is_valid()) {
VSG::storage->material_add_instance_owner(instance->material_override, instance);
@@ -1264,13 +1264,15 @@ void VisualServerScene::_update_instance_lightmap_captures(Instance *p_instance)
}
}
-void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario) {
+bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario) {
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
Transform light_transform = p_instance->transform;
light_transform.orthonormalize(); //scale does not count on lights
+ bool animated_material_found = false;
+
switch (VSG::storage->light_get_type(p_instance->base)) {
case VS::LIGHT_DIRECTIONAL: {
@@ -1303,6 +1305,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
continue;
}
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
+
float max, min;
instance->transformed_aabb.project_range_in_plane(base, min, max);
@@ -1558,6 +1564,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
} else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
+
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
}
@@ -1609,6 +1619,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
} else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
}
@@ -1645,6 +1658,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
} else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
}
@@ -1655,6 +1671,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
} break;
}
+
+ return animated_material_found;
}
void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
@@ -2096,7 +2114,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
if (redraw) {
//must redraw!
- _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
+ light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
}
}
}
@@ -3244,11 +3262,13 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
bool can_cast_shadows = true;
+ bool is_animated = false;
if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_OFF) {
can_cast_shadows = false;
} else if (p_instance->material_override.is_valid()) {
can_cast_shadows = VSG::storage->material_casts_shadows(p_instance->material_override);
+ is_animated = VSG::storage->material_is_animated(p_instance->material_override);
} else {
if (p_instance->base_type == VS::INSTANCE_MESH) {
@@ -3263,12 +3283,15 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
- break;
- }
+ } else {
- if (VSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- break;
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+
+ if (VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
}
}
@@ -3290,12 +3313,15 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
- break;
- }
- if (VSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- break;
+ } else {
+
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+ if (VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
}
}
@@ -3312,6 +3338,10 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
} else {
can_cast_shadows = false;
}
+
+ if (mat.is_valid() && VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
} else if (p_instance->base_type == VS::INSTANCE_PARTICLES) {
bool cast_shadows = false;
@@ -3331,12 +3361,15 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
- break;
- }
+ } else {
- if (VSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- break;
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+
+ if (VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
}
}
}
@@ -3356,6 +3389,8 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
geom->can_cast_shadows = can_cast_shadows;
}
+
+ geom->material_is_animated = is_animated;
}
}
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index 0d4737f268..38c5258116 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -192,14 +192,9 @@ public:
singleton->instance_set_base(self, RID());
}
- virtual void base_changed() {
+ virtual void base_changed(bool p_aabb, bool p_materials) {
- singleton->_instance_queue_update(this, true, true);
- }
-
- virtual void base_material_changed() {
-
- singleton->_instance_queue_update(this, false, true);
+ singleton->_instance_queue_update(this, p_aabb, p_materials);
}
Instance() :
@@ -247,6 +242,7 @@ public:
List<Instance *> lighting;
bool lighting_dirty;
bool can_cast_shadows;
+ bool material_is_animated;
List<Instance *> reflection_probes;
bool reflection_dirty;
@@ -261,6 +257,7 @@ public:
lighting_dirty = false;
reflection_dirty = true;
can_cast_shadows = true;
+ material_is_animated = true;
gi_probes_dirty = true;
}
};
@@ -488,7 +485,7 @@ public:
_FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance);
_FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance);
- _FORCE_INLINE_ void _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario);
+ _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario);
void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe);
void _render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass);