glsl-shaders
Skill213 starsChanged 2 months agoMITView on GitHub
MUST READ before writing GLSL or creating a glslTOP, glslmultiTOP, glslMAT or glslPOP: docked DATs, uniforms and the Colors page, TD's built-in functions and samplers, feedback and multi-pass, reading compile errors. Every built-in named here compiled on TD 2025.33230.
In this repository30 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- web/llms-full.txtllms.txt
- web/llms.txtllms.txt
- add-mcp-toolSkill
- agent-testsSkill
- briefSkill
- build-uiSkill
- collabSkill
- create-extensionSkill
- create-operatorSkill
- debug-operatorSkill
- externalize-operatorSkill
- manage-annotationsSkill
- mcp-tools-referenceSkill
- merge-divergent-toxSkill
- movie-exportSkill
- multi-instanceSkill
- multi-session-etiquetteSkill
- operator-gotchasSkill
- parameter-designSkill
- pop-networksSkill
- publish-specimenSkill
- releaseSkill
- run-testsSkill
- specimen-authoringSkill
- td-api-referenceSkill
- td-recoverySkill
- testingSkill
- visual-aestheticsSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
Read compile results from <name>_info: op.errors() says only "Compile failed".
- Very specific: line 69
Verify by looking: capture_top the output (a Quality: FAIL is a black or flat frame) and read <name>_info after every edit.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- Generated by Embody/Envoy - Do not remove this comment - sha:ba697c6b4d3a77c7 -->GLSL Shaders
Three hosts: glslTOP/glslmultiTOP (pixels, or compute over an image), glslMAT (vertex + pixel over geometry), glslPOP (compute over points; the POP side lives in /pop-networks). Every function and parameter below compiled live on TD 2025.33230 (probed 2026-09-25). Anything you add beyond them: check the parameter with describe_op_type and the function with the docked info DAT before trusting it.
The docked-DAT contract
- Creating a
glslTOP/glslmultiTOPdocks<name>_pixel,<name>_compute,<name>_info, withpixeldat/computedatalready pointing at them. AglslMATdocks<name>_vertex,<name>_pixel,<name>_info(vdat/pdat). AglslPOPdocks<name>_computeand<name>_info. - Name the operator at creation (
glsl_<purpose>): dock names and the*datreferences are snapshots taken then and do not follow a later rename. - Write the shader INTO the docked DAT (
set_dat_content/edit_dat_content). Delete the dock you do not use (_computefor a pixel shader) so it does not ship as dead weight. One exception: several GLSL ops running identical code point at ONE shared DAT and differ by uniforms (tdxn-economy.md). create_ophugs the docks under the host; anexecute_pythonbuild must place them itself (/create-operator).- Read compile results from
<name>_info:op.errors()says only "Compile failed".get_op_errorsreturns them asshaderErrors, and every DAT write to a shader rides back_effects.new_shader_errors. Fix those before building further.
What TD gives you (never redeclare, never paste an alternative)
- No
#versionline: TD injects one, and writing your own fails with "'#version' : must occur first in shader".texture(), nevertexture2D()("function not supported in this version; use texture() instead"). - Inputs:
sTD2DInputs[i],sTD3DInputs[i],sTD2DArrayInputs[i],sTDCubeInputs[i], indexed per TYPE, not per connector.TD_NUM_2D_INPUTS(and the 3D/array/cube twins) bound a loop and guard a dynamic index.uTD2DInfos[i].resanduTDOutputInfo.resare(1/w, 1/h, w, h).vUV.stis the 0-1 texture coordinate when there is no custom vertex shader.uTDPassis the multi-pass index,uTDCurrentDepththe 3D slice. - Lookups:
sTDNoiseMap(256x256 random),sTDSineLookup. - Functions:
TDOutputSwizzle(vec4)on EVERY color you write out (channel order is wrong without it),TDDither,TDPerlinNoise(vec2|vec3|vec4)andTDSimplexNoise(vec2|vec3|vec4)(both in -1..1, available in TOP, MAT and glslPOP shaders on this build),TDHSVToRGB,TDRGBToHSV,TDRotateOnAxis(rad, axis),TDRotateX/Y/Z(rad). - Compute in a
glslTOP(mode=compute): declarelayout(local_size_x = 8, local_size_y = 8) in;, write withTDImageStoreOutput(0, ivec3(gl_GlobalInvocationID.xy, 0), TDOutputSwizzle(color)), read the output back withTDImageLoadOutput(0, ivec3(...)). glslTOPhas exactly 3 input connectors.glslmultiTOPtakes more and adds POP buffer reads (buffer0pop,buffer0attr,buffer0name->TDBuffer_<Name>(idx)in the shader). Reach forglslmultiTOPwhenever you need a fourth input or a POP attribute.
Uniforms
- Vectors page:
vec0name+vec0valuex/y/z/w, a sequence (grow it withop.seq.vec.numBlocks = N). On a TOP or MAT the SHADER declares the uniform and TD infers the type from the declaration (uniform vec4 uParams;); there is novec0typehere, and an undeclared name silently reads nothing. Pack four values per vec; the values take expressions (absTime.seconds * parent.Fx.par.Speed). - Colors page:
color0name+color0rgbr/g/b+color0alpha->uniform vec4 uTint;with a colour swatch in the dialog. Use it for colours instead of a raw vec. - Constants page:
const0name/const0valueare baked in at compile time, so every change RECOMPILES the shader. Runtime values belong on Vectors; constants only for true compile-time switches. glslPOPinverts one rule: its uniforms are AUTO-DECLARED from the Vectors page (uniform highp float uSpeed;by default). Declaring them again is a "Redeclaration" error, and the type comes fromvec0type(float,vec2..vec4,int,uint, ...). Samplers, Arrays, Matrices and Buffers pages follow the same shape on every host.
Pixel shader minimum
uniform vec4 uParams; // Vectors page: vec0name = uParams
layout(location = 0) out vec4 fragColor;
void main() {
vec4 c = texture(sTD2DInputs[0], vUV.st);
fragColor = TDOutputSwizzle(c * uParams.x);
}Output format and resolution are parameters, not shader code: format (rgba8fixed clamps to 0-1 -- data, feedback and HDR need rgba16float or rgba32float), outputresolution (useinput, custom with resolutionw/resolutionh, fit, ...). There is no resolution parameter. premultrgbbyalpha defaults ON and multiplies RGB by your alpha -- turn it off on an op whose alpha carries data. Multiple render targets: numcolorbufs, declare layout(location = 1) out vec4 fragField;, and pull buffer N with a Render Select TOP (set its format to float).
glslMAT
One combined DAT with #ifdef TD_VERTEX_SHADER / #ifdef TD_PIXEL_SHADER guards, set as BOTH vdat and pdat; keep _info.
- Vertex:
TDDeform(TDPos())gives the world position (never rawTDPos()-- instancing and deformers ride on TDDeform),TDDeformNorm(TDNormal())the world normal,TDWorldToProj(worldPos)isgl_Position,TDCameraIndex()goes out as aflat intvarying,TDPointColor()/TDInstanceColor(c)carry point and instance colour. - Pixel:
TDCheckDiscard()first;uTDMats[cam].camInverse[3].xyzis the camera position; loopTD_NUM_LIGHTSwithTDLightingPBR(i, diffuseColor, specularColor, worldPos, normal, shadowStrength, shadowColor, viewDir, roughness)(aTDPBRResultwith.diffuse/.specular) andTD_NUM_ENV_LIGHTSwithTDEnvLightingPBR(inout diffuse, inout specular, i, diffuseColor, specularColor, normal, viewDir, roughness, ambientOcclusion);TDFog(color, worldPos, cam); thenTDOutputSwizzle(TDDither(color))intooFragColor[0], declaredlayout(location = 0) out vec4 oFragColor[TD_NUM_COLOR_BUFFERS];. - Transparency needs
blendingON and honestsrcblend/destblend(one,zero,sa,omsa, ...) with the alpha pairsrcblenda/destblenda;cullface=neithershows both faces of filled POP geometry. - Extending a PBR look: start from a
pbrMATand pulseoutputshader-- TD writes its own vertex and pixel code into a new glslMAT for you to edit.
Feedback and multi-pass
- Feedback: Constant TOP (clear) -> Feedback TOP -> glsl -> Null TOP; the Feedback TOP's
topnames the null that closes the loop,resetpulseresets it. Close the loop BEFORE compiling shaders that depend on the fed-back texture. Bound every loop perperformance.md: fixed resolution inside it, decay below 1, reset wired, bypassed while wiring. - One feedback is one iteration per frame. Iterative solvers use
npasseson the GLSL op instead: pass N+1 sees pass N on input 0,uTDPasstells you which. - 3D output:
type=texture3d,depth=custom,customdepth=N; the shader runs once per slice withuTDCurrentDepth.constantTOPandnoiseTOPhave nocustomdepth, so seed a volume from a smallglslTOP, not from them.
Discipline
- A built-in operator beats a shader when one exists (Noise, Ramp, Lookup, Composite, Level TOPs; Math and Lookup CHOPs). GLSL is for what they cannot express: advection, solvers, custom lighting, per-point compute.
- Bound every loop with a constant and guard dynamic sampler or array indexes with
TD_NUM_*: an out-of-bounds index can take TD down (/td-api-reference, Heavy-Build Safety). centroidis a reserved word in GLSL 4.60.me.time.stepdoes not exist: delta time isabsTime.stepSeconds(or1.0 / me.time.rate).- Externalize shader DATs with
externalize_op(tagglsl) so they diff in git; edit the file, TD recompiles. - Verify by looking:
capture_topthe output (aQuality: FAILis a black or flat frame) and read<name>_infoafter every edit. A shader that compiles and renders TD's fallback pattern still reads as an error in the info DAT.
Topics cross-checked against Derivative's TDMCPSkills td-glsl-shaders with permission; every claim above was recompiled live on 2025.33230 before it was written down.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

