TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Writing a small ray tracer in Rust and Zig

260 pointsby cyber1almost 6 years ago

9 comments

skrebbelalmost 6 years ago
This is an awesome post.<p>At the risk of shedding it to bikes, one point that the author makes is that Zig&#x27;s lack of operator overloading makes him write vector math like this:<p><pre><code> if (discriminant &gt; 0.0) { &#x2F;&#x2F; I stared at this monster for a while to ensure I got it right return uv.sub(n.mul(dt)).mul(ni_over_nt).sub(n.mul(math.sqrt(discriminant))); } </code></pre> He signs off with:<p>&gt; <i>How do C programmers manage?</i><p>The answer is simple: we assign names to intermediate results. Now, I have absolutely no idea what that expression computes, because I suck at graphics programming and math in general. Please pretend that these are proper mathy terms:<p><pre><code> if (discriminant &gt; 0.0) { const banana = uv.sub(n.mul(dt)) const apple = banana.mul(ni_over_nt) const pear = n.mul(math.sqrt(discriminant) return apple.sub(pear) } </code></pre> I&#x27;m convinced that there&#x27;s a proper mathy&#x2F;lighting-y word for each component in that expression. Of course this approach totally breaks down if you&#x27;re copying expressions from papers or articles without understanding why they are correct (which is how I do all my graphics programming). I do find that naming variables is often a great way to force myself to grok what&#x27;s going on.
评论 #20335442 未加载
评论 #20333289 未加载
评论 #20333448 未加载
评论 #20333359 未加载
评论 #20336676 未加载
评论 #20333762 未加载
oconnor663almost 6 years ago
&gt; But rendering in separate threads turned out to be (unsurprisingly) harder than the way I would do it in C++...It was a bit frustrating to figure out how to accomplish this. Googling yielded a few stack overflow posts with similar questions, and were answered by people basically saying use my crate!<p>Based on some discussion in r&#x2F;rust (<a href="https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;c7t5za&#x2F;writing_a_small_ray_tracer_in_rust_and_zig&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;c7t5za&#x2F;writing_a_smal...</a>) I went ahead and added a Rayon-based answer to that SO question (<a href="https:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;56840441&#x2F;823869" rel="nofollow">https:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;56840441&#x2F;823869</a>). That&#x27;s been the de facto standard for data parallelism in Rust for the last few years. But the article highlights that discovering the de facto standards is still a challenge for new Rust users -- does anyone know of a well-maintained list of the 10-20 most critical crates that new users should familiarize themselves with after reading The Book? Things like Rayon and lazy_static. The ranked search results at <a href="https:&#x2F;&#x2F;crates.io&#x2F;crates?sort=recent-downloads" rel="nofollow">https:&#x2F;&#x2F;crates.io&#x2F;crates?sort=recent-downloads</a> are <i>almost</i> good enough, but they include a lot of transitive dependencies that new users shouldn&#x27;t care about. (I.e. `regex` is a very important crate, but `aho-corasick` is usually only downloaded as a dependency of `regex`.)
评论 #20333472 未加载
评论 #20328848 未加载
评论 #20332837 未加载
评论 #20333547 未加载
评论 #20335349 未加载
forrestthewoodsalmost 6 years ago
What a delightful post. Author wrote a very nice description of things they learned from a little weekend project. No preaching or ranting or opinionating. Just “I did a thing and here’s what I learned”. That’s easily my favorite type of blog post.<p>Thanks for sharing! ️
tntnalmost 6 years ago
&gt; I wrapped my objects in atomic reference counters, and wrapped my pixel buffer in a mutex<p>Rust people, is there a way to tell the compiler that each thread gets its own elements? Do you really have to either (unnecessarily) add a lock or reach for unsafe?
评论 #20332546 未加载
评论 #20332521 未加载
评论 #20332540 未加载
评论 #20332533 未加载
评论 #20332530 未加载
评论 #20332504 未加载
jorangreefalmost 6 years ago
Zig is worth supporting on Patreon: <a href="https:&#x2F;&#x2F;www.patreon.com&#x2F;andrewrk" rel="nofollow">https:&#x2F;&#x2F;www.patreon.com&#x2F;andrewrk</a>
mrecalmost 6 years ago
I didn&#x27;t quite grok this bit:<p>&gt; <i>The ability to return values from if expressions and blocks is awesome and I don’t know how I’ve managed to live up until now without it. Instead of conditionally assigning to a bunch of variables it is better to return them from an if expression instead.</i><p>The example shown (aside from the fact it&#x27;s assigning a tuple, which is a different point) would naturally be a ternary in C&#x2F;C++. Does the awesomeness kick in for more complicated examples where you want intermediate vars etc in the two branches?
评论 #20334774 未加载
评论 #20334208 未加载
评论 #20339019 未加载
MrGilbertalmost 6 years ago
Really cool post. I always dreamed of writing a small realtime, raytraced game, with lights etc. Basically a roguelike in 3D. I never managed to finish it, and this project reminds me of it.
olodusalmost 6 years ago
I really don&#x27;t think these languages should be set opposite to one another as much as they do. I mean, I get why they are. They take up almost the same position and have quite different ways to view security and lang design. And they both try to grow and compete. But still. I think there are some space for them both. I would really think it would be cool to spend my working hours programming Rust for safety and switching to Zig whenever I have to code an unsafe block (all of it compiling to webasm :o )
评论 #20333425 未加载
keylealmost 6 years ago
That was a really fun read... Now if the author could do it in nim and v-lang...