Page MenuHome

Cycles: Add NanoVDB support for rendering volumes
ClosedPublic

Authored by Patrick Mours (pmoursnv) on Sep 3 2020, 4:52 PM.
Tokens
"Love" token, awarded by lrevardel."Love" token, awarded by franMarz."Love" token, awarded by kenziemac130."Love" token, awarded by Raimund58."Love" token, awarded by marcog."Like" token, awarded by IPv6."Love" token, awarded by BlackRainbow."Love" token, awarded by ReinhardK."Love" token, awarded by swerner."Love" token, awarded by jtheninja."Love" token, awarded by manitwo."Love" token, awarded by brecht.

Details

Summary

NanoVDB (https://www.aswf.io/nanovdb/) is a platform-independent sparse volume data structure that makes it possible to use OpenVDB volumes on the GPU. This patch uses it for volume rendering in Cycles, replacing the previous usage of dense 3D textures.

This is a preliminary patch and not finished yet, but is in a working state.
I tried to keep changes to a minimum for now and am therefore using NanoVDB only for data look up, as an in-place replacement for 3D textures. This is not necessarily the most optimal way to use it, since the NanoVDB API also has helpers to do traversal etc. that may benefit from node caching which this approach completly circumvents (each look up does a full traversal of the NanoVDB data structure). But it's the simplest way to get one of the biggest benefits into Cycles, which is memory savings due to the sparsity of the data.
This is also still missing some optimizations (render times are currently slightly worse compared to 3D textures) and there are open questions, e.g. with regards to how the NanoVDB library should be referenced. It is now part of official OpenVDB in a side branch, so could be added to the external OpenVDB package already built with Blender. But it may also be added separately or even taken into the source tree (extern/), since it's header-only. The current code does the second option and expects a copy of the NanoVDB code in the external libraries directory (on Windows \lib\win64_vc15\nanovdb for example). Also, this only implements nearest and linear sampling right now. Cycles technically supports cubic sampling too, but I'm not sure it's actually possible to hit that on a VDB volume (which always defaults to linear sampling from the looks of it)? So I haven't added that in this version of the patch to reduce amount of code.

To enable, set the WITH_NANOVDB CMake option and put a copy of https://github.com/AcademySoftwareFoundation/openvdb/tree/feature/nanovdb/nanovdb into a nanovdb subdirectory in your Blender libraries path. Note that that version of NanoVDB is currently missing a fix that makes SampleFromVoxels work for vector types, so you may have to comment out the code that handles IMAGE_DATA_TYPE_NANOVDB_FLOAT3 for this patch to compile, until NanoVDB is updated.

Image of the bunny sample data set rendered with NanoVDB using OptiX:

Diff Detail

Repository
rB Blender
Branch
cycles_nanovdb (branched from master)
Build Status
Buildable 9964
Build 9964: arc lint + arc unit

Event Timeline

Patrick Mours (pmoursnv) requested review of this revision.Sep 3 2020, 4:52 PM
Patrick Mours (pmoursnv) created this revision.
Patrick Mours (pmoursnv) edited the summary of this revision. (Show Details)Sep 3 2020, 4:56 PM
Patrick Mours (pmoursnv) edited the summary of this revision. (Show Details)Sep 3 2020, 5:11 PM

Looks good so far. Quite similar to what I have been playing with, I took the same approach with IMAGE_DATA_TYPE_NANOVDB_FLOAT. We should also be able to pass Blender simulation volumes through as NanoVDB.

I applied this patch succesfully to our build, but I see no difference, I'm trying the Moana VDB set and the memory consumption is the same, do I have to do something to enable it?

I applied this patch succesfully to our build, but I see no difference, I'm trying the Moana VDB set and the memory consumption is the same, do I have to do something to enable it?

Hi @Juan Gea (juang3d). Did you grab a copy of the necessary files off of github and add them to your library folder? And did you compile your build using the CMake option WITH_NANOVDB?

I applied this patch succesfully to our build, but I see no difference, I'm trying the Moana VDB set and the memory consumption is the same, do I have to do something to enable it?

Hi @Juan Gea (juang3d). Did you grab a copy of the necessary files off of github and add them to your library folder? And did you compile your build using the CMake option WITH_NANOVDB?

Yes. I’ve configured everything in a Cmake-GUI and defined the path to the NanoVDB folder, everything was built without trouble, but I see no change when I render

I don’t know what else to suggest, sorry @juan3d 🤔

@Juan Gea (juang3d) This patch does not compile with the current official NanoVDB (it needs some upcoming changes that are not in there yet), see last paragraph in the description. So if it compiles successfully without changes you are missing something and NanoVDB support is not active.

  • make deps: Update OpenVDB to 7.1 beta with nanovdb.
  • Cycles: Added fallback to nearest neighbor sampling for nanovdb float3 grids.
  • Merge branch 'master' into arcpatch-D8794

Fixing diff - was against wrong branch.

Someone please take arcanist away from me, I clearly don't know how to use it.

  • Merge branch 'master' into arcpatch-D8794

Now the necessary dependencies (OpenVDB 7.1.1, nanovdb branch) can be built with make deps - tested on Linux and macOS. Linux will use FindNanoVDB.cmake, macOS and Windows currently expect the nanovdb headers in $LIBDIR/nanovdb/include. This probably will need to be changed depending on whether nanovdb remains part of OpenVDB or if it becomes a separate package.

NanoVDB interpolation for non-scalar VDB grids will fall back to nearest neighbour sampling as a temporary measure until NanoVDB supports interpolation of those types.

It's the result that counts ;). Looks good, thanks!

I applied this patch succesfully to our build, but I see no difference, I'm trying the Moana VDB set and the memory consumption is the same, do I have to do something to enable it?

Hi @Juan Gea (juang3d). Did you grab a copy of the necessary files off of github and add them to your library folder? And did you compile your build using the CMake option WITH_NANOVDB?

Yes. I’ve configured everything in a Cmake-GUI and defined the path to the NanoVDB folder, everything was built without trouble, but I see no change when I render

@Juan Gea (juang3d) This patch does not compile with the current official NanoVDB (it needs some upcoming changes that are not in there yet), see last paragraph in the description. So if it compiles successfully without changes you are missing something and NanoVDB support is not active.

Thanks Patrick, then it must be disabled but I don't see any message about it.

Is it possible to build this with the recent updates done by @Stefan Werner (swerner) ?

I'm eager to test it to see the gains :D

This all looks quite straightforward.

For performance, if render time is only slightly worse then I don't think we will need an option for users to choose between dense and sparse. But it would be interesting to see numbers after optimization. And hopefully we can then later remove the dense 3D texture code and always use NanoVDB.

Tricubic filtering is quite important as a feature to have I think, most smoke sims look quite bad without it, so probably that is needed before we can turn this on for users.

It would also be great to support half float. In my experience, most cloud / smoke / fire type volume grids can be rendered just fine with half float, with little to no visual difference compared to full float.

I'm fine with this getting committed before it's fully optimized or feature complete. If we do that building NanoVDB as part of make deps should also become a WITH_NANOVDB option, since we'd still stick to the official OpenVDB 7.0 release for Blender releases.

Added support for tricubic interpolation.
Also, https://github.com/AcademySoftwareFoundation/openvdb/tree/feature/nanovdb was updated, so this removes the workaround for vector types and enables an optimization that disables some caching code which is not currently of use for a small performance increase.

Did a quick benchmark at 50% 1920x1080 using OptiX:

RTX 8000Mem
Dense02:58560.61M
NanoVDB03:17146.82M

So currently roughly a 10% hit in performance still, but with huge memory savings.

10% is not that bad, it may be hard to get much closer?

I think this would be a feature for 2.92, but it could go into master before that. That would require a WITH_NANOVDB option for make deps so the libraries can remain unchanged for 2.91.

We can also wait until master is open for bigger changes on October 21 and enable it immediately, either way is fine with me.

Made NanoVDB optional in dependencies build (WITH_NANOVDB CMake flag)

This also means by default make deps will build OpenVDB 7.0.0 again as before and will only use the NanoVDB branch (which is currently based on OpenVDB 7.1.1) when the WITH_NANOVDB flag is set.
With this is should now be possible to disable NanoVDB from builds entirely so it could probably be merged, but enabled only in a later release.

Added missing WITH_NANOVDB check for Linux harvesting.

This revision is now accepted and ready to land.Oct 2 2020, 6:20 PM

Question, I tried to build with it and CUDA/Optix enabled, I assume it’s not yet GPU compatible, right? Because I get some errors, I have not tried without CUDA, but I assumed that was the limitation yet.

This works with CPU, CUDA, OptiX and OpenCL (GPU compatibility is the main point of this, since on the CPU OpenVDB could have been used directly). But as noted in the commit you need to build both dependencies (the build_deps script) and Blender with the WITH_NANOVDB flag. The precompiled libraries one usually uses to build instead have not been updated yet to include NanoVDB.

This works with CPU, CUDA, OptiX and OpenCL (GPU compatibility is the main point of this, since on the CPU OpenVDB could have been used directly). But as noted in the commit you need to build both dependencies (the build_deps script) and Blender with the WITH_NANOVDB flag. The precompiled libraries one usually uses to build instead have not been updated yet to include NanoVDB.

Oh!

Thanks, sorry for the question then, I assumed that NanoVDB was already in the pre-compiled libraries, my bad, thanks.