Agent skill

Cesiumjs Custom Shader

by CesiumGS in CesiumGS/cesiumjs-skills

CustomShader authoring — vertexShaderText and fragmentShaderText against VertexInput, FragmentInput, FeatureIds, Metadata, czmmodelMaterial.

Apache-2.0Auto-check passedGame Development

Install Cesiumjs Custom Shader

skills CLI
$ npx skills add CesiumGS/cesiumjs-skills --skill cesiumjs-custom-shader -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install CesiumGS/cesiumjs-skills cesiumjs-custom-shader --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/CesiumGS/cesiumjs-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/cesiumjs-custom-shader .claude/skills/cesiumjs-custom-shader && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
cesiumjs-custom-shader
GitHub stars
189
Token cost
~5.1k tokens
SKILL.md length
1,643 words
Files
11
Skills in repo
14
Repo updated
First seen
Licence
Apache-2.0

At a glance

CustomShader authoring — vertexShaderText and fragmentShaderText against VertexInput, FragmentInput, FeatureIds, Metadata, czmmodelMaterial.

  • Works in 12 steps: Coordinate-space suffix required.… → positionMC is valid in fragment shader —… → Vertex displacement does not update… → …
  • Reading EXTmeshfeatures
  • SKILL.md covers Out of scope, Minimal example, Applying a CustomShader and Constructor reference, plus 16 more sections
  • Runs JavaScript scripts from its folder

What it does

Cesiumjs Custom Shader is an agent skill from CesiumGS/cesiumjs-skills. CustomShader authoring — vertexShaderText and fragmentShaderText against VertexInput, FragmentInput, FeatureIds, Metadata, czmmodelMaterial. Use when reading EXTmeshfeatures or EXTstructuralmetadata property textures/tables, vertex displacement, or shading VoxelPrimitive.

Its SKILL.md is about 5.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 11 other files (for example `REFERENCE.md`, `examples/01-diffuse-tint.js` and `examples/02-texture-swap.js`).

It sits in Game Development, covering Shaders. The repository describes itself as: Curated agent skills for CesiumJS development. The licence is Apache-2.0.

When your agent uses it

  • Reading EXTmeshfeatures
  • EXTstructuralmetadata property textures/tables
  • Vertex displacement
  • Shading VoxelPrimitive

Example prompts

  • “/cesiumjs-custom-shader”

Requirements

  • Node.js

Workflow steps

12 steps, taken from the first numbered list in SKILL.md.

  1. Coordinate-space suffix required. positionEC in vertex, normalMC in fragment, or any bare position/normal/tangent/bitangent throws…
  2. positionMC is valid in fragment shader — despite the MC suffix. Only normalMC/tangentMC/bitangentMC are FS-rejected.
  3. Vertex displacement does not update bounding sphere. Displaced vertices may be frustum-culled unexpectedly.
  4. Cesium3DTileStyle + CustomShader = undefined behavior. Per upstream JSDoc. Choose one per tileset.
  5. SAMPLER_CUBE rejected at construction. Use SAMPLER_2D only.
  6. Parameter-name contract. vsInput, vsOutput, fsInput, material are scanned by regex — renaming breaks codegen.
  7. TextureUniform URL-vs-typedArray XOR. Supplying both or neither throws. typedArray requires width + height.
  8. Alpha writes on opaque models are silently ignored under INHERIT. Set translucencyMode: CustomShaderTranslucencyMode.TRANSLUCENT — do not…
  9. customShader.destroy() required. Call when disposing of a shader that holds texture uniforms — otherwise its TextureManager leaks GPU…
  10. vsOutput.pointSize overrides Cesium3DTileStyle point sizing. Don't set it unless intended.
  11. Metadata property IDs are sanitized. Non-alphanumeric → _; leading gl_ stripped; collisions are undefined behavior.
  12. UINT metadata now preserves signedness (1.139+, #13135). Use uint x = fsInput.metadata.prop;, not int x = ....

What it can do on your machine

Read from SKILL.md and the folder at commit 5f4792c. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships script files (JavaScript), which the agent can run.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Cesiumjs Custom Shader loads about 5.1k tokens when it runs. Until then it costs about 75 tokens; SKILL.md has 1,643 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~75
When it runs · the whole SKILL.md, loaded when a task matches
~5.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from CesiumGS/cesiumjs-skills at commit 5f4792c, republished under its Apache-2.0 licence (© CesiumGS). 1,643 words, ~5,087 tokens.

Download SKILL.mdSave it as .claude/skills/cesiumjs-custom-shader/SKILL.md (or your agent's skills folder). This skill also uses 10 other files; get the full folder from GitHub.
name
cesiumjs-custom-shader
description
CustomShader authoring — vertexShaderText and fragmentShaderText against VertexInput, FragmentInput, FeatureIds, Metadata, czm_modelMaterial. Use when reading EXT_mesh_features or EXT_structural_metadata property textures/tables, vertex displacement, or shading VoxelPrimitive.

CesiumJS CustomShader

Version baseline: CesiumJS 1.144. All imports use ES module style.

CustomShader injects user GLSL into the Model / Cesium3DTileset / VoxelPrimitive rendering pipeline. It exposes glTF attributes, feature IDs, and EXT_structural_metadata to per-vertex and per-fragment code, and returns values through the built-in czm_modelVertexOutput and czm_modelMaterial structs.

Use this skill for writing the shader body. Use:

  • cesiumjs-materials-shaders — for Fabric Material, ImageBasedLighting, PostProcessStage (bloom, SSAO, FXAA, tonemapping).
  • cesiumjs-3d-tiles — for declarative per-feature coloring via Cesium3DTileStyle, and for VoxelPrimitive setup/configuration.
  • cesiumjs-models-particles — for Model.fromGltfAsync, animations, ModelFeature.getProperty().

Out of scope

  • Fabric Material for entity polylines/polygons/walls — see cesiumjs-materials-shaders.
  • PostProcessStage screen-space effects — see cesiumjs-materials-shaders.
  • ImageBasedLighting — see cesiumjs-materials-shaders.
  • Cesium3DTileStyle declarative JSON styling — see cesiumjs-3d-tiles. Do not combine with CustomShader on the same tileset.
  • Authoring EXT_structural_metadata / EXT_mesh_features in glTF — tooling concern, not runtime.

Minimal example

js
import { CustomShader, Model } from "cesium";

const shader = new CustomShader({
  fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
      material.diffuse = vec3(1.0, 0.0, 0.0);
    }
  `,
});

const model = await Model.fromGltfAsync({ url: "./aircraft.glb", customShader: shader });
viewer.scene.primitives.add(model);

Note: Writing material.alpha requires translucencyMode: CustomShaderTranslucencyMode.TRANSLUCENT — see "Translucency" below. On opaque models with the default INHERIT mode, alpha writes are silently ignored.

Visual eval framing: after adding a shadered Model, wait until the model is ready enough to render, then frame a known target point explicitly. Do not rely on the first post-load frame or on a tiny default-scale model. For public model evals, set minimumPixelSize (usually 256-400), use a moderate scale, and add a silhouette or strong color tint when the shader effect is the thing being judged.

Applying a CustomShader

Model — constructor option or mutable property:

js
const model = await Model.fromGltfAsync({ url, customShader });
model.customShader = newShader;     // hot-swap
model.customShader = undefined;     // clear

Cesium3DTileset — constructor option or mutable property. Only Model-backed tile content is affected (not native I3S or other formats):

js
const tileset = await Cesium3DTileset.fromUrl(url, { customShader });
tileset.customShader = newShader;

Per the Cesium3DTileset.customShader JSDoc: "Using custom shaders with a Cesium3DTileStyle may lead to undefined behavior." The property is also marked @experimental — it uses 3D Tiles spec surface that is not final and may change without Cesium's standard deprecation policy.

VoxelPrimitive — fragment-only subset (see "VoxelPrimitive shader subset" below):

js
const voxelPrimitive = new VoxelPrimitive({ provider, customShader });

The engine calls customShader.update(frameState) automatically each frame. When finished with a CustomShader, call customShader.destroy() to release GPU texture resources owned by its TextureManager.

Constructor reference

js
new CustomShader({
  mode,                  // CustomShaderMode — default MODIFY_MATERIAL
  lightingModel,         // LightingModel — if omitted, model's default is preserved
  translucencyMode,      // CustomShaderTranslucencyMode — default INHERIT
  uniforms,              // { [name]: { type: UniformType, value } } — default {}
  varyings,              // { [name]: VaryingType } — default {}
  vertexShaderText,      // string or undefined
  fragmentShaderText,    // string or undefined
});

Either vertexShaderText or fragmentShaderText is typically required. See REFERENCE.md for exhaustive enum values.

Shader function signatures

The runtime calls these from generated pipeline stages. Parameter names are part of the contract — renaming them breaks the shader.

glsl
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) { ... }
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { ... }

Uniforms

Declare uniforms with { type, value }. The type is a UniformType value; the JS value type must match (e.g. VEC3 → Cartesian3). Uniforms are accessible in GLSL by their declared name.

js
import { CustomShader, UniformType, TextureUniform, Cartesian3 } from "cesium";

const shader = new CustomShader({
  uniforms: {
    u_tint:   { type: UniformType.VEC3,      value: new Cartesian3(1.0, 0.5, 0.2) },
    u_time:   { type: UniformType.FLOAT,     value: 0.0 },
    u_detail: { type: UniformType.SAMPLER_2D, value: new TextureUniform({ url: "./detail.png", repeat: true }) },
  },
  fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
      vec3 d = texture(u_detail, fsInput.attributes.texCoord_0).rgb;
      material.diffuse = mix(material.diffuse, u_tint, d.r + 0.1 * sin(u_time));
    }
  `,
});

// Update at runtime. For Cartesian/Matrix values, setUniform clones into existing storage.
shader.setUniform("u_time", performance.now() / 1000);

TextureUniform accepts either url (string or Resource) or typedArray + width + height — exactly one (constructor throws otherwise). Other options: repeat (default true), pixelFormat, pixelDatatype, minificationFilter, magnificationFilter, maximumAnisotropy.

SAMPLER_CUBE is declared on UniformType but rejected at construction — throws DeveloperError("CustomShader does not support samplerCube uniforms"). Only SAMPLER_2D is supported.

Varyings

Declared varyings are emitted as out <type> <name> in the vertex shader and in <type> <name> in the fragment shader. Write in vertex, read in fragment.

js
import { CustomShader, VaryingType } from "cesium";

const shader = new CustomShader({
  varyings: { v_worldHeight: VaryingType.FLOAT },
  vertexShaderText: `
    void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {
      v_worldHeight = vsInput.attributes.positionMC.z;
    }
  `,
  fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
      float t = clamp(v_worldHeight / 100.0, 0.0, 1.0);
      material.diffuse = mix(vec3(0.2,0.4,0.8), vec3(1.0,0.8,0.2), t);
    }
  `,
});

VaryingType supports FLOAT, VEC2–VEC4, MAT2–MAT4. No INT/BOOL/SAMPLER variants.

Modes & lighting

CustomShaderMode:

  • MODIFY_MATERIAL (default) — runs after the material stage, before lighting. czm_modelMaterial is populated with PBR/texture results; the shader refines them.
  • REPLACE_MATERIAL — skips the material stage entirely. Shader sets every field procedurally. Cheaper when the source material is not needed.

LightingModel:

  • UNLIT — skip lighting; material.diffuse becomes the final color (alpha still applied). Flat-shaded.
  • PBR — physically-based with IBL when available.
  • Omitted — preserves the model's default lighting. Omit unless overriding intentionally.

Pair REPLACE_MATERIAL + UNLIT for pure procedural flat shading (no material sampling, no lighting).

Translucency

CustomShaderTranslucencyMode governs how alpha writes interact with the render pass:

  • INHERIT (default) — alpha is only honored if the source material is translucent.
  • OPAQUE — force opaque pass.
  • TRANSLUCENT — force translucent pass.

Pitfall: writing material.alpha on an opaque model with INHERIT silently does nothing. Set translucencyMode: CustomShaderTranslucencyMode.TRANSLUCENT to make alpha writes effective.

js
import { CustomShader, CustomShaderTranslucencyMode } from "cesium";

const shader = new CustomShader({
  translucencyMode: CustomShaderTranslucencyMode.TRANSLUCENT,
  fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
      material.diffuse = vec3(0.2, 0.6, 1.0);
      material.alpha = 0.5;   // honored because translucencyMode is TRANSLUCENT
    }
  `,
});

See examples/04-translucent-override.js.

Attributes

vsInput.attributes and fsInput.attributes expose glTF vertex attributes. Names are case-sensitive and coordinate-space suffixes are required — the constructor rejects bare position/normal/tangent/bitangent.

Common fields (full table in REFERENCE.md):

  • positionMC — model coords, valid in VS and FS
  • positionWC — world (ECEF) coords, fragment only, low-precision
  • positionEC — eye coords, fragment only
  • normalMC / normalEC — vertex / fragment
  • tangentMC / tangentEC, bitangentMC / bitangentEC
  • texCoord_N, color_N, joints_N, weights_N

Coordinate-space validation. The constructor scans shader text and throws DeveloperError("<name> is not available in the <stage> shader. Did you mean <alt> instead?") for invalid combinations. Examples: positionEC in vertex, normalMC in fragment.

Custom underscore-prefixed glTF attributes (_FEATURE_ID_0, _SURFACE_TEMP) are lowercased and un-prefixed: fsInput.attributes.surface_temp.

FeatureIds

vsInput.featureIds / fsInput.featureIds unify three glTF sources into one struct:

  • featureId_N — feature ID attributes and implicit attributes from EXT_mesh_features (N is the array index in the primitive's featureIds array). Also covers feature ID textures, which are fragment-shader-only.
  • instanceFeatureId_N — per-instance feature IDs from EXT_instance_features + EXT_mesh_gpu_instancing.
  • Named aliases — if glTF specifies "label": "perVertex", then featureIds.perVertex is also available.
  • Legacy 3D Tiles 1.0 BATCH_ID / _BATCHID → transparently renamed to featureId_0.

GLSL type is always int. WebGL 1 loses precision above 2^24.

glsl
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
  int id = fsInput.featureIds.featureId_0;
  if (id == 0)      material.diffuse = vec3(1.0, 0.2, 0.2);  // roof
  else if (id == 1) material.diffuse = vec3(0.2, 0.8, 0.2);  // wall
}

See examples/03-feature-id-tileset.js.

Metadata

EXT_structural_metadata surfaces three source types (all addressable from shaders as of 1.139):

  • Property attributes — per-vertex. Vertex and fragment shaders.
  • Property textures — per-texel. Fragment only.
  • Property tables — per-feature, keyed by feature ID. Added in 1.139 (#13124).
glsl
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
  float t = fsInput.metadata.temperature;
  float tMin = fsInput.metadataStatistics.temperature.minValue;
  float tMax = fsInput.metadataStatistics.temperature.maxValue;
  float v = (t - tMin) / (tMax - tMin);
  material.diffuse = vec3(v, 0.0, 1.0 - v);
}

Property ID sanitization (GLSL identifier rules):

  • Non-alphanumeric runs → single _ (temperature ℃ → temperature_)
  • Leading gl_ stripped (gl_custom → custom)
  • Leading digit prefixed with _ (12345 → _12345)
  • Post-sanitization collisions → undefined behavior

Sibling structs: metadataClass.<prop>.noData | defaultValue | minValue | maxValue (class-schema bounds) and metadataStatistics.<prop>.minValue | maxValue | mean | median | standardDeviation | variance | sum (populated only when tileset.json declares statistics).

1.139 breaking change (#13135): unsigned integer metadata is no longer cast to signed int. Assigning a UINT property to a GLSL int (int x = fsInput.metadata.myUint;) no longer compiles. Use the matching unsigned type.

Public assets without EXT_structural_metadata on a .glb are scarce — most real-world metadata lives on 3D Tiles. See examples/06-metadata-ramp.js (Cesium3DTileset target).

czm_modelVertexOutput & czm_modelMaterial

czm_modelVertexOutput (vertex shader's inout vsOutput):

glsl
struct czm_modelVertexOutput {
  vec3 positionMC;    // initialized to vsInput.attributes.positionMC
  float pointSize;    // overrides gl_PointSize and Cesium3DTileStyle point sizing
};

Gotcha: mutating positionMC displaces vertices but does not update the primitive's bounding sphere. Heavily displaced vertices can be frustum-culled.

czm_modelMaterial (fragment shader's inout material). All colors are linear RGB. Conditional fields specularWeight / anisotropic* / clearcoatFactor... appear only when KHR_materials_specular / _anisotropy / _clearcoat is active on the primitive (see REFERENCE.md for the full #ifdef-guarded struct):

glsl
struct czm_modelMaterial {
  vec4 baseColor; vec3 diffuse; float alpha;
  vec3 specular;  float roughness;
  vec3 normalEC;  float occlusion;  vec3 emissive;
  // + conditional PBR extension fields
};
Show full SKILL.md (670 more words)Show less

Built-in czm_* automatic uniforms

Available without declaration. Most useful for CustomShader: czm_frameNumber, czm_pi, czm_model, czm_view, czm_projection, czm_modelView, czm_normal, czm_lightDirectionEC, czm_sunDirectionWC, czm_eyeHeight, czm_sceneMode, czm_viewerPositionWC, czm_splitPosition. Full catalog in REFERENCE.md.

VoxelPrimitive shader subset

Fragment-only. Executes at every raymarching step along the view ray; the final pixel composites all steps. Supplying vertexShaderText is silently ignored.

Reduced struct availability:

  • fsInput.attributes — only positionEC and normalEC.
  • fsInput.featureIds — not present.
  • fsInput.metadata — fully supported.
  • fsInput.metadataClass — not present.
  • fsInput.metadataStatistics — only minValue and maxValue.

Assigning customShader = undefined falls back to VoxelPrimitive.DefaultCustomShader. See examples/07-voxel-shader.js. For VoxelPrimitive setup (provider, shape, modelMatrix, nearestSampling), see cesiumjs-3d-tiles.

1.130 breaking change (#12636): fsInput.voxel.positionUv | positionShapeUv | positionLocal were removed. Use fsInput.attributes.positionEC instead. fsInput.voxel.surfaceNormal → fsInput.attributes.normalEC. 1.142 fix (#13517): the built-in default voxel shader handles common metadata types more robustly. Keep a custom shader only when you need explicit classification, coloring, filtering, or raymarch-step logic.

Common patterns

FileTargetDemonstrates
examples/01-diffuse-tint.jsModelTime uniform driving material.diffuse
examples/02-texture-swap.jsModelTextureUniform, SAMPLER_2D, setUniform
examples/03-feature-id-tileset.jsCesium3DTilesetfsInput.featureIds.featureId_0 classification coloring
examples/04-translucent-override.jsModel (opaque source)CustomShaderTranslucencyMode.TRANSLUCENT
examples/05-vertex-displacement.jsModelvsOutput.positionMC + normal offset
examples/06-metadata-ramp.jsCesium3DTilesetfsInput.metadata.<prop> + metadataStatistics normalization
examples/07-voxel-shader.jsVoxelPrimitiveFS-only subset, per-voxel metadata

CesiumJS 1.139-1.142 version notes

Verbatim from upstream CHANGES.md:

Breaking (1.139, #13135):

Custom Shaders that rely on metadata derived from the EXT_structural_metadata extension no longer cast unsigned integer metadata types to signed integers. Any existing custom shaders that assign UINT-type metadata to local integers (e.g. int myMetadata = vsInput.metadata.myUintMetadata) will no longer compile.

Breaking (1.139, #13170): Fixed precision of point cloud attributes when accessed in a custom fragment shader.

Addition (1.139, #13124): Access to metadata from property tables (previously only attributes/textures).

Addition (1.139, #13135): More metadata types via property textures.

Fix (1.139, #13231): Metadata variable regex extended to metadataClass and metadataStatistics.

Fix (1.139.1, #13247): NGA-GPM local extension + custom shader regression fix.

Fix (1.140, #13258): Custom shaders are no longer disabled for primitives with missing metadata when the metadata exists on the class definition.

Addition (1.140, #13323): Limited double-precision metadata support via downcasting.

Fix (1.142, #13517): Improved default voxel shader for common metadata types.

Breaking (1.130, #12636): Voxel FragmentInput restructured (see VoxelPrimitive section).

Gotchas & pitfalls

  1. Coordinate-space suffix required. positionEC in vertex, normalMC in fragment, or any bare position/normal/tangent/bitangent throws DeveloperError at construction with a suggested alternative.
  2. positionMC is valid in fragment shader — despite the MC suffix. Only normalMC/tangentMC/bitangentMC are FS-rejected.
  3. Vertex displacement does not update bounding sphere. Displaced vertices may be frustum-culled unexpectedly.
  4. Cesium3DTileStyle + CustomShader = undefined behavior. Per upstream JSDoc. Choose one per tileset.
  5. SAMPLER_CUBE rejected at construction. Use SAMPLER_2D only.
  6. Parameter-name contract. vsInput, vsOutput, fsInput, material are scanned by regex — renaming breaks codegen.
  7. TextureUniform URL-vs-typedArray XOR. Supplying both or neither throws. typedArray requires width + height.
  8. Alpha writes on opaque models are silently ignored under INHERIT. Set translucencyMode: CustomShaderTranslucencyMode.TRANSLUCENT — do not just write material.alpha and expect it to work.
  9. customShader.destroy() required. Call when disposing of a shader that holds texture uniforms — otherwise its TextureManager leaks GPU resources.
  10. vsOutput.pointSize overrides Cesium3DTileStyle point sizing. Don't set it unless intended.
  11. Metadata property IDs are sanitized. Non-alphanumeric → _; leading gl_ stripped; collisions are undefined behavior.
  12. UINT metadata now preserves signedness (1.139+, #13135). Use uint x = fsInput.metadata.prop;, not int x = ....
  13. customShader on Cesium3DTileset is @experimental. May change without Cesium's standard deprecation policy.
  14. Tilesets: only Model-backed tile content uses CustomShader. Native I3S and other formats are unaffected.

Performance tips

  • REPLACE_MATERIAL skips the material stage (textures, PBR inputs not sampled).
  • LightingModel.UNLIT skips lighting math — combine with REPLACE_MATERIAL for flat procedural shading.
  • Write to varyings in vertex rather than recomputing per-fragment.
  • Avoid per-frame setUniform of SAMPLER_2D — it triggers async texture reload. Use url once and hold the reference.
  • Call customShader.destroy() on teardown to release GPU texture resources.

See also

  • REFERENCE.md — full struct tables (Attributes, FeatureIds, Metadata/Class/Statistics), enum value tables, built-in czm_* uniform catalog, coordinate-space validation error reference.
  • examples/ — seven compile-tested snippets. examples/_sandcastle-template.html is the internal scaffold; examples/README.md documents the layout.
  • cesiumjs-materials-shaders — Fabric Material, ImageBasedLighting, PostProcessStage.
  • cesiumjs-3d-tiles — Cesium3DTileStyle, Cesium3DTileset setup, VoxelPrimitive instantiation.
  • cesiumjs-models-particles — Model.fromGltfAsync, ModelFeature.getProperty(), animations.
  • cesiumjs-primitives — Fabric on Appearances for classic Primitive geometry.
  • CesiumJS Custom Shader Guide — Documentation/CustomShaderGuide/README.md on CesiumGS/cesium main.

© CesiumGS, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 10 other files in skills/cesiumjs-custom-shader of CesiumGS/cesiumjs-skills.

  • SKILL.md
  • REFERENCE.md
  • examples/01-diffuse-tint.js
  • examples/02-texture-swap.js
  • examples/03-feature-id-tileset.js
  • examples/04-translucent-override.js
  • examples/05-vertex-displacement.js
  • examples/06-metadata-ramp.js
  • examples/07-voxel-shader.js
  • examples/README.md
  • examples/_sandcastle-template.html

Open the folder on GitHubat commit 5f4792c

Compare with similar skills

Cesiumjs Custom Shader next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Cesiumjs Custom Shader compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Cesiumjs Custom Shader this skillCesiumGS/cesiumjs-skills189—~5.1kAutomated safety check: PassApache-2.0
PixijsRSamaium/CanvasEngine4012 repos~1.6kAutomated safety check: PassMIT
New ExperimentTresjs/tres3.8k—~782Automated safety check: PassMIT
Assets Shader List AllIvanMurzak/Unity-MCP4.4k—~435Automated safety check: PassApache-2.0
Handle Sdr Tonemap Lutclshortfuse/renodx4.5k—~7.3kAutomated safety check: PassMIT
Unreal Material and VFX Workflowflopperam/unreal-engine-mcp1.1k—~927Automated safety check: PassNone

Similar skills

  • Pixijs

    RSamaium/CanvasEngine

    Use this skill first for ANY PixiJS v8 task; it routes to the right specialized skill for the job.

    401 GitHub starsUsed in 2 repos~1.6k tokens
    Game DevelopmentAuto-check passed
  • New Experiment

    Tresjs/tres

    Create a new experiment in TresJS Lab with all necessary files

    3.8k GitHub stars~782 tokensUpdated yesterday
    Game DevelopmentAuto-check passed
  • Assets Shader List All

    IvanMurzak/Unity-MCP

    List all shaders available in the project assets and packages, sorted by name.

    4.4k GitHub stars~435 tokensUpdated yesterday
    Game DevelopmentAuto-check passed
  • Handle Sdr Tonemap Lut

    clshortfuse/renodx

    RenoDX HLSL/Slang shader workflow for proven shader-side SDR tonemap, hard clip, LUT, color grade, and HDR bridge changes.

    4.5k GitHub stars~7.3k tokensUpdated yesterday
    Game DevelopmentAuto-check passed
  • Unreal Material and VFX Workflow

    flopperam/unreal-engine-mcp

    Walks an Unreal Engine MCP agent through building materials, Niagara particle systems, Chaos destruction, and curve assets with inspect-then-edit steps.

    1.1k GitHub stars~927 tokensUpdated 3 mo ago
    Game DevelopmentAuto-check passed
  • Rdc CLI

    BANANASJIM/rdc-cli

    A skill your agent uses when working with RenderDoc capture files (.rdc), analyzing GPU frames, tracing shaders, inspecting draw calls, or running CI assertions against GPU captures.

    182 GitHub stars~2.9k tokensUpdated 2 days ago
    Game DevelopmentAuto-check passed

More from CesiumGS/cesiumjs-skills

All 14 skills in this repo
  • Cesiumjs 3D Tiles

    CesiumGS/cesiumjs-skills

    CesiumJS 3D Tiles - Cesium3DTileset, compressed and CAD-style glTF content, MVTDataProvider, UrlTemplate3DTilesDataProvider, styling, metadata, feature picking, voxels, point clouds, I3S, Gaussian…

    189 GitHub stars~4.7k tokensUpdated 26 days ago
    Auto-check passed
  • Cesiumjs Core Utilities

    CesiumGS/cesiumjs-skills

    CesiumJS core utilities and networking - Resource, Color, Event, Request, RequestScheduler, error handling, helper functions, feature detection.

    189 GitHub stars~3.9k tokensUpdated 26 days ago
    Auto-check passed
  • Cesiumjs Materials Shaders

    CesiumGS/cesiumjs-skills

    CesiumJS materials and post-processing — Material, Fabric JSON, MaterialAppearance, ImageBasedLighting, PostProcessStage, PostProcessStageLibrary, bloom, depth of field, ambient occlusion, FXAA…

    189 GitHub stars~3.6k tokensUpdated 26 days ago
    Auto-check passed
  • Cesiumjs Spatial Math

    CesiumGS/cesiumjs-skills

    CesiumJS spatial math - Cartesian3, Cartographic, Matrix4, Quaternion, Transforms, Ellipsoid, BoundingSphere, projections, coordinate conversions.

    189 GitHub stars~4.6k tokensUpdated 26 days ago
    Auto-check passed
  • Cesiumjs Terrain Environment

    CesiumGS/cesiumjs-skills

    CesiumJS terrain, globe, and environment - TerrainProvider, Globe, sampleTerrain, atmosphere, sky, fog, lighting, shadows, panoramas.

    189 GitHub stars~5k tokensUpdated 26 days ago
    Auto-check passed
  • Cesiumjs Viewer Setup

    CesiumGS/cesiumjs-skills

    CesiumJS viewer setup - Viewer, CesiumWidget, widgets, Ion token, Scene configuration, SceneMode, factory helpers, geocoders, platform services.

    189 GitHub stars~5k tokensUpdated 26 days ago
    Auto-check passed

Questions about Cesiumjs Custom Shader

What does Cesiumjs Custom Shader do?

CustomShader authoring — vertexShaderText and fragmentShaderText against VertexInput, FragmentInput, FeatureIds, Metadata, czmmodelMaterial. Cesiumjs Custom Shader is an agent skill from CesiumGS/cesiumjs-skills. CustomShader authoring — vertexShaderText and fragmentShaderText against VertexInput, FragmentInput, FeatureIds, Metadata, czmmodelMaterial.

When should I use Cesiumjs Custom Shader?

Cesiumjs Custom Shader fits situations like: reading EXTmeshfeatures; EXTstructuralmetadata property textures/tables; vertex displacement; shading VoxelPrimitive.

How do I install Cesiumjs Custom Shader in Claude Code?

Run `npx skills add CesiumGS/cesiumjs-skills --skill cesiumjs-custom-shader -a claude-code`. Or copy the skill folder (skills/cesiumjs-custom-shader in CesiumGS/cesiumjs-skills) into .claude/skills/cesiumjs-custom-shader in your project. Claude Code loads it when a task matches its description.

How do I install Cesiumjs Custom Shader in Codex?

Run `npx skills add CesiumGS/cesiumjs-skills --skill cesiumjs-custom-shader -a codex`. Or copy the skill folder (skills/cesiumjs-custom-shader in CesiumGS/cesiumjs-skills) into .agents/skills/cesiumjs-custom-shader in your project. Codex loads it when a task matches its description.

Can I use Cesiumjs Custom Shader in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add CesiumGS/cesiumjs-skills --skill cesiumjs-custom-shader -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/cesiumjs-custom-shader, .gemini/skills/cesiumjs-custom-shader, .github/skills/cesiumjs-custom-shader and .opencode/skills/cesiumjs-custom-shader in your project.

What does Cesiumjs Custom Shader need to run?

Going by SKILL.md and its folder, Cesiumjs Custom Shader needs JavaScript for the scripts in its folder. Our summary lists: Node.js.

Does Cesiumjs Custom Shader access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Cesiumjs Custom Shader safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Cesiumjs Custom Shader use?

Cesiumjs Custom Shader is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Cesiumjs Custom Shader use?

About 5.1k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Cesiumjs Custom Shader?

Skills that share tags, products or a category with Cesiumjs Custom Shader: Pixijs (RSamaium/CanvasEngine, 401 stars), New Experiment (Tresjs/tres, 3.8k stars), Assets Shader List All (IvanMurzak/Unity-MCP, 4.4k stars) and Handle Sdr Tonemap Lut (clshortfuse/renodx, 4.5k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Cesiumjs Custom Shader?

CesiumGS (a GitHub organization) maintains it in CesiumGS/cesiumjs-skills, which has 189 GitHub stars. The repository holds 14 skills in this directory. The repository was last updated on September 14, 2026.

Source: CesiumGS/cesiumjs-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.