Skip to main content
vfx-dissolve is a skill from the Summer skill library: a guide your AI agent reads when the task matches, so it builds the good version on the first try. Dissolve effect: a mesh burns away with a glowing edge, from a noise-threshold ShaderMaterial.

When your agent uses it

  • Authoring a dissolve effect — an object disintegrating with a glowing burning edge (disintegrate, burn away, vanish into ash)
  • A defeated unit, teleport exit, or removed object should burn away with a glowing edge instead of vanishing

Install

summer setup installs every skill for your agent. To add only this one:
Swap claude-code for your agent, such as codex or cursor. See Skills for every option.

The skill

The dissolve shader samples 3D noise per fragment and clips pixels whose noise value is below a threshold uniform. Pixels just above the threshold are tinted with an emissive edge_color to fake the burning rim. Animate threshold from 0 to 1 over duration and the mesh appears to dissolve from “nothing missing” to “completely gone.” Used for enemy death, item pickups, transitions, summon FX. NOT a particle system — this is a material override on the target mesh itself.

When to use

  • “Enemy disintegrates when killed.”
  • “Item dissolves when picked up.”
  • “Banish the demon back to the void.”
  • “Thanos snap — character turns to dust.”
  • “Object burns away.”
  • “Stealth cloak fades the player out.”
  • The user wants an object to go away dramatically rather than queue_free() instantly.

When NOT to use

  • The user wants fire on the object that doesn’t consume it — use vfx-fire, not dissolve. Dissolve makes the mesh disappear; fire just sits on top.
  • The user wants a particle-driven ash cloud as the object disappears — pair this with vfx-smoke (recolor to ash gray) spawned at the dissolving mesh’s bounds.
  • The user wants a fade-out via alpha (cheap, no shader) — set transparency = TRANSPARENCY_ALPHA and tween albedo_color.a to 0. Dissolve is better but more expensive.
  • The user wants the world to dissolve in for a level transition — that’s a screen-space post-process, not this per-mesh recipe.
  • The character has skinned mesh + multiple materials — this works but you have to override every material slot. Confirm with user; consider a fade-out instead.

Recipe

1. Files to create

No .tscn needed — this overrides materials on existing meshes. dissolve.gdshader #includes the FBM noise file. A missing include is a hard compile error, so copy _building-blocks/noise-3d-fbm.gdshaderinc from this skill into res://addons/vfx/_building-blocks/ before writing the shader.

2. Shader code

addons/vfx/dissolve/dissolve.gdshader:

3. GDScript controller

addons/vfx/dissolve/dissolve_controller.gd:

4. Node tree

No new nodes added. The recipe overrides the material_override on every MeshInstance3D under the target.

5. Wire it in (MCP calls)

This recipe is script-driven — no scene mutation. Write the two files with summer_write_file (one of create_only or expected_sha256 is required), plus the .gdshaderinc, then call from gameplay code.
If the target needs the dissolve to be cosmetic-only (no queue_free):

5a. Iterate on the shader with ctx.make_shader (summer_run_script)

On engines with the geometry-tier ctx stdlib (see scene-scripting), prototype the shader BEFORE committing it to a file: ctx.make_shader(code, params) compiles the source and returns compile errors verbatim in the result (the make_shader_errors report entry, line numbers included) — no silent magenta material, no play-mode round-trip:
The loop: read the exact error from the report → fix that line → re-run. Once it compiles and a screenshot at threshold: 0.4 shows the edge glow, write the final source to dissolve.gdshader with summer_write_file so the controller can preload it. (The editor-side preview does not replace 5b — the tweened runtime effect still needs a play-mode check.)

5b. Verify

Both files are compiled code. Check them before claiming the dissolve works.
A missing noise-3d-fbm.gdshaderinc fails the whole shader, and the mesh then renders with the fallback material rather than dissolving.

6. Parameters to tune

Cookbook — named variants

enemy-burn-death (default)

Orange edge, 1.2s, fire-y character.

thanos-snap

Fast, fine grain, blue edge for the cosmic feel. Pair with vfx-smoke in pale gray for ash particles rising.

holy-banish

Slow, white edge, big halo. Add vfx-magic-glow underneath for a beam of light.

poison-melt

Slow, sickly green, watery look.

summon-arrival (use materialize_object)

Inverse of enemy-burn-death.

Anti-patterns

  • Calling dissolve_object and then queue_free immediately. The tween needs the node alive. Pass free_when_done = true (default) so the tween’s last call queues the free.
  • Dissolving a mesh with translucent materials (already transparency = ALPHA). The dissolve shader’s discard works in opaque pass; translucent meshes look weird. Convert to opaque or use a custom dissolve-with-alpha shader.
  • Dissolving a particle system (e.g., torch flame). The shader is spatial, not particles. Stop the particles, don’t try to dissolve them.
  • Forgetting to seed noise_offset per instance. Two enemies dissolving at the same frame use identical patterns → they look like clones. The included controller randomizes per-instance.
  • Using world-space noise on a moving target. The dissolve pattern slides over the surface as the mesh moves. Use use_object_space = true (default).
  • Treating VERTEX in fragment() as world space. It is view space. Sampling noise from it directly makes the pattern slide as the camera moves, and inverse(MODEL_MATRIX) * vec4(VERTEX, 1.0) is not object space either. Go through INV_VIEW_MATRIX first, as section 2 does.
  • Skipping the texture inheritance. The mesh dissolves but goes white because base_color defaults to white and no texture is set. The controller pulls from the original BaseMaterial3D; if your mesh uses a custom shader, manually wire the textures.
  • Dissolving a Skeleton3D directly. It’s not a mesh — recurse into MeshInstance3D children. The controller’s _collect_meshes does this.

Performance notes

  • Per fragment: one FBM noise call (4 octaves, 8 hashes each) + one branch + two 4×4 inversions. Sub-millisecond per dissolving object at 1080p covering 10% of the screen — an order-of-magnitude expectation, not a measurement. Profile if you need a number.
  • Multiple meshes on a character (head, body, weapon, cape): each gets its own override, and the cost scales with the number of materials. Still fine for a handful.
  • inverse(MODEL_MATRIX) runs per fragment. If you are dissolving a large screen-filling mesh and profiling says this hurts, hoist the object-space position into a varying computed in vertex().
  • discard defeats early-Z. For a screen full of dissolving enemies, consider cull_back (already enabled) and avoid stacking 20+ dissolves at once.
  • Mobile: drop noise_scale to a value the FBM can compute in 1–2 octaves, or replace the fbm3 include with a single-octave noise.

Edge cases

  • Mesh has multiple material slots. The controller only inherits slot 0. For multi-material meshes (helmet + body different textures), extend _override_material to loop over all surfaces with mi.set_surface_override_material(i, ...).
  • Skinned mesh deforming during dissolve. Object-space noise on a skinned mesh moves with the bones — looks fine. World-space noise (use_object_space = false) shears with deformation.
  • Mesh has emission already (glowing eyes, etc.). The dissolve shader resets EMISSION. To preserve the original emission, sample an emission_texture uniform and add it to the EMISSION line.
  • Threshold at exactly 1.0 leaves a single subpixel of geometry. The controller passes 1.0 as the final value; in practice this dissolves everything because no fbm3 returns above 1.0. If it doesn’t on your noise, clamp the final value to 1.05.
  • Re-materializing while the dissolve is still tweening. Both tweens run concurrently. Kill the previous tween first: store the returned Tween and call kill() before starting the next.

Fallback (no MCP)

Section 5 is fully automatable — summer_write_file writes all three files and summer_get_script_errors proves they parsed. Do not hand these steps to the user when the MCP tools are available. Without the MCP connection there is no engine to drive, so the user does it themselves:
  1. Create addons/vfx/_building-blocks/ and addons/vfx/dissolve/ and write the three files above.
  2. From any gameplay script, call DissolveController.dissolve_object(target_node).
  3. The controller handles material override, texture inheritance, tween, and freeing.
  4. Check the Errors dock — a missing .gdshaderinc fails the whole shader.

Handoff

After firing this recipe, suggest:
  • vfx-smoke — recolor pale gray, spawn at the target’s bounds for ash particles. Especially good for thanos-snap.
  • vfx-magic-glow — for holy-banish and summon-arrival variants, add a vertical beam of light at the target.
  • vfx-fire — pair enemy-burn-death with a brief flame burst at the start of the dissolve.
  • game-feel — add a slow-mo on enemy death (Engine.time_scale = 0.4 for 0.3 s) to emphasize the dissolve.
  • sound-effect — generate magical disintegration whoosh, fading shimmer, 1.5s and play in sync.

See also

  • _building-blocks/noise-3d-fbm.gdshaderinc — the FBM noise this shader includes
  • vfx-smoke — pair for the ash cloud
  • vfx-magic-glow — for arrival/departure beams
  • vfx-fire — for the burn-up variant pairing
  • gdscript-patterns — for the static-API class pattern

From a shell

No Summer MCP tools in this session? Run each one as a command; when summer --version is missing or below 4.0, use npx -y summer-engine@latest in place of summer. Fields are flags in kebab-case (--scene-path res://main.tscn) or one --input '<json>', and summer ops describe <op> prints the exact input. The summer-cli skill has the rest.

Files in this skill

  • scene-scripting: Build scenes, levels, HUDs and wiring with one editor GDScript (summer_run_script) instead of call chains.
  • sound-effect: Make sound effects (swings, hits, whooshes, reloads, UI): three versions to pick from, then wire them.
  • game-feel: Add juice: hit-flash, trauma camera shake and audio ducking, one hit fires all three.
  • vfx-fire: Fire effect: animated flames from GPUParticles3D, a particle shader and a noise color ramp.
  • vfx-magic-glow: Magic-glow effect: a pulsing OmniLight3D, drifting additive motes and an optional emission shader.
  • vfx-smoke: Smoke effect: a rising column or puff of soft particles with a noise and density falloff shader.

Source: library/skills/vfx-dissolve/SKILL.md, rendered from summer-engine@4.3.0 on npm.