{"id":5530,"date":"2021-10-05T16:30:19","date_gmt":"2021-10-05T22:30:19","guid":{"rendered":"http:\/\/www.realtimerendering.com\/blog\/?p=5530"},"modified":"2021-10-05T16:34:07","modified_gmt":"2021-10-05T22:34:07","slug":"back-of-the-business-card-ray-tracers","status":"publish","type":"post","link":"https:\/\/www.realtimerendering.com\/blog\/back-of-the-business-card-ray-tracers\/","title":{"rendered":"Back of the Business Card Ray Tracers"},"content":{"rendered":"\n<p>Basic ray tracing is a simple algorithm. As sometimes given as proof, there are two business card ray tracers I know of: Paul Heckbert&#8217;s and Andrew Kensler&#8217;s. You can see Andrew&#8217;s explanation <a href=\"http:\/\/eastfarthing.com\/blog\/2016-01-12-card\/\" data-type=\"URL\" data-id=\"http:\/\/eastfarthing.com\/blog\/2016-01-12-card\/\">here<\/a> (as well as links to ports), the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Leet\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Leet\">leet<\/a> code <a href=\"https:\/\/gist.github.com\/sungiant\/9524044\" data-type=\"URL\" data-id=\"https:\/\/gist.github.com\/sungiant\/9524044\">here<\/a>, and an involved revisit and optimization and CUDA-ization of this code by Fabien Sanglard <a href=\"https:\/\/fabiensanglard.net\/revisiting_the_businesscard_raytracer\/index.html\" data-type=\"URL\" data-id=\"https:\/\/fabiensanglard.net\/revisiting_the_businesscard_raytracer\/index.html\">here<\/a>.<\/p>\n\n\n\n<p>Andrew&#8217;s dates from somewhere <a href=\"https:\/\/www.linkedin.com\/in\/andrew-kensler\/\" data-type=\"URL\" data-id=\"https:\/\/www.linkedin.com\/in\/andrew-kensler\/\">during 2005-2009<\/a>, when he was avoiding writing his thesis. Paul&#8217;s dates from 1987, including tricks he learned from Darwyn Peachey and Joe Cychosz. His links are <a href=\"http:\/\/www.cs.cmu.edu\/~ph\/\" data-type=\"URL\" data-id=\"http:\/\/www.cs.cmu.edu\/~ph\/\">here<\/a>, the code&#8217;s <a href=\"http:\/\/www.cs.cmu.edu\/~ph\/src\/minray\/minray.card.c\">here<\/a> and unminimized <a href=\"http:\/\/www.realtimerendering.com\/resources\/GraphicsGems\/gemsiv\/minray\/\">here<\/a>, and the whole thing is written up in <em>Graphics Gems IV<\/em>. Which I wish was free on the (legal) web at this point&#8230; But through the miracle of Google Books, you can find most of the article <a href=\"https:\/\/books.google.com\/books?id=brDfBAAAQBAJ&amp;pg=PA375&amp;lpg=PA375&amp;dq=paul+heckbert+%22minimal+ray+tracer+programming+contest%22&amp;source=bl&amp;ots=7_V4oY8inO&amp;sig=ACfU3U0v18mO5gM-GZB5uu3H6q9StMPBMg&amp;hl=en&amp;sa=X&amp;ved=2ahUKEwiJhobwp7TzAhUNTt8KHdgWCNcQ6AF6BAgCEAM#v=onepage&amp;q=paul%20heckbert%20%22minimal%20ray%20tracer%20programming%20contest%22&amp;f=false\" data-type=\"URL\" data-id=\"https:\/\/books.google.com\/books?id=brDfBAAAQBAJ&amp;pg=PA375&amp;lpg=PA375&amp;dq=paul+heckbert+%22minimal+ray+tracer+programming+contest%22&amp;source=bl&amp;ots=7_V4oY8inO&amp;sig=ACfU3U0v18mO5gM-GZB5uu3H6q9StMPBMg&amp;hl=en&amp;sa=X&amp;ved=2ahUKEwiJhobwp7TzAhUNTt8KHdgWCNcQ6AF6BAgCEAM#v=onepage&amp;q=paul%20heckbert%20%22minimal%20ray%20tracer%20programming%20contest%22&amp;f=false\">here<\/a> and missing page 379 (just the code listing) <a href=\"https:\/\/books.google.com\/books?id=CCqzMm_-WucC&amp;pg=PA375&amp;lpg=PA375&amp;dq=paul+heckbert+%22minimal+ray+tracer+programming+contest%22&amp;source=bl&amp;ots=mvit18HKgk&amp;sig=ACfU3U0DkBGo6Y-KX64CLLCBbKb7O6X8fA&amp;hl=en&amp;sa=X&amp;ved=2ahUKEwiJhobwp7TzAhUNTt8KHdgWCNcQ6AF6BAgDEAM#v=onepage&amp;q=paul%20heckbert%20%22minimal%20ray%20tracer%20programming%20contest%22&amp;f=false\" data-type=\"URL\" data-id=\"https:\/\/books.google.com\/books?id=CCqzMm_-WucC&amp;pg=PA375&amp;lpg=PA375&amp;dq=paul+heckbert+%22minimal+ray+tracer+programming+contest%22&amp;source=bl&amp;ots=mvit18HKgk&amp;sig=ACfU3U0DkBGo6Y-KX64CLLCBbKb7O6X8fA&amp;hl=en&amp;sa=X&amp;ved=2ahUKEwiJhobwp7TzAhUNTt8KHdgWCNcQ6AF6BAgDEAM#v=onepage&amp;q=paul%20heckbert%20%22minimal%20ray%20tracer%20programming%20contest%22&amp;f=false\">here<\/a>.<\/p>\n\n\n\n<p>Yesterday I realized I likely had never seen the output of Paul&#8217;s ray tracer. I installed Ghostscript to look at his file, but it was pretty beat:<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/mail.google.com\/mail\/u\/0?ui=2&amp;ik=e4696b2a5e&amp;attid=0.1&amp;permmsgid=msg-a:r-4119042144581684991&amp;th=17c4cb1f356058d9&amp;view=fimg&amp;sz=s0-l75-ft&amp;attbid=ANGjdJ_EMYKv2fkXPybqQvRl201cNmUCduHHTG1yAKAy_fkwPc5WR6sUwAQDtTD1GqxYoQn5nwFHyQBHeKhm-M3-tzIY3_XN3E56Iq1PLbjcTBNyxdWBYCS2uObggxQ&amp;disp=emb&amp;realattid=17c4cb04824cb971f161\" alt=\"\"\/><figcaption>Yeah, definitely ray tracing, or something<\/figcaption><\/figure>\n\n\n\n<p>So I compiled Paul&#8217;s minimized code, finding a few small syntax errors that VS 2019 didn&#8217;t like so much. Adding a PPM header to the image file dumped, it&#8217;s this:<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"516\" height=\"516\" src=\"http:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image.png\" alt=\"\" class=\"wp-image-5531\" srcset=\"https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image.png 516w, https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-300x300.png 300w, https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-150x150.png 150w\" sizes=\"auto, (max-width: 516px) 100vw, 516px\" \/><\/a><figcaption>32 x 32<\/figcaption><\/figure>\n\n\n\n<p>So, better, I can see spheres. I upped the resolution &#8211; it took a whole 10 seconds to run on a single CPU:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"http:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-1-1024x1024.png\" alt=\"\" class=\"wp-image-5532\" srcset=\"https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-1.png 1024w, https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-1-300x300.png 300w, https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-1-150x150.png 150w, https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-1-768x768.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>1024 x 1024<\/figcaption><\/figure>\n\n\n\n<p>Not stunning, but now I know!<br><br>And today I ran across <a href=\"https:\/\/my.eng.utah.edu\/~cs6965\/slides\/Introductionx2.pdf\">a set of lecture slides<\/a> from the University of Utah which shows both of these business-card ray tracers&#8217; results, page 22 on. Oddly, the image shown there has different colors &#8211; maybe gamma correction or something?<\/p>\n\n\n\n<p>Anyway, now you can say you&#8217;ve seen it, too. And here&#8217;s the back of my copy of Paul&#8217;s business card, in the flesh, as it were:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"803\" height=\"448\" src=\"http:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-2.png\" alt=\"\" class=\"wp-image-5533\" srcset=\"https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-2.png 803w, https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-2-300x167.png 300w, https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-2-768x428.png 768w, https:\/\/www.realtimerendering.com\/blog\/wp-content\/uploads\/2021\/10\/image-2-500x279.png 500w\" sizes=\"auto, (max-width: 803px) 100vw, 803px\" \/><\/a><\/figure>\n\n\n\n<p>Me, I was thrilled that 34-year-old code basically still ran, with minimal messing about.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Basic ray tracing is a simple algorithm. As sometimes given as proof, there are two business card ray tracers I know of: Paul Heckbert&#8217;s and Andrew Kensler&#8217;s. You can see Andrew&#8217;s explanation here (as well as links to ports), the leet code here, and an involved revisit and optimization and CUDA-ization of this code by [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[642,55],"class_list":["post-5530","post","type-post","status-publish","format-standard","hentry","category-misc","tag-business-card","tag-ray-tracing"],"_links":{"self":[{"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/posts\/5530","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/comments?post=5530"}],"version-history":[{"count":3,"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/posts\/5530\/revisions"}],"predecessor-version":[{"id":5536,"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/posts\/5530\/revisions\/5536"}],"wp:attachment":[{"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/media?parent=5530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/categories?post=5530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.realtimerendering.com\/blog\/wp-json\/wp\/v2\/tags?post=5530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}