@babylonjs/lite-gl 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/effect.d.ts CHANGED
@@ -135,8 +135,8 @@ export declare function setEffectFloatArray(engine: GLEngineContext, effect: GLE
135
135
  export declare function setEffectFloatArray4(engine: GLEngineContext, effect: GLEffect, name: string, array: Float32Array | number[]): void;
136
136
  /** `gl.uniform1iv` — a flat int array (`Effect.setIntArray`). Not value-cached. */
137
137
  export declare function setEffectIntArray(engine: GLEngineContext, effect: GLEffect, name: string, array: Int32Array | number[]): void;
138
- /** Bind a texture to the sampler's pre-assigned unit (§4.4). NO `gl.uniform1i`
139
- * is issued — that was done exactly once per program lifetime during
138
+ /** Bind a texture to the sampler's pre-assigned unit, or pass `null` to unbind
139
+ * that unit (§4.4). NO `gl.uniform1i` is issued — that was done exactly once per program lifetime during
140
140
  * finalization. This is the key win over Babylon's `Effect.setTexture` which
141
141
  * re-issues the sampler binding on every call. */
142
- export declare function setEffectTexture(engine: GLEngineContext, effect: GLEffect, samplerName: string, tex: GLTexture): void;
142
+ export declare function setEffectTexture(engine: GLEngineContext, effect: GLEffect, samplerName: string, tex: GLTexture | null): void;
package/effect.js CHANGED
@@ -403,8 +403,8 @@ export function setEffectIntArray(engine, effect, name, array) {
403
403
  }
404
404
  engine.gl.uniform1iv(loc, array);
405
405
  }
406
- /** Bind a texture to the sampler's pre-assigned unit (§4.4). NO `gl.uniform1i`
407
- * is issued — that was done exactly once per program lifetime during
406
+ /** Bind a texture to the sampler's pre-assigned unit, or pass `null` to unbind
407
+ * that unit (§4.4). NO `gl.uniform1i` is issued — that was done exactly once per program lifetime during
408
408
  * finalization. This is the key win over Babylon's `Effect.setTexture` which
409
409
  * re-issues the sampler binding on every call. */
