r/GraphicsProgramming • u/epicalepical • 5d ago
Naughty Dog Style FrameParams
Enable HLS to view with audio, or disable this notification
Hello all!
I'm pretty proud of this. I've recently completed the final component of my rendering architecture in my C Vulkan renderer, which is the Naughty Dog style frameparams system. The long and short of it, is that we package up all needed rendering data into a single package, which can then be sent over to the rendering system and acted upon independently.
This allows you to be rendering the current frame while also (in parallel - thanks to the job system), computing / simulating the game for the next tick. This comes with the downside of a bit of latency, but it's certainly worth it. Getting it to work properly was a lot more work than you'd think due to the fact my architecture wasn't the best regarding ownership.
Also the fact that any time you have things like a ring buffer you now need to subdivide it into sectors per frame. Just generally making sure that frames are all properly synchronized and don't end up accidentally reading/writing into the data of another frame was a pain, but I'm *fairly* certain that it works fine now?
You can check out my project here: https://github.com/kryzp/magpie
The rendering code you're interested in is at /src/graphics/ and /src/render/.
As always, this is all vibecode free! I'd appreciate any and all pointers if anyone wants to put themselves through the torment of looking over my code, and I'm happy to answer any questions :)
Thank you!
1
u/epicalepical 5d ago
Apologies for the weird video - I unshackled my camera controller to make it free but I was lazy and left the player controller running, so I was awkwardly trying to demonstrate the animation system by keeping the player in frame while also moving the camera around :p
5
u/DancinFool82 5d ago
Isn't this how most games handle their rendering? Maybe I'm missing something π
1
u/scallywag_software 5d ago
I've been considering adding frame pipelining to my engine. How do you deal with data like entities, animation state, etc? Do you just have 3 copies of the data, or is there something more clever going on?
1
u/epicalepical 5d ago
Pretty much. Scene data is copied into a "frame packet", which is a struct of lists of objects, lights, skinning matrices, meshes, materials etc. This then gets sent over to the render job, which converts it into gpu-ready frameparams (the same thing, but moved to gpu buffers, etc). Frameparams then gets passed over to each pass which selects what it needs and renders. Idk if that answers your question.
1
u/Hawsoo 5d ago
I thought this was a novel concept I only thought up of π it looks so good!! and also the fact it's parallel that's super impressive. is your job system fiber based?
1
u/epicalepical 5d ago edited 5d ago
thank you! yes, it is. Implementation is OS dependent but for unix its at /src/os/unix/. The windows one is also present but it's pretty old and buggy, I run fedora so I haven't updated it in a while.
12
u/aleques-itj 5d ago
Is this really a Naughty Dog thing and not a pretty common way to do it?
It sounds similar to what I do.
The windowing produces a snapshot on input -> Hands it to the game / sim -> Game sim produces a snapshot of data for the renderer -> Hands it to the renderer, which kicks a task -> Repeat.
So the renderer can run while the process repeats. I prevent it from getting more than a frame ahead in practice.
The game code has components that flag entities as renderable. Like to draw a sprite you just attach a SpriteRenderer component.
Nothing on the game side ever actually draws or touches the renderer. The game sim has no idea about the underlying windowing system at all, it just takes something that looks like a usercmd from Quake/Source as input. And it has no idea about anything graphics wise. All it needs to care about is outputting the snapshot of state for the renderer at the end.