WIP
To run the editor in the docker container, the Dockerfile needs to contain:
EXPOSE 8080
ENV NVIDIA_DRIVER_CAPABILITIES compute,graphics,utility
RUN apt-get update \
&& apt-get install -y \
libxext6 \
libegl1Then run with the NVIDIA runtime selected (https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html):
docker run --runtime=nvidia --net=host --gpus=all ...- git
- C++ compiler
- CMake at least 3.25
- Python 3.x
- Vulkan runtime/loader:
- Windows: Vulkan Runtime (
vulkan-1) - Linux: system Vulkan loader/driver packages
- macOS: MoltenVK (or the macOS Vulkan SDK)
- Windows: Vulkan Runtime (
- NVIDIA Driver Version at least 550.0 (https://developer.nvidia.com/vulkan/video/get-started)
- Vulkan video at least 1.3.275.0 (checked during editor startup, prints out a message if the upgrade is needed)
- Download the latest Vulkan SDK from: https://vulkan.lunarg.com/sdk/home#linux
- Follow the instructions for manual installation in section
Install the SDK: https://vulkan.lunarg.com/doc/view/latest/linux/getting_started.html
VULKAN_SDK_VERSION="1.3.275.0"
cd ~
mkdir vulkan
cd vulkan
wget "https://sdk.lunarg.com/sdk/download/${VULKAN_SDK_VERSION}/linux/vulkansdk-linux-x86_64-${VULKAN_SDK_VERSION}.tar.xz"
tar xf "vulkansdk-linux-x86_64-${VULKAN_SDK_VERSION}.tar.xz"
echo "source ~/vulkan/${VULKAN_SDK_VERSION}/setup-env.sh" >> ~/.profile
. ~/.profile
# check the version
echo $VULKAN_SDK- vcpkg (recommended; required for Windows H.264 support)
pip install scikit-build wheel build numpy
For pytest:
pip install pytest parameterized
By default, editor is built with enabled NANOVDB_EDITOR_USE_GLFW which requires:
sudo apt-get install libgl1-mesa-devIn Conda environment:
- mesalib
The NANOVDB_EDITOR_USE_GLFW option can be disabled when using the editor in headless and streaming mode only. In that case, libvulkan.so.1 is built locally to ensure compatibility.
The NANOVDB_EDITOR_USE_H264 option is enabled by default. Make sure you have:
sudo apt-get install make# install homebrew from https://brew.sh
brew install cmake molten-vkNotes:
- If the Vulkan loader does not discover MoltenVK automatically on your machine, point
VK_ICD_FILENAMESandVK_DRIVER_FILESatMoltenVK_icd.json.
The project can use vcpkg for dependency management. If NANOVDB_EDITOR_USE_VCPKG is set, vcpkg.json automatically installs required dependencies.
NANOVDB_EDITOR_USE_H264 is supported on Windows only when NANOVDB_EDITOR_USE_VCPKG=ON. In that configuration, CMake consumes the openh264 package from vcpkg instead of the Unix-only source build path used on Linux.
To set up vcpkg:
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
bootstrap-vcpkg.batThe following dependencies are automatically managed by vcpkg.json:
- libe57format (and xerces-c dependency) when
NANOVDB_EDITOR_E57_FORMAT=ON - openh264
Put any data files into the data folder, which is linked to the location next to the libraries.
Shaders are generated into the shaders/_generated folder next to the libraries.
Run the build script with -h for available build options.
The Linux/macOS build script supports the following flags (combine as needed):
- -x: Perform a clean build (removes
build/, also forces shader recompile) - -r: Build in Release configuration
- -d: Build in Debug configuration
- -v: Enable verbose CMake build output
- -s: Compile Slang to ASM and clean shaders first
- -a: Build Debug with sanitizers enabled
- -p: Build and install the Python module (auto-installs
scikit-build-coreandwheel) - -e: Install the Python module in editable mode (use with
-p) - -t: Run tests (ctest + pytest); honors
-r/-dto pick configuration - -f: Disable GLFW for a headless build
- -c: Force CMake reconfigure (needed when switching build options like GLFW on/off)
Notes:
- If neither
-rnor-dis provided (and not using-por-t), the script defaults to a Release build. - For Python builds (
-p),-dselects Debug wheels; otherwise Release is used. - CMake configure is skipped automatically when the build directory already exists. Use
-cto force reconfigure when changing options (e.g., switching between GLFW enabled/disabled).
Examples:
# Clean Release build
./build.sh -x -r
# Debug build with sanitizers
./build.sh -a
# Headless Release build (GLFW disabled)
./build.sh -f -r
# Build and install Python package (Release)
./build.sh -p
# Build and install Python package in Debug, editable mode
./build.sh -p -d -e
# Run tests (defaults to Release tests)
./build.sh -t
# Generate Slang ASM during build
./build.sh -s -r
# Rebuild after changing options
./build.sh -r -c./build.shOptionally, rename the config file config next to the build script to config.ini and set the environment variables (use unquoted values; build.bat passes them to CMake with quotes):
MSVS_VERSION=Visual Studio 17 2022
USE_VCPKG=ON
NANOVDB_EDITOR_E57_FORMAT=ON
VCPKG_ROOT=path/to/vcpkg
When USE_VCPKG=ON, NANOVDB_EDITOR_USE_H264 defaults to ON on Windows. Without vcpkg, H.264 remains disabled on Windows because the fallback OpenH264 source build depends on Unix command-line tools.
Set NANOVDB_EDITOR_E57_FORMAT=ON to enable E57 support and install the optional vcpkg e57 feature on Windows.
To select a different profile for the Slang compiler (https://github.com/shader-slang/slang/blob/master/source/slang/slang-profile-defs.h):
SLANG_PROFILE="sm_5_1"
Then, run the build script:
./build.batAfter building, run the editor app:
./build/Release/pnanovdbeditorappThe libraries can be bundled into a Python package with a wrapper for the C-type functions. The following script will automatically install scikit-build, wheel, and build dependencies:
Build with -p to build and install the nanovdb_editor package.
./build.sh -p
python3 test/test_editor.py./build.sh -p
python3 test/test_streaming.pyAdd this line to the Python test script to print the PID of the process:
import os
print(os.getpid())- Build the debug configuration
- Run the test script; the console output will print the PID of the process
- Attach to the process:
With GDB:
gdb -p <PID>We keep the Vulkan headless FVDB viewer validated in both CI and local development with a shared integration suite and a consistent Docker image recipe.
./scripts/run_fvdb_viz_integration.sh mirrors the GitHub Actions job:
# Run release package tests (default)
./scripts/run_fvdb_viz_integration.sh
# Force rebuild the cached Docker image
./scripts/run_fvdb_viz_integration.sh --force-rebuild
# Validate the dev PyPI stream
./scripts/run_fvdb_viz_integration.sh --stream dev
# Smoke-test a locally built wheel
./scripts/run_fvdb_viz_integration.sh --local-wheel pymodule/dist/nanovdb_editor-*.whl
# Test against the latest fvdb-core nightly (pip install --pre)
./scripts/run_fvdb_viz_integration.sh --fvdb-nightlyHighlights:
- Ensures (and caches) the
nanovdb-editor_fvdb-<fvdb-core-version>Docker image with matching Torch/fvdb-core versions. - Prints the installed
nanovdb_editorversion inside the container before runningpytests/test_fvdb_viz_integration.py -vv -s --full-trace. - Prints the available Vulkan ICDs plus
vulkaninfo --summary, then fails fast iffvdb.vizcannot initialize instead of reporting a skipped upstream suite. - Accepts
--force-rebuildto bypass the local.cachetarball when you need a fresh base image.
.github/workflows/fvdb-viz-integration.yml runs on workflow_dispatch or workflow_call and:
- Resolves the package stream (release/dev) plus optional wheel artifact.
- Builds a lightweight
ubuntu:24.04-based Docker image with prebuilt fvdb-core wheels (pinned release or nightly viapip install --pre). - Runs the same pytest selector in Docker.
build-wheels.yml triggers two parallel integration jobs when run_fvdb_viz_integration is enabled: one against the pinned fvdb-core release and one against the latest nightly.
Shaders can have a defined struct with shader parameters that are intended to be shown in the editor's UI:
struct shader_params_t
{
float4 color;
bool use_color;
bool3 _pad1;
int _pad2;
};The editor uses one JSON schema for both shader-backed parameters and editor-only custom scene parameters. Shader-backed parameters live under the top-level key ShaderParams; custom scene parameters live under SceneParams. The two payloads have an identical field schema and are routed by their top-level key.
Shader-backed parameters can define UI defaults and bounds in a JSON file:
{
"ShaderParams": {
"color": {
"value": [1.0, 0.0, 1.0, 1.0],
"min": 0.0,
"max": 1.0,
"step": 0.01
}
}
}Editor-only custom scene parameters use the same field schema under the top-level SceneParams key, but each field must also declare type because there is no shader reflection to infer it:
{
"SceneParams": {
"exposure_bias": {
"type": "float",
"value": 0.0,
"min": -4.0,
"max": 4.0,
"step": 0.1,
"useSlider": true
},
"debug_slice": {
"type": "bool",
"value": false
},
"language_query": {
"type": "string",
"length": 128,
"value": "a red chair"
}
}
}Formal schema (applies under either ShaderParams or SceneParams):
ShaderParams/SceneParams: object whose keys are field names mapped to field-definition objects. UnderShaderParamsonly, the value may instead be an array of shader paths to define a group file.value: scalar or array initial value shown in the UI. Fortype: "string"it must be a JSON string.type: required for custom scene params; ignored for shader-backed params because the type comes from shader reflection.elementCount: optional explicit array length for custom scene params whenvalueis omitted or when zero-initialized storage is desired. Not valid fortype: "string"(uselengthinstead).length: required only fortype: "string"; positive integer capacity of thechar[length]buffer including the trailing\0. Capped at an editor-internal maximum.min: optional scalar or array lower bound for numeric widgets. Not valid fortype: "string".max: optional scalar or array upper bound for numeric widgets. Not valid fortype: "string".step: optional numeric increment for drag widgets. Defaults to0.01. Ignored fortype: "string".useSlider: optional boolean; renders a slider instead of a drag widget. Not valid fortype: "string".isBool: optional boolean; renders numeric0/1storage as a checkbox. Not valid fortype: "string".hidden: optional boolean; keeps the field mapped but hides it from the UI.
Supported scalar types: bool, int, int32, uint, uint32, int64, uint64, float, double, string.
Arrays are represented by using an array value or explicit elementCount; common reflected shader types such as float vectors and float4x4 are exposed this way.
type: "string" maps to a fixed-capacity char[length] in the reflected data type. The widget writes directly into the buffer on every keystroke, and map_params clients always observe the current widget contents. Clients that need to throttle per-string-change work (e.g. a text encoder) should debounce on their side.
Variables with _pad in the name are not shown in the UI.
Shader-backed parameters are shown in the object properties/shader parameter UI. Custom scene params are editor-only, loaded per scene through set_custom_scene_params(editor, scene, json_token, error_buf, error_buf_size) where json_token->str contains the JSON payload; on failure the function returns PNANOVDB_FALSE and writes a human-readable message into error_buf. Custom scene params are rendered in the dedicated Params window. They do not currently change object map_shader_params output.
To display a group of shader parameters from different shaders, define a group JSON file with shader paths:
{
"ShaderParams": [
"editor/editor.slang",
"test/test.slang"
]
}To convert the output to mp4:
ffmpeg -i input.h264 -c:v copy -f mp4 output.mp4
This project makes use of the following libraries:
- zlib – Compression library
- c-blosc – High-performance compressor optimized for binary data
- Vulkan-Headers – Vulkan API headers
- Vulkan-Loader – Vulkan ICD loader
- GLFW – Windowing, context, and input (optional)
- Dear ImGui – Immediate-mode GUI
- ImGuiFileDialog – File dialog for Dear ImGui
- ImGuiColorTextEdit – Syntax-highlighted text/code editor widget
- Slang – Shading language and compiler
- filewatch – Cross-platform file watching
- JSON for Modern C++ – JSON serialization for C++
- cnpy – Read/write NumPy .npy/.npz files from C++
- zstr – Transparent zlib iostream wrappers
- llhttp – High-performance HTTP parser
- Asio – Asynchronous networking and concurrency primitives
- RESTinio – Lightweight HTTP server framework
- fmt – Modern formatting library
- argparse – Header-only argument parser for C++17
- expected-lite – std::expected-like type for C++11/14/17
- libE57Format – E57 point cloud IO (optional)
- OpenH264 – H.264 encoder (optional)
- GoogleTest – C++ testing framework
Many thanks to the authors and contributors of these projects.