Writing FXPack Shaders: Difference between revisions
Add section: writing a shader with Claude (bot) |
Split into howto + reference; move tables to FXPack Shader Reference; no inline bold (bot) |
||
| Line 1: | Line 1: | ||
{{TOCright}} | |||
This is a task-oriented guide to writing your own MXWendler effect as an FXPack shader — from a minimal shader to packaging and installing, including how to have Claude write one for you. For the exact naming rules and the full uniform tables, see the companion page [[FXPack Shader Reference]]. | |||
See also: [[Effects]] · [[Tutorial Coupling Video with Effects and Audio Signals]] | See also: [[Effects]] · [[Tutorial Coupling Video with Effects and Audio Signals]] | ||
<div class="noprint"> | <div class="noprint"> | ||
== | ==Introduction== | ||
</div> | </div> | ||
An FXPack is a plain ZIP archive (extension <code>.fxpack</code>) holding one or more GLSL shader stages plus any auxiliary textures. Drop it into MXWendler's <code>effects/</code> folder and it becomes a new effect in Preload Preview, the Live Editor and on the Render Output — no recompilation needed. The shader ''is'' the plugin. | |||
/ | MXWendler feeds your shader live values and builds UI sliders/color pickers from specially-named uniforms (<code>mxw_..._mxw</code>). This guide shows the workflow; the [[FXPack Shader Reference]] lists every available uniform. | ||
<div class="noprint"> | <div class="noprint"> | ||
==A minimal fragment shader== | ==A minimal fragment shader== | ||
</div> | </div> | ||
The smallest useful effect — a brightness knob that fades to the original via Master: | The smallest useful effect — a brightness knob that fades to the original via a Master slider: | ||
<syntaxhighlight lang="glsl"> | <syntaxhighlight lang="glsl"> | ||
| Line 240: | Line 38: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Two things to remember (both explained in the [[FXPack Shader Reference]]): a slider is a <code>float</code> uniform with exactly six underscores whose name encodes label/range/default, and texture coordinates arrive in pixels, not 0..1. | |||
<div class="noprint"> | <div class="noprint"> | ||
| Line 287: | Line 87: | ||
Because an <code>.fxpack</code> is just a ZIP, you can inspect or fork any of the 130+ bundled effects: copy one, rename to <code>.zip</code>, unzip, edit the <code>.mxf</code>, re-zip. The bundled <code>ag_*</code> effects are an excellent library of worked examples. | Because an <code>.fxpack</code> is just a ZIP, you can inspect or fork any of the 130+ bundled effects: copy one, rename to <code>.zip</code>, unzip, edit the <code>.mxf</code>, re-zip. The bundled <code>ag_*</code> effects are an excellent library of worked examples. | ||
<div class="noprint"> | <div class="noprint"> | ||
| Line 349: | Line 138: | ||
* If the effect fails to load, MXWendler logs the reason (unknown uniform, wrong underscore count, missing aux texture). Paste that message back to Claude and ask it to fix it. | * If the effect fails to load, MXWendler logs the reason (unknown uniform, wrong underscore count, missing aux texture). Paste that message back to Claude and ask it to fix it. | ||
* To evolve a look, keep the conversation going: ''"add a Speed slider 0..5 default 1"'', ''"make the edges wrap instead of clamp"'', ''"tint the result with a color picker"''. Because the rules stay in context, Claude keeps emitting valid interface uniforms. | * To evolve a look, keep the conversation going: ''"add a Speed slider 0..5 default 1"'', ''"make the edges wrap instead of clamp"'', ''"tint the result with a color picker"''. Because the rules stay in context, Claude keeps emitting valid interface uniforms. | ||
* For temporal effects (trails, motion blur, feedback) tell Claude it may also request past frames with <code>uniform sampler2D mxw_tex_minus_N_mxw;</code> (N = frames back) — see [[#Input textures (samplers)|Input textures]]. | * For temporal effects (trails, motion blur, feedback) tell Claude it may also request past frames with <code>uniform sampler2D mxw_tex_minus_N_mxw;</code> (N = frames back) — see [[FXPack Shader Reference#Input textures (samplers)|Input textures]]. | ||
* Ask for an inline comment on each slider so the resulting shader stays self-documenting. | * Ask for an inline comment on each slider so the resulting shader stays self-documenting. | ||
| Line 355: | Line 144: | ||
Because every bundled effect is a plain ZIP, you can point [https://www.anthropic.com/claude-code Claude Code] (or any agent) at the <code>effects/</code> folder and ask it to unzip an existing <code>ag_*</code> effect, study the <code>.mxf</code>, and generate a variation — a fast way to build a family of related looks from a proven starting point. | Because every bundled effect is a plain ZIP, you can point [https://www.anthropic.com/claude-code Claude Code] (or any agent) at the <code>effects/</code> folder and ask it to unzip an existing <code>ag_*</code> effect, study the <code>.mxf</code>, and generate a variation — a fast way to build a family of related looks from a proven starting point. | ||
Tip: always give the shader a quick visual check in Preload Preview before using it on the Render Output. Claude gets the interface and the maths right the vast majority of the time, but only your eyes can confirm the ''look''. | |||
[[Category:Effects]] | [[Category:Effects]] | ||
Latest revision as of 16:31, 8 August 2026
Template:TOCright This is a task-oriented guide to writing your own MXWendler effect as an FXPack shader — from a minimal shader to packaging and installing, including how to have Claude write one for you. For the exact naming rules and the full uniform tables, see the companion page FXPack Shader Reference.
See also: Effects · Tutorial Coupling Video with Effects and Audio Signals
An FXPack is a plain ZIP archive (extension .fxpack) holding one or more GLSL shader stages plus any auxiliary textures. Drop it into MXWendler's effects/ folder and it becomes a new effect in Preload Preview, the Live Editor and on the Render Output — no recompilation needed. The shader is the plugin.
MXWendler feeds your shader live values and builds UI sliders/color pickers from specially-named uniforms (mxw_..._mxw). This guide shows the workflow; the FXPack Shader Reference lists every available uniform.
The smallest useful effect — a brightness knob that fades to the original via a Master slider:
#version 120
// input frame
uniform sampler2D mxw_tex_plus_0_mxw;
// dry/wet
uniform float mxw_vertslider_Master_0x0_1x0_1x0_mxw;
// user control: brightness 0..2, default 1
uniform float mxw_vertslider_Brightness_0x0_2x0_1x0_mxw;
void main(void)
{
vec2 tc = gl_TexCoord[0].xy; // pixel coordinates
vec4 src = texture2D(mxw_tex_plus_0_mxw, tc);
vec4 processed = vec4(src.rgb * mxw_vertslider_Brightness_0x0_2x0_1x0_mxw, src.a);
gl_FragColor = mix(src, processed, mxw_vertslider_Master_0x0_1x0_1x0_mxw);
}
Two things to remember (both explained in the FXPack Shader Reference): a slider is a float uniform with exactly six underscores whose name encodes label/range/default, and texture coordinates arrive in pixels, not 0..1.
This annotated version of the stock ag_Sine effect shows the coordinate helpers, a user slider and the Master mix working together:
#version 120
uniform sampler2D mxw_tex_plus_0_mxw; // current frame
uniform float mxw_vertslider_Master_0x0_1x0_1x0_mxw; // dry/wet
uniform float mxw_vertslider_Resolution_0x1_10x0_0x5_mxw; // user knob
uniform float mxw_reciprocalU_mxw;
uniform float mxw_reciprocalV_mxw;
uniform float mxw_maxU_mxw;
uniform float mxw_maxV_mxw;
vec2 normalizedTc(vec2 tc) { return tc * vec2(mxw_reciprocalU_mxw, mxw_reciprocalV_mxw); }
vec2 unNormalizedTc(vec2 tc) { return tc * vec2(mxw_maxU_mxw, mxw_maxV_mxw); }
void main(void)
{
vec2 tc = normalizedTc(gl_TexCoord[0].xy); // -> 0..1
tc = tc * 2.0 - 1.0; // -> -1..1
vec2 xy = abs(tc) * mxw_vertslider_Resolution_0x1_10x0_0x5_mxw;
vec2 val = fract(vec2(xy.x + sin(xy.y), xy.y + sin(xy.x)));
vec4 processed = texture2D(mxw_tex_plus_0_mxw, unNormalizedTc(val));
gl_FragColor = mix(texture2D(mxw_tex_plus_0_mxw, gl_TexCoord[0].xy),
processed,
mxw_vertslider_Master_0x0_1x0_1x0_mxw);
}
- Put your shader(s) in an
effects/folder and any images in atextures/folder. - Add a
readme.txtdescribing what the effect does. - ZIP those folders together (the folders must be at the root of the archive).
- Rename the resulting archive to
YourEffectName.fxpack. - Copy it into MXWendler's
effects/directory. It appears in the effect list on next start.
Because an .fxpack is just a ZIP, you can inspect or fork any of the 130+ bundled effects: copy one, rename to .zip, unzip, edit the .mxf, re-zip. The bundled ag_* effects are an excellent library of worked examples.
Large-language-model assistants such as Claude are very good at GLSL, and the FXPack interface is simple enough that Claude can write a complete, working effect in one go — provided you give it the MXWendler-specific rules, which it cannot know on its own. The trick is to paste the interface contract into the prompt, then describe the look you want.
A ready-to-use prompt
Copy this block into Claude, fill in the last line, and it will produce a valid .mxf:
You are writing a fragment shader for MXWendler's FXPack effect format. Follow these rules exactly:
- Target GLSL "#version 120".
- The current video frame is a sampler2D declared as:
uniform sampler2D mxw_tex_plus_0_mxw;
- Texture coordinates from gl_TexCoord[0].xy are in PIXELS (0..width, 0..height), NOT 0..1,
because the frame is a rectangle texture. Convert with these engine uniforms/helpers:
uniform float mxw_reciprocalU_mxw; // 1/width
uniform float mxw_reciprocalV_mxw; // 1/height
uniform float mxw_maxU_mxw; // width
uniform float mxw_maxV_mxw; // height
vec2 normalizedTc(vec2 tc) { return tc * vec2(mxw_reciprocalU_mxw, mxw_reciprocalV_mxw); } // ->0..1
vec2 unNormalizedTc(vec2 tc) { return tc * vec2(mxw_maxU_mxw, mxw_maxV_mxw); } // ->pixels
Always pass PIXEL coordinates to texture2D().
- Animate with time in milliseconds: uniform float mxw_millis_mxw;
- Expose user controls as sliders. A slider is a float uniform with EXACTLY 6 underscores:
uniform float mxw_vertslider_<Label>_<lo>_<hi>_<default>_mxw;
<Label> is a single CamelCase token (no spaces/underscores). Numbers encode '.' as 'x'
and a leading 'n' for negative: 0.5 -> 0x5, 100.0 -> 100x0, -0.5 -> n0x5.
- Optional RGBA color picker = vec4 with EXACTLY 7 underscores:
uniform vec4 mxw_colorcontrol_<Label>_<r>_<g>_<b>_<a>_mxw;
- Always include a Master dry/wet slider and cross-fade to the original at the end:
uniform float mxw_vertslider_Master_0x0_1x0_1x0_mxw;
gl_FragColor = mix(texture2D(mxw_tex_plus_0_mxw, gl_TexCoord[0].xy), processed,
mxw_vertslider_Master_0x0_1x0_1x0_mxw);
- Do not use any uniforms other than the ones above and your own private ones.
- Output nothing but the shader code.
Now write the effect: <DESCRIBE THE LOOK YOU WANT, e.g. "a horizontal chromatic-aberration
glitch whose strength pulses with time, with a Strength slider 0..20 default 5">
Turning Claude's output into an FXPack
- Save Claude's code as
effects/MyEffect.mxf. - Optionally add
textures/images and areadme.txt. - ZIP the folders and rename to
MyEffect.fxpack(see Packaging and installing). - Drop it into MXWendler's
effects/folder and restart.
Iterating
- If the effect fails to load, MXWendler logs the reason (unknown uniform, wrong underscore count, missing aux texture). Paste that message back to Claude and ask it to fix it.
- To evolve a look, keep the conversation going: "add a Speed slider 0..5 default 1", "make the edges wrap instead of clamp", "tint the result with a color picker". Because the rules stay in context, Claude keeps emitting valid interface uniforms.
- For temporal effects (trails, motion blur, feedback) tell Claude it may also request past frames with
uniform sampler2D mxw_tex_minus_N_mxw;(N = frames back) — see Input textures. - Ask for an inline comment on each slider so the resulting shader stays self-documenting.
Using Claude Code on the effect library
Because every bundled effect is a plain ZIP, you can point Claude Code (or any agent) at the effects/ folder and ask it to unzip an existing ag_* effect, study the .mxf, and generate a variation — a fast way to build a family of related looks from a proven starting point.
Tip: always give the shader a quick visual check in Preload Preview before using it on the Render Output. Claude gets the interface and the maths right the vast majority of the time, but only your eyes can confirm the look.