Interactive 3D Visualization of Large Cayley Graphs via Vulkan.
cgvR
Interactive 3D visualization of large Cayley and state-space graphs via Vulkan.
https://github.com/user-attachments/assets/9af70289-d865-44db-b0a0-e67269fdd120
Overview
Cayley graphs of permutation puzzles (TopSpin, Rubik's cube, etc.) and game state graphs can have millions of nodes — far too many to render at once. cgvR provides GPU-accelerated 3D rendering on top of the Datoviz Vulkan engine, plus force-directed layout and camera/path animation utilities for exploring such graphs interactively.
Key features
- Vulkan rendering of nodes (points) and edges (segments), driven by Datoviz.
- Layout algorithms: Fruchterman-Reingold in pure R (
cgv_layout_fr) and a Barnes-Hut O(n log n) version in C (cgv_layout_fr_bh) for large graphs. - Camera control: fly (WASD + mouse), orbit, arcball;
cgv_fly_toto a node andcgv_fly_pathalong a Catmull-Rom spline of waypoints. - Path highlighting with custom colors, node scale and edge width.
- Video recording via ffmpeg pipe (
cgv_record_start/cgv_record_stop). - Headless mode (
cgv_viewer(..., offscreen = TRUE)) for tests and scripted offline rendering.
Dependencies
| Package | Role |
|---|---|
| cayleyR | Optional — Cayley graph construction, BFS, pathfinding |
System requirements
Supported operating systems (matches Datoviz upstream):
- Linux x86_64 — Ubuntu 22.04 or later (glibc 2.34+).
- macOS 12 or later — x86_64 and arm64 (Apple silicon M1–M4).
- Windows 10 or later — x86_64.
Vulkan support is auto-detected at install time. If the dependencies are missing, the package falls back to a stub build (see below).
Ubuntu / Debian — to enable full rendering:
sudo apt install libvulkan-dev libglfw3-dev pkg-config build-essential \
mesa-vulkan-drivers
# Optional, only for cgv_record_*:
sudo apt install ffmpeg
Shaders and cglm headers are bundled — no need for glslc or cmake. Tested on Ubuntu 22.04+ (matches upstream Datoviz: glibc 2.34+).
Windows — install Rtools and the LunarG Vulkan SDK. Make sure the VULKAN_SDK environment variable is set before R CMD INSTALL. Internet access during install is required — configure.win downloads the prebuilt datoviz.dll from GitHub releases (cached in inst/lib/ afterwards). Optional: ffmpeg.exe on PATH for cgv_record_*.
macOS 12 or later (x86_64 and arm64) — install dependencies via Homebrew plus the LunarG Vulkan SDK (which ships MoltenVK):
brew install glfw pkg-config
# Then install LunarG Vulkan SDK from
# https://vulkan.lunarg.com/sdk/home#mac
# and 'export VULKAN_SDK=...' before R CMD INSTALL.
configure auto-detects Darwin (sets OS_MACOS=1, links against the system MoltenVK loader, applies -mmacosx-version-min=12.0). GLFW pulls the required Cocoa / IOKit / CoreFoundation frameworks via its own pkg-config --libs glfw3.
A working Vulkan GPU driver is required at runtime regardless of platform (Mesa / NVIDIA / AMD on Linux, vendor driver on Windows, MoltenVK on macOS).
Build options
Force or skip the native build:
install.packages("cgvR", configure.args = "--with-vulkan") # require Vulkan; error if missing
install.packages("cgvR", configure.args = "--without-vulkan") # always stub build
Enable SIMD acceleration for fpng PNG screenshots (SSE4.1 + PCLMUL on x86):
install.packages("cgvR", configure.args = "--with-simd")
Combine flags as needed:
install.packages("cgvR", configure.args = "--with-vulkan --with-simd")
Installation
# install.packages("remotes")
remotes::install_github("Zabis13/cgvR")
# Optional: enable SIMD acceleration for fpng (PNG screenshots).
# Disabled by default for portability. Requires SSE4.1 + PCLMUL.
remotes::install_github("Zabis13/cgvR", configure.args = "--with-simd")
Quick start
library(cgvR)
# Build a small graph
n <- 100L
edges <- cbind(sample.int(n, 200, replace = TRUE),
sample.int(n, 200, replace = TRUE))
# Force-directed 3D layout
pos <- cgv_layout_fr(n, edges, n_iter = 200L, seed = 1L)
# Open a viewer and upload the graph
v <- cgv_viewer(1280, 720, "cgvR demo")
cgv_background(v, "black")
cgv_set_graph(v, 1:n, edges,
positions = pos,
node_values = as.double(seq_len(n)),
node_sizes = rep(8, n))
# Highlight a path
cgv_highlight_path(v, c(1, 5, 17, 42), color = "#FF2200",
node_scale = 1.6, edge_width = 3.0)
# Camera + run loop (right-click drag = rotate, scroll = zoom)
cgv_camera(v, position = c(20, 16, 24), target = c(0, 0, 0))
cgv_run(v)
More examples in inst/examples/:
demo_small_graph.R— random 100-node graph with FR layout.demo_cycles_bh.R— TopSpin cycles, Barnes-Hut FR layout.demo_tictactoe.R— Tic-Tac-Toe game graph, color = move number.demo_record.R,demo_cycles_bh_record.R— video recording.
Architecture
R API → .Call → C layer → Datoviz (Vulkan visuals)
↕
cayleyR (optional graph ops)
Datoviz, cglm and GLFW are compiled from sources bundled in src/ and linked statically into cgvR.so. The only external runtime dependency is libvulkan.so.
Stub build (no Vulkan)
If Vulkan or GLFW are missing at install time (or you pass --without-vulkan), cgvR falls back to a stub build: only a tiny C file is compiled, the package installs cleanly, and all rendering APIs (cgv_viewer, cgv_run, …) raise an informative error when called. Pure-R helpers like cgv_layout_fr() keep working. Use cgv_is_stub_build() to detect this mode at runtime.
License
MIT.