6 ms·
The GPU loves arrays of structures AoS, since all vertex data fits in its triangle assembly cache. Once given to the GPU, the software side doesnt really care f
by smallstepforman 4mo ago
The GPU loves arrays of structures AoS, since all vertex data fits in its triangle assembly cache. Once given to the GPU, the software side doesnt really care for all vertex parameters so this optimisation is pointless. Only relavent when you have instance rendering (leaves, grass) but then you only need an array of vec3’s, not the other parameters so back to normal arrays.
Meanwhile, game engines need operator overloading for adding/multiplying vectors (spatial transforms, lighting, physics) and core zig design philosophy prevents operator overloading.
Blind leading the blind. Disclaimer - I do professional rendering engines.
- awesan 4mo agoZig is adding native vectors including operator support, there are some recent issues/prs about this topic. The general technique of SoA is pretty useful both in games and other applications, but of course I cannot speak to the specific use-case you are describing.
- nvme0n1p1 4mo agoZig vectors force data into SIMD registers even if that would make the code slower. They're a specialty type. You should only reach for vectors if you would have used SIMD intrinsics in C for example.
- e4m2 4mo agoZig vectors do not necessarily force data into SIMD registers; a scalar implementation would work equally well. This is not just a theoretical argument, because Zig code that uses `@Vector` also has to compile for architectures that do not have SIMD instructions. That being said, the parent commenter is actually referring to other recent proposals as opposed to existing `@Vector` functionality: https://codeberg.org/ziglang/zig/issues/32032 https://codeberg.org/ziglang/zig/issues/32032 https://codeberg.org/ziglang/zig/issues/35376 https://codeberg.org/ziglang/zig/issues/35376
- nvme0n1p1 4mo agoInteresting, so zig might have both "vectors" and "vecs"? I guess naming is another thing to fix before 1.0 <g>
- beepbooptheory 4mo agoSo is the argument that any SoA is pointless? Or just for GPU stuff? Because this isn't really talking about all that one way or another. Also does one really need operator overloading? That feels a little strong. I've gotten by with functions just fine.. Does that make the GPU not like me Mr. wise engineer?
- geysersam 4mo agoGenuine question: why do you think game engines need operator overloading? I mean, what's wrong with generic functions like add, multiply, dot etc.
- aaaashley 4mo agoNot GP, but I've written game engines and rendering engines. Vector operations are just common enough that having to write `.mul` every time is a huge pain, especially when you put many of them together for a large formula. Compare: (physics_data.velocity + omega * change) * frame_delta_time to physics_data.velocity.add(omega.mul(change)).mul(frame_delta_time) We learn to read and think about math a certain way, which is incompatible with Zig. Also, Zig's design philosophy of "reading code over writing code" is incompatible with the kind of small modification-test-cycles required when doing games, and creative programming in general. So Zig is sort of DOA anyway for that kind of thing. But I've been using Zig for non-game projects and it's been fantastic, so definitely not "Blind leading the blind" for the overall language design, imo.
- smj-edison 4mo agoI've been thinking about a way around this, and I'd be interested to see if comptime with a DSL wouldn't be too unwieldy. Something like math("(v + Ω * c) * Δt", .{ .v = physics_data.velocity, .@"Ω" = omega, .c = change, .@"Δt" = frame_delta_time}) I know this is already possible with comptime, though I haven't implemented it yet since I haven't needed vector math in what I'm working on currently. Can't decide whether using math names is better or worse than using the full variable names though.
- stouset 4mo agoAll this just to prevent people from using + - * / and ^. Why?
- smj-edison 4mo agoAndrew talks about it because it introduces hidden control flow where you're expecting simple operators. In Zig anything that deals with control flow is a keyword (including short circuiting and, which is `and` instead of `&&`). I'd argue though that the real disadvantage to having overloadable arithmetic is that you're limited to one implementation. This is actually my biggest beef with Rust, namely traits/type classes. It locks you into a single implementation when you may want to do something different based on the context. Zig pushes the dispatch decision to the callsite, not a trait subsystem (see how Zig implements hash mays for example). So I'd personally prefer to use a DSL, since it lets me specify what type of dispatch to use.
- Ciantic 4mo agoRust should (eventually) support arrays of structures via compile-time reflection: https://fnordig.de/2026/03/25/rust-reflection-and-a-multi-array-list/ https://fnordig.de/2026/03/25/rust-reflection-and-a-multi-ar...
- smj-edison 4mo agoI didn't realize compile time reflection was back on track, that's really exciting!
- the__alchemist 4mo ago> Meanwhile, game engines need operator overloading for adding/multiplying vectors (spatial transforms, lighting, physics) and core zig design philosophy prevents operator overloading. This is a frustrating decision. My use cases for low level languages overlap closely with my use cases for vectors (etc) with operator overloading. It was one of the first things which put a bad taste in my mouth about Zig.
- flohofwoe 4mo agoZig has a builtin vector type and will get a builtin matrix type. The only useful thing that's missing from shading language vector-math syntax is swizzling, but you don't get that via operator overloading either (and for dot- and cross-product you'll still need a function, but that's also in line with shading languages).
- fasterik 4mo agoOn the other hand, SIMD loves SoA, and so does the CPU cache. It all depends on what you're doing with your data. Zig professes to be a C replacement, not a C++ replacement, so leaving out operator overloading is consistent with that design goal. But I agree, I would prefer to program in a language that expresses mathematical relationships more naturally.
- flohofwoe 4mo agoSplitting fat vertex component data into multiple streams also often makes sense in rendering engines (e.g. not all vertex shaders might need all vertex components). Strict SoA or strict AoS hardly ever makes sense, but an 'inbetween' approach often does (maybe call it SoAoS) - and this should be possible just fine with Zig's comptime approach, e.g. only apply the SoA transform to the toplevel items of a struct. As for CPU-side vector math: Zig already has a @Vector type (which will probably be renamed to @Simd) and it will get a builtin matrix type. With those two things, the main reason for operator overloading in game/rendering engines is pretty much handled via builtin types.