EDAN30 Photorealistic Computer Graphics. Seminar 2, Bounding Volume Hierarchy. Magnus Andersson, PhD student

Similar documents
INFOGR Computer Graphics. J. Bikker - April-July Lecture 11: Acceleration. Welcome!

Accelerating Geometric Queries. Computer Graphics CMU /15-662, Fall 2016

Acceleration Data Structures

Lecture 2 - Acceleration Structures

Accelerated Raytracing

Computer Graphics. - Spatial Index Structures - Philipp Slusallek

Announcements. Written Assignment2 is out, due March 8 Graded Programming Assignment2 next Tuesday

Dual-Split Trees Supplemental Materials

Acceleration Data Structures. Michael Doggett Department of Computer Science Lund university

Bounding Volume Hierarchies. CS 6965 Fall 2011

Spatial Data Structures. Steve Rotenberg CSE168: Rendering Algorithms UCSD, Spring 2017

Ray Tracing Acceleration Data Structures

Computer Graphics. - Ray-Tracing II - Hendrik Lensch. Computer Graphics WS07/08 Ray Tracing II

Spatial Data Structures

Ray Tracing with Spatial Hierarchies. Jeff Mahovsky & Brian Wyvill CSC 305

improving raytracing speed

Intersection Acceleration

Parallel Physically Based Path-tracing and Shading Part 3 of 2. CIS565 Fall 2012 University of Pennsylvania by Yining Karl Li

INFOMAGR Advanced Graphics. Jacco Bikker - February April Welcome!

Spatial Data Structures

Lecture 4 - Real-time Ray Tracing

Ray Tracing Performance

In the previous presentation, Erik Sintorn presented methods for practically constructing a DAG structure from a voxel data set.

Ray Tracing. Cornell CS4620/5620 Fall 2012 Lecture Kavita Bala 1 (with previous instructors James/Marschner)

Dynamic Bounding Volume Hierarchies. Erin Catto, Blizzard Entertainment

Accelerating Ray-Tracing

Spatial Data Structures

Ray Intersection Acceleration

Spatial Data Structures

Acceleration Structures. CS 6965 Fall 2011

CPSC / Sonny Chan - University of Calgary. Collision Detection II

Spatial Data Structures

Acceleration Data Structures for Ray Tracing

Topics. Ray Tracing II. Intersecting transformed objects. Transforming objects

Ray Intersection Acceleration

EDAN30 Photorealistic Computer Graphics. Seminar 1, Whitted Ray Tracing (And then some!) Magnus Andersson, PhD student

Ray Tracing. Computer Graphics CMU /15-662, Fall 2016

Topics. Ray Tracing II. Transforming objects. Intersecting transformed objects

Recall: Inside Triangle Test

Ray Tracing III. Wen-Chieh (Steve) Lin National Chiao-Tung University

Using Bounding Volume Hierarchies Efficient Collision Detection for Several Hundreds of Objects

Spatial Data Structures and Speed-Up Techniques. Tomas Akenine-Möller Department of Computer Engineering Chalmers University of Technology

Ray Tracing Acceleration. CS 4620 Lecture 20

Stackless BVH Collision Detection for Physical Simulation

Programming projects. Assignment 1: Basic ray tracer. Assignment 1: Basic ray tracer. Assignment 1: Basic ray tracer. Assignment 1: Basic ray tracer

Questions from Last Week? Extra rays needed for these effects. Shadows Motivation

CS 431/636 Advanced Rendering Techniques

SPATIAL DATA STRUCTURES. Jon McCaffrey CIS 565

Computer Graphics. Bing-Yu Chen National Taiwan University The University of Tokyo

More Hidden Surface Removal

kd-trees for Volume Ray-Casting

COMP 175: Computer Graphics April 11, 2018

Ray-tracing Acceleration. Acceleration Data Structures for Ray Tracing. Shadows. Shadows & Light Sources. Antialiasing Supersampling.

Ray Casting. Outline in Code. Outline. Finding Ray Direction. Heckbert s Business Card Ray Tracer. Foundations of Computer Graphics (Fall 2012)

