|
Post by inventordave on Apr 9, 2020 0:59:47 GMT
Hi. I am implementing the bounding box algorithm. On page 202, where it describes a bounds(group) function, it says the following:
"...to convert a point from object space to it's parent space, multiply the point by the object's transformation matrix."
I'm not following. Do I multiply the point of a corner of a Shape 's BB by the same Shape 's transformation matrix? Won't that convert the point to World space rather than the "parent" (Group) space?
Help me out here.
|
|
fremag
Junior Member
Posts: 73
|
Post by fremag on Apr 11, 2020 9:21:16 GMT
Hi, The book doesn't give a lot of details about this so I think you'd better go directly to this bonus chapter: www.raytracerchallenge.com/bonus/bounding-boxes.htmlThere are more details, tests and the last section about BVH is very good to optimize your program.
|
|
|
Post by inventordave on Apr 26, 2020 20:24:47 GMT
I am currently working through the bonus chapter on bounding boxes. For the test Scenario: A group has a bounding box that contains its children I am almost getting the correct result. Here are the results I'm getting:
b.max = tuple {x: 4, y: 7, z: -1, w: 1} b.min = tuple {x: -4.5, y: -3, z: -5, w: 1}
As you can see, it is only out on the .max z-component. It should be 4.5, not -1. I haven't refactored my code yet, so I won't upload it to my github for perusal (EDIT: See later post for the link and description), but I have sensibly and correctly implemented according to the instructions, and so far every test I've needed to pass, I've passed. The odd thing is, it's only the z-component on 1 of the points. Specifically I can tell you the transform(bounding_box, matrix) function is not in error - I essentially cut-and-pasted the pseudo-code. Here is my bounding_box.addBB() (add bounding box) function:
BB.addBB = function(b) { this.min=point(window.min(this.min.x,b.min.x), window.min(this.min.y,b.min.y), window.min(this.min.z,b.min.z)) this.max=point(window.max(this.max.x,b.max.x), window.max(this.max.y,b.max.y), window.max(this.max.z,b.max.z)) };
And here are my min() and max() functions:
function max() { var val = -Infinity; for (var a = 0; a < arguments.length; a++) if (arguments[a] > val) val = arguments[a] return val }
function min() { var val = Infinity; for (var a = 0; a < arguments.length; a++) if (arguments[a] < val) val = arguments[a] return val }
Clearly, it is implemented in Javascript. Any input would be appreciated!
Just to be sure, here is my bounding_box.transform() function:
BB.transform = function(m) { var p = [] p.push(this.min) p.push(point(this.min.x, this.min.y, this.max.z)) p.push(point(this.min.x, this.max.y, this.min.z)) p.push(point(this.min.x, this.max.y, this.max.z)) p.push(point(this.max.x, this.min.y, this.min.z)) p.push(point(this.max.x, this.min.y, this.max.z)) p.push(point(this.max.x, this.max.y, this.min.z)) p.push(this.max) var new_bbox = new BB(), res
for (var i = 0; i < 8 /* p.length */; i++) { res = multiply_matrix_by_tuple(m,p[i]) new_bbox.addP(res) }
return new_bbox };
|
|
|
Post by inventordave on Apr 27, 2020 9:20:20 GMT
Update: I replaced my min() and max() calls for the built-in Math.min() and Math.max(), made no difference.
|
|
|
Post by inventordave on Apr 27, 2020 9:37:41 GMT
I have relented and uploaded my current codebase onto GitHub. It can be found here: github.com/leeodea/rt-dtPlease note, the vast majority of what you are looking for is in the file "rt.p+e.js" (which stands for projectile+environment). It is where the implementation of my Shapes and Groups is. Also, "rt.tests.js" has 2 tests as it's last 2 functions. The last one, bb_test_1() is the test we are currently discussing. (Note, many older tests are now broken - it doesn't matter). Load "raytracer.html" into your browser, open up the console, and type bb_test_1() to run the test. The debugger will kick in, and you can peek at box.min and box.max . My codebase is not at all refactored, so sorry about that, but it is written/formatted for readability. (Final note: Don't load object file "FinalBaseMesh.obj" and then click "render obj!", it takes hours.)
|
|
fremag
Junior Member
Posts: 73
|
Post by fremag on Apr 27, 2020 13:21:36 GMT
Hi,
In BB.addP function:
if(p.x<this.min.z) this.min.z=p.z else if(p.z>this.max.z) this.max.z=p.z
You should check:
if(p.z<this.min.z)
Sometimes, copy/paste is your best ennemy when you code
|
|
|
Post by inventordave on Apr 27, 2020 15:43:23 GMT
Awesome, thanks bro! Test passing. Now onto implementing BVH, see if I can get the preview render time down from 6-odd hours.
|
|
|
Post by inventordave on Apr 27, 2020 20:23:02 GMT
Lol. With my BVH optimisation implemented, my 150x84 rendering of a scene containing a mesh object of ~50k triangles has gone from 6.something hours to 165.4 SECONDS, less than 3 mins. I used a threshold of 1000. Insane. (I also cached the inverse(transform) calculations.)
|
|
fremag
Junior Member
Posts: 73
|
Post by fremag on Apr 29, 2020 9:44:16 GMT
Good job ! Now I think you can improve the ray transform function: function transform(r_in, m) { // p69
//var r = copyObj(r_in); var r = JSON.parse(JSON.stringify(r_in))
var res = multiply_matrix_by_tuple(m, r.origin); var res2 = multiply_matrix_by_tuple(m, r.direction);
r.origin = res; r.direction = res2;
return r; } Why do you use Json here ? Just to create a copy of r_in ?
What do you think of this instead:
var res = multiply_matrix_by_tuple(m, r_in.origin); var res2 = multiply_matrix_by_tuple(m, r_in.direction); var r = new ray(res, res2); return r;
|
|
|
Post by inventordave on May 2, 2020 9:20:23 GMT
No longer noticing post update emails in my inbox....
Thanks for the observation! I'm updating the code now. Bit of an odd thing for me to do, tbh...
|
|