# Shader API Horizon has no shader packs today: the earlier implementation was removed on 2026-10-24. Two things will replace it, designed separately: a **Horizon shader API**, described here, and a clean-room loader for the existing pack format (its own spec; it is not part of this API). Both sit on the same renderer hooks, agreed between the two. ## Overview: what a shader author will be able to do Write WGSL against documented stages of Horizon's renderer, with typed inputs, options the player can change, a reload as soon as a file is saved and an overlay that shows what each pass costs and draws. The renderer keeps everything that makes it fast (culling, batching, LOD, the mesher); a pack changes how surfaces and light look, not how the world is fed to the GPU. ## The design - **A pack** is a folder or a zip with `horizon-shaders.toml` (id, name, version, the `api` line, the stages it uses, its options) and WGSL files. No preprocessor and no other shading language: WGSL is what wgpu validates and compiles for Vulkan, Metal and DirectX 12. - **Stages, not pipelines.** A stage is a function with a fixed signature that the renderer calls inside its own pass, for example a terrain material (`fn material(input: TerrainInput) -> Surface`), the lighting of the visible surfaces, the sky, an optional shadow pass, and a chain of full-screen post passes ending in the frame. A pack that leaves a stage out gets vanilla's look for it. - **Typed inputs.** Each stage receives structs (the frame: time, camera, sun and moon, weather, fog; the surface: position, normal, block and its light) whose WGSL is generated from the Rust types the renderer uploads. The generated reference lists every field with its unit and range, and a test fails when it drifts. - **Options are WGSL `override` constants.** The manifest declares each option (on/off, a number in a range, a choice) with its default; the game shows them on the pack's settings screen and sets them when it builds the pipeline. No text substitution, and every option combination is validated the same way. - **Hot reload.** The game watches the pack's folder. A saved file is validated with naga and the stage rebuilt; on an error the last good version keeps drawing and the error, with its file and line, is shown in the overlay. - **Debug overlay.** GPU time per stage and pass (timestamp queries), the targets each pass writes (show any of them full-screen), the pack's options and its compile errors. - **Budgets.** A pack declares the targets and passes it needs; the renderer refuses more than its limits, and the benchmark ([benchmark-report.md](../benchmark-report.md)) records the pack and its cost, so "fast" stays measured. - **Off by default.** Without a pack the renderer is vanilla's look, and no pack code runs. ## Guide, reference and examples None yet. When the first stage lands: a guide here, a generated reference (`shaders-reference.md`) and an example pack in the repository that the renderer's tests load. ## Stability Not started. The first stages will be experimental (opt-in), then preview once a reference, an example and a test pack exist ([stability.md](stability.md)). ## Not there yet Everything on this page. The order: the renderer hooks shared with the format loader, then the material and post stages with options and hot reload, then the overlay, lighting, sky and shadow stages. ## Changelog - 2026-10-24: the earlier shader pack code was removed; this API is designed from scratch.