Scene Management. Video Game Technologies 11498: MSc in Computer Science and Engineering 11156: MSc in Game Design and Development

Anti-aliased and accelerated ray tracing. University of Texas at Austin CS384G - Computer Graphics

Lecture 25 of 41. Spatial Sorting: Binary Space Partitioning Quadtrees & Octrees

Point Cloud Filtering using Ray Casting by Eric Jensen 2012 The Basic Methodology

Ray Tracing Acceleration. CS 4620 Lecture 22

B-KD Trees for Hardware Accelerated Ray Tracing of Dynamic Scenes

Lesson 05. Mid Phase. Collision Detection

Geometric Structures 2. Quadtree, k-d stromy

Accelerating Ray Tracing

CS 465 Program 5: Ray II

Today. Acceleration Data Structures for Ray Tracing. Cool results from Assignment 2. Last Week: Questions? Schedule

Lecture 11 - GPU Ray Tracing (1)

Anti-aliased and accelerated ray tracing. University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell

Last Time: Acceleration Data Structures for Ray Tracing. Schedule. Today. Shadows & Light Sources. Shadows

TRaX programming examples

Ray Casting. To Do. Outline. Outline in Code. Foundations of Computer Graphics (Spring 2012) Heckbert s Business Card Ray Tracer

INFOMAGR Advanced Graphics. Jacco Bikker - February April Welcome!

Fast BVH Construction on GPUs

SAH guided spatial split partitioning for fast BVH construction. Per Ganestam and Michael Doggett Lund University

Universiteit Leiden Computer Science

Improving Memory Space Efficiency of Kd-tree for Real-time Ray Tracing Byeongjun Choi, Byungjoon Chang, Insung Ihm

Advanced Ray Tracing

CS 4620 Program 4: Ray II

Computer Graphics (CS 543) Lecture 13b Ray Tracing (Part 1) Prof Emmanuel Agu. Computer Science Dept. Worcester Polytechnic Institute (WPI)

Chapter 20: Binary Trees

Chapter 11 Global Illumination. Part 1 Ray Tracing. Reading: Angel s Interactive Computer Graphics (6 th ed.) Sections 11.1, 11.2, 11.

CS535 Fall Department of Computer Science Purdue University

Warped parallel nearest neighbor searches using kd-trees

Trees can be used to store entire records from a database, serving as an in-memory representation of the collection of records in a file.

Kinetic BV Hierarchies and Collision Detection

Lecture 11: Ray tracing (cont.)

Balanced Search Trees

Speeding Up Ray Tracing. Optimisations. Ray Tracing Acceleration

CS580: Ray Tracing. Sung-Eui Yoon ( 윤성의 ) Course URL:

l Without collision detection (CD), it is practically impossible to construct e.g., games, movie production tools (e.g., Avatar)

CS 6958 LECTURE 11 CACHES

Holger Dammertz August 10, The Edge Volume Heuristic Robust Triangle Subdivision for Improved BVH Performance Holger Dammertz, Alexander Keller

Computer Graphics. Bing-Yu Chen National Taiwan University

MSBVH: An Efficient Acceleration Data Structure for Ray Traced Motion Blur

Logistics. CS 586/480 Computer Graphics II. Questions from Last Week? Slide Credits

Bounding Volume Hierarchies

Ray Casting. 3D Rendering. Ray Casting. Ray Casting. Ray Casting. Ray Casting

Reading Ray Intersection Chapter 2: Geometry and Transformations Acceleration Covers basic math and PBRT implementation: read on your own

Acceleration. Digital Image Synthesis Yung-Yu Chuang 10/11/2007. with slides by Mario Costa Sousa, Gordon Stoll and Pat Hanrahan

Collision and Proximity Queries

Computer Graphics Ray Casting. Matthias Teschner

Transcription:

EDAN30 Photorealistic Computer Graphics Seminar 2, 2012 Bounding Volume Hierarchy Magnus Andersson, PhD student (magnusa@cs.lth.se)

