Source-derived reference

Shader Pack Reference

This page is based on Sulkan's current source tree. It documents how packs are discovered, normalized, mounted, and expected to match Sulkan's shader pipeline contracts.

Discovery path

Sulkan scans the game directory's shaders/ folder. In local development that is typically run/shaders.

Supported sources

A folder directly under shaders/ or a .zip directly under shaders/. Both are normalized before activation.

Generated active pack

External packs are mounted through resourcepacks/sulkan_shaderpack_active with a generated pack.mcmeta.

What Sulkan actually loads

Sulkan supports two shader content sources: the built-in shader set bundled in assets/sulkan/shaders, and external packs discovered from the game's shaders/ directory. External packs are not mounted directly in place. They are normalized into a generated resource pack and then reloaded through Minecraft's resource-pack system.

Pack IDs are derived from the folder name or zip filename. The built-in pack always uses __builtin__. If a selected external pack disappears, Sulkan falls back to the built-in pack automatically.

Pack contract

Layout and normalization rules

Layout inside pack Result
assets/sulkan/shaders/... Used as-is. This is the native Sulkan namespace.
shaders/... Remapped to assets/sulkan/shaders/... during staging. This is the simplest format for pack authors.
pack.png Preserved when present and copied into the generated active resource pack.
Representative base template
shader-pack.zip
|- README.md
|- pack.png
|- shaders/
|  |- core/
|  |  |- shadow_depth.vsh
|  |  |- shadow_depth.fsh
|  |  |- entity_shadow_depth.vsh
|  |  |- entity_shadow_depth.fsh
|  |  |- terrain_shadow.vsh
|  |  |- terrain_shadow.fsh
|  |  |- entity_shadow.vsh
|  |  |- entity_shadow.fsh
|  |  |- terrain.vsh
|  |  |- terrain.fsh
|  |  |- water.vsh
|  |  |- water.fsh
|  |  |- ao.vsh
|  |  |- xegtao_evaluate.fsh
|  |  |- xegtao_denoise.fsh
|  |  |- ao_apply.fsh
|  |  |- volumetric_clouds.vsh
|  |  |- volumetric_clouds.fsh
|  |  |- volumetric_clouds_composite.fsh
|  |  |- atmosphere_composite.fsh
|  |  |- bloom_prefilter.fsh
|  |  |- bloom_downsample.fsh
|  |  |- bloom_blur.fsh
|  |  |- bloom_composite.fsh
|  |  |- luminance_downsample.fsh
|  |  |- exposure_adapt.fsh
|  |  |- fxaa.fsh
|  |- include/
|  |  |- chunksection.glsl
|  |  |- held_light.glsl
|  |  |- scene_tonemap.glsl
|  |  |- shadow_sampling.glsl
|  |  |- sulkan_terrain_core.glsl
|  |  |- terrain_atlas_sampling.glsl
|  |  |- wind.glsl
Entry mapping rules
  • Path separators are normalized to /.
  • Leading / characters are removed.
  • Entries containing .. are rejected outright.
  • A leading container directory is trimmed when the nested path begins with assets/, shaders/, or pack.png.
  • A pack is considered supported only when at least one normalized file lands under assets/sulkan/shaders.
What base-shader.zip actually ships

Shadows

shadow_depth.*, entity_shadow_depth.*, terrain_shadow.*, entity_shadow.*

Eight core files plus receiver-side helpers like shadow_sampling.glsl.

Terrain and water

terrain.*, water.*

Main world receiver surface, water scene shading, and wind-aware terrain paths.

Ambient occlusion

ao.vsh, xegtao_evaluate.fsh, xegtao_denoise.fsh, ao_apply.fsh

The full screen-space AO chain is in the downloadable base template.

Clouds and atmosphere

volumetric_clouds.*, volumetric_clouds_composite.fsh, atmosphere_composite.fsh

Cloud rendering, cloud composite, and the late fog or sky atmosphere composite are all present.

Bloom, exposure, and FXAA

bloom_*.fsh, luminance_downsample.fsh, exposure_adapt.fsh, fxaa.fsh

The late post chain is part of the starter pack, not something authors have to reconstruct later.

Shared helpers

include/*.glsl

Seven shared include files are bundled so pack authors can follow the exact helper layer the current source tree uses.

Entrypoints you can override

Any file under Sulkan's shader namespace can be overridden, but the main pack-facing entrypoints live in assets/sulkan/shaders/core. The most reliable approach is to treat Sulkan as its own shader target rather than assuming foreign pack layouts will be partially adapted.

Shadows

shadow_depth.*, entity_shadow_depth.*, terrain_shadow.*, entity_shadow.*

Terrain and entity caster and receiver passes. These are the most coupled entrypoints because they depend on shared split and depth bindings.

Water and terrain

water.*, terrain.*

Water uses scene color, scene depth, and shadow data. Terrain paths also rely on lightmap and atlas bindings.

Ambient occlusion

ao.vsh, xegtao_evaluate.fsh, xegtao_denoise.fsh, ao_apply.fsh

Screen-space AO evaluation, denoise, and composite passes.

Clouds and atmosphere

volumetric_clouds.*, volumetric_clouds_composite.fsh, atmosphere_composite.fsh

Late-stage sky and post composite passes.

Bloom and exposure

bloom_prefilter.fsh, bloom_downsample.fsh, bloom_blur.fsh, bloom_composite.fsh, luminance_downsample.fsh, exposure_adapt.fsh

Post-processing chain for bloom and exposure adaptation.

Anti-aliasing

fxaa.fsh

Late full-screen anti-aliasing pass. It is pack-facing even though it is toggled separately from the quality presets.

Shared includes

include/chunksection.glsl, include/held_light.glsl, include/scene_tonemap.glsl, include/shadow_sampling.glsl, include/sulkan_terrain_core.glsl, include/terrain_atlas_sampling.glsl, include/wind.glsl

Override these with care. Receiver behavior often depends on shared helper code as much as on the main entrypoint.

Stable binding contracts

Sulkan's Java side centralizes shader-facing resource names in a single binding registry. For pack authors, the stable contract is the combination of entrypoint names, uniform block names, sampler names, and compile-time defines that the live pipelines already expect.

Binding Type Current usage
ShadowMatrices UBO Terrain shadow caster matrices for core/shadow_depth.*.
EntityShadowMatrices UBO Entity shadow caster matrices for core/entity_shadow_depth.* and entity receiver vertex work.
TerrainShadowSplits UBO Receiver-side shadow split ranges and matrices used by terrain, entity, and water receivers.
WaveUniforms UBO Water animation and wave parameters shared by water shading and terrain helpers.
Sampler1 Sampler Overlay sampler used by the entity receiver path.
Sampler3 Sampler Water scene color capture. Used for refraction and surface blur.
Sampler4 / 6 / 7 Sampler Terrain shadow depth cascades 0 through 2. Current source tree exposes three terrain cascades, not four.
Sampler5 Sampler Water scene depth capture. Used for thickness, intersection, and refraction depth tests.
Sampler8 Sampler Held-light spotlight shadow depth.
Sampler9 Sampler Dynamic entity shadow depth.
Important note

Several passes also depend on vanilla-style bindings such as Sampler0 for the base texture or atlas and Sampler2 for the lightmap. Those are visible in the shipped GLSL files and should stay declared where the pipeline expects them, even though the Sulkan-specific registry focuses on the extra binding contract above.

Recommended workflow

Author from the template, not from guesswork

  • Start from run/shaders/base-pass-through or the downloadable base-shader.zip. The template mirrors the current built-in shader tree, including shadows, terrain, water, AO, clouds, atmosphere, bloom, exposure, FXAA, and include helpers.
  • Preserve entrypoint names, block names, and sampler names unless you are changing the Java pipeline definitions and GLSL together.
  • Edit one subsystem at a time. Stabilize terrain or water first, then AO, then clouds or atmosphere, then the late post chain.
  • Keep the short shaders/... layout while authoring locally, then zip the pack contents and drop the archive into the shaders/ folder.
  • After reload, check the client log for [Sulkan] Compiled pipeline ... lines. A successful Gradle build is not enough to prove runtime shader compatibility.
  • The template preserves optional defines such as ALPHA_CUTOUT, PER_FACE_LIGHTING, NO_OVERLAY, EMISSIVE, and DISSOLVE. Do not strip them unless you are sure the pass no longer needs them.
Template pack

The repository includes a source-aligned starter at run/shaders/base-pass-through. The repo copy and downloadable zip mirror Sulkan's current built-in shader tree, so the template already includes AO, clouds, atmosphere, bloom, exposure, FXAA, terrain, water, shadows, and shared include helpers.

Download base-shader.zip
Template-defined optional macros
ALPHA_CUTOUT
PER_FACE_LIGHTING
NO_OVERLAY
EMISSIVE
DISSOLVE

Common failure modes

Sulkan tries to fail soft. Unsupported entries still show up in the UI summary, and invalid selections fall back safely. That does not make authoring errors obvious by default, so these are the first cases to check.

Symptom Likely cause
Pack ignored entirely No normalized file landed under assets/sulkan/shaders.
Zip looks correct but still fails A leading container directory is only trimmed when the nested path begins with assets/, shaders/, or pack.png.
Folder or archive is listed as unsupported Common causes are unreadable folders, invalid zip archives, wrong internal layout, or non-zip files placed directly in shaders/.
Selection silently falls back If the configured external pack disappears, Sulkan normalizes the selection back to __builtin__.