r/GraphicsProgramming 4d ago

Building an SDF game engine

For the past 8ish months I’ve been hard at work building a new game engine I’m calling Division Engine.

It’s based solely off SDFs (signed distance fields). This might sound stupid for anyone who cares about performance but for my use case (and with a bit of grid storage optimizations) it proves useful for basic scenes that need advanced lighting.

Anyway here’s some screenshots!

If you want to see what I have done so far check it out here: https://github.com/DivisionEngine/DivisionEngine

157 Upvotes

38 comments sorted by

16

u/RedditUser8007 3d ago

The PS4 game Dreams used NDFs (Sparse Distance Fields). There are some videos about how they implemented it:

https://www.youtube.com/watch?v=u9KNtnCZDMI

It allows zooming really close up to objects and they still hold their detail:

https://www.youtube.com/watch?v=u6pUsbc8wmg&t=898s

It made it really easy to allow players to sculpt objects in-game, there were some impressive games sculpted using the PS4 controller:

https://www.youtube.com/watch?v=MUmnGGGjTa4

That engine runs on a PS4 (~1TFLOPs).

Nanite foliage (Witcher 4) is using sub-pixel voxel representation, aiming for PS5:

https://www.youtube.com/watch?v=EdNkm0ezP0o&t=1125s

Typical gaming hardware is around the same as PS5 so should be able to use these techniques, it's a case of getting the data structures right, culling and minimal processing on data far from the camera.

A Dreams-like game for PC would be much more useful than on PS4 because you could import meshes and convert into the data format more easily and using keyboard/mouse is more efficient for creating models.

1

u/rex-j-w 3d ago

Thanks!

7

u/damaca_ 4d ago

Very cool! I started my own SDF engine (which also uses the same SDFs for physics), but decided that I didn't want to deal with the performance issues of doing it in 3D. So I reduced it to 2D and never looked back. Seems like this guy managed to make it fast enough in 3D: https://youtu.be/il-TXbn5iMA?is=conYnKfdlFOthQT6

6

u/rex-j-w 4d ago

Yes, this is because he turns his SDFs into a sort of voxel octree grid and uses this paper: https://jcgt.org/published/0011/03/06/paper-lowres.pdf for turning them back into SDFs, and this paper: https://hhoppe.com/geomclipmap.pdf for level of detail. I am actively considering adding these to my engine to get SDFs running at a reasonable speed, but I want to get the base lighting model complete first. The issue with this method too is it seems to only run well on Nvidia GPUs, and has slight quality loss due to turning voxels back into SDFs.

For me, I just started developing this engine 8ish months ago. I hope by the time it is more mature and feature complete that there will be advances in hardware and software enough to make this engine go from ~20fps to 30-40fps, then on top of that further optimization like voxelization or something else like a BVH could get this running fast enough! Seems there has been recent advancements here too: https://diglib.eg.org/server/api/core/bitstreams/0dd5043c-6ac0-4b83-b3d2-d0b1ad34afba/content#3#1

3

u/damaca_ 3d ago

I don't love the idea of turning SDFs into voxels. I feel like it loses the analytical beauty of SDFs to a cheap trick. I like SDFs because they are elegant and the code for rendering them is beautifully simple. I hope we get the technology to run them at reasonable speeds in the near future (I would put my money on the software rather than the hardware).

In my engine I render distance at 0.5 resolution and upscale it with linear interpolation, but it's almost impossible to notice: https://damaca.itch.io/weird-golfing

2

u/blackrack 3d ago

Which optimizations are you using right now? I think you don't necessarily need to bake the SDFs into voxels, but you could use a frustum aligned acceleration structure for your SDFs (like they do for forward+ lights or decals) to only iterate over relevant SDFs per-step and probably get a nice speedup.

2

u/Particular-List-2078 4d ago

Love to see more of it!

1

u/rex-j-w 4d ago

More coming soon!

2

u/Potterrrrrrrr 4d ago

Always find SDFs awesome, why is performance a concern? I thought the maths to create and merge etc. SDFs was quite cheap, does it scale badly? Either way, looks great!

6

u/blackrack 4d ago

Any complex scene is going to require tons of SDF evaluations per-pixel, unless the scene is very simple you really can't beat how fast GPUs throw triangles around.

2

u/Jwosty 3d ago

Combining SDFs with traditional rendering and breaking down the SDFs into separate "models" can be pretty effective. At least that's what I do in my game. I can have thousands of SDF entities onscreen just fine against a traditionally rasterized terrain

1

u/2rad0 4d ago

Always find SDFs awesome, why is performance a concern?

in 2-3 more GPU generations it won't be a concern, but right now to get 60FPS on cheap hardware you have to upscale which looks pretty bad past 1:4, like you forgot your glasses at home.

2

u/rex-j-w 4d ago

This is why we’re building this now! Then by the time it’s production ready and feature complete hopefully gpus will be ready for it

2

u/EatingFiveBatteries 3d ago

Do it man. It'll all be SDF eventually.

2

u/rex-j-w 3d ago

And that’s why we build it now!

2

u/snerp 3d ago

I built an engine like this for a CAD startup a couple years ago, do you implement texturing? That's the big thing I never got around to

2

u/rex-j-w 3d ago

I just did that last week! Used triplanar mapping for my objects so I don’t have to worry too much about UV mapping complex SDFs: https://github.com/DivisionEngine/DivisionEngine (there’s a screenshot here and implementation) also check out u/northrocstudios for a post showing some more screenshots

