vtkSlang: typed shader customization for VTK’s WebGPU backend

Hi all,

I’d like to introduce vtkSlang, a library for typed shader customization in WebGPU renderers. Write a Slang type, select it by name, and let the compiler check the contract.

VTK’s OpenGL backend supports shader customization through string replacements at tags such as //VTK::Color::Impl. These are flexible, but a mistyped tag can silently do nothing, available variables depend on mapper state, and compilation errors point into generated GLSL. vtkSlang gives customization points explicit interfaces and reports invalid implementations in the supplied module.

I’m proposing its integration into VTK’s WebGPU backend and would love your feedback on the architecture.

Give your actor some stripes

prop->SetSlangModule(R"(
  module my_hooks;
  import vtkslang_hooks;
  public struct Stripes : IShaderHooks {
    float3 tint;
    public override void color(inout FragmentContext f) {
      if (frac(f.positionVC.y * 4.f) > 0.5f)
        f.diffuseColor = tint;
    }
  };)");
prop->SetSlangSpecialization("IShaderHooks", "Stripes");

const float rgb[3] = { 0.08f, 0.65f, 0.90f };
prop->GetFragmentCustomUniforms()->SetUniform3f("hooks.tint", rgb);

Same geometry, camera and lighting. Default shading on the left; the Stripes hook with a blue tint on the right.

Rename color to colour, and the compiler points straight to the invalid override:

error[E30854]: 'colour' marked as 'override' is not overriding any base declarations
 --> vtkslang-embedded:/my_hooks.slang:6:26
  |
6 | public override void colour(inout FragmentContext f) {
  |                      ^^^^^^ 'colour' marked as 'override' is not overriding any base declarations

That’s line 6, column 26 in the supplied module. One less mystery to hunt through generated shader code.

Hooks handle small adjustments; interfaces such as IMaterial and ILightingModel replace entire stages. Fields become named parameters, and [Range] and [Label] attributes supply metadata for UI controls.

Three pieces, clear responsibilities

  • vtkSlang is a BSD-3-Clause C++17 library, currently at 0.1.0. It owns the shared shader interfaces and shading sequence, compilation, reflection and parameter packing. It makes no WebGPU calls.
  • VTK::RenderingSlang wraps it through vtkSlangShaderManager, with VTK::CommonCore as its VTK dependency. It builds a stub when VTK_USE_SLANG is off.
  • VTK::RenderingWebGPU owns VTK’s shader programs, binding policy and GPU objects.

The separate library also serves anari-webgpu, allowing compatible materials and hooks to travel between renderers. Sharing the parameter packer has already fixed a matrix-layout bug in that integration.

The architecture document covers the interfaces, runtime flow, binding layout and API changes. Feedback on the design is welcome, and thanks to everyone who has helped shape it so far!

Sankhesh