melonJS
    Preparing search index...

    Class Sprite3d

    A textured quad in 3D space — the 3D counterpart of Sprite, for rendering sprites under a Camera3d (the 2.5D workflow: characters, pickups, foliage, signs, particles in a 3D scene). It's a thin Mesh subclass, so it rides the same world-space mesh pipeline (depth testing, frustum culling) and supports the same material features (lit, emissive, alphaCutoff).

    Its headline feature is billboarding — keeping the quad facing the camera regardless of camera orientation (see Sprite3d#billboard). With billboarding off it's a fixed-orientation quad (decals, posters, ground markers).

    Frame animation is supported through the same API as Sprite (Sprite3d#addAnimation, Sprite3d#setCurrentAnimation, Sprite3d#play/pause/stop) — pass framewidth/frameheight for a spritesheet, or a packed TextureAtlas, exactly as you would for a 2D Sprite. Both share the FrameAnimation engine, so the timing, looping and chaining behavior is identical; Sprite3d maps the current frame onto the quad each step — including packer rotated and trimmed regions, mapped to full parity with the 2D Sprite.

    Camera3d only. Like Mesh, Sprite3d renders through the 3D world-space path; under a 2D Camera2d it falls back to the mesh's self-projection and billboarding has no effect (a 2D scene has no camera orientation to face). Use a regular Sprite for 2D.

    Anchoring. Unlike its Mesh parent — where anchorPoint is inert on the 3D path and transforms pivot at the model origin — Sprite3d's anchorPoint is live: the anchor is baked into the quad's local vertices (never applied as a renderer transform on either camera path) and can be changed at runtime via anchorPoint.set(...), which re-bakes the quad and re-derives the cull bounds. Same key, convention and centered default as the 2D Sprite, including the named presets ("bottom", …).

    import { Application, Camera3d, Sprite3d } from "melonjs";

    // a 3D app (Camera3d is required for billboarding)
    const app = new Application(1024, 768, { cameraClass: Camera3d });

    // a tree that always faces the camera but stays upright (2.5D).
    // its texture has a transparent background — the mesh pass is opaque, so
    // `alphaCutoff` (default 0.5) discards those texels for a clean silhouette.
    const tree = new Sprite3d(0, 0, {
    image: "tree", // a preloaded image with transparency
    width: 64, height: 96,
    z: -200, // 3D depth (world z)
    billboard: true, // = "cylindrical"
    // alphaCutoff: 0.5, // the default — lower it to keep softer edges,
    // or set 0 for a fully-opaque quad
    });
    app.world.addChild(tree); // add it to the game world, like any Renderable

    // an animated, fully camera-facing pickup from a spritesheet, mirrored
    const coin = new Sprite3d(0, 0, {
    image: "coins",
    framewidth: 32, frameheight: 32,
    width: 48, height: 48,
    billboard: "spherical",
    alphaCutoff: 0.5, // cut out the transparent frame background
    });
    coin.addAnimation("spin", [0, 1, 2, 3, 4, 5]);
    coin.setCurrentAnimation("spin");
    coin.flipX(); // face the other way (mirrors the sprite)
    app.world.addChild(coin);

    // a character anchored at the feet, so `pos` sits on the ground plane
    // instead of at the sprite's geometric center
    const hero = new Sprite3d(0, 0, {
    image: "hero",
    width: 48, height: 64,
    billboard: "cylindrical",
    anchorPoint: "bottom", // == { x: 0.5, y: 1 }
    });

    Hierarchy (View Summary)

    Index
    • Parameters

      • x: number

        world x position

      • y: number

        world y position

      • settings: {
            alphaCutoff?: number;
            anchorPoint?: any;
            anims?: object[];
            billboard?: string | boolean;
            emissive?: number[] | Float32Array<ArrayBufferLike>;
            flipX?: boolean;
            flipY?: boolean;
            frameheight?: number;
            framewidth?: number;
            height?: number;
            image?: string | HTMLImageElement | Texture2d;
            lit?: boolean;
            region?: string;
            width?: number;
            z?: number;
        }

        configuration

        • OptionalalphaCutoff?: number

          alpha cutout threshold (see Mesh). The mesh pass is opaque (no alpha blending), so this defaults to 0.5 to discard a sprite's transparent background (clean cutout silhouette, correct depth, no sorting). Set 0 for a fully-opaque quad, or tune the threshold.

        • OptionalanchorPoint?: any

          anchor of the quad relative to pos — same key, normalized 0..1 convention (x: 0 left→1 right, y: 0 top→1 bottom) and centered default as the 2D Sprite. Also accepts the named presets "center", "top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right". Baked into the quad's local vertices (composes with billboarding, flips, and trimmed/rotated atlas frames) — never applied as a renderer transform on either camera path. Mutable at runtime via this.anchorPoint.set(...) (re-bakes the quad and re-derives the cull bounds). Invalid values throw.

        • Optionalanims?: object[]

          predefined animations (same shape as Sprite)

        • Optionalbillboard?: string | boolean

          billboard mode: false (fixed orientation), true / "cylindrical" (faces the camera but stays upright — the 2.5D default), or "spherical" (faces the camera on all axes). Only applies under a Camera3d.

        • Optionalemissive?: number[] | Float32Array<ArrayBufferLike>

          emissive color (see Mesh)

        • OptionalflipX?: boolean

          mirror the sprite horizontally (see Sprite3d#flipX)

        • OptionalflipY?: boolean

          mirror the sprite vertically (see Sprite3d#flipY)

        • Optionalframeheight?: number

          height of a single frame within a spritesheet

        • Optionalframewidth?: number

          width of a single frame within a spritesheet (enables frame animation)

        • Optionalheight?: number

          quad height in world units

        • Optionalimage?: string | HTMLImageElement | Texture2d

          the sprite texture (image name, image, or a Texture2d asset such as a TextureAtlas). Alias: settings.texture.

        • Optionallit?: boolean

          shade through the lit mesh batcher (see Mesh)

        • Optionalregion?: string

          region name when using a texture atlas (see TextureAtlas)

        • Optionalwidth?: number

          quad width in world units (pixels)

        • Optionalz?: number

          3D depth (world z); also settable later via .depth

      Returns Sprite3d

    alpha: number

    Define the renderable opacity
    Set to zero if you do not wish an object to be drawn

    • Renderable#setOpacity
    • Renderable#getOpacity
    1.0
    
    alphaCutoff: number

    Alpha cutout threshold. A fragment whose final alpha is below this value is discarded — a hard-edged cutout (foliage, fences, chain-link, decals) that needs no blending or back-to-front sorting. 0 (the default) disables the cutout and the mesh renders fully opaque. Set by the glTF loader from a material's alphaMode: "MASK" / alphaCutoff. GPU mesh path only (the Canvas renderer ignores it).

    0
    
    alphaMap: TextureAtlas | undefined

    Per-texel opacity map (MTL map_d), or undefined. Its red channel multiplies the fragment's alpha before Mesh#alphaCutoff is applied, so a single material can cut out per pixel — the shape of a leaf, the holes in a chain-link fence — where alphaCutoff alone can only threshold uniformly across the whole material.

    Only meaningful alongside a non-zero alphaCutoff: without one there is nothing to discard against. GPU mesh path only.

    alwaysUpdate: boolean

    Whether the renderable object will always update, even when outside of the viewport

    false
    
    ancestor: Container | Entity

    a reference to the parent object that contains this renderable

    undefined
    
    anchorPoint: ObservablePoint

    The anchor point is used for attachment behavior, and/or when applying transformations.
    The coordinate system places the origin at the top left corner of the frame (0, 0) and (1, 1) means the bottom-right corner

    a Renderable's anchor point defaults to (0.5,0.5), which corresponds to the center position.

    Note: Object created through Tiled will have their anchorPoint set to (0, 0) to match Tiled Level editor implementation. To specify a value through Tiled, use a json expression like json:{"x":0.5,"y":0.5}, or (since 19.9) a plain string preset such as bottom.
    At construction time, settings.anchorPoint also accepts the named presets "center", "top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right" on every renderable that consumes it (Sprite, Entity, Collectable, ImageLayer, Text, BitmapText, Sprite3d and subclasses).

    <0.5,0.5>
    
    applyAnchorTransform: boolean

    Whether Renderable#preDraw applies the Renderable#anchorPoint offset to the renderer transform.

    When true (the default), the renderable is shifted by -anchorPoint × (width, height) so its anchor — not its top-left corner — aligns with its position. Correct for sprites and other 2D renderables.

    Set to false for a renderable that emits its own final world coordinates and takes its origin from geometry rather than a bounds box — e.g. a Mesh on the Camera3d world-space path (a 3D mesh is positioned by its transform and has no anchor). The WebGL mesh batcher reuses this same renderer transform as its view matrix, so applying the normalized anchor there would shift every mesh by half its OWN bounds box; because scene meshes size that box per node, props and the platforms they rest on would drift apart and overlap.

    true
    

    Mesh#preDraw

    autoTransform: boolean

    When enabled, an object container will automatically apply any defined transformation before calling the child draw method.

    true
    
    // enable "automatic" transformation when the object is activated
    onActivateEvent: function () {
    // reset the transformation matrix
    this.currentTransform.identity();
    // ensure the anchor point is the renderable center
    this.anchorPoint.set(0.5, 0.5);
    // enable auto transform
    this.autoTransform = true;
    ....
    }
    billboard: string | boolean

    Billboard mode — keeps the quad facing the active Camera3d:

    • false (default) — fixed orientation (a flat quad in the XY plane; decals, posters, ground markers).
    • true / "cylindrical" — faces the camera but stays upright (rotates only around the world up axis). The 2.5D default — trees, characters, items.
    • "spherical" — faces the camera on all axes (particles, glints).

    Only applies under a Camera3d; ignored on the 2D path.

    Note: while billboarding, orientation comes from the camera, so the renderable's currentTransform (rotate() / scale() / parent-container transforms) and meshScale are not applied — only pos / depth, flipX / flipY, and the quad's authored size. With billboarding false the standard Mesh world transform applies as usual.

    false
    
    blendMode: string

    the blend mode to be applied to this renderable — any of the modes listed on CanvasRenderer#setBlendMode, honoured identically by every renderer

    "normal"
    
    • CanvasRenderer#setBlendMode
    • WebGLRenderer#setBlendMode
    body: PhysicsBody

    the renderable physics body — the handle returned by the active PhysicsAdapter's addBody (or constructed imperatively via new Body(...)). Typed as the portable PhysicsBody interface; cast to the adapter-specific concrete type (MatterAdapter.Body, BuiltinAdapter.Body, or the legacy Body class) to reach native fields.

    // define a new Player Class
    class PlayerEntity extends me.Sprite {
    // constructor
    constructor(x, y, settings) {
    // call the parent constructor
    super(x, y , settings);

    // define a basic walking animation
    this.addAnimation("walk", [...]);
    // define a standing animation (using the first frame)
    this.addAnimation("stand", [...]);
    // set the standing animation as default
    this.setCurrentAnimation("stand");

    // add a physic body
    this.body = new me.Body(this);
    // add a default collision shape
    this.body.addShape(new me.Rect(0, 0, this.width, this.height));
    // configure max speed, friction, and initial force to be applied
    this.body.setMaxVelocity(3, 15);
    this.body.setFriction(0.4, 0);
    this.body.force.set(3, 0);
    this.isKinematic = false;

    // set the display to follow our position on both axis
    app.viewport.follow(this, app.viewport.AXIS.BOTH);
    }

    ...

    }
    bodyDef: object | undefined

    Declarative body definition consumed by the active PhysicsAdapter when this renderable is added to a container. Adapter API only — leave undefined if you build a body imperatively via this.body = new Body(...).

    When set, the parent container forwards it to world.adapter.addBody(this, this.bodyDef), which constructs the underlying physics body (matter, builtin SAT, …) and assigns the engine-portable wrapper to this.body. This is the engine-portable path: the same bodyDef produces an equivalent body under any adapter.

    Typical fields: type ("static"/"dynamic"/"kinematic"), shapes, collisionType, collisionMask, restitution, frictionAir, density, gravityScale, isSensor, maxVelocity, fixedRotation. See BodyDefinition.

    undefined
    
    castGroundShadow: boolean | undefined

    Cast a soft dark ellipse — a "blob" shadow — on the ground beneath this mesh (#1515).

    Not a simulated shadow, deliberately: what a 2.5D scene needs from one is contact — where the object is standing, and how far off the ground it is mid-jump. It costs one extra draw per shadowed object, shares one geometry and one texture with every other shadow in the scene, and is inert while false.

    Requires a GPU backend and a Camera3d: the shadow rides the retained world-space path, so the Canvas renderer and the 2D-camera path draw none.

    Left unset (undefined, the default) this follows the application's castGroundShadow setting — with one safeguard: a scene-wide opt-in skips meshes with no vertical extent, because a flat plane lying on the floor is the floor, and shadowing it with itself smears the whole ground. Setting the property here is an explicit instruction and always obeyed, safeguard included.

    undefined
    

    Mesh#shadowGroundY

    cullBackFaces: boolean

    whether to cull back-facing triangles

    true
    
    currentTransform: Matrix3d

    the renderable transformation matrix (4x4). For standard 2D use, only the 2D components are used (rotate around Z, scale X/Y, translate X/Y). For 3D use (e.g. Mesh), the full 4x4 matrix supports rotation around any axis, 3D translation, and perspective projection. Use the rotate(), scale(), and translate() methods rather than modifying this directly.

    depth: number
    edges: Vector2d[]

    The edges here are the direction of the nth edge of the polygon, relative to the nth point. If you want to draw a given edge from the edge value, you must first translate to the position of the starting point.

    emissive: Float32Array<ArrayBufferLike> | undefined

    Emissive (self-illumination) color as an [r, g, b] Float32Array (0..1, may exceed 1 for HDR glow), added on top of the lit/unlit color so the surface glows independently of the scene lights (neon, lava, screens, glowing eyes). undefined (the default) means no emission and keeps the mesh on the lean path. Set by the glTF loader from a material's emissiveFactorKHR_materials_emissive_strength) and by the OBJ loader from an MTL's Ke. GPU mesh path only (WebGL and WebGPU; the Canvas renderer ignores it).

    floating: boolean

    If true, this renderable will be rendered using screen coordinates, as opposed to world coordinates. Use this, for example, to define UI elements.

    false
    
    fog: boolean | undefined

    Whether this mesh is affected by the camera's distance fog (Camera3d#setFog).

    Left unset (undefined, the default) the mesh fogs whenever the camera drawing it has fog — which for a scene that never enables fog means never. Set it to false and this mesh is never fogged, however far away it is: the escape hatch for something that has to stay readable at any distance, such as an objective marker or a waypoint. true is accepted for symmetry and behaves as the default.

    It exempts the mesh, not the ground shadow it casts. A blob is a mark on the floor and fogs with the floor it lies on — one staying crisp under an object whose surroundings had dissolved would read as a fault rather than as emphasis. The blob quad is also shared by every caster in the scene, so it carries no per-object state to read.

    Emissive surfaces fog too — light travelling through fog is attenuated like anything else — so a neon sign that should punch through wants fog: false rather than a brighter emissive.

    undefined
    

    Camera3d#setFog

    // the world fogs; this waypoint stays readable at any distance
    camera.setFog({ near: 1200, far: 7000 });

    const marker = new Mesh(0, 0, {
    ...beaconGeometry,
    emissive: [1, 0.6, 0],
    fog: false,
    });
    // or afterwards, on anything already built
    marker.fog = false;
    groups: {
        count: number;
        materialName: string | null;
        opacity: number;
        start: number;
        texture: TextureAtlas | undefined;
        tint: Color;
    }[]

    Per-material submesh groups, populated when the OBJ contains multiple usemtl directives AND a matching MTL is bound via the material setting. Each entry slices the shared indices buffer; field shape (start, count, materialName) matches the glTF "groups" convention.

    Under the per-vertex color baking path (tier 2), the tint / opacity fields here are informational — the actual rendered color is baked into vertexColors at construction time. Mutating groups[i].tint after construction has no visible effect; use mesh.tint for runtime color multiplication, or rebuild the Mesh with new material settings.

    GUID: string

    (G)ame (U)nique (Id)entifier"
    a GUID will be allocated for any renderable object added
    to an object container (including the app.world container)

    indices: number[]

    a list of indices for all vertices composing this polygon

    isDirty: boolean

    when true the renderable will be redrawn during the next update cycle

    true
    
    isKinematic: boolean

    If true then physic collision and input events will not impact this renderable

    true
    
    isPersistent: boolean

    make the renderable object persistent over level changes

    false
    
    lit: boolean

    Whether this mesh is lit by the active stage's Light3d lights. When true it renders through the lit mesh batcher (diffuse shading from the scene's lights, using Mesh#originalNormals); when false (the default) it uses the lean unlit path and pays no lighting cost. The glTF loader sets this on scene meshes when the scene has lights. Only meaningful under a Camera3d on a GPU backend.

    false
    

    A mask limits rendering elements to the shape and position of the given mask object. So, if the renderable is larger than the mask, only the intersecting part of the renderable will be visible.

    undefined
    
    // apply a mask in the shape of a Star
    myNPCSprite.mask = new me.Polygon(myNPCSprite.width / 2, 0, [
    // draw a star
    {x: 0, y: 0},
    {x: 14, y: 30},
    {x: 47, y: 35},
    {x: 23, y: 57},
    {x: 44, y: 90},
    {x: 0, y: 62},
    {x: -44, y: 90},
    {x: -23, y: 57},
    {x: -47, y: 35},
    {x: -14, y: 30}
    ]);
    meshScale: number

    Uniform world-space scale (pixels per source unit) applied along the Camera3d world path. Defaults to width. Scene loaders (e.g. glTF) set this independently of width / height so those can describe the renderable's world-space bounds (used for frustum culling) while the geometry is still scaled by this factor — width alone can't serve both roles for a non-normalized scene mesh.

    settings.width
    
    name: string

    The name of the renderable

    ""
    
    onended: Function

    a callback fired when the current animation completes a cycle.

    onVisibilityChange: Function

    an event handler that is called when the renderable leave or enter a camera viewport

    undefined
    
    this.onVisibilityChange = function(inViewport) {
    if (inViewport === true) {
    console.log("object has entered the in a camera viewport!");
    }
    };
    originalNormals: Float32Array<ArrayBufferLike> | undefined

    the source per-vertex normals (x,y,z triplets), or undefined if the mesh was built without them. Supplied by the glTF loader; used for lit shading under a Camera3d (see Light3d).

    originalVertices: Float32Array<ArrayBufferLike>

    the original (untransformed) vertex positions as x,y,z triplets

    points: Vector2d[]

    Array of points defining the Polygon
    Note: If you manually change points, you must call recalcafterwards so that the changes get applied correctly.

    origin point of the Polygon

    postEffects: any[]

    the list of post-processing shader effects applied to this renderable (GPU backends — WebGL and WebGPU). Effects are applied in order. Use addPostEffect, getPostEffect, and removePostEffect to manage effects, or assign directly. On the Canvas renderer effects stay inert (the scene keeps rendering un-effected).

    []
    
    // add effects via helper methods
    mySprite.addPostEffect(new DesaturateEffect(renderer));
    mySprite.addPostEffect(new VignetteEffect(renderer));
    // assign directly
    mySprite.postEffects = [new SepiaEffect(renderer), new VignetteEffect(renderer)];
    projectionMatrix: Matrix3d

    Projection matrix applied automatically before the model transform in draw(). Defaults to a perspective projection (45° FOV, camera at z=-2.5) suitable for viewing unit-cube-sized geometry. Set to identity for orthographic (flat) projection. Most users don't need to modify this — the default works for standard OBJ models.

    rightHanded: boolean

    Treat the source geometry as right-handed (Y-up, e.g. glTF) under the Camera3d world path. The default (false) Y-up→Y-down bridge negates Y only — a reflection, which mirrors the scene left/right. When true, the bridge negates Y and Z (a 180° rotation about X, determinant +1) so chirality is preserved and the result matches the authoring tool (no mirror); triangle winding is left untouched since a rotation doesn't invert it.

    false
    
    shadowGroundY: number | undefined

    World Y of the floor the shadow lands on, or undefined (the default) to mean "this object is standing on the ground" — the shadow sits at the object's own base, at full strength, and does not shrink or fade.

    Set it, and the shadow shrinks and fades as the object rises above it: the readable part of a jump. The game already knows this value from collision, which is why it is not derived — deriving it from the object's live bounds would make the "ground" jump with the jumper, so the height could never be anything but zero.

    Render space is Y-DOWN, so the floor is a greater Y than the object above it.

    undefined
    
    shadowOpacity: number

    Opacity of the shadow directly beneath the object, before any height fade.

    0.45
    
    shininess: number

    Specular exponent — how tight the highlight is. The MTL Ns range is 0..1000; higher is a smaller, harder highlight (polished metal), lower is a broad sheen (satin). 0 (the default) disables the specular term outright however bright Mesh#specular is, which is what keeps a material declaring neither on the diffuse-only path.

    0
    
    specular: Float32Array<ArrayBufferLike> | undefined

    Specular (highlight) color as an [r, g, b] Float32Array, or undefined for a purely diffuse surface — which is the default, and what every mesh rendered as before this existed.

    Drives a Blinn-Phong highlight on the lit mesh path, so it needs lit: true, a Light3d, and normals. Set by the OBJ loader from an MTL's Ks; paired with Mesh#shininess, which decides how tight the highlight is. A Ks with no Ns produces nothing — the exponent is what turns the term on.

    Mesh#shininess

    texture: any
    textureGroups:
        | { count: number; start: number; texture: TextureAtlas }[]
        | undefined

    Index ranges that each need their own diffuse texture bound, for a multi-material model whose materials carry different map_Kd maps (#1573) — undefined whenever one binding covers the whole mesh, which is every single-material model and every Kd-only one.

    The GPU backends draw one indexed range per entry instead of one range for the whole mesh; adjacent materials sharing a texture are already merged here, so the list is the minimum number of draws the model needs. An explicit settings.texture suppresses the split entirely — asking for one texture is asking for one texture.

    The Canvas renderer ignores this: a multi-material mesh takes its per-triangle solid-fill path there and never samples a texture at all.

    textureRepeat: string | undefined

    Per-mesh texture wrap mode ("repeat" / "repeat-x" / "repeat-y" / "no-repeat"), or undefined to sample with the texture's own wrap. Some assets author UVs outside the [0, 1] range and rely on the sampler repeating the texture (this is the glTF default sampler behavior); the mesh would otherwise clamp to the edge texels and look flat / untextured.

    Kept on the mesh and threaded to the batcher at draw time — sampler state per use, like a GL sampler object — so it never mutates the per-image TextureAtlas shared with every other consumer of the same image (#1503). Two meshes (or a mesh and a sprite) can point at one image with different wrap modes; the texture cache keys GL units by (source, repeat) so each wrap gets its own GL texture. Applied only to a real texture — never the shared white-pixel fallback, which is global and must stay "no-repeat".

    transparent: boolean | undefined

    Whether this mesh draws in the transparent pass — blended, back-to-front, writing no depth — instead of the opaque one.

    Left unset (undefined, the default) the mesh goes transparent whenever the draw resolves to fractional alpha, so setOpacity(0.5) simply fades it. That is the useful default because the opaque path writes premultiplied colour with blending off: a faded mesh comes out darkened toward black rather than see-through, which is a defect rather than a contract — the fully transparent end of the same range used to paint an opaque black silhouette until it was fixed.

    Set it true when the transparency lives in the TEXTURE rather than in the opacity — a soft-edged glow, smoke, a glTF material with alphaMode: "BLEND". The automatic check reads the draw's alpha and cannot see into the texture. The glTF loader does not set this for you: one loaded mesh can merge several materials, and this flag routes the whole mesh, so a "BLEND" material sharing geometry with an opaque one would drag the opaque half into the transparent pass. Note that alphaCutoff discards texels before blending sees them, so a soft edge needs a low cutoff (see Sprite3d, which lowers its default for exactly this). The cutoff thresholds the MATERIAL's alpha, not the drawn alpha, so a fading cutout mesh keeps its shape rather than disappearing at its own threshold.

    The pass composites premultiplied, which is what the mesh vertex stage always emits. A texture uploaded with straight alpha and drawn with transparent: true therefore reads slightly bright at its soft texels; upload it premultiplied (the default) and it is exact.

    Renderable#blendMode is honoured per entry, with one limit: the advanced modes ("overlay", "difference", and the rest that need a compositing pass) fall back to "normal" here on both backends, since the pass rasterizes directly into the target.

    Set it false to keep a mesh in the opaque pass however it is faded — it will darken rather than fade, and it will keep writing depth.

    Sorting is per object, by distance from the camera, so two intersecting or mutually enclosing transparent meshes may pop as the camera moves; split them, or accept it. Needs a GPU backend and a Camera3d — the 2D-camera path is unaffected.

    undefined
    

    Renderable#blendMode

    // a ghost that fades in — nothing else needed
    ghost.setOpacity(0.4);

    // a glow that blends at full opacity, and additively
    const glow = new Mesh(0, 0, {
    ...quad,
    texture: glowTexture,
    transparent: true,
    blendMode: "additive",
    alphaCutoff: 0,
    });
    type: string = "Rectangle"

    The shape type (used internally).

    updateWhenPaused: boolean

    Whether to update this object when the game is paused.

    false
    
    uvs: Float32Array<ArrayBufferLike>

    texture coordinates as u,v pairs

    vertexColors: Uint32Array<ArrayBufferLike> | undefined

    Per-vertex color buffer (one packed Uint32 per vertex) populated for multi-material meshes. The mesh batcher reads from this when present, pushing the per-vertex color as the aColor attribute — so multi-material rendering needs no extra draw calls per material vs single-material rendering (the batcher still chunks very large meshes across multiple draws to fit its vertex/index buffer limits, same as the single-material path). Multiplied at render time by the global mesh.tint, so runtime tint mutation still works as expected (flash, fade, team color, etc.).

    Vertices were split per-material at parse time (each material has its own dedup scope in the OBJ parser), so every vertex belongs to exactly one material group and carries that group's color unambiguously.

    This is also what settings.vertexColors and Mesh#setVertexColor populate, so procedural geometry can carry a gradient a per-object tint cannot express. undefined when every vertex is plain white.

    Mesh#setVertexColor

    vertexCount: number

    number of vertices

    vertices: Float32Array<ArrayBufferLike>

    the projected vertex positions.

    Not refreshed on the retained Camera3d path. There, geometry is uploaded once in model space and placed by the GPU, so nothing projects vertices per frame and this array holds whatever it last did. It is still maintained by the Canvas renderer and by the 2D camera path. Engine consumers that need current world positions — Mesh#getBounds3d, Mesh#toPolygon — derive them on demand instead of reading this; user code should do the same.

    To edit geometry, write to Mesh#originalVertices and set Mesh#needsUpdate.

    visibleInAllCameras: boolean

    If true, this floating renderable will be rendered by all cameras (e.g. background image layers). If false (default), floating elements are only rendered by the default camera (e.g. UI/HUD elements). Only applies to floating renderables in multi-camera setups.

    false
    
    • get isFloating(): boolean

      Whether the renderable object is floating (i.e. used screen coordinates), or contained in a floating parent container

      Returns boolean

      Renderable#floating

    • set needsUpdate(value: any): void

      Signal that this mesh's geometry itself has changed — its vertices, UVs, indices, normals or per-vertex colours were edited in place.

      Placement is not geometry: moving, rotating, scaling or re-tinting a mesh needs no signal, because those are applied when drawing rather than stored in the geometry. Only reach for this after writing into Mesh#originalVertices and friends directly.

      Parameters

      • value: any

      Returns void

      // deform the mesh, then tell it the shape moved
      mesh.originalVertices[1] += 10;
      mesh.needsUpdate = true;
    • get shader(): any

      A custom shader hosted on this mesh's draw, replacing the built-in mesh shading: a GLShader carrying a {vertex, fragment} GLSL program (hosted by the WebGL renderer) and/or a complete wgsl module (hosted by the WebGPU renderer — see the GLShader class docs for the module contract). One object serves both backends; a shader without a realization for the active backend (or null) degrades to the built-in shading. The tint, texture, placement and (for lit meshes) light data keep flowing through their usual uniforms — the custom shader decides what to do with them.

      Returns any

      me.loader.preload([{ name: "toon", type: "shader", src: {
      vertex: "shaders/toon.vert", // GLSL pair for WebGL
      fragment: "shaders/toon.frag",
      wgsl: "shaders/toon.wgsl", // complete module for WebGPU
      }}], () => {
      myMesh.addPostEffect(me.loader.getShader("toon"));
      });
    • set shader(value: any): void

      Parameters

      • value: any

      Returns void

      since 19.2.0 — use addPostEffect / getPostEffect / removePostEffect instead

    • get tint(): Color

      define a tint for this renderable. a (255, 255, 255) r, g, b value will remove the tint effect.

      Returns Color

      (255, 255, 255)
      
      // add a red tint to this renderable
      this.tint.setColor(255, 128, 128);
      // remove the tint
      this.tint.setColor(255, 255, 255);
    • set tint(value: Color): void

      Parameters

      • value: Color

      Returns void

    • Add an animation, identical to Sprite#addAnimation.

      Parameters

      • name: string

        animation id

      • index: string[] | number[] | object[]

        frame indices / names (see Sprite#addAnimation)

      • Optionalanimationspeed: number

        cycling speed in ms

      Returns number

      number of frames added

    • Returns true if the polygon contains the given point.
      (Note: it is highly recommended to first do a hit test on the corresponding
      bounding rect, as the function can be highly consuming with complex shapes)

      Parameters

      • x: number

        x coordinate or a vector point to check

      • y: number

        y coordinate

      Returns boolean

      True if the polygon contain the point, otherwise false

      if (polygon.contains(10, 10)) {
      // do something
      }
      // or
      if (polygon.contains(myVector2d)) {
      // do something
      }
    • Returns true if the polygon contains the given point.
      (Note: it is highly recommended to first do a hit test on the corresponding
      bounding rect, as the function can be highly consuming with complex shapes)

      Parameters

      Returns boolean

      True if the polygon contain the point, otherwise false

      if (polygon.contains(10, 10)) {
      // do something
      }
      // or
      if (polygon.contains(myVector2d)) {
      // do something
      }
    • Returns true if the rectangle contains the given rectangle

      Parameters

      • rectangle: Rect

        rectangle to test

      Returns boolean

      True if the rectangle contain the given rectangle, otherwise false

      if (rect.containsRectangle(myRect)) {
      // do something
      }
    • Mirror the sprite horizontally (e.g. flip a character to face the other way). Unlike the 2D Sprite, the flip mirrors the quad's local geometry so it works for every billboard mode and for rotated/trimmed atlas regions alike. Takes effect immediately on the current frame.

      Parameters

      • Optionalflip: boolean = true

      Returns Sprite3d

      Reference to this object for method chaining

    • Where this renderable IS in the game world — its own pos plus every ancestor's, as a Vector3d so the z component is summed across the chain too (important for Camera3d's frustum culling, which previously read obj.depth — local pos.z — and mis-culled children nested under a container with its own non-zero depth).

      Reach for this for anything positional: culling, distance checks, hit tests, placing one renderable relative to another. It is cheap, and it is what the engine's own culling uses.

      Reach for Renderable#getWorldTransform instead when a position is not enough — when rotation, scale or flip along the ancestor chain matters, or when you need to map an arbitrary point rather than just the origin. This method sums translations only, so under a rotated or scaled ancestor it reports where the renderable's pivot is and nothing about how its content is oriented.

      Note the two also frame the question differently. This one is "where am I"; getWorldTransform() is "what space is my content drawn in". For a Container those coincide, because a container offsets its children by its own position. For a leaf they differ by exactly that position, which a leaf applies inside its own draw().

      The returned vector is pooled and reused — copy it if you need to hold onto the value across another call.

      Returns Vector3d

      this renderable's absolute position

      Renderable#getWorldTransform

    • The mesh's world-space 3D axis-aligned bounding box. This is the 3D analog of Renderable#getBounds (which returns a flat 2D box from width/height and so cannot describe a mesh's real extent).

      Computed on demand by bounding the model-space geometry through the mesh's current placement, so it reflects the live transform and is valid before the mesh has ever been drawn. Meaningful for the Camera3d path; for the 2D path use Renderable#getBounds.

      The same AABB3d instance is returned each call (recomputed in place), so copy it (.clone()) if you need to keep it.

      Returns AABB3d

      the world-space bounding box (reused instance)

    • Protected

      The transform this renderable interposes between its ancestor's frame and the frame its own content is drawn in — a mirror of what Renderable#preDraw applies to the renderer, as a matrix.

      This is not Renderable#currentTransform. A renderable's placement is split across two members: pos holds where it is, and currentTransform holds only what rotate() / scale() / translate() accumulate — it never contains the position. preDraw composes the two by conjugation, so a rotation pivots about the renderable's position rather than the origin. On a renderable you never rotated, currentTransform is therefore the identity and says nothing about where its content lands, while this method returns the translation that actually places it.

      Container extends this with the offset it applies to its children, which a leaf renderable does not have: a leaf's own draw() places itself from pos.

      Parameters

      • out: Matrix3d

        matrix to write into; nothing is stored on the renderable itself, so callers own the lifetime

      Returns Matrix3d

      out, for chaining

      Renderable#getWorldTransform

    • Get post-processing shader effects. When called with a class, returns the first effect matching the given class. When called without arguments, returns the full effects array.

      Parameters

      • OptionaleffectClass: Function

        the effect class to search for

      Returns any

      the matching effect, the effects array, or undefined

      const desat = sprite.getPostEffect(DesaturateEffect);
      const allEffects = sprite.getPostEffect();
    • The space this renderable's content is drawn IN, as a matrix — the full form of Renderable#getAbsolutePosition, which sums positions up the ancestor chain and therefore cannot represent the rotation, scale or flip accumulated along the way.

      Reach for getAbsolutePosition() instead for ordinary positional work — culling, distance checks, hit tests. It is cheaper and it is what the engine culls with. Use this when a position is not enough:

      • an ancestor is rotated or scaled, so a translation cannot describe the result
      • you need to map an arbitrary point, not just the origin — a corner, a click position, one renderable's coordinates into another's space
      • you need to compose or invert the transform (inv(A) · B converts between two frames, which is how ParticleEmitter.referenceSpace measures particles against a container that is not their parent)

      The two also frame the question differently, and it shows on a leaf. getAbsolutePosition() is "where am I"; this is "what space is my content drawn in". For a Container those coincide, because a container offsets its children by its own position. For a leaf they differ by exactly that position, which a leaf applies inside its own draw(). So with no rotation, scale or flip anywhere, a container's translation column equals its getAbsolutePosition() while a leaf's equals its PARENT's.

      The walk stops at a floating ancestor, because a floating renderable draws in screen space: Container#draw resets the transform outright for those, so the chain genuinely ends there rather than continuing to the root.

      The camera needs no special handling — Camera2d folds its view transform into the root container's currentTransform, so it is picked up like any other level.

      Parameters

      • out: Matrix3d

        matrix to write into; nothing is stored on the renderable itself, so callers own the lifetime

      Returns Matrix3d

      out, for chaining

      Renderable#getAbsolutePosition

      // map a point from one renderable's space into another's
      const from = a.getWorldTransform(new Matrix3d());
      const into = b.getWorldTransform(new Matrix3d()).invert();
      const point = new Vector2d(10, 20); // in a's space
      from.apply(point); // -> world
      into.apply(point); // -> b's space
      // just need to know where something is? use the cheaper call
      const where = renderable.getAbsolutePosition();
    • Returns true if the vertices composing this polygon form a convex shape (vertices must be in clockwise order).

      Returns boolean | null

      true if the vertices are convex, false if not, null if not computable

    • Legacy collision callback — fires every frame this renderable body is overlapping another body. Kept for backward compatibility with code written against pre-19.5 melonJS; semantics are unchanged from the 19.4 contract.

      NOTE — onCollision is NOT equivalent to Renderable.onCollisionActive. The two handlers exist side by side and have intentionally different contracts:

      onCollision (legacy) onCollisionActive (modern)
      Cadence for dynamic-dynamic pairs 2× per frame per side 1× per frame per side
      response.a semantics Fixed per pair (first body in detector call) Always the receiver (response.a === this)
      response.b semantics Fixed per pair Always the partner (response.b === other)
      response.normal / response.depth ✓ — normal.y < -0.7 = "push me up"
      return false to skip push-out ✓ (honored by SAT) ✗ — use bodyDef.isSensor or setSensor instead

      If you're writing new code, prefer onCollisionActive. Keep onCollision only when its every-frame, return-false, fixed-a/b semantics are what you want.

      Parameters

      • response: ResponseObject

        the SAT response object; the legacy handler receives this, not the adapter's CollisionResponse, which is why normal and depth are absent from the table above

      • other: Renderable

        the other renderable touching this one (a reference to response.a or response.b)

      Returns boolean

      true if the object should respond to the collision (its position and velocity will be corrected); the return value is only honored by the builtin SAT adapter.

      // legacy collision handler — note the receiver-side check on response.a
      onCollision(response) {
      if (response.b.body.collisionType === me.collision.types.ENEMY_OBJECT) {
      this.pos.sub(response.overlapV);
      this.hurt();
      return false; // skip the SAT push-out
      }
      return true;
      }
    • OnDestroy Notification function
      Called by engine before deleting the object. Receives whatever destroy(...args) was called with — the production path (Container.removeChildNow) passes nothing. Stage has its own onDestroyEvent, which does forward the active Application.

      Parameters

      • ..._args: any[]

        forwarded by destroy(...args); normally empty

      Returns void

    • Play (and optionally switch to) an animation, identical to Sprite#play.

      Parameters

      • Optionalname: string

        animation id to play; omit to resume

      • Optionaloptions: string | object | Function

        loop / chain / completion behavior

      Returns Sprite3d

      Reference to this object for method chaining

    • Rotate this renderable by the specified angle (in radians). When called with just an angle, rotates around the Z axis (2D rotation). When called with an angle and a Vector3d axis, rotates around that axis in 3D.

      Parameters

      • angle: number

        The angle to rotate (in radians)

      • Optionalv: any

        the axis to rotate around (defaults to Z axis for 2D)

      Returns Renderable

      Reference to this object for method chaining

    • scale the renderable around his anchor point. Scaling actually applies changes to the currentTransform member which is used by the renderer to scale the object when rendering. It does not scale the object itself. For example if the renderable is an image, the image.width and image.height properties are unaltered but the currentTransform member will be changed.

      Parameters

      • x: number

        a number representing the abscissa of the scaling vector.

      • Optionaly: number = x

        a number representing the ordinate of the scaling vector.

      • Optionalz: number = 1

        a number representing the depth of the scaling vector.

      Returns Renderable

      Reference to this object for method chaining

    • Select the active animation, identical to Sprite#setCurrentAnimation.

      Parameters

      • name: string

        animation id

      • OptionalresetAnim: string | object | Function

        loop / chain / completion behavior

      • Optionalpreserve_dt: boolean = false

      Returns Sprite3d

      Reference to this object for method chaining

    • set new value to the Polygon

      Parameters

      • x: number

        position of the Polygon

      • y: number

        position of the Polygon

      • points: PolygonVertices | LineVertices

        array of vector or vertices defining the Polygon

      Returns Sprite3d

      this instance for object chaining

    • Set one vertex's colour, multiplied into Mesh#tint.

      The mesh starts carrying per-vertex colour on the first call — every other vertex is white until coloured, so a mesh built without settings.vertexColors looks unchanged until you touch it.

      Out-of-range indices are ignored rather than throwing, matching InstancedMesh#setInstanceColor.

      Bumps Mesh#needsUpdate for you: the retained Camera3d path uploads geometry once and compares the version, so a colour written without it would apply on the immediate path and silently not on the retained one.

      Parameters

      • index: number

        the vertex to colour

      • color: Color

        the vertex colour

      Returns void

      // fade a procedural terrain toward the sky with distance
      for (let i = 0; i < mesh.vertexCount; i++) {
      const t = Math.min(1, mesh.originalVertices[i * 3 + 2] / 6000);
      mesh.setVertexColor(i, haze.copy(ground).lerp(sky, t));
      }
    • Shifts the Polygon to the given position vector.

      Parameters

      • x: number

        The x coordinate or a vector point to shift to.

      • Optionaly: number

        The y coordinate. This parameter is required if the first parameter is a number.

      Returns void

      polygon.shift(10, 10);
      // or
      polygon.shift(myVector2d);
    • Shifts the Polygon to the given position vector.

      Parameters

      Returns void

      polygon.shift(10, 10);
      // or
      polygon.shift(myVector2d);
    • Render the mesh at its current state (transforms, projection, tint) to an offscreen canvas. The returned canvas can be used with renderer.drawImage(), as a Sprite image source, or converted to an ImageBitmap via createImageBitmap().

      Returns HTMLCanvasElement

      an offscreen canvas containing the rendered mesh

      // snapshot the mesh and create a Sprite from it
      const canvas = mesh.toCanvas();
      const sprite = new me.Sprite(100, 100, { image: canvas });

      // or draw directly
      renderer.drawImage(mesh.toCanvas(), 100, 100);
    • Render the mesh at its current state to an ImageBitmap. Useful for creating textures or sprites from the rendered mesh.

      Returns Promise<ImageBitmap>

      a promise that resolves to an ImageBitmap of the rendered mesh

      const bitmap = await mesh.toImageBitmap();
      const sprite = new me.Sprite(100, 100, { image: bitmap });
    • update the bounding box for this shape.

      Parameters

      • Optionalabsolute: boolean = true

        update the bounds size and position in (world) absolute coordinates

      Returns Bounds

      this shape bounding box Rectangle object