This seminar We want to go from hundreds of triangles to thousands (or millions!) This assignment has few, but tricky, tasks.

Results List BVH 256x256 pixels, 3x3 samples 512x512 pixels, 5x5 samples 493 s 16.7 s

Elephants!

Overview Image 1 <<Raytracer>> 1 Scene 1 <<RayAccelerator>> * <<Node>> 1 * Camera PointLight <<Primitive>> <<Intersectable>> 1 <<Material>> Triangle * Mesh Sphere

Overview Yuck! Image 1 <<Raytracer>> 1 Scene 1 ListAccelerator * <<Node>> 1 * Camera PointLight <<Primitive>> <<Intersectable>> 1 <<Material>> Triangle * Mesh Sphere

Overview Image 1 <<Raytracer>> 1 Scene 1 BVH * <<Node>> 1 * Camera PointLight <<Primitive>> <<Intersectable>> 1 <<Material>> Triangle * Mesh Sphere

kd-tree vs. BVH vs. BIH vs. OcTree vs. Uniform Grid vs.... What acceleration structure should you choose??

kd-tree vs. BVH vs. BIH vs. OcTree vs. Uniform Grid vs.... What acceleration structure should you choose?? Still an area of active research. It varies what s in fashion

kd-tree vs. BVH vs. BIH vs. OcTree vs. Uniform Grid vs.... What acceleration structure should you choose?? Still an area of active research. It varies what s in fashion Short answer = It depends on your application Ray tracing (primary rays only?, GI?, ) Collision detection? Animated? Memory/speed tradeoffs Scene dependent Implementation dependent

kd-tree vs. BVH vs. BIH vs. OcTree vs. Uniform Grid vs.... What acceleration structure should you choose?? Still an area of active research. It varies what s in fashion Short answer = It depends on your application You ll find yourself playing around with different alternatives before settling on a suitable structure

kd-tree vs. BVH kd-tree (50s) Implementation from assignments two years ago. BVH (49s) This year s reference implementation. (Only tested on this Elephant scene)

kd-tree vs. BVH kd-tree (50s) Implementation from assignments two years ago. BVH (49s) This year s reference implementation. + The BVH will be useful for other purposes in a later lab

Assignment 2 Construction Intersection Surface Area Heuristic (Optional) Further Optimizations (Optional)

Assignment 2 Construction Intersection Surface Area Heuristic (Optional) Further Optimizations (Optional)

Construction You will need to create a new class BVHAccelerator which inherits from <<RayAccelerator>> For this assignment you must implement void build(const std::vector<intersectable *> &objects); and you will probably need something like void build_recursive(int left_index, int right_index, AABB box, BVHNode *node, int depth);

Construction, brief overview We begin with a bunch of Intersectables

Construction, brief overview Find bounding box centroids of all intersectables

Construction, brief overview Find the world bounding box and create a root node

Construction, brief overview Use some splitting criteria to find a sensible division of the elements into new child nodes

Construction, brief overview Continue to split recursively until each node contains only one or a few elements

Construction, brief overview Now, when shooting rays we don t have to test all Intersectables anymore!

Construction So what is a sensible splitting criteria? Why not use mid-point splitting, since it s easy to understand and implement Works well when primitives are fairly evenly distributed

Construction So what is a sensible splitting criteria? Why not use mid-point splitting, since it s easy to understand and implement Works well when primitives are fairly evenly distributed You can try to come up with a different criteria if you want to I tried splitting on the mean and median. Both were outperformed by mid-point splitting

Construction Find the mid point of the largest axis

Construction Sort the bounding box centroids in the largest axis direction. Then split into a left and a right side

Construction Lather, rinse and repeat. Terminate when a node contains few intersectables (I used 4, which worked well)

Construction There is a hazard in getting all intersectables on one side we could end up with empty nodes!

Construction If this happens, you can, for example revert to median or mean splitting (median split is depicted above)

Construction Now that you know the general concepts of a BVH, we will discuss in-depth how we keep track of our nodes and intersectables throughout the contruction process.

