ShaderEffect/ShaderNodeRhi/ShaderCompilerinfrastructure for mounting per-frame shader passes inside a Qt Quick scene graph, plus the zone-aware UBO extension used by the overlay.
Qt Quick's built-in ShaderEffect doesn't support multipass, compute shaders, custom UBO layouts, or shader-file #include. This library replaces it with three cooperating pieces:
ShaderEffect** — a QQuickItem subclass that owns one render node, exposes shader source and parameters as Q_PROPERTYs, and delegates uniform packing to a pluggable IUniformExtension (declared in `phosphor-shaders`).ShaderNodeRhi** — the scene-graph render node. Owns the QRhi pipeline, vertex and index buffers, the uniform buffer object (UBO), texture bindings, and per-pass targets. Supports multipass via ping-pong buffers, input-channel textures (iChannel0..3, Shadertoy-style), and writeable depth attachments.ShaderCompiler** — a runtime GLSL to SPIR-V compiler using Qt6::ShaderToolsPrivate. Feeds into Qt's shader pipeline. Caches compiled modules keyed on source-hash and target-API, so re-entering the editor doesn't recompile unchanged shaders.A second pair of types specialises the base node for the zone-overlay case: ZoneShaderNodeRhi adds a labels texture binding and zone counts in the base UBO, and ZoneUniformExtension writes zone rects, fill / border colours, and per-zone parameters into the UBO tail. They are optional — non-zone shader effects use ShaderEffect + ShaderNodeRhi directly.
| Type | Purpose |
|---|---|
PhosphorRendering::ShaderEffect | The QQuickItem you instantiate in QML |
PhosphorRendering::ShaderNodeRhi | The QRhi-backed scene-graph node it owns |
PhosphorRendering::ShaderCompiler | GLSL to SPIR-V pipeline with on-disk cache |
PhosphorRendering::ZoneShaderNodeRhi | Zone-aware subclass: labels texture + zone counts in BaseUniforms::appField0/1 |
PhosphorRendering::ZoneShaderCommon | Shared layout constants (MaxZones, GLSL-matching struct) |
PhosphorRendering::ZoneUniformExtension | IUniformExtension writing zone rects / colours / params |
In QML:
import PhosphorRendering 1.0
ShaderEffect {
anchors.fill: parent
fragmentShader: "qrc:/shaders/neon-city/effect.frag"
bufferShaderPaths: [
"qrc:/shaders/neon-city/buffer.frag"
]
customParams: [0.7, 1.0, 0.35, 0.0] // packed into UBO
customColors: ["#3B82F6", "#A855F7"]
// Optional: a uniform extension feeds per-zone data into the UBO tail
uniformExtension: ZoneUniformExtension { zones: view.zones }
}ShaderNodeRhi inside the render thread. The item just carries paths and parameters. This avoids the GPU-resource-lifetime bugs that plague naive ShaderEffect reimplementations.bufferShaderPaths to a non-empty list enables the multipass path.BaseUniforms + extension. The base layout from `phosphor-shaders` is Shadertoy-compatible; consumers attach an IUniformExtension to append application-specific data. Zone rendering uses ZoneUniformExtension; animations use a different one declared in `phosphor-animation`.QtCore, QtGui, QtQuick, QtSvgBaseUniforms, IUniformExtensionQt6::ShaderToolsPrivate for runtime compilationShaderRegistry, parameter metadata, wallpaper provider, include resolver.