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

Proposal for new bvh split method (approach Nr. 3) - divide and conquer with std::sort() #1391

Closed
wants to merge 0 commits into from

Conversation

relief7
Copy link
Contributor

@relief7 relief7 commented Feb 19, 2024

Hi Steve!

please find proposal for "new bvh split method (approach Nr. 3) - divide and conquer with std::sort()" based on latest dev branch in this pull request (see further info in issue reply).

Thanks,
Markus

Copy link
Collaborator

@hollasch hollasch left a comment

Choose a reason for hiding this comment

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

If you agree to these changes, then we also need to do the following work:

  • Make the same changes to bvh.h in src/TheRestOfYourLife.
  • Update the text and any listings for books 2 & 3
  • Add an entry to the CHANGELOG.md file.
  • Please add your name to books/acknowledgments.md.

Comment on lines 33 to 31
for (size_t object_index=0; object_index < size; object_index++)
bbox = aabb(bbox, src_objects[object_index]->bounding_box());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Simplify to:

for (auto& obj : src_objects)
    bbox = aabb(bbox, obj->bounding_box());

// Build the bounding box of the span of source objects.
bbox = aabb::empty;
for (size_t object_index=start; object_index < end; object_index++)

size_t size = src_objects.size ();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Move size definition down below the line:

auto objects = src_objects; // A modifiable array of the source scene objects

Comment on lines 46 to 52
} else if (size == 2) {
if (comparator(objects[0], objects[1])) {
left = objects[0];
right = objects[1];
} else {
left = objects[start+1];
right = objects[start];
left = objects[1];
right = objects[0];
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since we're rewriting this, let's fix issue #1327 in the same commit. Please simplify this case to the following:

...
} else if (size == 2) {
    left = objects[0];
    right = objects[1];
} else {
...

(Ordering the two child objects in this case accomplishes nothing.)

@relief7
Copy link
Contributor Author

relief7 commented Feb 20, 2024

Hi Steve!
Thank you for the great feedback! I totally forgot about the code in the other chapters and the book! 🤣
Will try to do another round and re-submit! After all these changes, the bvh construction will be so easy that even a pre-schooler can understand it. 😄
Thanks,
Markus

@wlbksy
Copy link
Contributor

wlbksy commented Feb 23, 2024

You can improve further by writing a helper function to do the job.

  1. bvh_node(const vector& objs) first sort all the objects.
  2. call the helper function to do the split job so that you don't have to sort every level down the tree.

This reduce the current $O(n\lg^2 n)$ to $O(n\lg n)$

@relief7
Copy link
Contributor Author

relief7 commented Feb 23, 2024

Hi @wlbksy!
Thank you for your suggestion! I am not sure if I can follow though... Don't we need to sort in every level because we are randomly switching up the axis of sorting in each level?

int axis = random_int(0,2);
auto comparator = (axis == 0) ? box_x_compare
                : (axis == 1) ? box_y_compare
                              : box_z_compare;

So a good sort for x in the beginning might not be an optimal sort for z a few levels further down, for example. Or am I misunderstanding this issue?

@armansito
Copy link
Contributor

armansito commented Feb 23, 2024

Hi @wlbksy! Thank you for your suggestion! I am not sure if I can follow though... Don't we need to sort in every level because we are randomly switching up the axis of sorting in each level?

int axis = random_int(0,2);
auto comparator = (axis == 0) ? box_x_compare
                : (axis == 1) ? box_y_compare
                              : box_z_compare;

So a good sort for x in the beginning might not be an optimal sort for z a few levels further down, for example. Or am I misunderstanding this issue?

I agree, you need to know the spatial subdivision axis and position at each level and the BVH construction code is already handling this.

As an alternative, if we really wanted to eliminate all the redundant copies and vector allocations, we could allow the BVH construction to sort the object list in-place without creating any intermediate vectors. The code would look very similar to the original listing but instead remove the const qualifier from the src_objects declaration. If preserving the original order of the input objects is important, the input could be copied once and the in-place sort could operate over that initial copy (but I'm not sure if that's really necessary).

@hollasch any thoughts?

@relief7
Copy link
Contributor Author

relief7 commented Feb 23, 2024

Hi @armansito

I personally think that this is a great idea! It would probably be super fast and efficient.

I always wondered why we are doing the indexing and copying the vector in the first place because doing both kind of negate each other.

My proposal works around the issue to simplify the indexing (because it would not be needed) but what you are suggesting is probably the most elegant solution with the smallest RAM and CPU footprint. 😄

@wlbksy
Copy link
Contributor

wlbksy commented Feb 24, 2024

Hi @wlbksy! Thank you for your suggestion! I am not sure if I can follow though... Don't we need to sort in every level because we are randomly switching up the axis of sorting in each level?

int axis = random_int(0,2);
auto comparator = (axis == 0) ? box_x_compare
                : (axis == 1) ? box_y_compare
                              : box_z_compare;

So a good sort for x in the beginning might not be an optimal sort for z a few levels further down, for example. Or am I misunderstanding this issue?

Oh, you're right. I missed this random axis switching.

@relief7
Copy link
Contributor Author

relief7 commented Feb 26, 2024

Hi!
apologies for closing and opening a new pull request (still trying to get the hang of github 😆).

I made some tests with your suggestions, @armansito (see results in my previous bvh thread #1388 ).

IMHO, this would be the most elegant solution to most issues, so a new bvh method such as the one from my original proposal would not really be needed anymore. There is also a pull request #1409 with corresponding code and book changes, Steve @hollasch , in case you find it useful.

Thanks!

@hollasch
Copy link
Collaborator

@relief7 relief7 force-pushed the dev branch from 7e62d8e to b11548c
7 hours ago

You didn't force-push the RayTracing:dev branch did you?

@relief7
Copy link
Contributor Author

relief7 commented Feb 27, 2024

@relief7 relief7 force-pushed the dev branch from 7e62d8e to b11548c
7 hours ago

You didn't force-push the RayTracing:dev branch did you?

No, as you can see in the status message:

image

I am only modifying the dev branch in my own fork and submitting pr's from there. I wouldn't even have the administrative rights to commit any changes to your repository, would I?

@hollasch
Copy link
Collaborator

Phew! Thanks @relief7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants