VTK::RenderingWebGPU#
Description#
This module contains the WebGPU native backend for RenderingCore. Currently, it supports rendering polygonal geometry in different representations with point/cell scalar-mapped colors.
When both the RenderingOpenGL2 and RenderingWebGPU libraries are linked, the user must provide preferences to select the rendering backend at runtime. This can be done in two ways:
Pass command line arguments to your application
--vtk-factory-prefer RenderingBackend=WebGPUor--vtk-factory-prefer RenderingBackend=OpenGL2. Then, you will need to invokevtkObjectFactory::InitializePreferencesFromCommandLineArgs(argc, argv)in your main function before creating any VTK object.Alternatively, set the
VTK_FACTORY_PREFERenvironment variable toRenderingBackend=WebGPUorRenderingBackend=OpenGL2.
Building VTK with Dawn (Highly Experimental)#
Prerequisites#
Git
tools for building VTK
A compiler C++ 20 compatible (eg: clang-19 or newer) required to compile Dawn. [VTK supports C++17 compilers]. Not required if using pre-built dawn binaries
Desktop#
On desktop (Linux, macOS, and Windows), this module runs on Dawn’s WebGPU implementation, through the C API. You can get Dawn with any of these two methods:
Build Dawn from source.
Fetch pre-built Dawn binaries built in release mode.
These two methods are supported on all three operating systems. Pre-build Dawn binaries are available only for linux-x86_64, windows-x86_64, macos-x86_64 and macos-arm64. If you are on a different platform, you will need to build Dawn from source.
Here, VTK_SOURCE_DIR is the path to the root of the VTK source directory, and VTK_BUILD_DIR is the path to the directory where you want to build VTK.
Build Dawn from source#
Dawn should be built at tag v20260720.160313.
Here, DAWN_INSTALL_DIR should point to the directory where Dawn is installed (should contain lib and include directories).
# Clone the repo and checkout the required version
git clone https://github.com/google/dawn dawn && cd dawn
git checkout v20260720.160313
cmake -S . -B out/Debug -GNinja -DDAWN_FETCH_DEPENDENCIES=ON -DDAWN_ENABLE_INSTALL=ON -DDAWN_BUILD_MONOLITHIC_LIBRARY=SHARED
cmake --build out/Debug
cmake --install out/Debug --prefix ${DAWN_INSTALL_DIR}
Fetch pre-built Dawn binaries#
Run the following command to fetch pre-built Dawn binaries. This will download and install Dawn to VTK_SOURCE_DIR/.gitlab.
cd "${VTK_SOURCE_DIR}"
CMAKE_CONFIGURATION="fedora" cmake -P .gitlab/ci/download_dawn.cmake
export DAWN_INSTALL_DIR="${VTK_SOURCE_DIR}/.gitlab/dawn"
cd "${VTK_SOURCE_DIR}"
CMAKE_CONFIGURATION="macos_arm64" cmake -P .gitlab/ci/download_dawn.cmake
export DAWN_INSTALL_DIR="${VTK_SOURCE_DIR}/.gitlab/dawn"
cd "${VTK_SOURCE_DIR}"
CMAKE_CONFIGURATION="macos_x86_64" cmake -P .gitlab/ci/download_dawn.cmake
export DAWN_INSTALL_DIR="${VTK_SOURCE_DIR}/.gitlab/dawn"
cd "$env:VTK_SOURCE_DIR"
$env:CMAKE_CONFIGURATION="windows"; cmake -P .gitlab/ci/download_dawn.cmake
$env:DAWN_INSTALL_DIR="$env:VTK_SOURCE_DIR\.gitlab\dawn"
After you are finished, you should see a new directory VTK_SOURCE_DIR/.gitlab/dawn which contains the pre-built Dawn binaries. Set DAWN_INSTALL_DIR to VTK_SOURCE_DIR/.gitlab/dawn so that you can pass it to CMake when configuring VTK’s build.
Configure and build VTK#
Run the following commands to configure and build VTK with WebGPU support.
cmake \
-S "${VTK_SOURCE_DIR}" \
-B "${VTK_BUILD_DIR}" \
-GNinja \
-DVTK_ENABLE_WEBGPU=ON \
-DDawn_DIR="${DAWN_INSTALL_DIR}/lib/cmake/Dawn" \
-DVTK_BUILD_TESTING=ON
cmake --build "${VTK_BUILD_DIR}"
cmake `
-S "$env:VTK_SOURCE_DIR" `
-B "$env:VTK_BUILD_DIR" `
-DCMAKE_BUILD_TYPE=Release `
-GNinja `
-DVTK_ENABLE_WEBGPU=ON `
-DDawn_DIR="$env:DAWN_INSTALL_DIR/lib/cmake/Dawn" `
-DVTK_BUILD_TESTING=ON
cmake --build "$env:VTK_BUILD_DIR"
Warning
When copy pasting the commands on Windows, please paste them into a Powershell window and not a Command prompt!
Warning
On Windows, ensure that you are using the same CMAKE_BUILD_TYPE for both building Dawn and configuring VTK. Or else, you will see a linker error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in vtkRenderingWebGPUObjectFactory.cxx.obj.
WebAssembly#
On WebAssembly, this module uses the WebGPU implementation provided by the browser. You do not need to build Dawn from source or fetch pre-built Dawn binaries. You just need to configure and build VTK with Emscripten. It takes care of linking the WebGPU implementation provided by the browser (with the --use-port=emdawnwebgpu flag).
Configure and build VTK#
Run the following commands to configure and build VTK for WASM with WebGPU support.
emcmake cmake \
-S "${VTK_SOURCE_DIR}" \
-B "${VTK_BUILD_DIR}" \
-GNinja \
-DVTK_ENABLE_WEBGPU=ON \
-DBUILD_SHARED_LIBS=OFF \
-DVTK_BUILD_TESTING=ON
cmake --build "${VTK_BUILD_DIR}"
Running Tests#
WebGPU Tests#
cd ${VTK_BUILD_DIR}
ctest -R RenderingWebGPU -V
cd $env:VTK_BUILD_DIR
ctest -R RenderingWebGPU -V
Rendering Core Tests#
To run the RenderingCore tests with VTK::RenderingWebGPU:
cd ${VTK_BUILD_DIR}
ctest -R RenderingCoreCxx-WebGPU -V
cd $env:VTK_BUILD_DIR
ctest -R RenderingCoreCxx-WebGPU -V
WebGPU Runtime Loading#
VTK’s WebGPU module resolves a WebGPU implementation library at runtime through a proc table. The eventual goal is to decouple the compile-time and runtime dependencies so that the same VTK build works with different native WebGPU runtimes (Dawn, wgpu-native) or browser WebGPU via Emscripten.
Note
This decoupling is not complete. When Dawn is found at configure time the module
links no implementation: the wgpu* names are redirected to a dispatch table
that the proc table fills in, so the only requirement is that an implementation
can be found at runtime. vtkWebGPUConfiguration::Initialize() fails with a
diagnostic if none can be.
On Emscripten there is no library to resolve: --use-port=emdawnwebgpu links the
implementation into the module, so the proc table reports itself loaded without
opening anything.
The implementation uses lazy initialization that is thread-safe and loads on first access. The library is opened with global symbol visibility, so direct calls to the WebGPU C API resolve against it without modification. Missing libraries are reported at initialization (not link time), with clear diagnostic messages. If functions are unavailable, wrappers return safe values for graceful fallback.
Architecture#
The implementation consists of two layers:
vtkWebGPUProcTable (C interface): loads the WebGPU implementation library and resolves function pointers using the runtime’s proc address function.
vtkWebGPUProcLoader (C++ singleton, internal): wraps the proc table with lazy initialization. Provides
IsLoaded()andLoad(), and is reached throughvtkWebGPUConfiguration::Initialize().
VTK’s sources call the WebGPU C API by its ordinary names. The build forces
Private/vtkWebGPUProcDispatch.h into the module’s own sources and its tests,
and that header #defines each wgpu* name to the matching entry in a table of
function pointers, filled in from wgpuGetProcAddress once the library is open.
The forced include keeps the redirect off installed headers and out of anything
a consumer compiles.
Private/vtkWebGPUProcDispatch.{h,cxx} are generated. After updating
ThirdParty/webgpuheaders, regenerate them and commit the result:
python3 Rendering/WebGPU/generate_proc_dispatch.py
Handles cannot take the entry points as template arguments any more - the
address of a table entry is not a constant expression - so vtkWebGPU::Handle
takes a traits type whose AddRef/Release call through the table instead.
Initialization flow: vtkWebGPUConfiguration::Initialize() invokes
vtkWebGPUProcLoader::GetInstance(), which loads the WebGPU implementation
library (e.g., libwgpu_dawn.so), resolves function pointers via the proc
table, then creates a WebGPU adapter and device.
Standard WebGPU Headers#
VTK vendors a copy of the upstream
webgpu-headers C API in
ThirdParty/webgpuheaders. It defines the core WebGPU types (WGPUInstance,
WGPUDevice, etc.) and the function signatures that the proc table resolves at
runtime.
This vendored copy is what VTK compiles against on every platform, including
builds that link Dawn — VTK::webgpuheaders is a public dependency, so its
include directory is searched ahead of any implementation’s. VTK is therefore
decoupled from a particular implementation at the header level: the API cannot
change underneath VTK, and downstream consumers resolve the same header through
find_package(VTK).
Both VTK’s public headers and its implementation files use the C API only. No
C++ wrapper (webgpu_cpp.h) is vendored or included; ownership of the C handles
is expressed with Private/vtkWebGPUHandle.h. The module builds as C++17 and
the installed interface does not require C++20 of its consumers.
Upstream deliberately declares only the standard API. Implementations extend it
through nextInChain, using WGPUSType values from blocks upstream reserves for
them. The two extensions VTK uses — Dawn’s adapter power preference and
emdawnwebgpu’s canvas selector — are declared in
Private/vtkWebGPUImplExtensions.h, each behind the compile-time flag for the
implementation that provides it.
Library Search Strategy#
If an explicit library path is given to the loader, it is tried first and on its own. Otherwise the proc table tries the following names, in this order:
libwgpu_dawn.so(the default when no path is supplied)libwebgpu_dawn.solibwgpu_dawn.so.0(versioned variant)libwebgpu_dawn.so.0(versioned variant)libwgpu_dawn.dylib(macOS)libwebgpu_dawn.dylib(macOS)wgpu_dawn.dll(Windows)webgpu_dawn.dll(Windows)
An explicit path is opened through vtkDynamicLoader on every platform. A bare
name is opened with LoadLibraryW on Windows, so that the standard DLL search
order applies: vtkDynamicLoader routes a name through
Encoding::ToWindowsExtendedPath, which resolves it against the current working
directory instead of searching PATH. Elsewhere vtkDynamicLoader maps onto
dlopen/dlsym.
Custom paths: You can override the search by setting environment variables:
Linux:
LD_LIBRARY_PATH=/path/to/libmacOS:
DYLD_LIBRARY_PATH=/path/to/libWindows:
PATH=\path\to\lib
Or by naming the library outright: set VTK_WEBGPU_LIBRARY to the path of the
implementation to load, and the search above is skipped.
Debugging and Diagnostics#
Library loading failed:
Check if the WebGPU library is installed:
ldconfig -p | grep -E '(wgpu_dawn|webgpu_dawn)'(Linux), or verify in/usr/libor/opt/local/lib(macOS), orPATH(Windows)Ensure the library is in a standard search path or set
LD_LIBRARY_PATH=/path/to/lib(Linux),DYLD_LIBRARY_PATH(macOS), orPATH(Windows)Test library loading directly:
python3 -c "import ctypes; ctypes.CDLL('/path/to/libwgpu_dawn.so')"(adjust path/name as needed)
Function not found:
Verify the function name is spelled correctly and the length is correct (must match string length in bytes)
Check if the loaded library version exports the function:
nm /usr/lib/libwgpu_dawn.so | grep wgpuFunctionNameEnable debug output in vtkWebGPUProcTable.cxx during development
Features#
The following features are currently implemented:
vtkPolyData Rendering: Supports point, line, and triangle primitives.
Glyph Rendering: Supports point, line, and triangle primitives.
Composite vtkPolyData Rendering: Supports point, line, and triangle primitives.
Scalar Mapped Coloring:
Point scalar mapped coloring of surfaces.
Cell scalar mapped coloring.
Actor Representations:
VTK_POINTSVTK_WIREFRAMEVTK_SURFACEVTK_SURFACEwith edge visibility
Lighting:
Based on VTK headlights.
Supports point/cell normals.
Rendering Adjustments:
Point size adjustments.
Line width adjustments for wireframe and surface with edges.
Depth Testing: Enables correct rendering of 3D objects.
Selections: Hardware selector can pick cells, composite datasets and actors.
Compute Shader API#
The compute shader API allows offloading work from the CPU to the GPU using WebGPU compute shaders.
User-level information: Compute API User Guide
Developer-level information: Compute API Developer Guide
Future Work#
Since WebGPU is already an abstraction over graphics APIs, this module avoids creating another level of abstraction. Helper classes in the Private/vtkWebGPU<Thing>Internals files ensure cleaner bind group initialization code.
The module uses the WebGPU C API throughout. Ownership of the C handles is
expressed with VTK’s own reference-counted wrapper in
Private/vtkWebGPUHandle.h, which provides the RAII the wgpu:: C++ types used
to supply.
Planned improvements include:
Volume mappers
Dual-depth peeling
Advanced lighting
Platform-native render windows for Windows, macOS, Android, iOS and wayland.
References#
Here are some valuable resources for learning WebGPU:
-
Complete introduction to using WebGPU
-
Builds an efficient glTF renderer in WebGPU using JavaScript.
Discusses various rendering pitfalls and optimizations.
-
A collection of single-file examples demonstrating various WebGPU use cases in C.
-
Similar to LearnOpenGL and Vulkan tutorials.
Covers window setup, triangle rendering, buffers, textures, and 3D rendering.
-
Beginner-friendly tutorial using wgpu.rs.
-
Introductory tutorial covering WebGPU concepts using JavaScript.
How to Render a WebGPU Triangle (Series)
Explains swapchain and image presentation in detail.
-
A well-organized WebGPU API and WGSL summary.
For WGSL specification, refer to: WGSL Spec