Crafter.Graphics/examples
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jorijn van der Graaf 449d5da553
docs: where the NVIDIA descriptor-heap faults stand on 615.78.08
The heap acceleration-structure read still needs the rewrite on
615.78.08; the READMEs say so and point at HeapASRead --no-workaround
for checking a newer driver. Dynamic descriptor indexing in hit shaders
is fixed there, which the README and the Sponza and SponzaBench notes
now say, and the VulkanTriangle investigation no longer contradicts
itself about llvmpipe, which advertises VK_EXT_descriptor_heap now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 03:03:17 +02:00
..
CustomShader feat(vulkan): run the compute/UI path without VK_EXT_descriptor_heap 2026-10-06 17:28:46 +02:00
Decompression SPDX license update 2026-07-22 18:09:06 +02:00
HDRBloom SPDX license update 2026-07-22 18:09:06 +02:00
HelloDom SPDX license update 2026-07-22 18:09:06 +02:00
HelloUI SPDX license update 2026-07-22 18:09:06 +02:00
HelloWindow SPDX license update 2026-07-22 18:09:06 +02:00
InputSystem SPDX license update 2026-07-22 18:09:06 +02:00
RayQueryPick SPDX license update 2026-07-22 18:09:06 +02:00
RTMultiShadow SPDX license update 2026-07-22 18:09:06 +02:00
RTStress SPDX license update 2026-07-22 18:09:06 +02:00
RTVolume feat(vulkan): run the compute/UI path without VK_EXT_descriptor_heap 2026-10-06 17:28:46 +02:00
Sponza docs: where the NVIDIA descriptor-heap faults stand on 615.78.08 2026-10-19 03:03:17 +02:00
SponzaBench docs: where the NVIDIA descriptor-heap faults stand on 615.78.08 2026-10-19 03:03:17 +02:00
VulkanTriangle docs: where the NVIDIA descriptor-heap faults stand on 615.78.08 2026-10-19 03:03:17 +02:00
LICENSE SPDX license update 2026-07-22 18:09:06 +02:00
README.md test(webgpu-rt): RTMultiShadow example exercising N shadow rays/pixel/bounce (#30) 2026-06-09 22:45:33 +00:00

Examples

Each example is a self-contained crafter-build project that depends on the parent Crafter.Graphics via LocalProject. To build and run any of them:

cd examples/<name>
crafter-build -r

Index

HelloWindow

Minimum viable program: open a window, run the event loop. No Vulkan rendering. Useful as a smoke test for Device::Initialize + Window + the platform backend.

VulkanTriangle

Ray-traced single triangle through vkCmdTraceRaysKHR. Shows the full ray-tracing setup: DescriptorHeapVulkan with image and buffer slots, PipelineRTVulkan from raygen / miss / closesthit SPIR-V, BLAS via Mesh::Build, TLAS via RenderingElement3D::BuildTLAS, direct vkWriteResourceDescriptorsEXT for swapchain views, RTPass on window.passes. Smallest test of the bindless ray-tracing path.

HelloUI

Compute-shader UI demo using all three UI tiers:

  • Tier 3 components: DrawButton, DrawSlider, DrawProgressBar, composed via Rect::SubRect for resize-safe layout.
  • Tier 2 standard shaders: DispatchQuads for the background and components, DispatchCircles for a cursor-tracking dot, DispatchText for the button label (with the FontAtlas wired up to UIRenderer).
  • Tier 1 is available too — any custom ComputeShader registered on the same heap can be dispatched alongside the standard ones.

Hit-testing and animation are user code (see the EventListener subscriptions on window.onMouseMove / onMouseLeftClick); the library does not track widgets or focus.

Drop a TTF in this directory as font.ttf before running (the example loads it via Font("font.ttf")).

InputSystem

Guided tour of Crafter::Input: name actions ("Jump", "Move", "Fire", "Look", "Zoom"), bind them to keys / mouse / gamepad (with composite bindings for WASD-as-Vector2 and analog sticks), and consume them as events. Demonstrates:

  • The compile-time Key(CrafterKeys::Space) helper that folds to a per-platform raw scancode — bindings stay cross-platform-readable in source while runtime data stores raw codes only.
  • All four action types (Button, Axis1D, Vector2) with multiple bindings per action (any-of semantics).
  • Map::StartRebind — press R, then press any input to remap "Jump" at runtime. Captured input is filtered out for that frame.
  • BindingToString / BindingFromString round-trip — print the default bindings as the on-disk format.
  • Gamepad hot-plug events: plug a controller in mid-run and the bindings start firing immediately.

Console-driven (no UI rendering needed); focus the window and watch stdout.

CustomShader

Tier 1 demo: a user-authored compute shader (inverse-circle.comp.glsl) running alongside the shipped drawQuads. The custom shader inverts RGB under each item-circle — exactly the kind of effect attempt #2's closed shader couldn't express. Shows:

  • Defining your own item POD struct in C++ + matching std430 struct in GLSL.
  • #include "../../shaders/ui-shared.glsl" for the bindless heap declarations + UIDispatchHeader push-constant contract.
  • ComputeShader::Load for the .spv, UIRenderer::RegisterBuffer for your SSBO, FillHeader to populate the standard prefix, and UIRenderer::Dispatch to launch — the same pattern the standard shaders use under the hood.
  • The inter-dispatch SHADER_WRITE → SHADER_READ|WRITE barrier is inserted automatically, so the custom shader sees the colored stripes drawn by the prior DispatchQuads and reads/writes the swapchain image safely.

RayQueryPick

Regression test for the WebGPU software ray-query shim. Builds a 512-instance TLAS and shoots one ray through a rayQuery=true PlainComputeShader, reading the committed hit back to the host and checking it against the analytically-known answer. Guards against the hardcoded-leaf-start TLAS-traversal bug (issue #25) that made every rayQuery pick miss for realistic instance counts. WebGPU/DOM only.

HDRBloom

Cross-backend-shaped HDR bloom on the WebGPU backend (issue #27). The RT pipeline's RESOLVE writes linear radiance into a user rgba16float texture (StorageImage2D, PipelineRTWebGPU::Init(..., RGBA16Float)), two PlainComputeShader passes threshold + blur it through float storage targets (UICustomBindingKind::StorageTexture), and a UI custom shader composites scene + bloom with a Reinhard tonemap onto the canvas. Exercises the three primitives an HDR post-process chain needs: float textures, write-only storage-texture bindings, and pre-tonemap radiance out of the wavefront. The threshold/blur passes run from onBeforeUpdate so each gets its own queue submit — the storage-write → sampled-read barrier WebGPU only provides between submits (or between passes), never within a single compute pass. WebGPU/DOM only; the same chain is wireable on Vulkan today via an offscreen HDR heap image + a composite RenderPass (the present path records passes generically and barriers between them).

RTMultiShadow

Multi-light shadowing through the wavefront RT pipeline (issue #30). Five pillars on a checkered ground, four colored point lights; the closest-hit emits one shadow ray per light from the same invocation, so up to four rays per pixel resolve in a single SHADE pass. Exercises both halves of the >1-ray-per-pixel-per-bounce widening: the atomic rtAccumulate (per-channel f32 CAS — concurrent same-pixel adds don't race) and RTPass::raysPerPixel (scales the ray/hit/payload buffers so the per-light emits aren't capacity-dropped). Any regression shows up as flickering dark noise or a missing shadow color in the overlap regions. WebGPU/DOM only.