410
410
  export function setEffectTexture(engine, effect, samplerName, tex) {
package/effect.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"effect.js","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"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","sourcesContent":["import type { GLEngineContext } from \"./context.js\";\nimport { compileShader, getLinkError, isLinkComplete, linkProgram } from \"./shader.js\";\nimport { bindTexture, type GLTexture } from \"./texture.js\";\n\n/** Inputs to `createEffect`: shader sources plus the uniform, sampler and\n * attribute names whose locations are resolved during readiness finalization. */\nexport interface GLEffectOptions {\n /** Human-readable label, surfaced in compile/link error messages. */\n name: string;\n /** GLSL ES 3.00 source, ready for `gl.shaderSource`. */\n vertexSource: string;\n /** GLSL ES 3.00 source, ready for `gl.shaderSource`. */\n fragmentSource: string;\n /** Declared uniform names. Locations are resolved during readiness\n * finalization. Names not declared here are legal but allocate cache\n * slots lazily on first setter use. */\n uniformNames: readonly string[];\n /** Declared sampler names, in unit-assignment order. Each gets a fixed\n * texture unit assigned during readiness finalization, and\n * `gl.uniform1i(loc, unit)` is called exactly once per program lifetime\n * (re-run after `webglcontextrestored`). */\n samplerNames: readonly string[];\n /** Default `[\"position\"]`. The first attribute is bound to location 0 via\n * `gl.bindAttribLocation(program, 0, name)` BEFORE link, so the shared\n * fullscreen-quad VAO always feeds the same location. */\n attributeNames?: readonly string[];\n /** Optional `#define` block. Each unique `defines` string must be paired\n * with the same vertex/fragment source via a separate `createEffect` call —\n * the package does NOT cache compiled variants. */\n defines?: string;\n}\n\n/** A compiled + linked shader program with cached uniform, sampler and\n * attribute locations. Created by `createEffect`; most fields are managed\n * internally — drive it via `isEffectReady` / `useEffect` / the `setEffect*`\n * setters rather than mutating it directly. */\nexport interface GLEffect {\n /** The `name` from the originating `GLEffectOptions`. */\n readonly name: string;\n /** The options this effect was created from (retained for context-restore). */\n readonly options: GLEffectOptions;\n /** The live `WebGLProgram`. Swapped for a fresh handle after context-restore. */\n program: WebGLProgram;\n /** @internal */\n _vs: WebGLShader;\n /** @internal */\n _fs: WebGLShader;\n /** Resolved during readiness finalization. Missing names map to `null` —\n * setters with a `null` location are silent no-ops (matches Babylon). */\n uniformLocations: { [name: string]: WebGLUniformLocation | null };\n /** Fixed unit assignment for declared samplers, index into\n * `_state.boundTextures`. */\n samplerUnits: { [name: string]: number };\n /**\n * True once `gl.uniform1i(samplerLoc, unit)` has been issued for every\n * declared sampler. Cleared on context-lost so finalization re-runs.\n * @internal\n */\n _samplersAssigned: boolean;\n /** Resolved attribute locations, keyed by attribute name. */\n attributeLocations: { [name: string]: number };\n /**\n * Last-UPLOADED scalar floats. A setter that skips the upload must NOT\n * update this — otherwise a later real set with the same value would\n * incorrectly elide and the GPU would keep stale data.\n * @internal\n */\n readonly _lastF1: { [name: string]: number };\n /**\n * Last-UPLOADED vector floats (vec2/vec3/vec4). Plain `number[]` (NOT\n * `Float32Array`) so values like `0.1` compare equal across frames.\n * @internal\n */\n readonly _lastVec: { [name: string]: number[] };\n /** @internal */\n readonly _lastI1: { [name: string]: number };\n /** True once the program has linked and finalization has run; the\n * `setEffect*` setters are no-ops until then. Poll `isEffectReady` to advance it. */\n isReady: boolean;\n /** @internal */\n _compileError: string | null;\n /** @internal */\n _disposed: boolean;\n /**\n * Number of live `createEffect` callers sharing this effect (and its one\n * `WebGLProgram`). `createEffect` returns the cached effect and bumps this\n * when an identical descriptor is requested; `disposeEffect` decrements it\n * and only tears the program down when it reaches 0.\n * @internal\n */\n _refCount: number;\n /**\n * The `_effectCache` key this effect was stored under (the source\n * descriptor). Used by `disposeEffect` to evict the cache entry at refcount\n * 0.\n * @internal\n */\n _cacheKey: string;\n /**\n * Callbacks fired exactly once on the first transition to ready.\n * @internal\n */\n readonly _onCompiled: ((effect: GLEffect) => void)[];\n /**\n * Replay closure for context-restore. Re-compiles + relinks into a fresh\n * `program` field. Finalization happens lazily on the next `isEffectReady`\n * poll.\n * @internal\n */\n _restore: (engine: GLEngineContext) => void;\n}\n\n/** Compile + link a new effect. Does NOT block on link completion — `isReady`\n * starts false; consumers poll `isEffectReady` (typically from their render\n * callback) to drive finalization. */\nexport function createEffect(engine: GLEngineContext, options: GLEffectOptions): GLEffect {\n const attribs = options.attributeNames ?? [\"position\"];\n const gl = engine.gl;\n\n // Per-engine cache keyed by the source descriptor. Identical descriptors\n // share ONE GLEffect (and thus one WebGLProgram), so `useEffect`'s\n // current-program cache can elide redundant `gl.useProgram` across the\n // consumers. The key covers every input that affects the program or its\n // readiness finalization, joined by a NUL separator (cannot appear in GLSL).\n const cacheKey = [options.vertexSource, options.fragmentSource, options.defines ?? \"\", attribs.join(\",\"), options.uniformNames.join(\",\"), options.samplerNames.join(\",\")].join(\n \"\\u0000\"\n );\n const cached = engine._effectCache.get(cacheKey);\n if (cached !== undefined && !cached._disposed) {\n cached._refCount++;\n return cached;\n }\n\n const compileErr: (string | null)[] = [null];\n const finalVS = applyDefines(options.vertexSource, options.defines);\n const finalFS = applyDefines(options.fragmentSource, options.defines);\n\n const vs = compileShader(gl, finalVS, gl.VERTEX_SHADER, compileErr);\n if (vs === null) {\n throw new Error(`lite-gl: ${options.name} vertex compile failed: ${compileErr[0] ?? \"unknown\"}`);\n }\n const fs = compileShader(gl, finalFS, gl.FRAGMENT_SHADER, compileErr);\n if (fs === null) {\n gl.deleteShader(vs);\n throw new Error(`lite-gl: ${options.name} fragment compile failed: ${compileErr[0] ?? \"unknown\"}`);\n }\n const program = linkProgram(gl, vs, fs, attribs);\n if (program === null) {\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n throw new Error(`lite-gl: ${options.name} program allocation failed`);\n }\n\n const effect: GLEffect = {\n name: options.name,\n options,\n program,\n _vs: vs,\n _fs: fs,\n uniformLocations: {},\n samplerUnits: {},\n _samplersAssigned: false,\n attributeLocations: {},\n _lastF1: {},\n _lastVec: {},\n _lastI1: {},\n isReady: false,\n _compileError: null,\n _disposed: false,\n _refCount: 1,\n _cacheKey: cacheKey,\n _onCompiled: [],\n _restore: () => {},\n };\n\n effect._restore = (target: GLEngineContext): void => {\n const g = target.gl;\n const newVS = compileShader(g, applyDefines(options.vertexSource, options.defines), g.VERTEX_SHADER, [null]);\n const newFS = compileShader(g, applyDefines(options.fragmentSource, options.defines), g.FRAGMENT_SHADER, [null]);\n if (newVS === null || newFS === null) {\n effect._compileError = \"context-restore: shader compile failed\";\n return;\n }\n const newProg = linkProgram(g, newVS, newFS, attribs);\n if (newProg === null) {\n g.deleteShader(newVS);\n g.deleteShader(newFS);\n effect._compileError = \"context-restore: program allocation failed\";\n return;\n }\n effect.program = newProg;\n effect._vs = newVS;\n effect._fs = newFS;\n effect.isReady = false;\n effect._samplersAssigned = false;\n effect.uniformLocations = {};\n effect.attributeLocations = {};\n effect._compileError = null;\n };\n\n engine._effects.push(effect);\n engine._effectCache.set(cacheKey, effect);\n return effect;\n}\n\n/** Poll the link state and, on first success, run finalization (uniform-\n * location resolution + one-shot sampler-unit `uniform1i` assignment +\n * `_onCompiled` callbacks). Returns `true` once the effect is usable. */\nexport function isEffectReady(engine: GLEngineContext, effect: GLEffect): boolean {\n if (effect.isReady) {\n return true;\n }\n if (effect._disposed || engine._isLost || engine._disposed) {\n return false;\n }\n if (effect._compileError !== null) {\n return false;\n }\n if (!isLinkComplete(engine.gl, effect.program, engine.caps.parallelShaderCompile)) {\n return false;\n }\n const linkErr = getLinkError(engine.gl, effect.program);\n if (linkErr !== null) {\n effect._compileError = linkErr;\n console.error(`lite-gl: ${effect.name} link failed:`, linkErr);\n return false;\n }\n finalizeEffect(engine, effect);\n return true;\n}\n\n/** Resolves uniform/attribute locations, binds the program (cached), and\n * issues the one-time `gl.uniform1i(samplerLoc, unit)` per declared sampler. */\nfunction finalizeEffect(engine: GLEngineContext, effect: GLEffect): void {\n const gl = engine.gl;\n const program = effect.program;\n for (const name of effect.options.uniformNames) {\n effect.uniformLocations[name] = gl.getUniformLocation(program, name);\n }\n const attribs = effect.options.attributeNames ?? [\"position\"];\n for (const name of attribs) {\n effect.attributeLocations[name] = gl.getAttribLocation(program, name);\n }\n // Switch to this program via the cached helper so _state.currentProgram\n // stays consistent — no raw gl.useProgram outside useEffect.\n useEffect(engine, effect);\n let unit = 0;\n for (const name of effect.options.samplerNames) {\n const loc = gl.getUniformLocation(program, name);\n if (loc !== null) {\n gl.uniform1i(loc, unit);\n }\n effect.samplerUnits[name] = unit;\n unit++;\n }\n effect._samplersAssigned = true;\n effect.isReady = true;\n // Fire and clear the one-shot ready callbacks.\n const cbs = effect._onCompiled.slice();\n effect._onCompiled.length = 0;\n for (const cb of cbs) {\n try {\n cb(effect);\n } catch (err) {\n console.error(`lite-gl: ${effect.name} onCompiled callback threw`, err);\n }\n }\n}\n\n/** Fires `cb` synchronously if the effect is already ready; otherwise queues\n * it for the next finalization. */\nexport function executeWhenCompiled(engine: GLEngineContext, effect: GLEffect, cb: (e: GLEffect) => void): void {\n if (isEffectReady(engine, effect)) {\n cb(effect);\n return;\n }\n effect._onCompiled.push(cb);\n}\n\n/** Decrement the share count and, on the last release, delete the effect's\n * program + shaders, unregister it from the context + cache, and clear the\n * cached current-program if it pointed at this effect. A shared effect (still\n * referenced by another `createEffect` caller) is kept alive. Call exactly ONCE\n * per `createEffect` (each call decrements the ref count); safe (no-op) once the\n * effect is fully torn down. */\nexport function disposeEffect(engine: GLEngineContext, effect: GLEffect): void {\n if (effect._disposed) {\n return;\n }\n if (--effect._refCount > 0) {\n return;\n }\n effect._disposed = true;\n effect.isReady = false;\n const i = engine._effects.indexOf(effect);\n if (i !== -1) {\n engine._effects.splice(i, 1);\n }\n engine._effectCache.delete(effect._cacheKey);\n if (!engine._isLost && !engine._disposed) {\n engine.gl.deleteProgram(effect.program);\n engine.gl.deleteShader(effect._vs);\n engine.gl.deleteShader(effect._fs);\n }\n if (engine._state.currentProgram === effect.program) {\n engine._state.currentProgram = null;\n }\n effect._onCompiled.length = 0;\n}\n\n/** Cached `gl.useProgram`. No-op when the effect is not ready or already current. */\nexport function useEffect(engine: GLEngineContext, effect: GLEffect): void {\n if (engine._isLost || engine._disposed || effect._disposed) {\n return;\n }\n if (engine._state.currentProgram === effect.program) {\n return;\n }\n engine.gl.useProgram(effect.program);\n engine._state.currentProgram = effect.program;\n}\n\n/* ──────────────────────────── cached setters ────────────────────────────\n *\n * Each setter has the shape:\n * 1. bail when context lost / effect not ready (no cache write)\n * 2. lookup uniform location; bail on null (no cache write)\n * 3. compare against last-UPLOADED value; bail on equality\n * 4. write to cache, issue gl.uniform*\n *\n * Step 3's comparison is intentionally bit-equal (===) — NaN inputs re-upload\n * every frame because `NaN !== NaN`, which is the correct safety net for\n * caller bugs.\n */\n\n/** Cached `gl.uniform1f`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectFloat(engine: GLEngineContext, effect: GLEffect, name: string, x: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n if (effect._lastF1[name] === x) {\n return;\n }\n effect._lastF1[name] = x;\n engine.gl.uniform1f(loc, x);\n}\n\n/** Cached `gl.uniform2f`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectFloat2(engine: GLEngineContext, effect: GLEffect, name: string, x: number, y: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n let v = effect._lastVec[name];\n if (v !== undefined && v[0] === x && v[1] === y) {\n return;\n }\n if (v === undefined) {\n v = [x, y];\n effect._lastVec[name] = v;\n } else {\n v[0] = x;\n v[1] = y;\n }\n engine.gl.uniform2f(loc, x, y);\n}\n\n/** Cached `gl.uniform3f`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectFloat3(engine: GLEngineContext, effect: GLEffect, name: string, x: number, y: number, z: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n let v = effect._lastVec[name];\n if (v !== undefined && v[0] === x && v[1] === y && v[2] === z) {\n return;\n }\n if (v === undefined) {\n v = [x, y, z];\n effect._lastVec[name] = v;\n } else {\n v[0] = x;\n v[1] = y;\n v[2] = z;\n }\n engine.gl.uniform3f(loc, x, y, z);\n}\n\n/** Cached `gl.uniform4f`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectFloat4(engine: GLEngineContext, effect: GLEffect, name: string, x: number, y: number, z: number, w: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n let v = effect._lastVec[name];\n if (v !== undefined && v[0] === x && v[1] === y && v[2] === z && v[3] === w) {\n return;\n }\n if (v === undefined) {\n v = [x, y, z, w];\n effect._lastVec[name] = v;\n } else {\n v[0] = x;\n v[1] = y;\n v[2] = z;\n v[3] = w;\n }\n engine.gl.uniform4f(loc, x, y, z, w);\n}\n\n/** Cached `gl.uniform3f` from an r/g/b color object. Delegates to `setEffectFloat3`. */\nexport function setEffectColor3(engine: GLEngineContext, effect: GLEffect, name: string, c: { r: number; g: number; b: number }): void {\n setEffectFloat3(engine, effect, name, c.r, c.g, c.b);\n}\n\n/** Cached `gl.uniform4f` from an r/g/b/a color object. Delegates to `setEffectFloat4`. */\nexport function setEffectColor4(engine: GLEngineContext, effect: GLEffect, name: string, c: { r: number; g: number; b: number; a: number }): void {\n setEffectFloat4(engine, effect, name, c.r, c.g, c.b, c.a);\n}\n\n/** Cached `gl.uniform2f` from an `{x,y}` vector object — the lite-gl equivalent\n * of Babylon's `Effect.setVector2`. Delegates to `setEffectFloat2`. */\nexport function setEffectVector2(engine: GLEngineContext, effect: GLEffect, name: string, v: { x: number; y: number }): void {\n setEffectFloat2(engine, effect, name, v.x, v.y);\n}\n\n/** Cached `gl.uniform4f` from an r/g/b/a color WITHOUT premultiplication — the\n * lite-gl equivalent of Babylon's `Effect.setDirectColor4`. Delegates to\n * `setEffectFloat4` (lite-gl never premultiplies in the uniform setters, so\n * this matches `setEffectColor4`; the distinct name eases the ShapeBuilder\n * port). */\nexport function setEffectDirectColor4(engine: GLEngineContext, effect: GLEffect, name: string, c: { r: number; g: number; b: number; a: number }): void {\n setEffectFloat4(engine, effect, name, c.r, c.g, c.b, c.a);\n}\n\n/** Cached `gl.uniform1i`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectInt(engine: GLEngineContext, effect: GLEffect, name: string, x: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n if (effect._lastI1[name] === x) {\n return;\n }\n effect._lastI1[name] = x;\n engine.gl.uniform1i(loc, x);\n}\n\n/* ── Matrix / array setters (uploaded every call — not value-cached) ──────────\n *\n * Matrices and arrays usually change every frame; element-wise caching would\n * cost more than the upload it saves, so these always issue the GL call (the\n * location lookup + ready guards still apply). They cover the ShapeBuilder\n * surface (`setMatrix3x3`, `setFloatArray`, `setFloatArray4`) plus a general\n * 4×4 matrix setter for any future mesh consumer. */\n\n/** `gl.uniformMatrix4fv` from a column-major 4×4 matrix — the lite-gl\n * equivalent of Babylon's `Effect.setMatrix`. Not value-cached. */\nexport function setEffectMatrix(engine: GLEngineContext, effect: GLEffect, name: string, matrix: Float32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniformMatrix4fv(loc, false, matrix);\n}\n\n/** `gl.uniformMatrix3fv` from a column-major 3×3 matrix — the lite-gl\n * equivalent of Babylon's `Effect.setMatrix3x3`. Not value-cached. */\nexport function setEffectMatrix3x3(engine: GLEngineContext, effect: GLEffect, name: string, matrix: Float32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniformMatrix3fv(loc, false, matrix);\n}\n\n/** `gl.uniform1fv` — a flat float array (`Effect.setFloatArray` / `setArray`).\n * Not value-cached. */\nexport function setEffectFloatArray(engine: GLEngineContext, effect: GLEffect, name: string, array: Float32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniform1fv(loc, array);\n}\n\n/** `gl.uniform4fv` — an array of `vec4`s (`Effect.setFloatArray4` / `setArray4`).\n * Not value-cached. */\nexport function setEffectFloatArray4(engine: GLEngineContext, effect: GLEffect, name: string, array: Float32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniform4fv(loc, array);\n}\n\n/** `gl.uniform1iv` — a flat int array (`Effect.setIntArray`). Not value-cached. */\nexport function setEffectIntArray(engine: GLEngineContext, effect: GLEffect, name: string, array: Int32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniform1iv(loc, array);\n}\n\n/** Bind a texture to the sampler's pre-assigned unit (§4.4). NO `gl.uniform1i`\n * is issued — that was done exactly once per program lifetime during\n * finalization. This is the key win over Babylon's `Effect.setTexture` which\n * re-issues the sampler binding on every call. */\nexport function setEffectTexture(engine: GLEngineContext, effect: GLEffect, samplerName: string, tex: GLTexture): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const unit = effect.samplerUnits[samplerName];\n if (unit === undefined) {\n return;\n }\n bindTexture(engine, unit, tex);\n}\n\n/** Resolve (and cache) a vertex-attribute location by name — the lite-gl\n * equivalent of Babylon's `Effect.getAttributeLocationByName`. Locations for\n * declared `attributeNames` are resolved during finalization; this also serves\n * the mesh / instancing path, where attribute names are not declared up-front.\n * Returns `-1` when the attribute is absent (matching `gl.getAttribLocation`).\n * @internal */\nexport function getEffectAttributeLocation(engine: GLEngineContext, effect: GLEffect, name: string): number {\n const cached = effect.attributeLocations[name];\n if (cached !== undefined) {\n return cached;\n }\n const loc = engine.gl.getAttribLocation(effect.program, name);\n effect.attributeLocations[name] = loc;\n return loc;\n}\n\n/* ──────────────────────────── internal helpers ──────────────────────────── */\n\n/** Inject `options.defines` between the `#version`/precision header and the\n * user shader body. Supports a `// __DEFINES__` marker (preferred — keeps the\n * runtime regex-free, per spec §6.2) OR auto-detects the end of the leading\n * preprocessor / precision lines. */\nfunction applyDefines(source: string, defines: string | undefined): string {\n if (defines === undefined || defines.length === 0) {\n return source;\n }\n const marker = \"// __DEFINES__\";\n const idx = source.indexOf(marker);\n if (idx !== -1) {\n return source.slice(0, idx) + defines + source.slice(idx + marker.length);\n }\n // Fallback: insert after the last `precision` line (or after `#version`).\n const lines = source.split(\"\\n\");\n let insertAt = 0;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line === undefined) {\n continue;\n }\n const trimmed = line.trim();\n if (trimmed.startsWith(\"#version\") || trimmed.startsWith(\"precision \")) {\n insertAt = i + 1;\n }\n }\n lines.splice(insertAt, 0, defines);\n return lines.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"effect.js","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"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","sourcesContent":["import type { GLEngineContext } from \"./context.js\";\nimport { compileShader, getLinkError, isLinkComplete, linkProgram } from \"./shader.js\";\nimport { bindTexture, type GLTexture } from \"./texture.js\";\n\n/** Inputs to `createEffect`: shader sources plus the uniform, sampler and\n * attribute names whose locations are resolved during readiness finalization. */\nexport interface GLEffectOptions {\n /** Human-readable label, surfaced in compile/link error messages. */\n name: string;\n /** GLSL ES 3.00 source, ready for `gl.shaderSource`. */\n vertexSource: string;\n /** GLSL ES 3.00 source, ready for `gl.shaderSource`. */\n fragmentSource: string;\n /** Declared uniform names. Locations are resolved during readiness\n * finalization. Names not declared here are legal but allocate cache\n * slots lazily on first setter use. */\n uniformNames: readonly string[];\n /** Declared sampler names, in unit-assignment order. Each gets a fixed\n * texture unit assigned during readiness finalization, and\n * `gl.uniform1i(loc, unit)` is called exactly once per program lifetime\n * (re-run after `webglcontextrestored`). */\n samplerNames: readonly string[];\n /** Default `[\"position\"]`. The first attribute is bound to location 0 via\n * `gl.bindAttribLocation(program, 0, name)` BEFORE link, so the shared\n * fullscreen-quad VAO always feeds the same location. */\n attributeNames?: readonly string[];\n /** Optional `#define` block. Each unique `defines` string must be paired\n * with the same vertex/fragment source via a separate `createEffect` call —\n * the package does NOT cache compiled variants. */\n defines?: string;\n}\n\n/** A compiled + linked shader program with cached uniform, sampler and\n * attribute locations. Created by `createEffect`; most fields are managed\n * internally — drive it via `isEffectReady` / `useEffect` / the `setEffect*`\n * setters rather than mutating it directly. */\nexport interface GLEffect {\n /** The `name` from the originating `GLEffectOptions`. */\n readonly name: string;\n /** The options this effect was created from (retained for context-restore). */\n readonly options: GLEffectOptions;\n /** The live `WebGLProgram`. Swapped for a fresh handle after context-restore. */\n program: WebGLProgram;\n /** @internal */\n _vs: WebGLShader;\n /** @internal */\n _fs: WebGLShader;\n /** Resolved during readiness finalization. Missing names map to `null` —\n * setters with a `null` location are silent no-ops (matches Babylon). */\n uniformLocations: { [name: string]: WebGLUniformLocation | null };\n /** Fixed unit assignment for declared samplers, index into\n * `_state.boundTextures`. */\n samplerUnits: { [name: string]: number };\n /**\n * True once `gl.uniform1i(samplerLoc, unit)` has been issued for every\n * declared sampler. Cleared on context-lost so finalization re-runs.\n * @internal\n */\n _samplersAssigned: boolean;\n /** Resolved attribute locations, keyed by attribute name. */\n attributeLocations: { [name: string]: number };\n /**\n * Last-UPLOADED scalar floats. A setter that skips the upload must NOT\n * update this — otherwise a later real set with the same value would\n * incorrectly elide and the GPU would keep stale data.\n * @internal\n */\n readonly _lastF1: { [name: string]: number };\n /**\n * Last-UPLOADED vector floats (vec2/vec3/vec4). Plain `number[]` (NOT\n * `Float32Array`) so values like `0.1` compare equal across frames.\n * @internal\n */\n readonly _lastVec: { [name: string]: number[] };\n /** @internal */\n readonly _lastI1: { [name: string]: number };\n /** True once the program has linked and finalization has run; the\n * `setEffect*` setters are no-ops until then. Poll `isEffectReady` to advance it. */\n isReady: boolean;\n /** @internal */\n _compileError: string | null;\n /** @internal */\n _disposed: boolean;\n /**\n * Number of live `createEffect` callers sharing this effect (and its one\n * `WebGLProgram`). `createEffect` returns the cached effect and bumps this\n * when an identical descriptor is requested; `disposeEffect` decrements it\n * and only tears the program down when it reaches 0.\n * @internal\n */\n _refCount: number;\n /**\n * The `_effectCache` key this effect was stored under (the source\n * descriptor). Used by `disposeEffect` to evict the cache entry at refcount\n * 0.\n * @internal\n */\n _cacheKey: string;\n /**\n * Callbacks fired exactly once on the first transition to ready.\n * @internal\n */\n readonly _onCompiled: ((effect: GLEffect) => void)[];\n /**\n * Replay closure for context-restore. Re-compiles + relinks into a fresh\n * `program` field. Finalization happens lazily on the next `isEffectReady`\n * poll.\n * @internal\n */\n _restore: (engine: GLEngineContext) => void;\n}\n\n/** Compile + link a new effect. Does NOT block on link completion — `isReady`\n * starts false; consumers poll `isEffectReady` (typically from their render\n * callback) to drive finalization. */\nexport function createEffect(engine: GLEngineContext, options: GLEffectOptions): GLEffect {\n const attribs = options.attributeNames ?? [\"position\"];\n const gl = engine.gl;\n\n // Per-engine cache keyed by the source descriptor. Identical descriptors\n // share ONE GLEffect (and thus one WebGLProgram), so `useEffect`'s\n // current-program cache can elide redundant `gl.useProgram` across the\n // consumers. The key covers every input that affects the program or its\n // readiness finalization, joined by a NUL separator (cannot appear in GLSL).\n const cacheKey = [options.vertexSource, options.fragmentSource, options.defines ?? \"\", attribs.join(\",\"), options.uniformNames.join(\",\"), options.samplerNames.join(\",\")].join(\n \"\\u0000\"\n );\n const cached = engine._effectCache.get(cacheKey);\n if (cached !== undefined && !cached._disposed) {\n cached._refCount++;\n return cached;\n }\n\n const compileErr: (string | null)[] = [null];\n const finalVS = applyDefines(options.vertexSource, options.defines);\n const finalFS = applyDefines(options.fragmentSource, options.defines);\n\n const vs = compileShader(gl, finalVS, gl.VERTEX_SHADER, compileErr);\n if (vs === null) {\n throw new Error(`lite-gl: ${options.name} vertex compile failed: ${compileErr[0] ?? \"unknown\"}`);\n }\n const fs = compileShader(gl, finalFS, gl.FRAGMENT_SHADER, compileErr);\n if (fs === null) {\n gl.deleteShader(vs);\n throw new Error(`lite-gl: ${options.name} fragment compile failed: ${compileErr[0] ?? \"unknown\"}`);\n }\n const program = linkProgram(gl, vs, fs, attribs);\n if (program === null) {\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n throw new Error(`lite-gl: ${options.name} program allocation failed`);\n }\n\n const effect: GLEffect = {\n name: options.name,\n options,\n program,\n _vs: vs,\n _fs: fs,\n uniformLocations: {},\n samplerUnits: {},\n _samplersAssigned: false,\n attributeLocations: {},\n _lastF1: {},\n _lastVec: {},\n _lastI1: {},\n isReady: false,\n _compileError: null,\n _disposed: false,\n _refCount: 1,\n _cacheKey: cacheKey,\n _onCompiled: [],\n _restore: () => {},\n };\n\n effect._restore = (target: GLEngineContext): void => {\n const g = target.gl;\n const newVS = compileShader(g, applyDefines(options.vertexSource, options.defines), g.VERTEX_SHADER, [null]);\n const newFS = compileShader(g, applyDefines(options.fragmentSource, options.defines), g.FRAGMENT_SHADER, [null]);\n if (newVS === null || newFS === null) {\n effect._compileError = \"context-restore: shader compile failed\";\n return;\n }\n const newProg = linkProgram(g, newVS, newFS, attribs);\n if (newProg === null) {\n g.deleteShader(newVS);\n g.deleteShader(newFS);\n effect._compileError = \"context-restore: program allocation failed\";\n return;\n }\n effect.program = newProg;\n effect._vs = newVS;\n effect._fs = newFS;\n effect.isReady = false;\n effect._samplersAssigned = false;\n effect.uniformLocations = {};\n effect.attributeLocations = {};\n effect._compileError = null;\n };\n\n engine._effects.push(effect);\n engine._effectCache.set(cacheKey, effect);\n return effect;\n}\n\n/** Poll the link state and, on first success, run finalization (uniform-\n * location resolution + one-shot sampler-unit `uniform1i` assignment +\n * `_onCompiled` callbacks). Returns `true` once the effect is usable. */\nexport function isEffectReady(engine: GLEngineContext, effect: GLEffect): boolean {\n if (effect.isReady) {\n return true;\n }\n if (effect._disposed || engine._isLost || engine._disposed) {\n return false;\n }\n if (effect._compileError !== null) {\n return false;\n }\n if (!isLinkComplete(engine.gl, effect.program, engine.caps.parallelShaderCompile)) {\n return false;\n }\n const linkErr = getLinkError(engine.gl, effect.program);\n if (linkErr !== null) {\n effect._compileError = linkErr;\n console.error(`lite-gl: ${effect.name} link failed:`, linkErr);\n return false;\n }\n finalizeEffect(engine, effect);\n return true;\n}\n\n/** Resolves uniform/attribute locations, binds the program (cached), and\n * issues the one-time `gl.uniform1i(samplerLoc, unit)` per declared sampler. */\nfunction finalizeEffect(engine: GLEngineContext, effect: GLEffect): void {\n const gl = engine.gl;\n const program = effect.program;\n for (const name of effect.options.uniformNames) {\n effect.uniformLocations[name] = gl.getUniformLocation(program, name);\n }\n const attribs = effect.options.attributeNames ?? [\"position\"];\n for (const name of attribs) {\n effect.attributeLocations[name] = gl.getAttribLocation(program, name);\n }\n // Switch to this program via the cached helper so _state.currentProgram\n // stays consistent — no raw gl.useProgram outside useEffect.\n useEffect(engine, effect);\n let unit = 0;\n for (const name of effect.options.samplerNames) {\n const loc = gl.getUniformLocation(program, name);\n if (loc !== null) {\n gl.uniform1i(loc, unit);\n }\n effect.samplerUnits[name] = unit;\n unit++;\n }\n effect._samplersAssigned = true;\n effect.isReady = true;\n // Fire and clear the one-shot ready callbacks.\n const cbs = effect._onCompiled.slice();\n effect._onCompiled.length = 0;\n for (const cb of cbs) {\n try {\n cb(effect);\n } catch (err) {\n console.error(`lite-gl: ${effect.name} onCompiled callback threw`, err);\n }\n }\n}\n\n/** Fires `cb` synchronously if the effect is already ready; otherwise queues\n * it for the next finalization. */\nexport function executeWhenCompiled(engine: GLEngineContext, effect: GLEffect, cb: (e: GLEffect) => void): void {\n if (isEffectReady(engine, effect)) {\n cb(effect);\n return;\n }\n effect._onCompiled.push(cb);\n}\n\n/** Decrement the share count and, on the last release, delete the effect's\n * program + shaders, unregister it from the context + cache, and clear the\n * cached current-program if it pointed at this effect. A shared effect (still\n * referenced by another `createEffect` caller) is kept alive. Call exactly ONCE\n * per `createEffect` (each call decrements the ref count); safe (no-op) once the\n * effect is fully torn down. */\nexport function disposeEffect(engine: GLEngineContext, effect: GLEffect): void {\n if (effect._disposed) {\n return;\n }\n if (--effect._refCount > 0) {\n return;\n }\n effect._disposed = true;\n effect.isReady = false;\n const i = engine._effects.indexOf(effect);\n if (i !== -1) {\n engine._effects.splice(i, 1);\n }\n engine._effectCache.delete(effect._cacheKey);\n if (!engine._isLost && !engine._disposed) {\n engine.gl.deleteProgram(effect.program);\n engine.gl.deleteShader(effect._vs);\n engine.gl.deleteShader(effect._fs);\n }\n if (engine._state.currentProgram === effect.program) {\n engine._state.currentProgram = null;\n }\n effect._onCompiled.length = 0;\n}\n\n/** Cached `gl.useProgram`. No-op when the effect is not ready or already current. */\nexport function useEffect(engine: GLEngineContext, effect: GLEffect): void {\n if (engine._isLost || engine._disposed || effect._disposed) {\n return;\n }\n if (engine._state.currentProgram === effect.program) {\n return;\n }\n engine.gl.useProgram(effect.program);\n engine._state.currentProgram = effect.program;\n}\n\n/* ──────────────────────────── cached setters ────────────────────────────\n *\n * Each setter has the shape:\n * 1. bail when context lost / effect not ready (no cache write)\n * 2. lookup uniform location; bail on null (no cache write)\n * 3. compare against last-UPLOADED value; bail on equality\n * 4. write to cache, issue gl.uniform*\n *\n * Step 3's comparison is intentionally bit-equal (===) — NaN inputs re-upload\n * every frame because `NaN !== NaN`, which is the correct safety net for\n * caller bugs.\n */\n\n/** Cached `gl.uniform1f`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectFloat(engine: GLEngineContext, effect: GLEffect, name: string, x: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n if (effect._lastF1[name] === x) {\n return;\n }\n effect._lastF1[name] = x;\n engine.gl.uniform1f(loc, x);\n}\n\n/** Cached `gl.uniform2f`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectFloat2(engine: GLEngineContext, effect: GLEffect, name: string, x: number, y: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n let v = effect._lastVec[name];\n if (v !== undefined && v[0] === x && v[1] === y) {\n return;\n }\n if (v === undefined) {\n v = [x, y];\n effect._lastVec[name] = v;\n } else {\n v[0] = x;\n v[1] = y;\n }\n engine.gl.uniform2f(loc, x, y);\n}\n\n/** Cached `gl.uniform3f`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectFloat3(engine: GLEngineContext, effect: GLEffect, name: string, x: number, y: number, z: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n let v = effect._lastVec[name];\n if (v !== undefined && v[0] === x && v[1] === y && v[2] === z) {\n return;\n }\n if (v === undefined) {\n v = [x, y, z];\n effect._lastVec[name] = v;\n } else {\n v[0] = x;\n v[1] = y;\n v[2] = z;\n }\n engine.gl.uniform3f(loc, x, y, z);\n}\n\n/** Cached `gl.uniform4f`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectFloat4(engine: GLEngineContext, effect: GLEffect, name: string, x: number, y: number, z: number, w: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n let v = effect._lastVec[name];\n if (v !== undefined && v[0] === x && v[1] === y && v[2] === z && v[3] === w) {\n return;\n }\n if (v === undefined) {\n v = [x, y, z, w];\n effect._lastVec[name] = v;\n } else {\n v[0] = x;\n v[1] = y;\n v[2] = z;\n v[3] = w;\n }\n engine.gl.uniform4f(loc, x, y, z, w);\n}\n\n/** Cached `gl.uniform3f` from an r/g/b color object. Delegates to `setEffectFloat3`. */\nexport function setEffectColor3(engine: GLEngineContext, effect: GLEffect, name: string, c: { r: number; g: number; b: number }): void {\n setEffectFloat3(engine, effect, name, c.r, c.g, c.b);\n}\n\n/** Cached `gl.uniform4f` from an r/g/b/a color object. Delegates to `setEffectFloat4`. */\nexport function setEffectColor4(engine: GLEngineContext, effect: GLEffect, name: string, c: { r: number; g: number; b: number; a: number }): void {\n setEffectFloat4(engine, effect, name, c.r, c.g, c.b, c.a);\n}\n\n/** Cached `gl.uniform2f` from an `{x,y}` vector object — the lite-gl equivalent\n * of Babylon's `Effect.setVector2`. Delegates to `setEffectFloat2`. */\nexport function setEffectVector2(engine: GLEngineContext, effect: GLEffect, name: string, v: { x: number; y: number }): void {\n setEffectFloat2(engine, effect, name, v.x, v.y);\n}\n\n/** Cached `gl.uniform4f` from an r/g/b/a color WITHOUT premultiplication — the\n * lite-gl equivalent of Babylon's `Effect.setDirectColor4`. Delegates to\n * `setEffectFloat4` (lite-gl never premultiplies in the uniform setters, so\n * this matches `setEffectColor4`; the distinct name eases the ShapeBuilder\n * port). */\nexport function setEffectDirectColor4(engine: GLEngineContext, effect: GLEffect, name: string, c: { r: number; g: number; b: number; a: number }): void {\n setEffectFloat4(engine, effect, name, c.r, c.g, c.b, c.a);\n}\n\n/** Cached `gl.uniform1i`. No-op when context-lost, the effect isn't ready, the\n * uniform is absent, or the value is unchanged since last upload. */\nexport function setEffectInt(engine: GLEngineContext, effect: GLEffect, name: string, x: number): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n if (effect._lastI1[name] === x) {\n return;\n }\n effect._lastI1[name] = x;\n engine.gl.uniform1i(loc, x);\n}\n\n/* ── Matrix / array setters (uploaded every call — not value-cached) ──────────\n *\n * Matrices and arrays usually change every frame; element-wise caching would\n * cost more than the upload it saves, so these always issue the GL call (the\n * location lookup + ready guards still apply). They cover the ShapeBuilder\n * surface (`setMatrix3x3`, `setFloatArray`, `setFloatArray4`) plus a general\n * 4×4 matrix setter for any future mesh consumer. */\n\n/** `gl.uniformMatrix4fv` from a column-major 4×4 matrix — the lite-gl\n * equivalent of Babylon's `Effect.setMatrix`. Not value-cached. */\nexport function setEffectMatrix(engine: GLEngineContext, effect: GLEffect, name: string, matrix: Float32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniformMatrix4fv(loc, false, matrix);\n}\n\n/** `gl.uniformMatrix3fv` from a column-major 3×3 matrix — the lite-gl\n * equivalent of Babylon's `Effect.setMatrix3x3`. Not value-cached. */\nexport function setEffectMatrix3x3(engine: GLEngineContext, effect: GLEffect, name: string, matrix: Float32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniformMatrix3fv(loc, false, matrix);\n}\n\n/** `gl.uniform1fv` — a flat float array (`Effect.setFloatArray` / `setArray`).\n * Not value-cached. */\nexport function setEffectFloatArray(engine: GLEngineContext, effect: GLEffect, name: string, array: Float32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniform1fv(loc, array);\n}\n\n/** `gl.uniform4fv` — an array of `vec4`s (`Effect.setFloatArray4` / `setArray4`).\n * Not value-cached. */\nexport function setEffectFloatArray4(engine: GLEngineContext, effect: GLEffect, name: string, array: Float32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniform4fv(loc, array);\n}\n\n/** `gl.uniform1iv` — a flat int array (`Effect.setIntArray`). Not value-cached. */\nexport function setEffectIntArray(engine: GLEngineContext, effect: GLEffect, name: string, array: Int32Array | number[]): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const loc = effect.uniformLocations[name];\n if (loc === null || loc === undefined) {\n return;\n }\n engine.gl.uniform1iv(loc, array);\n}\n\n/** Bind a texture to the sampler's pre-assigned unit, or pass `null` to unbind\n * that unit (§4.4). NO `gl.uniform1i` is issued — that was done exactly once per program lifetime during\n * finalization. This is the key win over Babylon's `Effect.setTexture` which\n * re-issues the sampler binding on every call. */\nexport function setEffectTexture(engine: GLEngineContext, effect: GLEffect, samplerName: string, tex: GLTexture | null): void {\n if (engine._isLost || !effect.isReady) {\n return;\n }\n const unit = effect.samplerUnits[samplerName];\n if (unit === undefined) {\n return;\n }\n bindTexture(engine, unit, tex);\n}\n\n/** Resolve (and cache) a vertex-attribute location by name — the lite-gl\n * equivalent of Babylon's `Effect.getAttributeLocationByName`. Locations for\n * declared `attributeNames` are resolved during finalization; this also serves\n * the mesh / instancing path, where attribute names are not declared up-front.\n * Returns `-1` when the attribute is absent (matching `gl.getAttribLocation`).\n * @internal */\nexport function getEffectAttributeLocation(engine: GLEngineContext, effect: GLEffect, name: string): number {\n const cached = effect.attributeLocations[name];\n if (cached !== undefined) {\n return cached;\n }\n const loc = engine.gl.getAttribLocation(effect.program, name);\n effect.attributeLocations[name] = loc;\n return loc;\n}\n\n/* ──────────────────────────── internal helpers ──────────────────────────── */\n\n/** Inject `options.defines` between the `#version`/precision header and the\n * user shader body. Supports a `// __DEFINES__` marker (preferred — keeps the\n * runtime regex-free, per spec §6.2) OR auto-detects the end of the leading\n * preprocessor / precision lines. */\nfunction applyDefines(source: string, defines: string | undefined): string {\n if (defines === undefined || defines.length === 0) {\n return source;\n }\n const marker = \"// __DEFINES__\";\n const idx = source.indexOf(marker);\n if (idx !== -1) {\n return source.slice(0, idx) + defines + source.slice(idx + marker.length);\n }\n // Fallback: insert after the last `precision` line (or after `#version`).\n const lines = source.split(\"\\n\");\n let insertAt = 0;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line === undefined) {\n continue;\n }\n const trimmed = line.trim();\n if (trimmed.startsWith(\"#version\") || trimmed.startsWith(\"precision \")) {\n insertAt = i + 1;\n }\n }\n lines.splice(insertAt, 0, defines);\n return lines.join(\"\\n\");\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babylonjs/lite-gl",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "Function-based, tree-shakeable WebGL2 micro-engine for fullscreen effects, sprites and dynamic textures — the WebGL counterpart of @babylonjs/lite.",
5
5
  "keywords": [
6
6
  "babylon",
@@ -32,7 +32,7 @@
32
32
  }
33
33
  },
34
34
  "babylonLiteRelease": {
35
- "azureBuildId": "59052",
36
- "sourceVersion": "64710b56f9dfe175d919c635812f84c8872d467c"
35
+ "azureBuildId": "59326",
36
+ "sourceVersion": "488cc717dc6c3fb21ebabcb70b3cb8ccbb2f80cd"
37
37
  }
38
38
  }