Live data from Hacker News

Writing a small ray tracer in Rust and Zig

nelari.us

21–30 of 98 posts

Re: Writing a small ray tracer in Rust and Zig

#21

Earlier quoted context omitted.

I still don't understand why Rayon is not part of the Rust standard library. Rust was created to have easy and safe multithreading on the CPU, and Rayon is the clear winner in this space, for me it feels like something that should be part of Rust.

The Rust stdlib is specifically intended to be as lightweight as possible (while still providing those idiomatic abstractions that might be needed throughout the ecosystem, e.g. std.future) in order to avoid the Python "dead batteries" problem. What the Rust ecosystem is still lacking is a quasi-standard "Rust Platform" of best-practice library components where the community can freely deprecate something when a clea…

Rust needs something like Rust dev blessed "extension packs", in my opinion.

Sort of like VS Code has extension packs.

Basically have some metapackages for common development areas, that pull in community vetted, high quality libraries for certain areas.

Re: Writing a small ray tracer in Rust and Zig

#22
This is an awesome post.

At the risk of shedding it to bikes, one point that the author makes is that Zig's lack of operator overloading makes him write vector math like this:

    if (discriminant > 0.0) {
        // 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)));
    }
He signs off with:

> How do C programmers manage?

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:

    if (discriminant > 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)
    }
I'm convinced that there's a proper mathy/lighting-y word for each component in that expression. Of course this approach totally breaks down if you'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's going on.

Re: Writing a small ray tracer in Rust and Zig

#23
post #10

Earlier quoted context omitted.

I wonder if there’s a way to borrow noncontiguous slices.

unsafe is the tool u are looking for.

No, there are plenty of safe ways to achieve this in the standard library. The chunks and split families of functions on slices are all designed to do pretty much exactly this.

Re: Writing a small ray tracer in Rust and Zig

#24

This is an awesome post. At the risk of shedding it to bikes, one point that the author makes is that Zig's lack of operator overloading makes him write vector math like this: if (discriminant > 0.0) { // 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))); } He signs off with: > How do C programmers manage? The answer is simple: w…

In my experience writing math code the intermediary values get quite goofy Ex: orthogonal-vector-to-plane-bisecting-input-vector-and-first-column-vector

But I rather use crazy descriptive names than hiding it away. Otherwise it gets quite incomprehensible when you reread it 3 months later

Anyone else hit this problem? I suspect most people just reference a paper or book and use the letters to match the source ( x/y/n/m/etc. )

Re: Writing a small ray tracer in Rust and Zig

#25
post #24

This is an awesome post. At the risk of shedding it to bikes, one point that the author makes is that Zig's lack of operator overloading makes him write vector math like this: if (discriminant > 0.0) { // 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))); } He signs off with: > How do C programmers manage? The answer is simple: w…

In my experience writing math code the intermediary values get quite goofy Ex: orthogonal-vector-to-plane-bisecting-input-vector-and-first-column-vector But I rather use crazy descriptive names than hiding it away. Otherwise it gets quite incomprehensible when you reread it 3 months later Anyone else hit this problem? I suspect most people just reference a paper or book and use the letters to match the source ( x/y/n…

Yep, agree! I think extremely long variable names (when used locally), if necessary, are wildly underrated. I mean, we all know horror stories like SimpleBeanFactoryAwareAspectInstanceFactory, but they are really design problems much more than naming problems. They gave long variables a bad rep, undeservedly so. Inside an expression, names like that truly do wonders.

Re: Writing a small ray tracer in Rust and Zig

#26

This is an awesome post. At the risk of shedding it to bikes, one point that the author makes is that Zig's lack of operator overloading makes him write vector math like this: if (discriminant > 0.0) { // 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))); } He signs off with: > How do C programmers manage? The answer is simple: w…

The most principled approach there, I think, would be to build a little Expression data-structure, and then feed it to an evaluation routine, trusting the optimizer to compile the whole thing down to something efficient. If Rust didn't have operator overloading anyway, you could do the job with procedural macros.

In practice, if I had to write that quasi-monstrosity in something like C, I'd probably just comment it as clearly and liberally as possible, to the point where I manage to reassure the reader that the final expression is correct; and then add a // See above: Please DO NOT edit this expression directly!// comment as an extra caution.

Re: Writing a small ray tracer in Rust and Zig

#27
post #24

This is an awesome post. At the risk of shedding it to bikes, one point that the author makes is that Zig's lack of operator overloading makes him write vector math like this: if (discriminant > 0.0) { // 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))); } He signs off with: > How do C programmers manage? The answer is simple: w…

In my experience writing math code the intermediary values get quite goofy Ex: orthogonal-vector-to-plane-bisecting-input-vector-and-first-column-vector But I rather use crazy descriptive names than hiding it away. Otherwise it gets quite incomprehensible when you reread it 3 months later Anyone else hit this problem? I suspect most people just reference a paper or book and use the letters to match the source ( x/y/n…

I suspect most people just reference a paper or book and use the letters to match the source ( x/y/n/m/etc. )

If you do this (and I'll certainly admit that I do this as well) make sure you link to the paper in question somewhere in either comments or the documentation so that future developers can find the canonical reference to what the variables mean.

Re: Writing a small ray tracer in Rust and Zig

#28
post #2

I really don'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 switc…

In my mind/opinion, Rust is a potential replacement for C++, while Zig is a potential replacement for C, and both have their place in the world.

Rust feels more restrictive, but that may be the right approach for building large software projects with big, "diverse" (in terms of skill level) teams.

Zig is smaller and feels more nimble, and might be better suited for smaller teams working on smaller projects, and for getting results faster, while avoiding most of C's darker corners.

Re: Writing a small ray tracer in Rust and Zig

#29

This is an awesome post. At the risk of shedding it to bikes, one point that the author makes is that Zig's lack of operator overloading makes him write vector math like this: if (discriminant > 0.0) { // 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))); } He signs off with: > How do C programmers manage? The answer is simple: w…

So why not just write the original formula into the comment above the code? Maybe it's not the purest approach, but it sure would help parsing the code in this case.

Re: Writing a small ray tracer in Rust and Zig

#30

> 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! Based on some discussion in r/rust ( https://www.reddit.com/r/rust/comments/c7t5za/writing_a_smal... ) I went ahead a…

> 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?

I came across this exact thing recently: https://github.com/brson/stdx

Post reply on HN