summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_scene_cull.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_scene_cull.cpp')
-rw-r--r--servers/rendering/renderer_scene_cull.cpp79
1 files changed, 66 insertions, 13 deletions
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 26c50d25ca..c63152c11e 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -370,6 +370,22 @@ RID RendererSceneCull::instance_create() {
return instance_rid;
}
+void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) {
+ bool needs_instance = RSG::storage->mesh_needs_instance(p_instance->base, p_instance->skeleton.is_valid());
+ if (needs_instance != p_instance->mesh_instance.is_valid()) {
+ if (needs_instance) {
+ p_instance->mesh_instance = RSG::storage->mesh_instance_create(p_instance->base);
+ } else {
+ RSG::storage->free(p_instance->mesh_instance);
+ p_instance->mesh_instance = RID();
+ }
+ }
+
+ if (p_instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_set_skeleton(p_instance->mesh_instance, p_instance->skeleton);
+ }
+}
+
void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
@@ -384,6 +400,11 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
instance->octree_id = 0;
}
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->free(instance->mesh_instance);
+ instance->mesh_instance = RID();
+ }
+
switch (instance->base_type) {
case RS::INSTANCE_LIGHT: {
InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
@@ -450,7 +471,6 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
instance->base_data = nullptr;
}
- instance->blend_values.clear();
instance->materials.clear();
}
@@ -479,9 +499,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
case RS::INSTANCE_PARTICLES: {
InstanceGeometryData *geom = memnew(InstanceGeometryData);
instance->base_data = geom;
- if (instance->base_type == RS::INSTANCE_MESH) {
- instance->blend_values.resize(RSG::storage->mesh_get_blend_shape_count(p_base));
- }
+
} break;
case RS::INSTANCE_REFLECTION_PROBE: {
InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData);
@@ -520,6 +538,10 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
instance->base = p_base;
+ if (instance->base_type == RS::INSTANCE_MESH) {
+ _instance_update_mesh_instance(instance);
+ }
+
//forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it
RSG::storage->base_update_dependency(p_base, instance);
}
@@ -662,8 +684,9 @@ void RendererSceneCull::instance_set_blend_shape_weight(RID p_instance, int p_sh
_update_dirty_instance(instance);
}
- ERR_FAIL_INDEX(p_shape, instance->blend_values.size());
- instance->blend_values.write[p_shape] = p_weight;
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_set_blend_shape_weight(instance->mesh_instance, p_shape, p_weight);
+ }
}
void RendererSceneCull::instance_set_surface_material(RID p_instance, int p_surface, RID p_material) {
@@ -777,6 +800,9 @@ void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton)
//update the dependency now, so if cleared, we remove it
RSG::storage->skeleton_update_dependency(p_skeleton, instance);
}
+
+ _instance_update_mesh_instance(instance);
+
_instance_queue_update(instance, true, true);
}
@@ -1571,6 +1597,10 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
if (j == 0 || max > cull_max) {
cull_max = max;
}
+
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
+ }
}
if (cull_max > z_max) {
@@ -1671,6 +1701,8 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, z_max - z_min_cam, distances[i + 1], i, radius * 2.0 / texture_size, bias_scale * aspect_bias_scale * min_distance_bias_scale, z_max, uv_scale);
}
+ RSG::storage->update_mesh_instances();
+
scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, cull_count);
}
@@ -1711,9 +1743,15 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
+
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
+ }
}
}
+ RSG::storage->update_mesh_instances();
+
scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0);
scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, cull_count);
}
@@ -1763,9 +1801,13 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
}
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
+ }
}
}
+ RSG::storage->update_mesh_instances();
scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0);
scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, cull_count);
}
@@ -1800,9 +1842,15 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
}
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
+
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
+ }
}
}
+ RSG::storage->update_mesh_instances();
+
scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0);
scene_render->render_shadow(light->instance, p_shadow_atlas, 0, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, cull_count);
@@ -2143,6 +2191,10 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
}
}
+ if (ins->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_check_for_update(ins->mesh_instance);
+ }
+
ins->depth = near_plane.distance_to(ins->transform.origin);
ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15);
}
@@ -2159,6 +2211,8 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
ins->last_frame_pass = frame_number;
}
+ RSG::storage->update_mesh_instances();
+
/* STEP 5 - PROCESS LIGHTS */
RID *directional_light_ptr = &light_instance_cull_result[light_cull_count];
@@ -2344,6 +2398,9 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
} else if ((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
if (ins->baked_light) {
keep = true;
+ if (ins->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_check_for_update(ins->mesh_instance);
+ }
}
}
@@ -2355,6 +2412,8 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
}
}
+ RSG::storage->update_mesh_instances();
+
scene_render->render_sdfgi(p_render_buffers, i, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, sdfgi_cull_count);
//have to save updated cascades, then update static lights.
}
@@ -2795,13 +2854,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
int new_mat_count = RSG::storage->mesh_get_surface_count(p_instance->base);
p_instance->materials.resize(new_mat_count);
- int new_blend_shape_count = RSG::storage->mesh_get_blend_shape_count(p_instance->base);
- if (new_blend_shape_count != p_instance->blend_values.size()) {
- p_instance->blend_values.resize(new_blend_shape_count);
- for (int i = 0; i < new_blend_shape_count; i++) {
- p_instance->blend_values.write[i] = 0;
- }
- }
+ _instance_update_mesh_instance(p_instance);
}
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {