Your first shader pack
Download, run, and edit a complete native pack with one fullscreen exposure pass.
Download and try it
Download Sulkan Starter ZIP. It is a native format 1 pack with one Exposure control.
- Install Sulkan 0.5.1 and its dependencies.
- Put the ZIP in the active instance’s
shaders/folder. - Open Video Settings → Shaders, select Sulkan Starter, and enable shaders.
- Open Pack Settings, change Exposure to 1.5, and press Apply. The scene should brighten. Reset to 1.0 for the original exposure.
This adjusts the existing scene. It does not add clouds, shadows, or a new terrain lighting model. Selecting it replaces the active pack, including Sulkan Realistic.
1. Create the folder
Extract the ZIP for editing, then remove or rename the ZIP to avoid duplicate choices.
<active instance>/shaders/Sulkan-Starter/
├── sulkan.json
├── README.md
├── LICENSE
└── shaders/
└── exposure.fsh
Keep sulkan.json at the pack root. Paths resolve from this folder, not the GLSL file’s directory.
2. Understand the manifest
{
"version": 1,
"name": "Sulkan Starter",
"budgetMiB": 64,
"options": {
"EXPOSURE": { "label": "Exposure", "default": 1.0, "values": [0.5, 0.75, 1.0, 1.25, 1.5, 2.0] }
},
"resources": { "display": { "format": "RGBA8_UNORM" } },
"passes": [
{ "name": "exposure", "fragment": "shaders/exposure.fsh", "reads": { "Scene": "$scene" }, "writes": ["display"] }
],
"present": "display"
}
version: 1chooses the native format.EXPOSUREbecomes a GLSL define and an in-game setting. The default must appear in numericvalues.displayis full-viewport because scale defaults to 1.Scenebinds Minecraft’s pre-post-processing color,$scene.- The pass writes
display, which is then presented.
The 64 MiB budget suits this example at ordinary viewport sizes. Device overhead and temporary reload generations are additional. Very high resolutions may require a larger budget.
3. Read the shader
#version 450
layout(location = 0) in vec2 texCoord;
layout(location = 0) out vec4 fragColor;
uniform sampler2D Scene;
void main() {
vec4 scene = texture(Scene, texCoord);
fragColor = vec4(clamp(scene.rgb * float(EXPOSURE), 0.0, 1.0), scene.a);
}
Sulkan generates a fullscreen triangle. Input location 0 receives texture coordinates. Output location 0 corresponds to the first writes item.
For graphics, declare the sampler with the same key as reads. The loader assigns bindings; do not hardcode descriptor sets. float(EXPOSURE) matters because whole-valued options are emitted as integer literals.
4. Make a visible edit
Replace the output assignment with a warm tint:
vec3 tint = vec3(1.05, 1.0, 0.92);
fragColor = vec4(clamp(scene.rgb * float(EXPOSURE) * tint, 0.0, 1.0), scene.a);
Save, then disable and reselect the pack to load a fresh snapshot. Editing a file alone does not change the immutable active generation.
If compilation fails, inspect the first error for exposure.fsh in logs/latest.log. Keep the untouched ZIP as a baseline.
Next steps
Add another resource using Passes & resources, or animate effects with Frame uniforms. Inspect Sulkan Realistic for a complete scene implementation.
The independent starter sources are MIT licensed. The separate bundled pack retains its own port notes and licensing.