https://framer.com/m/Scenestage-vpFQV4.js

Io / Enhancements / SceneStage

SceneStage

SceneStage puts two glTF models on one WebGL stage and dissolves between them through a mud-normal edge. Camera, lights, each stage’s surface mode, the transition driver, particles and the post pass all come from one JSON schema.

Enhancements11 controlsglTF stageschema-driven
Enhancements2 controlsshader washbackground layer

Examples

Live specimens. Camera, lights, both stages, the transition and the post pass come from the AI Schema; the panel carries progress, the two model slots and the debug helpers.

Live

One stage, two models: a duck on stage A and an animated fox on stage B. The buttons write a different AI Schema into the page variable the component is bound to — the transition driver, both surface modes and the particle field are all schema keys. The JSON under the canvas is that same variable.

Props

Eleven controls on the instance panel: progress, the curtain, the sketch toggle, the two model slots and the debug helpers. Everything else — camera, lights, both stages, the transition and the post pass — is set through the AI Schema, listed below the panel rows.

PropTypeBehaviour
progressnumberTransition A → B, 0–1. Animate it with variants or an override; tweened per schema.transition.tween. Ignored when the driver is scroll or loop.
wipePositionnumberCurtain overlay: -1 off, 0 covering, 1 off the other side. NOTE: this panel prop is written into the shader every frame, so it overrides schema.wipe.position — bind the prop to drive it.
sketchActivebooleanTurns the sketch pass on. NOTE: like wipePosition, the panel prop overrides schema.sketch.active every frame; bind this prop rather than setting the schema key.
stageIdstringName used by the window "scenestage" event API.
schemaJSONstringThe AI Schema. Camera, lights, both stages, the transition, wipe, sketch, particles and post. Empty = the built-in hero defaults.
modelA / URLfile / stringGLB or glTF for stage A (schema.stageA.model = A). Draco supported; the URL is used when no file is uploaded.
modelB / URLfile / stringGLB or glTF for stage B (schema.stageB.model = B). Same fallback order.
mudNormalimageTileable normal map that shapes the transition edge. Falls back to schema.assets.mudNormal, then procedural.
fallbackImageimageShown when WebGL is unavailable.
schema.presetstringeditions-hero (the captured hero: particles, bloom, dark stages) or clean (no particles, no bloom, no ambient fog).
schema.cameraobjectfov, position, target, autoFit (re-aim at the model's bounding sphere) and padding.
schema.lightsobjectambient, key, keyPosition, environment (RoomEnvironment PBR) and envIntensity.
schema.stageAobjectmodel (none | A | B), normalize, modelScale / Position / Rotation, autoRotate, animation, mode, shadow, camera move, background, ambient.
schema.stageBobjectSame shape as stageA. Its background defaults to the dark token, which is what hologram mode needs.
schema.modeenumPer stage: textured | shaded | wireframe | hologram, each with its own settings object.
schema.animationobjectPer stage: play, clip, speed, scrub, from, to. scrub ties the clip to progress.
schema.transitionobjectdriver (manual | scroll | loop | hover | click | inView), progress, tween, loopSeconds, heroMode, centerPoint, mouseInfluence, darken, mudScale, glow, edgeFade.
schema.wipeobjectposition and colour of the curtain overlay.
schema.sketchobjectactive, reveal, color, center, lineWidth, lineStrength.
schema.particlesobjectenabled, plus groups[]: count, size, colour, opacity, blur, speed, turbulence, blink and size variation.
schema.postobjectbloom { enabled, intensity, threshold, smoothing, radius } and smaa.
schema.perfobjectperformance: maxPixelRatio, pauseOffscreen, respectReducedMotion.
schema.debugbooleanOverlay with live progress, scroll range, camera and load state. Turn it off before publishing.
schema.debugViewenumcomposite | A | B — bypass the transition and show one stage's raw render.
schema.assetsobjectmudNormal URL. A panel upload wins when both are present.
PropTypeBehaviour
progressnumberTransition A → B, 0–1. Animate it with variants or an override; tweened per schema.transition.tween. Ignored when the driver is scroll or loop.
wipePositionnumberCurtain overlay: -1 off, 0 covering, 1 off the other side. NOTE: this panel prop is written into the shader every frame, so it overrides schema.wipe.position — bind the prop to drive it.
sketchActivebooleanTurns the sketch pass on. NOTE: like wipePosition, the panel prop overrides schema.sketch.active every frame; bind this prop rather than setting the schema key.
stageIdstringName used by the window "scenestage" event API.
schemaJSONstringThe AI Schema. Camera, lights, both stages, the transition, wipe, sketch, particles and post. Empty = the built-in hero defaults.
modelA / URLfile / stringGLB or glTF for stage A (schema.stageA.model = A). Draco supported; the URL is used when no file is uploaded.
modelB / URLfile / stringGLB or glTF for stage B (schema.stageB.model = B). Same fallback order.
mudNormalimageTileable normal map that shapes the transition edge. Falls back to schema.assets.mudNormal, then procedural.
fallbackImageimageShown when WebGL is unavailable.
schema.presetstringeditions-hero (the captured hero: particles, bloom, dark stages) or clean (no particles, no bloom, no ambient fog).
schema.cameraobjectfov, position, target, autoFit (re-aim at the model's bounding sphere) and padding.
schema.lightsobjectambient, key, keyPosition, environment (RoomEnvironment PBR) and envIntensity.
schema.stageAobjectmodel (none | A | B), normalize, modelScale / Position / Rotation, autoRotate, animation, mode, shadow, camera move, background, ambient.
schema.stageBobjectSame shape as stageA. Its background defaults to the dark token, which is what hologram mode needs.
schema.modeenumPer stage: textured | shaded | wireframe | hologram, each with its own settings object.
schema.animationobjectPer stage: play, clip, speed, scrub, from, to. scrub ties the clip to progress.
schema.transitionobjectdriver (manual | scroll | loop | hover | click | inView), progress, tween, loopSeconds, heroMode, centerPoint, mouseInfluence, darken, mudScale, glow, edgeFade.
schema.wipeobjectposition and colour of the curtain overlay.
schema.sketchobjectactive, reveal, color, center, lineWidth, lineStrength.
schema.particlesobjectenabled, plus groups[]: count, size, colour, opacity, blur, speed, turbulence, blink and size variation.
schema.postobjectbloom { enabled, intensity, threshold, smoothing, radius } and smaa.
schema.perfobjectperformance: maxPixelRatio, pauseOffscreen, respectReducedMotion.
schema.debugbooleanOverlay with live progress, scroll range, camera and load state. Turn it off before publishing.
schema.debugViewenumcomposite | A | B — bypass the transition and show one stage's raw render.
schema.assetsobjectmudNormal URL. A panel upload wins when both are present.

Usage

Guidance carried over from the component definition.

Reach for SceneStage

A hero where one object becomes another: two glTF models, one dissolve, no video file.

Pages that need the same object in several surface treatments — textured, shaded, wireframe, hologram.

Scroll-, click- or hover-driven storytelling: the driver is one schema key, not a rebuild.

Anything that has to degrade gracefully — a fallback image covers readers without WebGL.

Reach for something else

One model the reader turns freely. That is ModelViewer3d; this is a staged transition, not an inspector.

A moving background with no 3D asset. SilkWave or FluidShaderBackground cost a fraction of the payload.

A photo cross-fade. LiquidMaskTimeline and DistortoSlider dissolve images without loading a WebGL stage.

Io — Enhancements

Every specimen above is a live component instance. Colour, type and radius resolve from the project theme tokens.

io

An experiment in what a design system becomes when AI can consume it.

© 2026 io

Contact me

Create a free website with Framer, the website builder loved by startups, designers and agencies.