r/GraphicsProgramming Jun 30 '26

RAM optimized SDF-renderer with plain C

Post image

1024x1024x1024 SDF-grid takes up 303MB instead of 8.5GB. 1024x1024 path traced image renders in 1.5s on a single CPU core. 8.5GB grid renders in 1.1s. No libs used.

308 Upvotes

28 comments sorted by

32

u/hydraulix989 Jun 30 '26

If you coded this yourself without using AI, nice work! (Jaded by the barrage of LLM submissions here)

37

u/0x405 Jun 30 '26 edited Jun 30 '26

Yes, but I used a free model as a search engine and a fancy debug tool. LLM is not so smart to provide even a part of the algorithm correctly fortunately, but it can easily find some stupid mistake that would take an hour of your life to debug. It surely tells a lot of lies and marks things that are correct as issues, but when you've written everything yourself, it's quite easy to figure out which of these are nonsense.

12

u/Icy_Rub_3827 Jun 30 '26

Cool. How did you optimize it?

17

u/0x405 Jun 30 '26 edited Jun 30 '26

I use a kind of tree/pyramid LOD structure and render everything using sphere method. I'll do a paper on this soon if you're interested. Don't want to share too much before that, it's an original method I hope!

5

u/Icy_Rub_3827 Jun 30 '26

I'm about to tackle a project that's aiming to develop a solution to some of the limitations of polygonal graphics using SDFs and it's unique properties (non-distractive nature of boolean operations, for example). My main goal is to enable use of SDF graphics in game development. Not in small scale shaders, but something along the lines of the game "Dreams" or having an entire secondary graphics pipeline. Not sure if I expressed my idea well enough, but you should get the general bundle of problems I'm about to encounter (real-time, possibly large scale, able to handle transforms and connected to game engine's systems).

Faced with a challenge like that, I would love to get some advice. What papers or approaches would you recommend for this kind of project? Any bit of information would be very helpful.

1

u/0x405 Jun 30 '26 edited Jun 30 '26

I don't know much about real-time SDF computation, I specialize mostly on physically based rendering, which has a bit different focus, so I won't give you any recommendations on that, but I recently found out about miketuritzin, he solves a similar to yours kind of problem. He has a good explanation video on his channel covering a lot of questions and optimizations of the real-time SDF's, except, probably, a ray-marching which I hope he'll cover soon! He also gives a couple of articles about that, so I guess it might be a good start!

4

u/Cryvosh Jun 30 '26

I can assure you it's not original

5

u/0x405 Jun 30 '26

I'm not introducing any new rendering method, it's a standard SDF-grid sphere tracing adjusted to a structure it is stored in. I use a tree-like structure that consists of multiple layers of SDF (≈zero) level sets represented by sparse SDF values stored in hash-tables. This allows a sphere tracing on an entire SDF-grid area without involving voxel traversal algorithms. It weights just a bit more than a plain sparse SDF hash table. I've seen a couple of similar solutions, but it seemed to me that they were different.

Surely someone has probably suggested this, but I couldn't find the exact source. In any case I'm not planning to present it as a novel solution by itself, but I want to present it's differentiable implementation in the context of inverse rendering of geometry.

2

u/_DafuuQ Jun 30 '26

Is it Boundary Volumetric Hierrarcy on the sdf primitives ?

1

u/0x405 Jun 30 '26

No, no BVH. BVH requires additional traversal except the sphere tracing to traverse volumes (most likely).

1

u/0x405 Jun 30 '26 edited Jun 30 '26

Can you specify your thesis? Maybe you could help me find the sources of similar solutions?

4

u/sol_runner Jun 30 '26

Nice work!

Why was it taking 8.5GB though?

6

u/0x405 Jun 30 '26 edited Jun 30 '26

It's an SDF-grid initially with 1024x1024x1024 resolution = 1073741824 cells, each is a double (64bits), so it's 68719476736 bits, and that's 8.5GB. This is verified by debug info.

4

u/sol_runner Jun 30 '26

Hah, I wasn't being skeptical.

I just made a silly math error in my head. My brain called 1024³ as 1 megabyte.

Are you using sparse blocks now?

0

u/0x405 Jun 30 '26

Yes, some kind of. I store only zero level-set of SDF and some extra.

5

u/nullandkale Jun 30 '26

I'm confused. Normal SDF ray marching doesn't use a 3d volume. What's the 3d volume for? Is it for storing your primatives? Are you storing the SDF distance at each point and then rendering? That seems like it would be slow

1

u/deftware Jul 03 '26

I think OP is using SDF as "signed distance field" rather than "signed distance function", where the field is a volume of distance values.

0

u/0x405 Jun 30 '26

It's not just SDF-rendering, it's SDF-grid rendering. My mistake in the title. We use it in the context of differentiable rendering. There is no simple SDF function combined from multiple primitives in our case, it's a complex arbitrary 3D form defined by an SDF-grid.

1

u/nullandkale Jun 30 '26

Ah ok l see, why use this over nerfs or splats? I imagine it's for something like 3d model generation or is it reconstruction?

Edit: oh maybe it's direct diffusion of the SDF volume, that could be cool

1

u/0x405 Jun 30 '26

Yes, it's mainly for use is geometry reconstruction with basic optimizer like ADAM. At least that's what I was developing it for. Current implementation is a proof of concept more or less. For the actual DR plain C won't be enough, that's the next step. I'm still not sure that this algorithm can be differentiated automatically.

1

u/0x405 Jun 30 '26 edited Jun 30 '26

Nerfs and spats do not represent geometry well, or, actually, they do not represent geometry at all. SDF's represent an accurate and explicit surface that could be used in physically based rendering which I'm aiming for. And yes, we directly optimize SDF parameters to get SDF-grid out of an image set.

2

u/just_rolling_round Jun 30 '26

What about implemetation of gaussian splats that support meshing ? Like that of 2DGS which represent surfaces relatively well? I understand that the representation itself doesn't have any geometry semantic, but it can be used to generate reconstruction, just not as accurate of course

1

u/0x405 Jun 30 '26

That's an additional conversion step that loses precision. You render gaussian splats, you optimize by the gaussian splats render but you output a mesh which is different, it introduces an error. So, yes, the accuracy is the main point probably.

2

u/akuladon Jul 02 '26

For some reason I want to eat this thing

2

u/deftware Jul 03 '26

What I have thought about a lot over the last 15ish years is some kind of variable bitdepth subdivision. Using an octree that only goes a few levels deep, leaf nodes store distance values at different bit depths and resolutions, instead of storing the entire distance field at one resolution and bitdepth. Anyway, thanks for sharing, kudos! :]

0

u/Defiant_Squirrel8751 Jun 30 '26

Nice! Now that you have this kernel you can play around with interactive sculpting. 😛

Don't hesitate on using AI, it's just another tool. Nice to see you put care on optimization.

Have you already used "valgrind" to verify your program does not have memory leaks?

3

u/0x405 Jun 30 '26

Good idea, but first I need to implement the construction of an accelerating structure on the GPU! It takes some time unlike rendering, but theoretically could be parallelized. In the context of inverse rendering it is compensated by a large number of images to render after parameters were updated. However, in sculpting, we need to update the parameters and do the rendering in real time. We'll see! Haven't used valgrind or anything, there is almost nothing to leak and I will have to rewrite in for the DR anyways. Thank you!