export default NoiseTexture2d; /** * What a {@link NoiseTexture2d} bakes WITH — its own settings, as opposed to * the field's. */ export type NoiseTexture2dBakeSettings = { /** * - baked texture width in pixels */ width?: number; /** * - baked texture height in pixels */ height?: number; /** * - an existing {@link Noise} to bake; when omitted * one is built from the forwarded field settings */ noise?: Noise; /** * - tile cleanly in both axes */ seamless?: boolean; /** * - edge blend band width as a * fraction (0..1) of the smaller dimension, when `seamless` */ seamlessBlendSkirt?: number; /** * - invert the noise value (`1 - v`) */ invert?: boolean; /** * - encode as a normal map */ asNormalMap?: boolean; /** * - normal steepness when `asNormalMap` */ bumpStrength?: number; /** * - map the noise * value to a color */ colorRamp?: import("../gradient.js").Gradient; /** * - sample in 3D (`getNoise3d`) using an * internal `time` as the third axis, advanced by {@link NoiseTexture2d#update} */ animated?: boolean; /** * - animation speed in noise z-units per second * (only used while `animated`) */ speed?: number; }; /** * Everything the constructor takes. * * The settings object is handed to {@link Noise} WHOLE when no `noise` instance * is given, so every field setting — `type`, `seed`, `frequency`/`scale`, * `octaves`, `gain`/`persistence`, `lacunarity`, `fractalType`, the domain-warp * settings — belongs here too. Spelling them out a second time is what would * drift; the intersection cannot. */ export type NoiseTexture2dSettings = NoiseTexture2dBakeSettings & import("../../math/noise.ts").NoiseSettings; /** * What a {@link NoiseTexture2d} bakes WITH — its own settings, as opposed to * the field's. * @typedef {object} NoiseTexture2dBakeSettings * @property {number} [width=256] - baked texture width in pixels * @property {number} [height=256] - baked texture height in pixels * @property {Noise} [noise] - an existing {@link Noise} to bake; when omitted * one is built from the forwarded field settings * @property {boolean} [seamless=false] - tile cleanly in both axes * @property {number} [seamlessBlendSkirt=0.1] - edge blend band width as a * fraction (0..1) of the smaller dimension, when `seamless` * @property {boolean} [invert=false] - invert the noise value (`1 - v`) * @property {boolean} [asNormalMap=false] - encode as a normal map * @property {number} [bumpStrength=1] - normal steepness when `asNormalMap` * @property {import("../gradient.js").Gradient} [colorRamp] - map the noise * value to a color * @property {boolean} [animated=false] - sample in 3D (`getNoise3d`) using an * internal `time` as the third axis, advanced by {@link NoiseTexture2d#update} * @property {number} [speed=1] - animation speed in noise z-units per second * (only used while `animated`) */ /** * Everything the constructor takes. * * The settings object is handed to {@link Noise} WHOLE when no `noise` instance * is given, so every field setting — `type`, `seed`, `frequency`/`scale`, * `octaves`, `gain`/`persistence`, `lacunarity`, `fractalType`, the domain-warp * settings — belongs here too. Spelling them out a second time is what would * drift; the intersection cannot. * @typedef {NoiseTexture2dBakeSettings & import("../../math/noise.ts").NoiseSettings} NoiseTexture2dSettings */ /** * A {@link Texture2d} that bakes a {@link Noise} field into a drawable canvas — * usable directly as a sprite image, a normal map, an image layer, or a custom * shader sampler. * * The bake runs on the CPU (renderer-agnostic, works under both the Canvas and * WebGL backends) and produces an `HTMLCanvasElement` returned by * {@link NoiseTexture2d#getTexture}. Three output modes: * - **grayscale** (default) — the noise value mapped to `[0, 255]`. * - **colorRamp** — the noise value mapped through a {@link Gradient}. * - **asNormalMap** — the noise treated as a height field and encoded as * tangent-space surface normals (RGB), for per-pixel lighting via * {@link Sprite#normalMap} + {@link Light2d}. * * With `seamless: true` the texture's edges are cross-faded so it tiles with a * much-reduced seam (an approximate, not pixel-exact, wrap); `seamlessBlendSkirt` * controls how wide that edge blend band is. With `animated: true` the field is * sampled in 3D (`getNoise3d`) using an internal `time` as the third axis — * call {@link NoiseTexture2d#update} from your update loop to evolve it. Each * re-bake bumps a `version` the renderer reads, so the GPU texture re-uploads * automatically (and only when it actually changed — explicit, version-based * invalidation). * * Note: live re-upload is currently wired through the lit **normal-map** * pipeline ({@link Sprite#normalMap} + {@link Light2d}). An `animated` texture * used as a plain color `image` bakes a static snapshot — the color texture * cache does not yet honor `version` — so animate normals, not albedos, for now. * @augments Texture2d * @category Game Objects * @example * // a seamless water normal map fed to a lit sprite * const ripples = new me.NoiseTexture2d({ * width: 256, height: 256, * type: "simplex", octaves: 4, frequency: 0.03, * seamless: true, asNormalMap: true, bumpStrength: 2, animated: true, speed: 0.6, * }); * const water = new me.Sprite(x, y, { image: albedo, normalMap: ripples }); * // drive it yourself from your Stage's update(dt): * ripples.update(dt); */ declare class NoiseTexture2d extends Texture2d { /** * @param {NoiseTexture2dSettings} [settings] - bake settings, plus any * {@link NoiseSettings} for the field itself */ constructor(settings?: NoiseTexture2dSettings); /** baked texture width in pixels @type {number} */ width: number; /** baked texture height in pixels @type {number} */ height: number; /** the noise field baked by this texture @type {Noise} */ noise: Noise; /** tile cleanly in both axes @type {boolean} */ seamless: boolean; /** edge blend band width (0..1 of the smaller dimension) @type {number} */ seamlessBlendSkirt: number; /** invert the noise value @type {boolean} */ invert: boolean; /** encode the field as a tangent-space normal map @type {boolean} */ asNormalMap: boolean; /** normal steepness when `asNormalMap` @type {number} */ bumpStrength: number; /** optional color ramp applied to the noise value @type {Gradient|null} */ colorRamp: Gradient | null; /** sample the field in 3D using `time` as the third axis @type {boolean} */ animated: boolean; /** animation speed in noise z-units per second @type {number} */ speed: number; /** the current animation time (third sampling axis) @type {number} */ time: number; /** * The current content revision, bumped on every {@link NoiseTexture2d#bake}. * Also stamped on the baked canvas (`getTexture().version`) so the renderer * re-uploads the GPU texture only when it actually changed. * @returns {number} */ get version(): number; /** * (Re)bake the texture from the current settings into the (reused) output * canvas. Called once on construction; {@link NoiseTexture2d#update} calls it * again per frame for animated textures. * @returns {NoiseTexture2d} this texture for chaining */ bake(): NoiseTexture2d; /** * Advance an animated texture by `dt` milliseconds and re-bake it. The * re-bake bumps the texture's `version`, so the renderer re-uploads the GPU * texture automatically on the next draw — no renderer/app handle needed. * * This is NOT auto-called by the engine; drive it from your own update loop * (e.g. {@link Stage#update}) for animated textures. No-op when not `animated`. * @param {number} dt - elapsed time since the last update, in milliseconds * @returns {NoiseTexture2d} this texture for chaining */ update(dt: number): NoiseTexture2d; /** * @returns {HTMLCanvasElement} the baked texture canvas */ getTexture(): HTMLCanvasElement; } import { Noise } from "../../math/noise.ts"; import Texture2d from "./texture2d.ts"; //# sourceMappingURL=noise_texture2d.d.ts.map