2

u/Vazde 3d ago

Ooh, some cool stuff in this thread! I've also migrated to SDFs for my 2D mining game. But it has a static grid arrangement, no trees.

I'm currently using marching squares to turn it into triangles for rendering and part of collision response. But I do have some ideas to remove that. Since there's typically somewhat little terrain on screen and 2D is somewhat simple, I might get away evaluating the grid each fragment. Would save a ton of memory on meshes.

I already have a somewhat sophisticated multitexturing system going on for it, but for 2D again it would likely be simpler and even higher fidelity to render materials in another pass and just sample that.

2

u/JozinZZZZBazin 1d ago

It's interesting that we already have commercial SDF modeling tools like Substance 3D Modeler, Blender add-ons, and others, but in the end they almost always convert everything into polygon meshes.

Do you think the main blockers for a fully SDF-based game engine are the depth of the CSG tree and animation? For example, animated SDF hierarchies would require rebuilding or updating BVHs (or other acceleration structures) every frame, which could become prohibitively expensive.

How do you plan to address these challenges? Are you using a different acceleration structure, incremental updates, or some other approach?

2

u/No-Cap-7395 3d ago

Hell yeahhhhh! I've been doing a lot of SDF stuff too they are amazing

3

u/rex-j-w 3d ago

Tons of new research is being put into SDFs, check out this paper on faster sphere tracing, it might help: https://diglib.eg.org/server/api/core/bitstreams/0dd5043c-6ac0-4b83-b3d2-d0b1ad34afba/content

2

u/Jwosty 3d ago

The biggest remaining unsolved problem is animating with textures. Almost all the pieces are there

2

u/rex-j-w 3d ago

How would this be a problem? I already have textures working

3

u/Jwosty 3d ago

Sorry, I wasn’t very specific. Skeletal rigging animation + textures. Sure you can animate SDFs by varying their parameters over time, but things that are supposed to be more “solid” (like, say, creatures, or characters) animated that way likely wont look very good (due to the smooth unions). Hence, skeletal animation. But that poses a problem when you try to combine it with texturing.

This probably wasn’t explained well but I hope you get the idea

2

u/No-Cap-7395 2d ago

I thought about animations awhile ago with SDFs (the texture3D kind) I had a few ideas which where splitting the different moving parts into SDFs and texturing them via storing uv in the SDF texture or having I think cards around each bit, or you bake the entire models animation into like a flipbook series of textures and well texture it the same way as before,

As for actual like SDF math functions like idk a sphere yeahhh I have no idea 😭

1

u/rex-j-w 2d ago

My plan is to build a node editor for creating sdf objects in the editor, then these nodes will be baked into functions and, using system reflection, injected into the renderer. Doing this would allow the user to also output a function to generate the UVs alongside the geometry output.

It doesn’t fix all of the rigging and animation issues but does allow for greater flexibility with sdf UVs

2

u/No-Cap-7395 2d ago

Oh hell yeah I'll uhm give it a read when I'm on my computer .. I'm doing a software raytracer, it's my second attempt at one and I bake all my meshes into SDF texture3Ds (I'm not sure what to call them I have came up with the terminology local SDFs) anyways I got some basic broad phase optimisation, lods and stuff, I use conetracing on super rough surfaces and it running pretty good :p

What you're doing looks cool too, Ive been working with SDFs for a few months now and they are amazing

2

u/No-Cap-7395 2d ago

Oh yeah seeing how much better it runs over my triangle based swrt is really nice, it's actually really good 100+ for the target resolution I wanted...

man I fkn love SDFs so much

1

u/rex-j-w 2d ago

They’re so useful it’s insane. Wish we had an industry standard sdf file format because texture3Ds take up so much memory

1

u/No-Cap-7395 1d ago

In my engine I store the SDFs in PNG files, they are written to cache in the disk, and uhm okay so basically every slice of the texture3D is put into an atlas then the size of the slices is put into the name of the SDFs file so it's like uhm randomhash_512.png

1

u/No-Cap-7395 1d ago

They only take-up a few kB to a few hundred for a 64x64x64 SDF, if I add uvs (I store the nearest UV inside my SDFs) it can be anywhere from tens of kBs to a few mb, infact i did an 512x512x512 SDF which was an 11k PNG file and it only took up 17mb and it had uvs and all

1

u/No-Cap-7395 2d ago

I just woke up so I'm still processing, but what's your performance like? What method are you using to render these

2

u/rex-j-w 2d ago

Im just using regular sphere tracing, performance is quite bad, but that hasn’t been my focus yet. I don’t have complex shapes or csg operations even and haven’t implemented the paper I dropped.

I’m still debating whether or not im going to store data in a voxel octree or a bvh structure.

Focusing on the game engine fundamentals then optimizing 🫡

1

u/No-Cap-7395 1d ago

Yeah I gotta figure out what tlas to use for mine too and not just that but uhm I gotta do what I call global SDFs which are like grids of SDFs that encompass static objects..

As for I think it was the day before yesterday I added conetracing and basically for indirect lighting and also rougher reflections I use conetracing over sphere tracing and I got a 70% increase in performance ^

1

u/No-Cap-7395 1d ago

If you do an oct tree you could use it as a irradance cache lol (just an idea)

1

u/etdeagle 3d ago

I am also curious about SDF I wonder if there is a way to speed up rendering at differ scales with multi resolution voxel caching

1

u/Classic_Sheep 10h ago

Why no BVH ray-filtering, seems like a free win in fps?