/** * additional import for TypeScript * @import {Color} from "./../math/color.ts"; * @import {Ellipse} from "./../geometries/ellipse.ts"; * @import Renderer from "./../video/renderer.js"; */ /** * A 2D point light. * * Light2d carries the *properties* of a light (color, radii, intensity, * height, flags, position) and asks the active renderer to render it * via `renderer.drawLight(this)`. The renderer picks the right machinery: * * - **WebGL**: a single quad through a shared procedural radial-falloff * fragment shader (`RadialGradientEffect`). One shader is reused across * every Light2d on the renderer; no per-light texture is allocated. * - **Canvas**: a small `Gradient` config object (cached per-light in a * `WeakMap` and rebuilt only when radii / color / intensity change), * rasterized via `Gradient.toCanvas()` on every draw into a single * shared `CanvasRenderTarget`, then composited with `drawImage`. The * per-light cache holds only the gradient stops, not the bitmap — the * render target is one-per-engine. * * Light2d itself is renderer-agnostic — no shader knowledge, no canvas * allocation, no renderer reference held. * @see stage.lights */ export default class Light2d extends Renderable { /** * Create a 2D point light. * * A `Light2d` is a first-class world Renderable: add it to a container * with `app.world.addChild(light)` (or any sub-container, including a * `Sprite`, so the light follows the parent via its transform). On * activation, the light auto-registers with the active `Stage`'s * lighting set so the ambient overlay (`Stage.ambientLight`) cuts a * hole at the light's visible area, and a radial gradient from the * given `color` (full intensity at center → fully transparent at the * radius) is composited additively on top — producing a soft spot * light. Rendering happens inside each `Camera2d`'s post-effect FBO * bracket so any camera shader (vignette, color-matrix, scanlines, * etc.) wraps the lighting output. * * Set `radiusY` to a different value than `radiusX` for a stretched * (elliptical) light. The `intensity` parameter scales the gradient's * inner alpha; the `Stage.ambientLight` color and alpha control how * dark the unlit areas are. Use `light.blendMode` to override the * default additive blend if needed. * @param {number} x - The horizontal position of the light's center (matches `Ellipse(x, y, w, h)` conventions). * @param {number} y - The vertical position of the light's center. * @param {number} radiusX - The horizontal radius of the light. * @param {number} [radiusY=radiusX] - The vertical radius of the light. * @param {Color|string} [color="#FFF"] - The color of the light at full intensity. * @param {number} [intensity=0.7] - The peak alpha of the radial gradient at the light's center (0–1). */ constructor(x: number, y: number, radiusX: number, radiusY?: number, color?: Color | string, intensity?: number); /** * the color of the light * @type {Color} * @default "#FFF" */ color: Color; /** * The horizontal radius of the light * @type {number} */ radiusX: number; /** * The vertical radius of the light * @type {number} */ radiusY: number; /** * The intensity of the light * @type {number} * @default 0.7 */ intensity: number; /** @ignore */ visibleArea: Ellipse; /** * When `true`, this light acts as a pure illumination source — * the gradient texture isn't drawn. The light still feeds the * `Stage` ambient-cutout pass and the WebGL lit-sprite * pipeline's per-frame uniforms, so normal-mapped sprites still * get shaded by it. Use this for SpriteIlluminator-style demos * where the light should be invisible (only its effect on * normal-mapped surfaces is what you want to see). * * Default `false`, preserving the legacy "soft glowing spot" * behavior. * @type {boolean} * @default false */ illuminationOnly: boolean; /** * Light height above the sprite plane (Z axis), in the same * units as `radiusX`/`radiusY`. Used by the WebGL lit-sprite * pipeline as the Z component of the light direction in the * `dot(normal, lightDir)` calculation: a low height makes the * lighting graze across the surface (long visible shadows on * normal-map detail), a high height makes it head-on (more * uniform brightness on the lit hemisphere). * * Default is `max(radiusX, radiusY) * 0.075` — a balanced look * at the asset's native scale that prevents lights at the * sprite's center from producing degenerate flat shading. * * Named `lightHeight` (not just `height`) to avoid colliding * with the bbox-height getter Light2d inherits from `Rect`. * @type {number} */ lightHeight: number; /** * Set new radii for this light. * * Updates `radiusX`/`radiusY` and the underlying bbox (via * `Renderable.resize(width, height)`) so `getBounds()` and * `getVisibleArea()` — which feed the ambient-cutout pass — track the * new size. The Canvas renderer's gradient cache auto-invalidates on * next draw via its property comparison; the WebGL procedural shader * adapts to the new dimensions automatically. * * Named `setRadii` (not `resize`) so it does not shadow * `Renderable.resize(width, height)` — code that operates on a * generic `Renderable` and calls `.resize(w, h)` keeps working when * the instance happens to be a `Light2d`. * @param {number} radiusX - new horizontal radius * @param {number} [radiusY=radiusX] - new vertical radius */ setRadii(radiusX: number, radiusY?: number): void; /** * returns a geometry representing the visible area of this light, in * world-space coordinates (so it aligns with the rendered gradient * regardless of camera scroll or container parenting). * @returns {Ellipse} the light visible mask */ getVisibleArea(): Ellipse; /** * update function * @returns {boolean} true if dirty */ update(): boolean; /** * preDraw this Light2d (automatically called by melonJS) * @param {Renderer} renderer - a renderer instance */ preDraw(renderer: Renderer): void; /** * draw this Light2d (automatically called by melonJS). * * Delegates to `renderer.drawLight(this)` — each renderer picks its * own implementation (procedural shader on WebGL; cached `Gradient` * rasterized into a shared `CanvasRenderTarget` on Canvas). Light2d * itself doesn't know which path is used. * @param {Renderer} renderer - a renderer instance */ draw(renderer: Renderer): void; /** * Auto-register this light with the active Stage's lighting set when * added to a container. The Stage uses that set to build the ambient * overlay cutouts; rendering the light itself is handled normally as * part of the world tree walk. * @ignore */ onActivateEvent(): void; /** * Auto-deregister this light from the active Stage's lighting set when * removed from a container. * @ignore */ onDeactivateEvent(): void; /** * Destroy function
* @ignore */ destroy(): void; } import Renderable from "./renderable.js"; import type { Color } from "./../math/color.ts"; import type { Ellipse } from "./../geometries/ellipse.ts"; import type Renderer from "./../video/renderer.js"; //# sourceMappingURL=light2d.d.ts.map