An introduction to shaders and their role in graphics rendering.
A shader is a small GPU program that changes how something is drawn. In Kraken, custom shaders are used as fragment effects; they receive the color, texture coordinates, textures, samplers, and uniform data for a draw call, then return the final pixel color.
That makes them a good fit for effects like:
Kraken currently exposes custom fragment shaders only. You do not write a custom vertex pipeline or compute shader for this feature yet, so most shader work in Kraken answers one question:
Given this pixel and the data I bound, what color should it become?
A fragment shader usually reads from three kinds of inputs:
Here is a tiny HLSL fragment shader that samples one texture and returns it:
Texture2D spriteTex : register(t0, space2);
SamplerState spriteSamp : register(s0, space2);
struct PSInput {
float4 v_color : COLOR0;
float2 v_uv : TEXCOORD0;
};
struct PSOutput {
float4 o_color : SV_Target;
};
PSOutput main(PSInput input) {
PSOutput output;
output.o_color = spriteTex.Sample(spriteSamp, input.v_uv) * input.v_color;
return output;
}
The texture and sampler are binding 0.
The v_color and v_uv fields are values supplied by Kraken's default draw path.
The output is a single color for the pixel being rendered.
Kraken's shader baker, pykraken bake, accepts HLSL input and produces the platform shader files Kraken needs.
This is the recommended path.
pykraken bake shaders/simple.frag.hlsl -o assets/shaders
You can still write GLSL, but Kraken does not bake GLSL for you.
If you choose GLSL, compile it yourself into the format your target platform needs,
then load the resulting shader by its base path with kn.shaders.Shader.
Use HLSL unless you have a reason not to:
HLSL gives you the smoothest Kraken workflow because pykraken bake can generate the runtime shader files for you. GLSL is for users who already have their own shader compilation step.
Shader resource bindings must be authored in a specific order. If the shader compiles but samples the wrong texture, reads empty uniform data, or behaves differently on another backend, this is the first thing to check.
Note:
Kraken currently exposes sampled textures and uniform buffers for custom shaders. Storage textures and storage buffers are not implemented yet.
Kraken's current custom shader API binds fragment resources only, so these are the rules you will use most often:
register(t0, space2), register(t1, space2), and so on.register(s0, space2), register(s1, space2), and so on.register(b0, space3), register(b1, space3), and so on.Texture2D baseTex : register(t0, space2);
Texture2D noiseTex : register(t1, space2);
SamplerState baseSamp : register(s0, space2);
SamplerState noiseSamp : register(s1, space2);
cbuffer WindUniform : register(b0, space3) {
float4 wind;
};
2.3.0 and increase from there.layout(set = 2, binding = 0) uniform sampler2D baseTex;
layout(set = 2, binding = 1) uniform sampler2D noiseTex;
layout(set = 3, binding = 0) uniform WindUniform {
vec4 wind;
};
[[texture]] entries are sampled textures.[[sampler]] entries use indices matching the sampled textures.[[buffer]] entries list uniform buffers.If you are using HLSL with Kraken's baker, you normally do not write these MSL bindings by hand.
For HLSL source, the fragment input should accept one vertex color and one vertex texture coordinate as such:
struct PSInput {
float4 v_color : COLOR0;
float2 v_uv : TEXCOORD0;
};
Keeping this convention in your shader source makes the generated platform shaders line up consistently.