Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cull fixes and optimizations #44656

Merged
merged 1 commit into from
Dec 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions core/math/aabb.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ class AABB {
Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;
Variant intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const;

_FORCE_INLINE_ void quantize(float p_unit);
_FORCE_INLINE_ AABB quantized(float p_unit) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be real_t.


_FORCE_INLINE_ void set_end(const Vector3 &p_end) {
size = p_end - position;
}
Expand Down Expand Up @@ -427,4 +430,28 @@ void AABB::grow_by(real_t p_amount) {
size.z += 2.0 * p_amount;
}

void AABB::quantize(float p_unit) {
size += position;

position.x -= Math::fposmodp(position.x, p_unit);
position.y -= Math::fposmodp(position.y, p_unit);
position.z -= Math::fposmodp(position.z, p_unit);

size.x -= Math::fposmodp(size.x, p_unit);
size.y -= Math::fposmodp(size.y, p_unit);
size.z -= Math::fposmodp(size.z, p_unit);

size.x += p_unit;
size.y += p_unit;
size.z += p_unit;

size -= position;
}

AABB AABB::quantized(float p_unit) const {
AABB ret = *this;
ret.quantize(p_unit);
return ret;
}

#endif // AABB_H
9 changes: 5 additions & 4 deletions core/math/dynamic_bvh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,17 +351,17 @@ void DynamicBVH::_update(Node *leaf, int lookahead) {
_insert_leaf(root, leaf);
}

void DynamicBVH::update(const ID &p_id, const AABB &p_box) {
ERR_FAIL_COND(!p_id.is_valid());
bool DynamicBVH::update(const ID &p_id, const AABB &p_box) {
ERR_FAIL_COND_V(!p_id.is_valid(), false);
Node *leaf = p_id.node;

Volume volume;
volume.min = p_box.position;
volume.max = p_box.position + p_box.size;

if ((leaf->volume.min == volume.min) && (leaf->volume.max == volume.max)) {
if (leaf->volume.min.is_equal_approx(volume.min) && leaf->volume.max.is_equal_approx(volume.max)) {
// noop
return;
return false;
}

Node *base = _remove_leaf(leaf);
Expand All @@ -375,6 +375,7 @@ void DynamicBVH::update(const ID &p_id, const AABB &p_box) {
}
leaf->volume = volume;
_insert_leaf(base, leaf);
return true;
}

void DynamicBVH::remove(const ID &p_id) {
Expand Down
2 changes: 1 addition & 1 deletion core/math/dynamic_bvh.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ class DynamicBVH {
void optimize_top_down(int bu_threshold = 128);
void optimize_incremental(int passes);
ID insert(const AABB &p_box, void *p_userdata);
void update(const ID &p_id, const AABB &p_box);
bool update(const ID &p_id, const AABB &p_box);
void remove(const ID &p_id);
void get_elements(List<ID> *r_elements);

Expand Down
17 changes: 17 additions & 0 deletions core/math/math_funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,23 @@ class Math {
value += 0.0;
return value;
}
static _ALWAYS_INLINE_ float fposmodp(float p_x, float p_y) {
float value = Math::fmod(p_x, p_y);
if (value < 0) {
value += p_y;
}
value += 0.0;
return value;
}
static _ALWAYS_INLINE_ double fposmodp(double p_x, double p_y) {
double value = Math::fmod(p_x, p_y);
if (value < 0) {
value += p_y;
}
value += 0.0;
return value;
}

static _ALWAYS_INLINE_ int posmod(int p_x, int p_y) {
int value = p_x % p_y;
if ((value < 0 && p_y > 0) || (value > 0 && p_y < 0)) {
Expand Down
27 changes: 23 additions & 4 deletions servers/rendering/renderer_scene_cull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1065,20 +1065,37 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
p_instance->transformed_aabb = new_aabb;

if (p_instance->scenario == nullptr || !p_instance->visible || Math::is_zero_approx(p_instance->transform.basis.determinant())) {
p_instance->prev_transformed_aabb = p_instance->transformed_aabb;
return;
}

//quantize to improve moving object performance
AABB bvh_aabb = p_instance->transformed_aabb;

if (p_instance->indexer_id.is_valid() && bvh_aabb != p_instance->prev_transformed_aabb) {
//assume motion, see if bounds need to be quantized
AABB motion_aabb = bvh_aabb.merge(p_instance->prev_transformed_aabb);
float motion_longest_axis = motion_aabb.get_longest_axis_size();
float longest_axis = p_instance->transformed_aabb.get_longest_axis_size();

if (motion_longest_axis < longest_axis * 2) {
//moved but not a lot, use motion aabb quantizing
float quantize_size = Math::pow(2.0, Math::ceil(Math::log(motion_longest_axis) / Math::log(2.0))) * 0.5; //one fifth
bvh_aabb.quantize(quantize_size);
}
}

if (!p_instance->indexer_id.is_valid()) {
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
p_instance->indexer_id = p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].insert(p_instance->transformed_aabb, p_instance);
p_instance->indexer_id = p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].insert(bvh_aabb, p_instance);
} else {
p_instance->indexer_id = p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].insert(p_instance->transformed_aabb, p_instance);
p_instance->indexer_id = p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].insert(bvh_aabb, p_instance);
}
} else {
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].update(p_instance->indexer_id, p_instance->transformed_aabb);
p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].update(p_instance->indexer_id, bvh_aabb);
} else {
p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].update(p_instance->indexer_id, p_instance->transformed_aabb);
p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].update(p_instance->indexer_id, bvh_aabb);
}
}

Expand Down Expand Up @@ -1124,6 +1141,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
}

pair.pair();

p_instance->prev_transformed_aabb = p_instance->transformed_aabb;
}

void RendererSceneCull::_unpair_instance(Instance *p_instance) {
Expand Down
1 change: 1 addition & 0 deletions servers/rendering/renderer_scene_render.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class RendererSceneRender {

AABB aabb;
AABB transformed_aabb;
AABB prev_transformed_aabb;

struct InstanceShaderParameter {
int32_t index = -1;
Expand Down