Node class BVH node class (inner class of BVHAccelerator) class BVHNode { private: AABB bbox; bool leaf; unsigned int n_objs; unsigned int index; // if leaf == false: index to left child node, // else if leaf == true: index to first Intersectable in Objs vector public: void setaabb(aabb &bbox_) { } void makeleaf(unsigned int index_, unsigned int n_objs_) {...} void makenode(unsigned int left_index_, unsigned int n_objs) {...} // n_objs in makenode is for debug purposes only, and may be omitted later on }; bool isleaf() { return leaf; } unsigned int getindex() { return index; } unsigned int getnobjs() { return n_objs; } AABB &getaabb() { return bbox; };

Construction Incoming intersectables objects Copy to BVH Intersectable list Objs In the build()-function we get a list of unsorted Intersectable pointers, which we copy to a local vector. At the same time we calculate the world bounding box.

Construction NodeList BVH Intersectable list Objs Set up a NodeList vector, which will hold our nodes. (We also happen to know that the number of nodes needed will be at most 2n 1 nodes, if the leaf nodes contain 1 element each).

Construction n_nodes NodeList root Objs left_index Set left_index = 0, right_index = Objs.size() and n_nodes = 1. Set the world bounding box to the root node using BVHNode::setAABB(box). Then start building recursively. right_index

Construction n_nodes NodeList node Objs left_index First, check if the number of intersectables is fewer than the threshold (let s say 2 in this case). It isn t. right_index

Construction n_nodes NodeList node This is now sorted! Objs left_index Find largest dimension d and sort the elements in that dimension. right_index

Construction n_nodes NodeList node split_index Objs left_index Find the split_index, where the mid point divides the primitives in a left and right side right_index

Construction n_nodes NodeList node split_index Objs left_index Find the split_index, where the mid point divides the primitives in a left and right side right_index

Construction n_nodes NodeList node split_index Objs left_index Find the split_index, where the mid point divides the primitives in a left and right side right_index

Construction n_nodes NodeList node split_index Objs left_index Find the split_index, where the mid point divides the primitives in a left and right side right_index

Construction n_nodes NodeList node Success! split_index Objs left_index Find the split_index, where the mid point divides the primitives in a left and right side right_index

Construction n_nodes NodeList node Success! split_index Objs (We could have used binary search) left_index right_index

Construction n_nodes NodeList left node right split_index Objs left_index right_index Allocate two new nodes (left and right) from the NodeList. The left node will have index n_nodes and the right one n_nodes + 1.

Construction n_nodes NodeList left node right split_index Objs left_index Initiate node (which is currently the root node) with BVHNode::makeNode(n_nodes). (The index to the right node is always n_nodes + 1) right_index

Construction n_nodes NodeList node left right split_index Objs left_index Calculate the bounding boxes for left and right and assign them to the two newly created nodes right_index

Construction n_nodes NodeList node left right split_index Objs left_index Call the build_recursive()-function for the left and then the right node. right_index

Construction n_nodes NodeList left node right split_index Objs left_index right_index Be sure to pass the correct Objs-vector indices to the left and right nodes. The left node is now responsible for [left_index, split_index) and the right node for [split_index, right_index).

Construction n_nodes NodeList node (Sorted) Objs left_index right_index Processing of the left node yields the following result

Construction n_nodes NodeList left node right split_index Objs left_index right_index

Construction n_nodes NodeList left node right Objs left_index right_index

Construction n_nodes NodeList node Objs left_index right_index Finally we have only 2 primitives in the node: (right_index left_index <= 2)

Construction n_nodes NodeList node Objs left_index right_index We initiate the current node as a leaf using void BVHNode::makeLeaf(left_index, right_index left_index);

Construction n_nodes NodeList Objs This is what we end up with when we re done.

Construction, Pseudo code Setup void build(const std::vector<intersectable *> &objects) Create new vector for Intersectable pointer copies Create new vector for the nodes Create Root node worldbox = AABB(); // world bounding box For each intersectable[i] in objects worldbox.include(intersectable[i] bounding box) Objs.push_back(intersectable[i]) EndFor Set world bounding box to root node build_recursive(0, Objs.size(), root, 0); The declaration was: void build_recursive(int left_index, int right_index, BVHNode *node, int depth);

Construction, Pseudo code Recursion void build_recursive(int left_index, int right_index, BVHNode *node, int depth) If ((right_index left_index) <= Threshold (other termination criteria)) Initiate current node as a leaf with primitives from Objs[left_index] to Objs[right_index] Else Split intersectables into left and right by finding a split_index Make sure that neither left nor right is completely empty Calculate bounding boxes of left and right sides Create two new nodes, leftnode and rightnode and assign bounding boxes Initiate current node as an interior node with leftnode and rightnode as children build_recursive(left_index, split_index, leftnode, depth + 1) build_recursive(split_index, right_index, rightnode, depth + 1) EndIf

Construction Sorting in C++ This is what I did at least #include <algorithm> // ComparePrimitives cmp; cmp.sort_dim = 0; // x = 0, y = 1, z = 2 std::sort(objs.begin() + from_index, objs.begin() + to_index, cmp); ComparePrimitives??

Construction Sorting in C++ class ComparePrimitives { public: bool operator() (Intersectable *a, Intersectable *b) { AABB box; a->getaabb(box); float ca = (box.mmax(sort_dim) + box.mmin(sort_dim)) * 0.5f; b->getaabb(box); float cb = (box.mmax(sort_dim) + box.mmin(sort_dim)) * 0.5f; return ca < cb; } }; int sort_dim;

Debug Scenes Test scenes used to verify your implementation Non-scrambled positions Scrambled positions

Debug Scenes Node<Primitives: 80> Node<Primitives: 40> Node<Primitives: 20> Node<Primitives: 10> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 0> Leaf<Primitives: 2, First primitive: 3> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 5> Leaf<Primitives: 2, First primitive: 8> Node<Primitives: 10> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 10> Leaf<Primitives: 2, First primitive: 13> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 15> Leaf<Primitives: 2, First primitive: 18> Node<Primitives: 20> Node<Primitives: 10> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 20> Leaf<Primitives: 2, First primitive: 23> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 25> Leaf<Primitives: 2, First primitive: 28> Node<Primitives: 10> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 30> Leaf<Primitives: 2, First primitive: 33> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 35> Leaf<Primitives: 2, First primitive: 38> Node<Primitives: 40> Node<Primitives: 20> Node<Primitives: 10> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 40> Leaf<Primitives: 2, First primitive: 43> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 45> Leaf<Primitives: 2, First primitive: 48> Node<Primitives: 10> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 50> Leaf<Primitives: 2, First primitive: 53> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 55> Leaf<Primitives: 2, First primitive: 58> Node<Primitives: 20> Node<Primitives: 10> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 60> Leaf<Primitives: 2, First primitive: 63> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 65> Leaf<Primitives: 2, First primitive: 68> Node<Primitives: 10> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 70> Leaf<Primitives: 2, First primitive: 73> Node<Primitives: 5> Leaf<Primitives: 3, First primitive: 75> Leaf<Primitives: 2, First primitive: 78>

Debug Scenes Node<Primitives: 80> Node<Primitives: 40> Node<Primitives: 21> Node<Primitives: 8> Leaf<Primitives: 4, First primitive: 0> Leaf<Primitives: 4, First primitive: 4> Node<Primitives: 13> Node<Primitives: 7> Leaf<Primitives: 4, First primitive: 8> Leaf<Primitives: 3, First primitive: 12> Node<Primitives: 6> Leaf<Primitives: 3, First primitive: 15> Leaf<Primitives: 3, First primitive: 18> Node<Primitives: 19> Node<Primitives: 7> Leaf<Primitives: 4, First primitive: 21> Leaf<Primitives: 3, First primitive: 25> Node<Primitives: 12> Node<Primitives: 6> Leaf<Primitives: 3, First primitive: 28> Leaf<Primitives: 3, First primitive: 31> Node<Primitives: 6> Leaf<Primitives: 3, First primitive: 34> Leaf<Primitives: 3, First primitive: 37> Node<Primitives: 40> Node<Primitives: 19> Node<Primitives: 6> Leaf<Primitives: 3, First primitive: 40> Leaf<Primitives: 3, First primitive: 43> Node<Primitives: 13> Node<Primitives: 6> Leaf<Primitives: 4, First primitive: 46> Leaf<Primitives: 2, First primitive: 50> Node<Primitives: 7> Leaf<Primitives: 4, First primitive: 52> Leaf<Primitives: 3, First primitive: 56> Node<Primitives: 21> Node<Primitives: 6> Leaf<Primitives: 3, First primitive: 59> Leaf<Primitives: 3, First primitive: 62> Node<Primitives: 15> Node<Primitives: 8> Leaf<Primitives: 4, First primitive: 65> Leaf<Primitives: 4, First primitive: 69> Node<Primitives: 7> Leaf<Primitives: 4, First primitive: 73> Leaf<Primitives: 3, First primitive: 77>

Assignment 2 Construction Intersection Surface Area Heuristic (Optional) Further Optimizations (Optional)

Intersection For this assignment you must implement Boolean test bool BVHAccelerator::intersect(const Ray& ray); Closest hit bool BVHAccelerator::intersect(const Ray& ray, Intersection& is); The two functions are very similar. If you have one of them, you can easily implement the other.

Closest hit Node Stack Closest-Hit Intersection Find closest intersection point

Closest hit Node Stack Closest-Hit Intersection World Bounding Box t max t min First check if we even hit the world bounding box. bool AABB::intersect(const Ray& r, float& tmin, float& tmax) const;

Closest hit Node Stack Closest-Hit Intersection Left Right t max t min Check the two children for intersection (again using AABB::intersect( )). In this case, both boxes were hit.

Closest hit Node Stack Closest-Hit Intersection Left Right t max t right0 t right0 t min t left0 Put the node furthest away on the stack along with it s hit parameter t. Traverse the closest node

Closest hit Node Stack Closest-Hit Intersection Left Right t max t right0 t min This time we only hit one node, which happens to be a leaf node

Closest hit Node Stack Closest-Hit Intersection t max t right0 t min Intersection test with each primitive in the leaf. bool Intersectable::intersect(const Ray& ray, Intersection& is) const;

Closest hit Node Stack Closest-Hit Intersection t right0 t min t max Store intersection and shorten ray.

Closest hit Node Stack Closest-Hit Intersection t right0 t min t max Pop the stack and recursively intersection test with the node.

Closest hit Node Stack Closest-Hit Intersection t right0 t min t max Optimization We can trivially reject the pop d node since its t-value is now further away than t max of the ray.

Closest hit Node Stack Closest-Hit Intersection t min t max Try to pop the stack again to fetch the next node but now it s empty, which means we re done!

Closest hit Node Stack Closest-Hit Intersection t min t max We found the closest hit with little effort!

Closest hit Node Stack No Intersection If there is no intersection, the Closest hit will of course be empty return false

Closest-Hit Intersection, Pseudo code LocalRay = Ray, CurrentNode = Root Check LocalRay intersection with Root (world box) No hit => return false For (infinity) If (NOT CurrentNode.isLeaf()) Intersection test with both child nodes Both nodes hit => Put the one furthest away on the stack. CurrentNode = closest node» continue Only one node hit => CurrentNode = hit node» continue No Hit: Do nothing (let the stack-popping code below be reached) Else // Is leaf For each primitive in leaf perform intersection testing Intersected => update LocalRay.maxT and store ClosestHit EndIf Pop stack until you find a node with t < LocalRay.maxT => CurrentNode = pop d Stack is empty? => return ClosestHit (no closest hit => return false, otherwise return true EndFor

Intersection Stack element struct StackItem { BVHNode *ptr; float t; }; Use either a C-style vector or C++ Stack class StackItem stack[max_stack_depth]; Stack<StackItem> stack;

Boolean Intersection, Pseudo code LocalRay = Ray, CurrentNode = Root Check LocalRay intersection with Root (world box) No hit => return false For (infinity) If (NOT CurrentNode.isLeaf()) Intersection test with both child nodes Both nodes hit => Put right one on the stack. CurrentNode = left node» Goto LOOP; Only one node hit => CurrentNode = hit node» Goto LOOP; No Hit: Do nothing (let the stack-popping code below be reached) Else // Is leaf For each primitive in leaf perform intersection testing Intersected => return true; EndIf Pop stack, CurrentNode = pop d node Stack is empty => return false EndFor

Debug Scenes Make these scenes work first Non-scrambled positions Scrambled positions

Intersection Elephants, without and with shadows Without shadows With shadows

Assignment 2 Construction Intersection Surface Area Heuristic (Optional) Further Optimizations (Optional)

Surface Area Heuristic c = estimated cost of traversing p and its children (l, r) c t = ~cost of performing one traversal iteration c i = ~cost of performing one intersection test n l, r = number of elements in child node S(B l, r ) = surface area of child node S(B p ) = surface area of parent node

Surface Area Heuristic Continue to split if c = estimated cost of traversing p and its children (l, r) c i = ~cost of performing one intersection test n p = number of elements in parent node We stop splitting and create a leaf when it s cheaper to intersect all the Intersectables, than to split the node further.

2x Surface Area Heuristic Parent SA 2x The parent surface area is passed by previous recursion iteration.

Surface Area Heuristic Parent SA For each axis. Begin by sorting elements. Then calculate cost c of each potential split

Surface Area Heuristic n l = 1 n r = 7 S(B Left SA l ) = S(B r ) = Right SA S(B p ) = Parent SA For each axis. Begin by sorting elements. Then calculate cost c of each potential split

Surface Area Heuristic n l = 2 n r = 6 S(B Left SA l ) = S(B r ) = Right SA S(B p ) = Parent SA For each axis. Begin by sorting elements. Then calculate cost c of each potential split

Surface Area Heuristic n l = 3 n r = 5 S(B Left SA l ) = S(B r ) = Right SA S(B p ) = Parent SA For each axis. Begin by sorting elements. Then calculate cost c of each potential split

Surface Area Heuristic n l = 4 n r = 4 S(B Left SA l ) = S(B r ) = Right SA S(B p ) = Parent SA For each axis. Begin by sorting elements. Then calculate cost c of each potential split

Surface Area Heuristic n l = 5 n r = 3 S(B Left SA l ) = S(B r ) = Right SA S(B p ) = Parent SA For each axis. Begin by sorting elements. Then calculate cost c of each potential split

Surface Area Heuristic And so on n l = 5 n r = 3 S(B Left SA l ) = S(B r ) = Right SA S(B p ) = Parent SA For each axis. Begin by sorting elements. Then calculate cost c of each potential split

Surface Area Heuristic Keep the best split (lowest c) over all three axes. Continue splitting for as long as it pays off ( )

Surface Area Heuristic Can be slow for large scenes... Optimize: Binned sorting Try only a few split planes Try selectively enabling/disabling SAH calculation at different levels Etc, etc...

Results Mid-point split SAH 512x512 pixels, 3x3 samples 512x512 pixels, 3x3 samples 60 s 49 s

Assignment 2 Construction Intersection Surface Area Heuristic (Optional) Further Optimizations (Optional)

Further Optimizations (Optional) Take a look inside bool AABB::intersect(const Ray &r, float &tmin, float &tmax) const; There is one expensive computation that can be pre-computed Loop unrolling may help slightly... The BVHNode class takes 36 bytes (if your implementation matches mine). This can be reduced (and more nicely aligned) Make sure that your <<Intersectable>>-intersection functions are optimized Avoid recursion and pay careful attention to inner loops be creative! (and/or use Google BVH Construction ;) There are other hard-core optimizations as well which are beyond the scope of this course..

Further Optimizations (Optional) Typical work distribution for a BVH

That is all. The second assignment is out now! As usual, we ll be active on the forum, so be sure to check in if you have any comments or questions!

Fin