babylonjs-addons 8.29.0 → 8.29.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"babylonjs.addons.min.js","mappings":"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","sources":["webpack://ADDONS/webpack/universalModuleDefinition","webpack://ADDONS/../../../dev/addons/src/msdfText/shaders/msdf.vertex.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/shadersWGSL/msdf.fragment.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/shaders/msdf.fragment.ts","webpack://ADDONS/external umd {\"root\":\"BABYLON\",\"commonjs\":\"babylonjs\",\"commonjs2\":\"babylonjs\",\"amd\":\"babylonjs\"}","webpack://ADDONS/../../../dev/addons/src/msdfText/shadersWGSL/msdf.vertex.ts","webpack://ADDONS/webpack/bootstrap","webpack://ADDONS/webpack/runtime/compat get default export","webpack://ADDONS/webpack/runtime/define property getters","webpack://ADDONS/webpack/runtime/hasOwnProperty shorthand","webpack://ADDONS/webpack/runtime/make namespace object","webpack://ADDONS/../../../../node_modules/tslib/tslib.es6.mjs","webpack://ADDONS/../../../dev/addons/src/atmosphere/atmospherePBRMaterialPlugin.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/atmospherePerCameraVariables.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/atmospherePhysicalProperties.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/sampling.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/atmosphereFragmentDeclaration.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/atmosphereUboDeclaration.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/depthFunctions.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/atmosphereFunctions.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/diffuseSkyIrradiance.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/fullscreenTriangle.vertex.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/diffuseSkyIrradianceLut.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/transmittance.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/transmittanceLut.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/compositeAerialPerspective.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/compositeSky.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/compositeGlobeAtmosphere.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/multiScattering.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/skyView.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/aerialPerspective.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/atmosphereVertexDeclaration.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/fontAsset.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/atmosphere.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/htmlMeshRenderer.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/pointerEventsCapture.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/pointerEventsCaptureBehavior.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/fitStrategy.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/htmlMesh.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/paragraphOptions.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/sdf/paragraph.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/textRenderer.ts","webpack://ADDONS/./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"babylonjs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"babylonjs-addons\", [\"babylonjs\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"babylonjs-addons\"] = factory(require(\"babylonjs\"));\n\telse\n\t\troot[\"ADDONS\"] = factory(root[\"BABYLON\"]);\n})((typeof self !== \"undefined\" ? self : typeof global !== \"undefined\" ? global : this), (__WEBPACK_EXTERNAL_MODULE__597__) => {\nreturn ","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfVertexShader\";\nconst shader = `#define BILLBOARD 1\n#define BILLBOARDSCREENPROJECTED 2\nattribute vec2 offsets;attribute vec4 world0;attribute vec4 world1;attribute vec4 world2;attribute vec4 world3;attribute vec4 uvs;uniform mat4 transform;uniform mat4 parentWorld;uniform mat4 view;uniform mat4 projection;uniform vec3 center;uniform int mode;varying vec2 atlasUV;void main(void) {mat4 world=mat4(world0,world1,world2,world3);vec4 worldPos=transform*(world*vec4(offsets.xy-vec2(0.5,0.5),0.,1.0));if (mode>=BILLBOARD) {vec3 viewPos=(view*parentWorld*vec4(0.,0.,0.,1.0)).xyz; \nif (mode==BILLBOARDSCREENPROJECTED) {viewPos.x/=viewPos.z;viewPos.y/=viewPos.z;viewPos.z=1.0;}\ngl_Position=projection*vec4(viewPos+worldPos.xyz,1.0); } else {vec3 viewPos=(view*parentWorld*worldPos).xyz; \ngl_Position=projection*vec4(viewPos,1.0); }\natlasUV=vec2(uvs.x+offsets.x*uvs.z,uvs.y+(1.0-offsets.y)*uvs.w);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const msdfVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfPixelShader\";\nconst shader = `var fontAtlas: texture_2d<f32>;var fontAtlasSampler: sampler;uniform uColor: vec4f;uniform thickness: f32;uniform uStrokeColor: vec4f;uniform uStrokeInsetWidth: f32;uniform uStrokeOutsetWidth: f32;varying atlasUV: vec2f;fn median(msdf: vec3<f32>)->f32 {let a=min(msdf.r,msdf.g);let b=max(msdf.r,msdf.g);return max(a,min(b,msdf.b));}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let s=textureSample(fontAtlas,fontAtlasSampler,input.atlasUV).rgb;let sigDist=median(s)-0.5+uniforms.thickness;let afwidth=length(vec2<f32>(dpdx(sigDist),dpdy(sigDist)));let alpha=clamp(sigDist/afwidth+0.5,0.0,1.0);let sigDistOutset=sigDist+uniforms.uStrokeOutsetWidth*0.5;let sigDistInset=sigDist-uniforms.uStrokeInsetWidth*0.5;let afwidthOutset=length(vec2<f32>(dpdx(sigDistOutset),dpdy(sigDistOutset)));let afwidthInset=length(vec2<f32>(dpdx(sigDistInset),dpdy(sigDistInset)));let outset=clamp(sigDistOutset/afwidthOutset+0.5,0.0,1.0);let inset=1.0-clamp(sigDistInset/afwidthInset+0.5,0.0,1.0);let border=outset*inset;let filledFragColor=vec4<f32>(uniforms.uColor.rgb,alpha*uniforms.uColor.a);let strokedFragColor=vec4<f32>(uniforms.uStrokeColor.rgb,border*uniforms.uStrokeColor.a);fragmentOutputs.color=mix(filledFragColor,strokedFragColor,border);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const msdfPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfPixelShader\";\nconst shader = `#extension GL_OES_standard_derivatives : enable\nprecision highp float;uniform sampler2D fontAtlas;uniform vec4 uColor;uniform vec4 uStrokeColor;uniform float uStrokeInsetWidth;uniform float uStrokeOutsetWidth;uniform float thickness;varying vec2 atlasUV;float median(vec3 msdf) {return max(min(msdf.r,msdf.g),min(max(msdf.r,msdf.g),msdf.b));}\nvoid main(void)\n{vec3 s=texture2D(fontAtlas,atlasUV).rgb;float sigDist=median(s)-0.5+thickness;float alpha=clamp(sigDist/fwidth(sigDist)+0.5,0.0,1.0);float sigDistOutset=sigDist+uStrokeOutsetWidth*0.5;float sigDistInset=sigDist-uStrokeInsetWidth*0.5;float outset=clamp(sigDistOutset/fwidth(sigDistOutset)+0.5,0.0,1.0);float inset=1.0-clamp(sigDistInset/fwidth(sigDistInset)+0.5,0.0,1.0);float border=outset*inset;vec4 filledFragColor=vec4(uColor.rgb,alpha*uColor.a);vec4 strokedFragColor=vec4(uStrokeColor.rgb,border*uStrokeColor.a);gl_FragColor=mix(filledFragColor,strokedFragColor,border);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const msdfPixelShader = { name, shader };\n","module.exports = __WEBPACK_EXTERNAL_MODULE__597__;","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfVertexShader\";\nconst shader = `#define BILLBOARD 1\n#define BILLBOARDSCREENPROJECTED 2\nattribute offsets: vec2f;attribute world0: vec4f;attribute world1: vec4f;attribute world2: vec4f;attribute world3: vec4f;attribute uvs: vec4f;uniform transform: mat4x4f;uniform parentWorld: mat4x4f;uniform view: mat4x4f;uniform projection: mat4x4f;uniform mode: u32;varying atlasUV: vec2f;@vertex\nfn main(input: VertexInputs)->FragmentInputs {let world=mat4x4<f32>(input.world0,input.world1,input.world2,input.world3);let localOffset=vec4<f32>(input.offsets-vec2<f32>(0.5,0.5),0.0,1.0);let worldPos=uniforms.transform*world*localOffset;if (uniforms.mode>=BILLBOARD) { \nvar viewPos=(uniforms.view*uniforms.parentWorld*vec4f(0.,0.,0.,1.0)).xyz;if (uniforms.mode==BILLBOARDSCREENPROJECTED) {viewPos=vec3f(viewPos.x/viewPos.z,viewPos.y/viewPos.z,1.0);} \nvertexOutputs.position=uniforms.projection*vec4<f32>(viewPos+worldPos.xyz,1.0);} else { \nlet viewPos=(uniforms.view*uniforms.parentWorld*worldPos).xyz;vertexOutputs.position=uniforms.projection*vec4<f32>(viewPos,1.0);}\nvertexOutputs.atlasUV=vec2<f32>(\ninput.uvs.x+input.offsets.x*input.uvs.z,\ninput.uvs.y+(1.0-input.offsets.y)*input.uvs.w\n);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const msdfVertexShaderWGSL = { name, shader };\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { MaterialDefines } from \"core/Materials/materialDefines\";\r\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { UniformBuffer } from \"core/Materials/uniformBuffer\";\r\n\r\nclass AtmospherePBRMaterialDefines extends MaterialDefines {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public USE_AERIAL_PERSPECTIVE_LUT: boolean;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public APPLY_AERIAL_PERSPECTIVE_INTENSITY = false;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS = false;\r\n\r\n /**\r\n * Constructs the {@link AtmospherePBRMaterialDefines}.\r\n * @param useAerialPerspectiveLut - Whether to use the aerial perspective LUT.\r\n */\r\n constructor(useAerialPerspectiveLut: boolean) {\r\n super();\r\n this.USE_AERIAL_PERSPECTIVE_LUT = useAerialPerspectiveLut;\r\n }\r\n}\r\n\r\nconst UboArray = [{ name: \"inverseViewportSize\", size: 2, type: \"vec2\" }];\r\nconst MakeUniforms = (atmosphere: Atmosphere) => ({\r\n ubo: UboArray,\r\n fragment: \"uniform vec2 inverseViewportSize;\\n\",\r\n externalUniforms: atmosphere.uniformBuffer.getUniformNames(),\r\n});\r\n\r\nconst PluginName = \"AtmospherePBRMaterialPlugin\";\r\nconst PluginPriority = 600;\r\n\r\n/**\r\n * Adds shading logic to a PBRMaterial that provides radiance, diffuse sky irradiance, and aerial perspective from the atmosphere.\r\n */\r\nexport class AtmospherePBRMaterialPlugin extends MaterialPluginBase {\r\n /**\r\n * Constructs the {@link AtmospherePBRMaterialPlugin}.\r\n * @param material - The material to apply the plugin to.\r\n * @param _atmosphere - The atmosphere to use for shading.\r\n * @param _isAerialPerspectiveEnabled - Whether to apply aerial perspective.\r\n */\r\n constructor(\r\n material: Material,\r\n private readonly _atmosphere: Atmosphere,\r\n private readonly _isAerialPerspectiveEnabled = false\r\n ) {\r\n super(\r\n material,\r\n PluginName,\r\n PluginPriority,\r\n {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n USE_CUSTOM_REFLECTION: _atmosphere.diffuseSkyIrradianceLut !== null,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n CUSTOM_FRAGMENT_BEFORE_FOG: _isAerialPerspectiveEnabled,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n USE_AERIAL_PERSPECTIVE_LUT: _isAerialPerspectiveEnabled && _atmosphere.isAerialPerspectiveLutEnabled,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n APPLY_AERIAL_PERSPECTIVE_INTENSITY: _isAerialPerspectiveEnabled && _atmosphere.aerialPerspectiveIntensity !== 1.0,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS: _isAerialPerspectiveEnabled && _atmosphere.aerialPerspectiveRadianceBias !== 0.0,\r\n },\r\n false, // addPluginToList -- false because we need to control when this is added to the list\r\n true, // enable\r\n true // resolveIncludes\r\n );\r\n\r\n this.doNotSerialize = true;\r\n\r\n // This calls `getCode` so we need to do this after having initialized the class fields.\r\n this._pluginManager._addPlugin(this);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getUniformBuffersNames(_ubos: string[]): void {\r\n const uniformBuffer = this._atmosphere.uniformBuffer;\r\n if (uniformBuffer.useUbo) {\r\n _ubos.push(uniformBuffer.name);\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getUniforms() {\r\n return MakeUniforms(this._atmosphere);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override isReadyForSubMesh(): boolean {\r\n let isReady = true;\r\n const atmosphere = this._atmosphere;\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n isReady = isReady && !!aerialPerspectiveLutRenderTarget?.isReady();\r\n }\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n isReady = isReady && !!transmittanceLutRenderTarget?.isReady();\r\n return isReady;\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getActiveTextures(_activeTextures: BaseTexture[]): void {\r\n const atmosphere = this._atmosphere;\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n if (aerialPerspectiveLutRenderTarget) {\r\n _activeTextures.push(aerialPerspectiveLutRenderTarget);\r\n }\r\n }\r\n\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n if (transmittanceLutRenderTarget) {\r\n _activeTextures.push(transmittanceLutRenderTarget);\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override bindForSubMesh(uniformBuffer: UniformBuffer): void {\r\n const atmosphere = this._atmosphere;\r\n const engine = atmosphere.scene.getEngine();\r\n\r\n // Bind the atmosphere's uniform buffer to the effect.\r\n const effect = uniformBuffer.currentEffect;\r\n if (effect) {\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n }\r\n\r\n const width = engine.getRenderWidth();\r\n const height = engine.getRenderHeight();\r\n uniformBuffer.updateFloat2(\"inverseViewportSize\", 1.0 / width, 1.0 / height);\r\n\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n uniformBuffer.setTexture(\"aerialPerspectiveLut\", aerialPerspectiveLutRenderTarget);\r\n }\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n uniformBuffer.setTexture(\"transmittanceLut\", transmittanceLutRenderTarget);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override prepareDefines(defines: AtmospherePBRMaterialDefines): void {\r\n const lastUseAerialPerspectiveLut = defines.USE_AERIAL_PERSPECTIVE_LUT;\r\n const lastApplyAerialPerspectiveIntensity = defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY;\r\n const lastApplyAerialPerspectiveRadianceBias = defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS;\r\n defines.USE_AERIAL_PERSPECTIVE_LUT = this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled;\r\n defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY = this._isAerialPerspectiveEnabled && this._atmosphere.aerialPerspectiveIntensity !== 1.0;\r\n defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS = this._isAerialPerspectiveEnabled && this._atmosphere.aerialPerspectiveRadianceBias !== 0.0;\r\n if (\r\n lastUseAerialPerspectiveLut !== defines.USE_AERIAL_PERSPECTIVE_LUT ||\r\n lastApplyAerialPerspectiveIntensity !== defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY ||\r\n lastApplyAerialPerspectiveRadianceBias !== defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\r\n ) {\r\n defines.markAllAsDirty();\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getSamplers(samplers: string[]): void {\r\n samplers.push(\"transmittanceLut\");\r\n if (this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled) {\r\n samplers.push(\"aerialPerspectiveLut\");\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getCustomCode(shaderType: string): Nullable<Record<string, string>> {\r\n // Assumed inputs are light0, vPositionW, normalW.\r\n // Only works for directional lights.\r\n if (shaderType !== \"fragment\") {\r\n return null;\r\n }\r\n\r\n const useUbo = this._atmosphere.scene.getEngine().supportsUniformBuffers;\r\n const directionToLightSnippet = useUbo ? \"-light0.vLightData.xyz\" : \"-vLightData0.xyz\";\r\n\r\n const useAtmosphereUbo = this._atmosphere.uniformBuffer.useUbo;\r\n const atmosphereImportSnippet = useAtmosphereUbo ? \"#include<atmosphereUboDeclaration>\" : \"#include<atmosphereFragmentDeclaration>\";\r\n\r\n return {\r\n CUSTOM_FRAGMENT_DEFINITIONS:\r\n this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled\r\n ? `uniform sampler2D transmittanceLut;\\r\\nprecision highp sampler2DArray;\\r\\nuniform sampler2DArray aerialPerspectiveLut;\\r\\n${atmosphereImportSnippet}\\r\\n#include<atmosphereFunctions>`\r\n : `uniform sampler2D transmittanceLut;\\r\\n${atmosphereImportSnippet}\\r\\n#include<atmosphereFunctions>`,\r\n CUSTOM_LIGHT0_COLOR: `\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + vec3(0., planetRadius, 0.);\r\n float positionRadius = length(positionGlobal);\r\n vec3 geocentricNormal = positionGlobal / positionRadius;\r\n vec3 directionToLight = ${directionToLightSnippet};\r\n float cosAngleLightToZenith = dot(directionToLight, geocentricNormal);\r\n diffuse0 = lightIntensity * sampleTransmittanceLut(transmittanceLut, positionRadius, cosAngleLightToZenith);\r\n }\r\n`,\r\n CUSTOM_REFLECTION: `\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + vec3(0., planetRadius, 0.);\r\n float positionRadius = length(positionGlobal);\r\n vec3 geocentricNormal = positionGlobal / positionRadius;\r\n\r\n vec3 directionToLight = ${directionToLightSnippet};\r\n float cosAngleLightToZenith = dot(directionToLight, geocentricNormal);\r\n\r\n vec2 uv = vec2(0.5 + 0.5 * cosAngleLightToZenith, (positionRadius - planetRadius) / atmosphereThickness);\r\n float irradianceScaleT = 0.5 * dot(normalW, geocentricNormal) + 0.5;\r\n float irradianceScale = ((-0.6652 * irradianceScaleT) + 1.5927) * irradianceScaleT + 0.1023;\r\n vec3 environmentIrradiance = lightIntensity * sampleReflection(irradianceSampler, uv).rgb;\r\n\r\n // Add a contribution here to estimate indirect lighting.\r\n const float r = 0.2;\r\n float indirect = getLuminance(environmentIrradiance) / max(0.00001, 1. - r);\r\n environmentIrradiance *= irradianceScale;\r\n environmentIrradiance += indirect;\r\n\r\n environmentIrradiance += additionalDiffuseSkyIrradiance;\r\n\r\n const float diffuseBrdf = 1. / PI;\r\n environmentIrradiance *= diffuseBrdf * diffuseSkyIrradianceIntensity;\r\n\r\n reflectionOut.environmentIrradiance = environmentIrradiance;\r\n reflectionOut.environmentRadiance.rgb = reflectionOut.environmentIrradiance;\r\n }\r\n`,\r\n // TODO: Support full ray marching if USE_AERIAL_PERSPECTIVE_LUT is disabled.\r\n CUSTOM_FRAGMENT_BEFORE_FOG: `\r\n #if USE_AERIAL_PERSPECTIVE_LUT\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + vec3(0., planetRadius, 0.);\r\n float distanceFromCamera = distance(positionGlobal, cameraPositionGlobal);\r\n\r\n vec4 aerialPerspective = vec4(0.);\r\n if (sampleAerialPerspectiveLut(\r\n gl_FragCoord.xy * inverseViewportSize,\r\n true,\r\n distanceFromCamera,\r\n NumAerialPerspectiveLutLayers,\r\n AerialPerspectiveLutKMPerSlice,\r\n AerialPerspectiveLutRangeKM,\r\n aerialPerspective)) {\r\n finalColor = aerialPerspective + (1. - aerialPerspective.a) * finalColor;\r\n }\r\n }\r\n #endif\r\n`,\r\n };\r\n }\r\n}\r\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Camera } from \"core/Cameras/camera\";\r\nimport type { IMatrixLike, IVector3Like, IVector4Like } from \"core/Maths/math.like\";\r\nimport { Matrix, Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Ray } from \"core/Culling/ray.core\";\r\nimport { Vector3Dot } from \"core/Maths/math.vector.functions\";\r\n\r\nconst TempRay = new Ray(Vector3.Zero(), Vector3.Zero());\r\n\r\n/**\r\n * Variables that are used to render the atmosphere and are computed per-camera.\r\n */\r\nexport class AtmospherePerCameraVariables {\r\n private _inverseViewProjectionMatrixWithoutTranslation = Matrix.Identity();\r\n private _directionToLightRelativeToCameraGeocentricNormal = Vector3.Up();\r\n private _cosAngleLightToZenith = 0;\r\n private _cameraRadius = 0;\r\n private _clampedCameraRadius = 0;\r\n private _cameraHeight = 0;\r\n private _clampedCameraHeight = 0;\r\n private _cameraPositionGlobal = new Vector3();\r\n private _clampedCameraPositionGlobal = new Vector3();\r\n private _cosCameraHorizonAngleFromZenith = 0;\r\n private _sinCameraAtmosphereHorizonAngleFromNadir = 0;\r\n private _cameraGeocentricNormal = Vector3.Up();\r\n private _cameraForward = Vector3.Down();\r\n private _cameraNearPlane = 0;\r\n private _cameraPosition = new Vector3();\r\n private _viewport = new Vector4();\r\n private _lastViewMatrix = Matrix.Identity();\r\n private _lastProjectionMatrix = Matrix.Identity();\r\n private _inverseViewMatrixWithoutTranslation = Matrix.Identity();\r\n private _inverseProjectionMatrix = Matrix.Identity();\r\n\r\n /**\r\n * The inverse view projection matrix is used to unproject rays.\r\n * To avoid precision issues, the translation part of the matrix has been removed.\r\n */\r\n public get inverseViewProjectionMatrixWithoutTranslation(): IMatrixLike {\r\n return this._inverseViewProjectionMatrixWithoutTranslation;\r\n }\r\n\r\n /**\r\n * The direction to the light relative to the geocentric normal under the camera.\r\n */\r\n public get directionToLightRelativeToCameraGeocentricNormal(): IVector3Like {\r\n return this._directionToLightRelativeToCameraGeocentricNormal;\r\n }\r\n\r\n /**\r\n * The cosine of the angle between the light direction and zenith.\r\n */\r\n public get cosAngleLightToZenith(): number {\r\n return this._cosAngleLightToZenith;\r\n }\r\n\r\n /**\r\n * The distance from the camera to the planet origin in kilometers.\r\n */\r\n public get cameraRadius(): number {\r\n return this._cameraRadius;\r\n }\r\n\r\n /**\r\n * The distance from the camera to the planet origin, clamped to the planet radius offset, in kilometers.\r\n */\r\n public get clampedCameraRadius(): number {\r\n return this._clampedCameraRadius;\r\n }\r\n\r\n /**\r\n * The height of the camera above the planet surface in kilometers.\r\n */\r\n public get cameraHeight(): number {\r\n return this._cameraHeight;\r\n }\r\n\r\n /**\r\n * The height of the camera above the planet surface, clamped to the planet radius offset, in kilometers.\r\n */\r\n public get clampedCameraHeight(): number {\r\n return this._clampedCameraHeight;\r\n }\r\n\r\n /**\r\n * The camera position in global space kilometers.\r\n */\r\n public get cameraPositionGlobal(): IVector3Like {\r\n return this._cameraPositionGlobal;\r\n }\r\n\r\n /**\r\n * The camera position, clamped to the planet radius offset, in global space kilometers.\r\n */\r\n public get clampedCameraPositionGlobal(): IVector3Like {\r\n return this._clampedCameraPositionGlobal;\r\n }\r\n\r\n /**\r\n * The cosine of the angle from the zenith to the horizon of the planet, measured from the camera position.\r\n */\r\n public get cosCameraHorizonAngleFromZenith(): number {\r\n return this._cosCameraHorizonAngleFromZenith;\r\n }\r\n\r\n /**\r\n * The sine of the angle from the nadir to the horizon of the atmosphere, measured from the camera position.\r\n */\r\n public get sinCameraAtmosphereHorizonAngleFromNadir(): number {\r\n return this._sinCameraAtmosphereHorizonAngleFromNadir;\r\n }\r\n\r\n /**\r\n * The geocentric normal of the camera in global space i.e., the normalization of {@link cameraPositionGlobal}.\r\n */\r\n public get cameraGeocentricNormal(): IVector3Like {\r\n return this._cameraGeocentricNormal;\r\n }\r\n\r\n /**\r\n * The camera's forward direction in world space.\r\n */\r\n public get cameraForward(): IVector3Like {\r\n return this._cameraForward;\r\n }\r\n\r\n /**\r\n * The distance to the near plane of the camera.\r\n */\r\n public get cameraNearPlane(): number {\r\n return this._cameraNearPlane;\r\n }\r\n\r\n /**\r\n * The camera's position in world space.\r\n */\r\n public get cameraPosition(): IVector3Like {\r\n return this._cameraPosition;\r\n }\r\n\r\n /**\r\n * The viewport for the camera.\r\n */\r\n public get viewport(): IVector4Like {\r\n return this._viewport;\r\n }\r\n\r\n /**\r\n * Updates the variables.\r\n * @param camera - The camera to update the variables for.\r\n * @param planetRadius - The radius of the planet in kilometers.\r\n * @param planetRadiusWithOffset - The radius of the planet with the offset in kilometers.\r\n * @param atmosphereRadius - The radius of the atmosphere in kilometers.\r\n * @param directionToLight - The direction to the light in world space.\r\n * @param originHeight - The height of the origin (distance from planet's surface) in kilometers.\r\n */\r\n public update(camera: Camera, planetRadius: number, planetRadiusWithOffset: number, atmosphereRadius: number, directionToLight: IVector3Like, originHeight: number): void {\r\n this._cameraNearPlane = camera.minZ;\r\n this._cameraForward.copyFrom(camera.getForwardRayToRef(TempRay, 1).direction);\r\n\r\n const engine = camera.getScene().getEngine();\r\n this._viewport.copyFromFloats(0.0, 0.0, engine.getRenderWidth(), engine.getRenderHeight());\r\n\r\n // Compute inverse view projection matrix, but remove the translational component to increase precision.\r\n const viewMatrix = camera.getViewMatrix();\r\n const projectionMatrix = camera.getProjectionMatrix();\r\n if (!this._lastViewMatrix.equals(viewMatrix) || !this._lastProjectionMatrix.equals(projectionMatrix)) {\r\n this._lastViewMatrix.copyFrom(viewMatrix);\r\n this._lastViewMatrix.setTranslation(Vector3.ZeroReadOnly);\r\n this._lastViewMatrix.invertToRef(this._inverseViewMatrixWithoutTranslation);\r\n\r\n this._lastProjectionMatrix.copyFrom(projectionMatrix);\r\n this._lastProjectionMatrix.invertToRef(this._inverseProjectionMatrix);\r\n this._inverseProjectionMatrix.multiplyToRef(this._inverseViewMatrixWithoutTranslation, this._inverseViewProjectionMatrixWithoutTranslation);\r\n }\r\n\r\n // Compute the global space position of the camera in kilometers.\r\n this._cameraPosition.copyFrom(camera.globalPosition);\r\n this._cameraPosition.scaleToRef(1.0 / 1000.0, this._cameraPositionGlobal);\r\n this._cameraPositionGlobal.y += planetRadius + originHeight;\r\n this._cameraHeight = this._cameraPositionGlobal.y - planetRadius;\r\n\r\n // Clamp the camera parameters.\r\n this._cameraRadius = this._cameraPositionGlobal.length();\r\n this._clampedCameraRadius = this._cameraRadius;\r\n this._cameraPositionGlobal.normalizeToRef(this._cameraGeocentricNormal);\r\n if (this._clampedCameraRadius < planetRadiusWithOffset) {\r\n this._clampedCameraRadius = planetRadiusWithOffset;\r\n this._cameraGeocentricNormal.scaleToRef(planetRadiusWithOffset, this._clampedCameraPositionGlobal);\r\n } else {\r\n this._clampedCameraPositionGlobal.copyFrom(this._cameraPositionGlobal);\r\n }\r\n\r\n this._cosCameraHorizonAngleFromZenith = ComputeCosHorizonAngleFromZenith(planetRadius, this._clampedCameraRadius);\r\n this._sinCameraAtmosphereHorizonAngleFromNadir = Math.min(1.0, atmosphereRadius / this._clampedCameraRadius);\r\n this._clampedCameraHeight = this._clampedCameraRadius - planetRadius;\r\n\r\n // Compute the direction to the light relative to the camera's geocentric normal.\r\n {\r\n this._cosAngleLightToZenith = Vector3Dot(directionToLight, this._cameraGeocentricNormal);\r\n const lightZenithSinAngle = Math.sqrt(Math.max(0.0, 1.0 - this._cosAngleLightToZenith * this._cosAngleLightToZenith));\r\n this._directionToLightRelativeToCameraGeocentricNormal.copyFromFloats(lightZenithSinAngle, this._cosAngleLightToZenith, 0.0);\r\n this._directionToLightRelativeToCameraGeocentricNormal.normalize();\r\n }\r\n }\r\n}\r\n\r\nconst ComputeCosHorizonAngleFromZenith = (planetRadius: number, radius: number): number => {\r\n const sinHorizonAngleFromNadir = Math.min(1, planetRadius / radius);\r\n const cosHorizonAngleFromNadir = Math.sqrt(1 - sinHorizonAngleFromNadir * sinHorizonAngleFromNadir);\r\n const cosHorizonAngleFromZenith = -cosHorizonAngleFromNadir;\r\n return cosHorizonAngleFromZenith;\r\n};\r\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { IAtmospherePhysicalPropertiesOptions } from \"./atmospherePhysicalPropertiesOptions\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { Vector3 } from \"core/Maths/math.vector\";\r\n\r\nconst DefaultPlanetRadius = 6360.0;\r\nconst DefaultPlanetRadiusOffset = 0.01;\r\nconst DefaultAtmosphereThickness = 100.0;\r\n\r\n// The scattering and absorption values are per kilometer measured at sea level.\r\nconst DefaultPeakRayleighScattering = new Vector3(0.005802, 0.013558, 0.0331);\r\nconst DefaultPeakMieScattering = new Vector3(0.003996, 0.003996, 0.003996);\r\nconst DefaultPeakMieAbsorption = new Vector3(0.000444, 0.000444, 0.000444);\r\nconst DefaultPeakOzoneAbsorption = new Vector3(0.00065, 0.001881, 0.000085);\r\n\r\n/**\r\n * Describes the physical properties of the atmosphere. Assumes a spherical planet.\r\n * - \"radius\" values describe a distance from the planet's center.\r\n * - \"height\" values describe a distance from the planet's surface.\r\n * - Distances are in kilometers unless otherwise specified. Angles are in radians.\r\n */\r\nexport class AtmospherePhysicalProperties {\r\n /**\r\n * Notification for when properties of the {@link AtmospherePhysicalProperties} are changed.\r\n */\r\n public readonly onChangedObservable = new Observable<AtmospherePhysicalProperties>();\r\n\r\n private _planetRadius: number;\r\n private _planetRadiusOffset: number;\r\n private _atmosphereThickness: number;\r\n private _rayleighScatteringScale: number;\r\n private _peakRayleighScattering = new Vector3();\r\n private _mieScatteringScale: number;\r\n private _peakMieScattering = new Vector3();\r\n private _mieAbsorptionScale: number;\r\n private _peakMieAbsorption = new Vector3();\r\n private _ozoneAbsorptionScale: number;\r\n private _peakOzoneAbsorption = new Vector3();\r\n\r\n // Inferred values.\r\n private _planetRadiusWithOffset = 0;\r\n private _planetRadiusSquared = 0;\r\n private _atmosphereRadius = 0;\r\n private _atmosphereRadiusSquared = 0;\r\n private _horizonDistanceToAtmosphereEdge = 0;\r\n private _horizonDistanceToAtmosphereEdgeSquared = 0;\r\n private _rayleighScattering = new Vector3();\r\n private _mieScattering = new Vector3();\r\n private _mieAbsorption = new Vector3();\r\n private _mieExtinction = new Vector3();\r\n private _ozoneAbsorption = new Vector3();\r\n\r\n /**\r\n * The radius of the planet in kilometers.\r\n */\r\n public get planetRadius(): number {\r\n return this._planetRadius;\r\n }\r\n public set planetRadius(value: number) {\r\n if (this._planetRadius !== value) {\r\n this._planetRadius = value;\r\n this._recomputeDimensionalParameters();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The squared radius of the planet in kilometers.\r\n */\r\n public get planetRadiusSquared(): number {\r\n return this._planetRadiusSquared;\r\n }\r\n\r\n /**\r\n * Offset applied to view points near the planet's surface. This should be greater than 0.\r\n * It prevents rendering issues close to the planet's surface.\r\n */\r\n public get planetRadiusOffset(): number {\r\n return this._planetRadiusOffset;\r\n }\r\n public set planetRadiusOffset(value: number) {\r\n if (this._planetRadiusOffset !== value) {\r\n this._planetRadiusOffset = value;\r\n this._recomputeDimensionalParameters();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * This is the {@link planetRadius} with the additional {@link planetRadiusOffset}, in kilometers.\r\n */\r\n public get planetRadiusWithOffset(): number {\r\n return this._planetRadiusWithOffset;\r\n }\r\n\r\n /**\r\n * The thickness of the atmosphere measured in kilometers.\r\n */\r\n public get atmosphereThickness(): number {\r\n return this._atmosphereThickness;\r\n }\r\n public set atmosphereThickness(value: number) {\r\n if (this._atmosphereThickness !== value) {\r\n this._atmosphereThickness = value;\r\n this._recomputeDimensionalParameters();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The combined planet radius and atmosphere thickness in kilometers.\r\n */\r\n public get atmosphereRadius(): number {\r\n return this._atmosphereRadius;\r\n }\r\n\r\n /**\r\n * The atmosphere radius squared in kilometers.\r\n */\r\n public get atmosphereRadiusSquared(): number {\r\n return this._atmosphereRadiusSquared;\r\n }\r\n\r\n /**\r\n * Horizon distance from the planet's surface to the outer edge of the atmosphere in kilometers.\r\n */\r\n public get horizonDistanceToAtmosphereEdge(): number {\r\n return this._horizonDistanceToAtmosphereEdge;\r\n }\r\n\r\n /**\r\n * Horizon distance from the planet's surface to the outer edge of the atmosphere, squared, in kilometers.\r\n */\r\n public get horizonDistanceToAtmosphereEdgeSquared(): number {\r\n return this._horizonDistanceToAtmosphereEdgeSquared;\r\n }\r\n\r\n /**\r\n * The scale applied to {@link peakRayleighScattering}.\r\n */\r\n public get rayleighScatteringScale(): number {\r\n return this._rayleighScatteringScale;\r\n }\r\n public set rayleighScatteringScale(value: number) {\r\n if (this._rayleighScatteringScale !== value) {\r\n this._rayleighScatteringScale = value;\r\n this._recomputeRayleighScattering();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Rayleigh scattering per kilometer at sea level for red, green, and blue wavelengths.\r\n */\r\n public get peakRayleighScattering(): Vector3 {\r\n return this._peakRayleighScattering;\r\n }\r\n public set peakRayleighScattering(value: Vector3) {\r\n if (!this._peakRayleighScattering.equals(value)) {\r\n this._peakRayleighScattering.copyFrom(value);\r\n this._recomputeRayleighScattering();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Rayleigh scattering per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by scaling {@link peakRayleighScattering} by {@link rayleighScatteringScale}.\r\n */\r\n public get rayleighScattering(): Vector3 {\r\n return this._rayleighScattering;\r\n }\r\n\r\n /**\r\n * The scale applied to {@link peakMieScattering}.\r\n */\r\n public get mieScatteringScale(): number {\r\n return this._mieScatteringScale;\r\n }\r\n public set mieScatteringScale(value: number) {\r\n if (this._mieScatteringScale !== value) {\r\n this._mieScatteringScale = value;\r\n this._recomputeMieScattering();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Mie scattering per kilometer at sea level for red, green, and blue wavelengths.\r\n */\r\n public get peakMieScattering(): Vector3 {\r\n return this._peakMieScattering;\r\n }\r\n public set peakMieScattering(value: Vector3) {\r\n if (!this._peakMieScattering.equals(value)) {\r\n this._peakMieScattering.copyFrom(value);\r\n this._recomputeMieScattering();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Mie scattering per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by scaling {@link mieScatteringScale} by {@link peakMieScattering}.\r\n */\r\n public get mieScattering(): Vector3 {\r\n return this._mieScattering;\r\n }\r\n\r\n /**\r\n * The scale applied to {@link peakMieAbsorption}.\r\n */\r\n public get mieAbsorptionScale(): number {\r\n return this._mieAbsorptionScale;\r\n }\r\n public set mieAbsorptionScale(value: number) {\r\n if (this._mieAbsorptionScale !== value) {\r\n this._mieAbsorptionScale = value;\r\n this._recomputeMieAbsorption();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Mie absorption per kilometer at sea level for red, green, and blue wavelengths.\r\n */\r\n public get peakMieAbsorption(): Vector3 {\r\n return this._peakMieAbsorption;\r\n }\r\n public set peakMieAbsorption(value: Vector3) {\r\n if (!this._peakMieAbsorption.equals(value)) {\r\n this._peakMieAbsorption.copyFrom(value);\r\n this._recomputeMieAbsorption();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Mie absorption per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by scaling {@link mieAbsorptionScale} by {@link peakMieAbsorption}.\r\n */\r\n public get mieAbsorption(): Vector3 {\r\n return this._mieAbsorption;\r\n }\r\n\r\n /**\r\n * The Mie extinction per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by adding the {@link mieAbsorption} to the {@link mieScattering}.\r\n */\r\n public get mieExtinction(): Vector3 {\r\n return this._mieExtinction;\r\n }\r\n\r\n /**\r\n * The scale applied to {@link peakOzoneAbsorption}.\r\n */\r\n public get ozoneAbsorptionScale(): number {\r\n return this._ozoneAbsorptionScale;\r\n }\r\n public set ozoneAbsorptionScale(value: number) {\r\n if (this._ozoneAbsorptionScale !== value) {\r\n this._ozoneAbsorptionScale = value;\r\n this._recomputeOzoneAbsorption();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The ozone absorption per kilometer measured at a height corresponding to it's peak concentration,\r\n * for red, green, and blue wavelengths.\r\n */\r\n public get peakOzoneAbsorption(): Vector3 {\r\n return this._peakOzoneAbsorption;\r\n }\r\n public set peakOzoneAbsorption(value: Vector3) {\r\n if (!this._peakOzoneAbsorption.equals(value)) {\r\n this._peakOzoneAbsorption.copyFrom(value);\r\n this._recomputeOzoneAbsorption();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The ozone absorption per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by scaling {@link peakOzoneAbsorption} by {@link ozoneAbsorptionScale}.\r\n */\r\n public get ozoneAbsorption(): Vector3 {\r\n return this._ozoneAbsorption;\r\n }\r\n\r\n /**\r\n * Constructs the {@link AtmospherePhysicalProperties}.\r\n * @param options - The options for the {@link AtmospherePhysicalProperties}.\r\n */\r\n constructor(options?: IAtmospherePhysicalPropertiesOptions) {\r\n this._planetRadius = options?.planetRadius ?? DefaultPlanetRadius;\r\n this._planetRadiusOffset = options?.planetRadiusOffset ?? DefaultPlanetRadiusOffset;\r\n this._atmosphereThickness = options?.atmosphereThickness ?? DefaultAtmosphereThickness;\r\n this._rayleighScatteringScale = options?.rayleighScatteringScale ?? 1.0;\r\n this._peakRayleighScattering.copyFrom(options?.peakRayleighScattering ?? DefaultPeakRayleighScattering);\r\n this._mieScatteringScale = options?.mieScatteringScale ?? 1.0;\r\n this._peakMieScattering.copyFrom(options?.peakMieScattering ?? DefaultPeakMieScattering);\r\n this._mieAbsorptionScale = options?.mieAbsorptionScale ?? 1.0;\r\n this._peakMieAbsorption.copyFrom(options?.peakMieAbsorption ?? DefaultPeakMieAbsorption);\r\n this._ozoneAbsorptionScale = options?.ozoneAbsorptionScale ?? 1.0;\r\n this._peakOzoneAbsorption.copyFrom(options?.peakOzoneAbsorption ?? DefaultPeakOzoneAbsorption);\r\n\r\n // Compute inferred values.\r\n this._recomputeDimensionalParameters();\r\n this._recomputeRayleighScattering();\r\n this._recomputeMieScattering();\r\n this._recomputeMieAbsorption();\r\n this._recomputeOzoneAbsorption();\r\n }\r\n\r\n private _recomputeDimensionalParameters(): void {\r\n this._planetRadiusWithOffset = this._planetRadius + this._planetRadiusOffset;\r\n this._planetRadiusSquared = this._planetRadius * this._planetRadius;\r\n this._atmosphereRadius = this._planetRadius + this._atmosphereThickness;\r\n this._atmosphereRadiusSquared = this._atmosphereRadius * this._atmosphereRadius;\r\n this._horizonDistanceToAtmosphereEdgeSquared = this._atmosphereRadiusSquared - this._planetRadiusSquared;\r\n this._horizonDistanceToAtmosphereEdge = Math.sqrt(this._horizonDistanceToAtmosphereEdgeSquared);\r\n }\r\n\r\n private _recomputeRayleighScattering(): void {\r\n this._peakRayleighScattering.scaleToRef(this._rayleighScatteringScale, this._rayleighScattering);\r\n }\r\n\r\n private _recomputeMieScattering(): void {\r\n this._peakMieScattering.scaleToRef(this._mieScatteringScale, this._mieScattering);\r\n this._recomputeMieExtinction();\r\n }\r\n\r\n private _recomputeMieAbsorption(): void {\r\n this._peakMieAbsorption.scaleToRef(this._mieAbsorptionScale, this._mieAbsorption);\r\n this._recomputeMieExtinction();\r\n }\r\n\r\n private _recomputeMieExtinction(): void {\r\n this._mieAbsorption.addToRef(this._mieScattering, this._mieExtinction);\r\n }\r\n\r\n private _recomputeOzoneAbsorption(): void {\r\n this._peakOzoneAbsorption.scaleToRef(this._ozoneAbsorptionScale, this._ozoneAbsorption);\r\n }\r\n}\r\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport { Clamp } from \"core/Maths/math.scalar.functions\";\r\nimport type { IColor4Like } from \"core/Maths/math.like\";\r\n\r\nconst MakeTempColor4Like = (): IColor4Like => {\r\n return {\r\n r: Number.NaN,\r\n g: Number.NaN,\r\n b: Number.NaN,\r\n a: Number.NaN,\r\n };\r\n};\r\n\r\nconst TmpColor1 = MakeTempColor4Like();\r\nconst TmpColor2 = MakeTempColor4Like();\r\nconst TmpColor3 = MakeTempColor4Like();\r\nconst TmpColor4 = MakeTempColor4Like();\r\n\r\n/**\r\n * Samples the texture data at the given uv coordinate using bilinear interpolation.\r\n * Note this will not match GPU sampling behavior exactly.\r\n * Currently assumes clamping behavior.\r\n * @param u - The u coordinate to sample.\r\n * @param v - The v coordinate to sample.\r\n * @param widthPx - The width of the texture in texels.\r\n * @param heightPx - The height of the texture in texels.\r\n * @param data - The texture data to sample.\r\n * @param result - The color to store the sample.\r\n * @param normalizeFunc - The function to normalize the texel values. Default is to divide by 255.\r\n * @returns The result color.\r\n */\r\nexport function Sample2DRgbaToRef<T extends IColor4Like>(\r\n u: number,\r\n v: number,\r\n widthPx: number,\r\n heightPx: number,\r\n data: Uint8Array | Uint16Array | Float32Array,\r\n result: T,\r\n normalizeFunc = (value: number) => value / 255.0\r\n): T {\r\n if (widthPx <= 0 || heightPx <= 0) {\r\n throw new Error(\"Sample2DRgbaToRef: widthPx and heightPx must be positive.\");\r\n }\r\n\r\n const expectedLength = widthPx * heightPx * 4;\r\n if (data.length < expectedLength) {\r\n throw new Error(`Sample2DRgbaToRef: data length (${data.length}) is less than required (${expectedLength}).`);\r\n }\r\n\r\n // Default to clamping behavior, but could support others.\r\n u = Clamp(u);\r\n v = Clamp(v);\r\n\r\n // Compute 4 nearest neighbor texels.\r\n const fractionalTexelX = Math.max(u * widthPx - 0.5, 0);\r\n const fractionalTexelY = Math.max(v * heightPx - 0.5, 0);\r\n const xLeft = Math.floor(fractionalTexelX);\r\n const xRight = Math.min(xLeft + 1, widthPx - 1);\r\n const yBottom = Math.floor(fractionalTexelY);\r\n const yTop = Math.min(yBottom + 1, heightPx - 1);\r\n\r\n // Sample nearest neighbor texels.\r\n const lowerLeftColor = TexelFetch2DRgbaToRef(xLeft, yBottom, widthPx, heightPx, data, TmpColor1, normalizeFunc);\r\n const upperLeftColor = TexelFetch2DRgbaToRef(xLeft, yTop, widthPx, heightPx, data, TmpColor2, normalizeFunc);\r\n const lowerRightColor = TexelFetch2DRgbaToRef(xRight, yBottom, widthPx, heightPx, data, TmpColor3, normalizeFunc);\r\n const upperRightColor = TexelFetch2DRgbaToRef(xRight, yTop, widthPx, heightPx, data, TmpColor4, normalizeFunc);\r\n\r\n // Compute weights.\r\n const tX = fractionalTexelX - xLeft;\r\n const tY = fractionalTexelY - yBottom;\r\n const oneMinusTX = 1.0 - tX;\r\n const oneMinusTY = 1.0 - tY;\r\n const w0 = oneMinusTX * oneMinusTY;\r\n const w1 = tX * oneMinusTY;\r\n const w2 = oneMinusTX * tY;\r\n const w3 = tX * tY;\r\n\r\n // Compute the result.\r\n result.r = lowerLeftColor.r * w0 + lowerRightColor.r * w1 + upperLeftColor.r * w2 + upperRightColor.r * w3;\r\n result.g = lowerLeftColor.g * w0 + lowerRightColor.g * w1 + upperLeftColor.g * w2 + upperRightColor.g * w3;\r\n result.b = lowerLeftColor.b * w0 + lowerRightColor.b * w1 + upperLeftColor.b * w2 + upperRightColor.b * w3;\r\n result.a = lowerLeftColor.a * w0 + lowerRightColor.a * w1 + upperLeftColor.a * w2 + upperRightColor.a * w3;\r\n return result;\r\n}\r\n\r\n/**\r\n * Fetches a texel from a 2D texture and stores the result in the given color.\r\n * @param x - The x coordinate in texels.\r\n * @param y - The y coordinate in texels.\r\n * @param width - The width of the texture in texels.\r\n * @param height - The height of the texture in texels.\r\n * @param data - The texture data to sample from.\r\n * @param result - The color to store the sampled color in.\r\n * @param normalizeFunc - The function to normalize the texel values. Default is to divide by 255.\r\n * @returns The result color.\r\n */\r\nconst TexelFetch2DRgbaToRef = <T extends IColor4Like>(\r\n x: number,\r\n y: number,\r\n width: number,\r\n height: number,\r\n data: Uint8Array | Uint16Array | Float32Array,\r\n result: T,\r\n normalizeFunc = (value: number) => value / 255.0\r\n): T => {\r\n const clampedTexelX = Clamp(x, 0, width - 1);\r\n const clampedTexelY = Clamp(y, 0, height - 1);\r\n const index = 4 * (clampedTexelY * width + clampedTexelX);\r\n result.r = normalizeFunc(data[index]);\r\n result.g = normalizeFunc(data[index + 1]);\r\n result.b = normalizeFunc(data[index + 2]);\r\n result.a = normalizeFunc(data[index + 3]);\r\n return result;\r\n};\r\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"atmosphereFragmentDeclaration\";\nconst shader = `uniform vec3 peakRayleighScattering;uniform float planetRadius;uniform vec3 peakMieScattering;uniform float atmosphereThickness;uniform vec3 peakMieAbsorption;uniform float planetRadiusSquared;uniform vec3 peakMieExtinction;uniform float atmosphereRadius;uniform vec3 peakOzoneAbsorption;uniform float atmosphereRadiusSquared;uniform float horizonDistanceToAtmosphereEdge;uniform float horizonDistanceToAtmosphereEdgeSquared;uniform float planetRadiusWithOffset;uniform float planetRadiusOffset;uniform float atmosphereExposure;uniform float aerialPerspectiveRadianceBias;uniform float inverseAtmosphereThickness;uniform float aerialPerspectiveTransmittanceScale;uniform mat4 inverseViewProjectionWithoutTranslation;uniform vec3 directionToLight;uniform float multiScatteringIntensity;uniform vec3 directionToLightRelativeToCameraGeocentricNormal;uniform float cameraRadius;uniform vec3 lightRadianceAtCamera;uniform float diffuseSkyIrradianceDesaturationFactor;uniform vec3 groundAlbedo;uniform float aerialPerspectiveSaturation;uniform vec3 minMultiScattering;uniform float diffuseSkyIrradianceIntensity;uniform vec3 cameraPositionGlobal;uniform float lightIntensity;uniform vec3 clampedCameraPositionGlobal;uniform float aerialPerspectiveIntensity;uniform vec3 cameraGeocentricNormal;uniform float clampedCameraRadius;uniform vec3 cameraForward;uniform float clampedCameraHeight;uniform vec3 cameraPosition;uniform float cosCameraHorizonAngleFromZenith;uniform vec4 viewport;uniform vec3 additionalDiffuseSkyIrradiance;uniform float cameraHeight;uniform float cameraNearPlane;uniform float originHeight;uniform float sinCameraAtmosphereHorizonAngleFromNadir;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const atmosphereFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"atmosphereUboDeclaration\";\nconst shader = `layout(std140,column_major) uniform;uniform Atmosphere {vec3 peakRayleighScattering;float planetRadius;vec3 peakMieScattering;float atmosphereThickness;vec3 peakMieAbsorption;float planetRadiusSquared;vec3 peakMieExtinction;float atmosphereRadius;vec3 peakOzoneAbsorption;float atmosphereRadiusSquared;float horizonDistanceToAtmosphereEdge;float horizonDistanceToAtmosphereEdgeSquared;float planetRadiusWithOffset;float planetRadiusOffset;float atmosphereExposure;float aerialPerspectiveRadianceBias;float inverseAtmosphereThickness;float aerialPerspectiveTransmittanceScale;mat4 inverseViewProjectionWithoutTranslation;vec3 directionToLight;float multiScatteringIntensity;vec3 directionToLightRelativeToCameraGeocentricNormal;float cameraRadius;vec3 lightRadianceAtCamera;float diffuseSkyIrradianceDesaturationFactor;vec3 groundAlbedo;float aerialPerspectiveSaturation;vec3 minMultiScattering;float diffuseSkyIrradianceIntensity;vec3 cameraPositionGlobal;float lightIntensity;vec3 clampedCameraPositionGlobal;float aerialPerspectiveIntensity;vec3 cameraGeocentricNormal;float clampedCameraRadius;vec3 cameraForward;float clampedCameraHeight;vec3 cameraPosition;float cosCameraHorizonAngleFromZenith;vec4 viewport;vec3 additionalDiffuseSkyIrradiance;float cameraHeight;float cameraNearPlane;float originHeight;float sinCameraAtmosphereHorizonAngleFromNadir;};\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const atmosphereUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"depthFunctions\";\nconst shader = `float reconstructDistanceFromCameraPlane(float depth,float cameraNearPlane) {return cameraNearPlane/(1.0-depth);}\nfloat sampleDistanceFromCameraPlane(sampler2D depthTexture,vec2 uv,float cameraNearPlane) {float depth=textureLod(depthTexture,uv,0.).r;return depth>=1. ? 0. : reconstructDistanceFromCameraPlane(depth,cameraNearPlane);}\nfloat reconstructDistanceFromCamera(float depth,vec3 cameraRayDirection,vec3 cameraForward,float cameraNearPlane) {float distanceFromCameraPlane=reconstructDistanceFromCameraPlane(depth,cameraNearPlane);return distanceFromCameraPlane/max(0.00001,dot(cameraForward,cameraRayDirection));}\nfloat reconstructDistanceFromCamera(\nsampler2D depthTexture,\nvec2 uv,\nvec3 cameraRayDirection,\nvec3 cameraForward,\nfloat cameraNearPlane) {float depth=textureLod(depthTexture,uv,0.).r;return depth>=1. ? 0. : reconstructDistanceFromCamera(depth,cameraRayDirection,cameraForward,cameraNearPlane);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const depthFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"core/Shaders/ShadersInclude/intersectionFunctions\";\n\nconst name = \"atmosphereFunctions\";\nconst shader = `#include<intersectionFunctions>\nconst vec2 MultiScatteringLutSize=vec2(32.0,32.0);const vec2 MultiScatteringLutDomainInUVSpace=(MultiScatteringLutSize-vec2(1.0))/MultiScatteringLutSize;const vec2 MultiScatteringLutHalfTexelSize=vec2(0.5)/MultiScatteringLutSize;const float NumAerialPerspectiveLutLayers=32.0;const vec3 AerialPerspectiveLutSize=vec3(16.0,64.0,NumAerialPerspectiveLutLayers);const vec2 DiffuseSkyIrradianceLutSize=vec2(64.0,16.0);const vec2 DiffuseSkyIrradianceLutDomainInUVSpace=(DiffuseSkyIrradianceLutSize-vec2(1.0))/DiffuseSkyIrradianceLutSize;const vec2 DiffuseSkyIrradianceLutHalfTexelSize=vec2(0.5)/DiffuseSkyIrradianceLutSize;const vec2 SkyViewLutSize=vec2(128.0,128.0);const vec2 SkyViewLutDomainInUVSpace=(SkyViewLutSize-vec2(1.0))/SkyViewLutSize;const vec2 SkyViewLutHalfTexelSize=vec2(0.5)/SkyViewLutSize;const float AerialPerspectiveLutKMPerSlice=4.0;const float AerialPerspectiveLutRangeKM=AerialPerspectiveLutKMPerSlice*NumAerialPerspectiveLutLayers;const float TransmittanceSampleCount=128.0;const float SkyViewLutSampleCount=30.0;const vec2 TransmittanceLutSize=vec2(256.,64.);const vec2 TransmittanceLutDomainInUVSpace=(TransmittanceLutSize-vec2(1.))/TransmittanceLutSize;const vec2 TransmittanceLutHalfTexelSize=vec2(0.5)/TransmittanceLutSize;const float TransmittanceHorizonRange=2.*TransmittanceLutHalfTexelSize.x;const float TransmittanceMaxUnoccludedU=1.-0.5*TransmittanceHorizonRange;const float TransmittanceMinOccludedU=1.+0.5*TransmittanceHorizonRange;vec2 uvToUnit(vec2 uv,vec2 domainInUVSpace,vec2 halfTexelSize) {return (uv-halfTexelSize)/domainInUVSpace;}\nvec2 unitToUV(vec2 unit,vec2 domainInUVSpace,vec2 halfTexelSize) {return unit*domainInUVSpace+halfTexelSize;}\nfloat sphereIntersectNearest(vec3 rayOrigin,vec3 rayDirection,float sphereRadius) {vec2 result=sphereIntersectFromOrigin(rayOrigin,rayDirection,sphereRadius);float c=dot(rayOrigin,rayOrigin)-sphereRadius*sphereRadius;return c>=0.0 ?\nresult.y :\nresult.x;}\nvoid moveToTopAtmosphere(\nvec3 cameraPosition,\nfloat positionRadius,\nvec3 positionGeocentricNormal,\nvec3 rayDirection,\nout bool intersectsAtmosphere,\nout vec3 cameraPositionClampedToTopOfAtmosphere) {intersectsAtmosphere=true;cameraPositionClampedToTopOfAtmosphere=cameraPosition;if (positionRadius>atmosphereRadius) {float tTop=sphereIntersectNearest(cameraPosition,rayDirection,atmosphereRadius);if (tTop>=0.0) {vec3 upOffset=-planetRadiusOffset*positionGeocentricNormal;cameraPositionClampedToTopOfAtmosphere=cameraPosition+rayDirection*tTop+upOffset;} else {intersectsAtmosphere=false;}}}\nvoid getSkyViewUVFromParameters(\nbool intersectsGround,\nfloat cosHorizonAngleFromZenith,\nfloat cosAngleBetweenViewAndZenith,\nfloat cosAngleBetweenViewAndLightOnPlane,\nout vec2 uv)\n{vec2 unit=vec2(0.0);if (intersectsGround) {float coord=(cosAngleBetweenViewAndZenith+1.0)/(cosHorizonAngleFromZenith+1.0);coord=sqrtClamped(coord); \nunit.y=0.5*coord; } else {float coord=(cosAngleBetweenViewAndZenith-cosHorizonAngleFromZenith)/(1.0-cosHorizonAngleFromZenith);coord=sqrtClamped(coord); \nunit.y=0.5*coord+0.5; }\n{float coord=0.5-0.5*cosAngleBetweenViewAndLightOnPlane;unit.x=coord;}\nuv=unitToUV(unit,SkyViewLutDomainInUVSpace,SkyViewLutHalfTexelSize);}\nvec4 sampleSkyViewLut(\nsampler2D skyViewLut,\nfloat positionRadius,\nvec3 geocentricNormal,\nvec3 rayDirection,\nvec3 directionToLight,\nfloat cosHorizonAngleFromZenith,\nout float cosAngleBetweenViewAndZenith,\nout bool isRayIntersectingGround) {cosAngleBetweenViewAndZenith=dot(rayDirection,geocentricNormal);if (positionRadius>atmosphereRadius) {float sinAngleBetweenViewAndNadir=sqrtClamped(1.-cosAngleBetweenViewAndZenith*cosAngleBetweenViewAndZenith);if (sinAngleBetweenViewAndNadir>sinCameraAtmosphereHorizonAngleFromNadir) {isRayIntersectingGround=false;return vec4(0.);}}\nvec3 sideVector=normalize(cross(geocentricNormal,rayDirection));vec3 forwardVector=normalize(cross(sideVector,geocentricNormal));vec2 lightOnPlane=normalize(vec2(dot(directionToLight,forwardVector),dot(directionToLight,sideVector)));float cosAngleBetweenViewAndLightOnPlane=lightOnPlane.x;float rayIntersectionScale=mix(0.95,1.,saturate((positionRadius-planetRadius)/atmosphereThickness));isRayIntersectingGround =\npositionRadius>planetRadius &&\n(rayIntersectionScale*cosAngleBetweenViewAndZenith)<=cosHorizonAngleFromZenith;vec2 uv;getSkyViewUVFromParameters(\nisRayIntersectingGround,\ncosHorizonAngleFromZenith,\ncosAngleBetweenViewAndZenith,\ncosAngleBetweenViewAndLightOnPlane,\nuv);return textureLod(skyViewLut,uv,0.);}\nfloat computeRayleighPhase(float onePlusCosThetaSq) {return 0.0596831037*onePlusCosThetaSq;}\nfloat computeMiePhaseCornetteShanks(float cosTheta,float onePlusCosThetaSq) {const float g=0.8;const float gSquared=g*g;const float oneMinusGSquared=1.-gSquared;const float onePlusGSquared=1.+gSquared;const float twoPlusGSquared=2.+gSquared;const float twoG=2.*g;const float threeOverEightPi=3./(8.*PI);return threeOverEightPi*oneMinusGSquared*onePlusCosThetaSq/(twoPlusGSquared*pow(onePlusGSquared-twoG*cosTheta,1.5));}\nfloat computeOzoneDensity(float normalizedViewHeight) {const float MinOzoneDensity=0.135;const float OneMinusMinOzoneDensity=1.-MinOzoneDensity;const float OzoneStartHeight=.15; \nconst float PeakOzoneHeight=.25;const float MaxOzoneHeight=0.6;const float InverseRampupDistance=1./(PeakOzoneHeight-OzoneStartHeight);const float InverseRampdownDistance=1./(MaxOzoneHeight-PeakOzoneHeight);float lowerAtmosphereDensity=MinOzoneDensity+OneMinusMinOzoneDensity*max(0.,normalizedViewHeight-OzoneStartHeight)*InverseRampupDistance;float sqrtUpperAtmosphereDensity=max(0.,1.-(normalizedViewHeight-PeakOzoneHeight)*InverseRampdownDistance);float upperAtmosphereDensity=sqrtUpperAtmosphereDensity*sqrtUpperAtmosphereDensity;float densityOzone=normalizedViewHeight<PeakOzoneHeight ? lowerAtmosphereDensity : upperAtmosphereDensity;return densityOzone;}\nvoid sampleMediumRGB(\nfloat viewHeight,\nout vec3 scatteringRayleigh,\nout vec3 scatteringMie,\nout vec3 extinction,\nout vec3 scattering) {float normalizedViewHeight=saturate(viewHeight*inverseAtmosphereThickness);float densityMie=exp(-83.333*normalizedViewHeight);float densityRayleigh=exp(-12.5*normalizedViewHeight);float densityOzone=computeOzoneDensity(normalizedViewHeight);scatteringRayleigh=densityRayleigh*peakRayleighScattering;scatteringMie=densityMie*peakMieScattering;scattering=scatteringMie+scatteringRayleigh;vec3 extinctionRayleigh=scatteringRayleigh;vec3 extinctionMie=densityMie*peakMieExtinction;vec3 extinctionOzone=densityOzone*peakOzoneAbsorption;extinction=extinctionRayleigh+extinctionMie+extinctionOzone;}\nvec3 computeTransmittance(vec3 rayOriginGlobal,vec3 rayDirection,float tMax,float sampleCount) {vec3 opticalDepth=vec3(0.);float t=0.;float sampleSegmentWeight=tMax/sampleCount;const float sampleSegmentT=0.3;for (float s=0.; s<sampleCount; s+=1.) {float newT=sampleSegmentWeight*(s+sampleSegmentT);float dt=newT-t;t=newT;vec3 scatteringRayleigh,scatteringMie,extinction,scattering;vec3 samplePositionGlobal=rayOriginGlobal+t*rayDirection;sampleMediumRGB(length(samplePositionGlobal)-planetRadius,scatteringRayleigh,scatteringMie,extinction,scattering);opticalDepth+=extinction*dt;}\nreturn exp(-opticalDepth);}\nvec2 getTransmittanceUV(float radius,float cosAngleLightToZenith,out float distanceToHorizon) {float radiusSquared=radius*radius;distanceToHorizon=sqrtClamped(radiusSquared-planetRadiusSquared);float cosAngleLightToZenithSquared=cosAngleLightToZenith*cosAngleLightToZenith;float discriminant=radiusSquared*(cosAngleLightToZenithSquared-1.)+atmosphereRadiusSquared;float distanceToAtmosphereEdge=max(0.,-radius*cosAngleLightToZenith+sqrtClamped(discriminant));float minDistanceToAtmosphereEdge=max(0.,atmosphereRadius-radius);float maxDistanceToAtmosphereEdge=distanceToHorizon+horizonDistanceToAtmosphereEdge;float cosAngleLightToZenithCoordinate=(distanceToAtmosphereEdge-minDistanceToAtmosphereEdge)/max(0.000001,maxDistanceToAtmosphereEdge-minDistanceToAtmosphereEdge);float distanceToHorizonCoordinate=distanceToHorizon/max(0.000001,horizonDistanceToAtmosphereEdge);vec2 unit=vec2(cosAngleLightToZenithCoordinate,distanceToHorizonCoordinate);return unit*TransmittanceLutDomainInUVSpace+TransmittanceLutHalfTexelSize; }\nvec4 sampleTransmittanceLut(sampler2D transmittanceLut,float positionRadius,float cosAngleLightToZenith) {float distanceToHorizon;vec2 uv=getTransmittanceUV(positionRadius,cosAngleLightToZenith,distanceToHorizon);float weight=smoothstep(TransmittanceMinOccludedU,TransmittanceMaxUnoccludedU,uv.x);return weight*textureLod(transmittanceLut,uv,0.);}\nvec3 sampleMultiScatteringLut(sampler2D multiScatteringLut,float radius,float cosAngleLightToZenith) {vec2 unit=vec2(0.5+0.5*cosAngleLightToZenith,(radius-planetRadius)/atmosphereThickness);vec2 uv=unitToUV(unit,MultiScatteringLutDomainInUVSpace,MultiScatteringLutHalfTexelSize);vec3 multiScattering=textureLod(multiScatteringLut,uv,0.).rgb;return max(minMultiScattering,multiScattering);}\nconst float uniformPhase=RECIPROCAL_PI4;void integrateScatteredRadiance(\nbool isAerialPerspectiveLut,\nfloat lightIntensity,\nsampler2D transmittanceLut,\n#ifndef COMPUTE_MULTI_SCATTERING\nsampler2D multiScatteringLut,\nfloat multiScatteringIntensity,\n#endif\nvec3 rayOriginGlobal,\nvec3 rayDirection,\nvec3 directionToLight,\nfloat tMaxMax,\nfloat sampleCount,\nfloat distanceToSurface,\nout vec3 radiance,\nout vec3 transmittance\n#if COMPUTE_MULTI_SCATTERING\n,out vec3 multiScattering\n#endif\n) {radiance=vec3(0.);transmittance=vec3(1.);\n#if COMPUTE_MULTI_SCATTERING\nmultiScattering=vec3(0.);\n#endif\nfloat tBottom=sphereIntersectNearest(rayOriginGlobal,rayDirection,planetRadius);float tTop=sphereIntersectNearest(rayOriginGlobal,rayDirection,atmosphereRadius);float tMax=0.;if (tBottom<0.) {if (tTop<0.) {return;} else {tMax=tTop;}} else {if (tTop>0.) {if (isAerialPerspectiveLut) {tMax=tTop;} else {tMax=min(tBottom,tTop);}}}\nif (distanceToSurface>0. && distanceToSurface<tMax) {tMax=distanceToSurface;}\ntMax=min(tMax,tMaxMax);\n#ifndef COMPUTE_MULTI_SCATTERING\nfloat cosTheta=dot(rayDirection,directionToLight);float onePlusCosThetaSq=1.+cosTheta*cosTheta;float rayleighPhase=computeRayleighPhase(onePlusCosThetaSq);float miePhase=computeMiePhaseCornetteShanks(cosTheta,onePlusCosThetaSq);\n#endif\nfloat transmittanceScale=isAerialPerspectiveLut ? aerialPerspectiveTransmittanceScale : 1.;float t=0.;float sampleSegmentWeight=tMax/sampleCount;const float sampleSegmentT=0.3;for (float s=0.; s<sampleCount; s+=1.) {float newT=sampleSegmentWeight*(s+sampleSegmentT);float dt=newT-t;t=newT;vec3 samplePositionGlobal=rayOriginGlobal+t*rayDirection;float sampleRadiusGlobal=length(samplePositionGlobal);vec3 sampleGeocentricNormal=samplePositionGlobal/sampleRadiusGlobal;float sampleCosAngleLightToZenith=dot(directionToLight,sampleGeocentricNormal);vec3 scatteringRayleigh,scatteringMie,extinction,scattering;sampleMediumRGB(sampleRadiusGlobal-planetRadius,scatteringRayleigh,scatteringMie,extinction,scattering);vec3 transmittanceToLight=sampleTransmittanceLut(transmittanceLut,sampleRadiusGlobal,sampleCosAngleLightToZenith).rgb;\n#if COMPUTE_MULTI_SCATTERING\nvec3 phaseTimesScattering=uniformPhase*scattering;vec3 S=transmittanceToLight*phaseTimesScattering;\n#else\nvec3 phaseTimesScattering=scatteringMie*miePhase+scatteringRayleigh*rayleighPhase;vec3 multiScatteredRadiance=sampleMultiScatteringLut(multiScatteringLut,sampleRadiusGlobal,sampleCosAngleLightToZenith);vec3 S=transmittanceScale*transmittanceToLight*phaseTimesScattering+multiScatteringIntensity*multiScatteredRadiance*scattering;\n#endif\nvec3 sampleOpticalDepth=extinction*dt;vec3 sampleTransmittance=exp(-sampleOpticalDepth);vec3 clampedExtinction=max(vec3(0.0000001),extinction);vec3 SInt=(S-S*sampleTransmittance)/clampedExtinction;radiance+=transmittance*SInt;\n#if COMPUTE_MULTI_SCATTERING\nvec3 MSInt=(scattering-scattering*sampleTransmittance)/clampedExtinction;multiScattering+=transmittance*MSInt;\n#endif\ntransmittance*=sampleTransmittance;}\n#if USE_GROUND_ALBEDO\nif (tMax==tBottom && tBottom>0.) {vec3 planetPos=rayOriginGlobal+tBottom*rayDirection;float planetPosRadius=length(planetPos);vec3 planetPosGeocentricNormal=planetPos/planetPosRadius;float nDotL=dot(directionToLight,planetPosGeocentricNormal);vec3 lightTransmittance=sampleTransmittanceLut(transmittanceLut,planetPosRadius,nDotL).rgb;const float diffuseBrdf=RECIPROCAL_PI;radiance+=lightTransmittance*transmittance*groundAlbedo*(nDotL*diffuseBrdf);}\n#endif\nradiance*=lightIntensity;}\nfloat layerIdxToAerialPerspectiveLayer(float layerIdx) {float layer=(layerIdx+1.)/NumAerialPerspectiveLutLayers;layer*=layer; \nlayer*=NumAerialPerspectiveLutLayers;return layer;}\nfloat toAerialPerspectiveDepth(float layer) {return layer*AerialPerspectiveLutKMPerSlice;}\nfloat toAerialPerspectiveLayer(float distance,float aerialPerspectiveLutDistancePerSlice) {return distance/aerialPerspectiveLutDistancePerSlice;}\nvec4 applyAerialPerspectiveSaturation(vec4 aerialPerspective) {float previousRadiance=getLuminance(aerialPerspective.rgb);aerialPerspective.rgb=mix(vec3(previousRadiance),aerialPerspective.rgb,aerialPerspectiveSaturation);return aerialPerspective;}\nvec4 applyAerialPerspectiveIntensity(vec4 aerialPerspective) {\n#if APPLY_AERIAL_PERSPECTIVE_INTENSITY\nif (aerialPerspectiveIntensity==0.) {aerialPerspective=vec4(0.);} else {float previousAlpha=aerialPerspective.a;aerialPerspective/=max(0.00001,previousAlpha);aerialPerspective*=pow(previousAlpha,1./aerialPerspectiveIntensity);}\n#endif\nreturn aerialPerspective;}\nvec4 applyAerialPerspectiveRadianceBias(vec4 aerialPerspective) {\n#if APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\nfloat originalRadiance=dot(aerialPerspective.rgb,LuminanceEncodeApprox);float targetRadiance=originalRadiance+aerialPerspectiveRadianceBias;if (originalRadiance>0.) {aerialPerspective*=max(0.,targetRadiance/originalRadiance);} else {aerialPerspective=max(vec4(0.),vec4(vec3(aerialPerspectiveRadianceBias),aerialPerspectiveRadianceBias));}\naerialPerspective.a=min(aerialPerspective.a,1.);\n#endif\nreturn aerialPerspective;}\nbool sampleAerialPerspectiveLut(\nvec2 screenUV,\nbool clampToLutRange,\nfloat distanceFromCamera,\nfloat numAerialPerspectiveLutLayers,\nfloat aerialPerspectiveLutKMPerSlice,\nfloat aerialPerspectiveLutRangeKM,\nout vec4 aerialPerspective) {aerialPerspective=vec4(0.);\n#if USE_AERIAL_PERSPECTIVE_LUT\nif (distanceFromCamera>0. &&\n(clampToLutRange || distanceFromCamera<aerialPerspectiveLutRangeKM) &&\nclampedCameraRadius<=atmosphereRadius) {float layer=toAerialPerspectiveLayer(distanceFromCamera,aerialPerspectiveLutKMPerSlice);float normalizedLayer=sqrt(layer/numAerialPerspectiveLutLayers); \nlayer=min(normalizedLayer*numAerialPerspectiveLutLayers,numAerialPerspectiveLutLayers);float weight=min(layer,1.);float layerIdx=max(0.,layer-1.);float floorLayerIdx=floor(layerIdx);vec4 aerialPerspectiveLayer0=textureLod(aerialPerspectiveLut,vec3(screenUV,floorLayerIdx),0.);vec4 aerialPerspectiveLayer1=textureLod(aerialPerspectiveLut,vec3(screenUV,floorLayerIdx+1.),0.);aerialPerspective=mix(aerialPerspectiveLayer0,aerialPerspectiveLayer1,layerIdx-floorLayerIdx);aerialPerspective.rgb*=atmosphereExposure;aerialPerspective=applyAerialPerspectiveSaturation(aerialPerspective);aerialPerspective=weight*applyAerialPerspectiveIntensity(aerialPerspective);aerialPerspective=applyAerialPerspectiveRadianceBias(aerialPerspective);return true;}\n#endif\nreturn false;}\n#if RENDER_TRANSMITTANCE\nvoid getTransmittanceParameters(vec2 uv,out float radius,out float cosAngleLightToZenith,out float distanceToAtmosphereEdge) {vec2 unit=uvToUnit(uv,TransmittanceLutDomainInUVSpace,TransmittanceLutHalfTexelSize);float distanceToHorizon=unit.y*horizonDistanceToAtmosphereEdge;float distanceToHorizonSquared=distanceToHorizon*distanceToHorizon;radius=sqrtClamped(distanceToHorizonSquared+planetRadiusSquared);float minDistanceToAtmosphereEdge=atmosphereRadius-radius;float maxDistanceToAtmosphereEdge=distanceToHorizon+horizonDistanceToAtmosphereEdge;distanceToAtmosphereEdge=minDistanceToAtmosphereEdge+unit.x*(maxDistanceToAtmosphereEdge-minDistanceToAtmosphereEdge);float distanceToAtmosphereEdgeSquared=distanceToAtmosphereEdge*distanceToAtmosphereEdge;cosAngleLightToZenith =\ndistanceToAtmosphereEdge<=0. ?\n1. :\n(horizonDistanceToAtmosphereEdgeSquared-distanceToAtmosphereEdgeSquared-distanceToHorizonSquared)/(2.*radius*distanceToAtmosphereEdge);cosAngleLightToZenith=clamp(cosAngleLightToZenith,-1.,1.);}\nvec4 renderTransmittance(vec2 uv) {float radius,cosAngleLightToZenith,distanceToAtmosphereEdgeAlongAngle;getTransmittanceParameters(uv,radius,cosAngleLightToZenith,distanceToAtmosphereEdgeAlongAngle);float sinAngleLightToZenith=sqrtClamped(1.-cosAngleLightToZenith*cosAngleLightToZenith);vec3 directionToLight=normalize(vec3(0.,cosAngleLightToZenith,sinAngleLightToZenith));vec3 transmittance=computeTransmittance(vec3(0.,radius,0.),directionToLight,distanceToAtmosphereEdgeAlongAngle,TransmittanceSampleCount);return vec4(transmittance,avg(transmittance));}\n#endif\n#if RENDER_MULTI_SCATTERING\nvec3 getSphereSample(float azimuth,float inclination,out float sinInclination) {sinInclination=sin(inclination);return vec3(sinInclination*sin(azimuth),cos(inclination),sinInclination*cos(azimuth));}\nconst float MultiScatteringInclinationSampleCount=8.;const float MultiScatteringAzimuthSampleCount=2.*MultiScatteringInclinationSampleCount;const float MultiScatteringLutSampleCount=64.;const float MultiScatteringAzimuthIterationAngle=TWO_PI/MultiScatteringAzimuthSampleCount;const float MultiScatteringInclinationIterationAngle=PI/MultiScatteringInclinationSampleCount;const float MultiScatteringAngleStepProduct=MultiScatteringAzimuthIterationAngle*MultiScatteringInclinationIterationAngle;vec4 renderMultiScattering(vec2 uv,sampler2D transmittanceLut) {vec2 unit=uvToUnit(uv,MultiScatteringLutDomainInUVSpace,MultiScatteringLutHalfTexelSize);float cosAngleLightToZenith=2.*unit.x-1.;float sinAngleLightToZenith=sqrtClamped(1.-cosAngleLightToZenith*cosAngleLightToZenith);vec3 directionToLight=normalize(vec3(0.,cosAngleLightToZenith,sinAngleLightToZenith));float rayOriginRadius=planetRadius+max(unit.y,0.001)*atmosphereThickness;vec3 rayOrigin=vec3(0.,rayOriginRadius,0.);vec3 inscattered=vec3(0.);vec3 multiScatteringTotal=vec3(0.);for (float i=0.5; i<MultiScatteringAzimuthSampleCount; ++i) {float azimuth=MultiScatteringAzimuthIterationAngle*i;for (float j=0.5; j<MultiScatteringInclinationSampleCount; ++j) {float inclination=MultiScatteringInclinationIterationAngle*j;float sinInclination;vec3 rayDirection=getSphereSample(azimuth,inclination,sinInclination);vec3 radiance;vec3 transmittance;vec3 multiScattering;integrateScatteredRadiance(\nfalse,\n1.,\ntransmittanceLut,\nrayOrigin,\nrayDirection,\ndirectionToLight,\n100000000.,\nMultiScatteringLutSampleCount,\n-1.,\nradiance,\ntransmittance,\nmultiScattering);float weight=RECIPROCAL_PI4*abs(sinInclination)*MultiScatteringAngleStepProduct;multiScatteringTotal+=multiScattering*weight;inscattered+=radiance*weight;}}\nvec3 multiScattering=inscattered/max(vec3(0.000001),vec3(1.)-multiScatteringTotal);return vec4(multiScattering,1.);}\n#endif\nfloat computeCosHorizonAngleFromZenith(float radius) {float sinAngleBetweenHorizonAndNadir=min(1.,planetRadius/radius);float cosHorizonAngleFromNadir=sqrt(1.-sinAngleBetweenHorizonAndNadir*sinAngleBetweenHorizonAndNadir);float cosHorizonAngleFromZenith=-cosHorizonAngleFromNadir;return cosHorizonAngleFromZenith;}\n#if RENDER_SKY_VIEW\nvoid getSkyViewParametersFromUV(\nfloat radius,\nvec2 uv,\nout float cosAngleBetweenViewAndZenith,\nout float cosAngleBetweenViewAndLightOnPlane) {vec2 unit=uvToUnit(uv,SkyViewLutDomainInUVSpace,SkyViewLutHalfTexelSize);float cosHorizonAngleFromZenith=computeCosHorizonAngleFromZenith(radius);if (unit.y<0.5) {float coord=2.*unit.y; \ncoord*=coord; \ncosAngleBetweenViewAndZenith=mix(-1.,cosHorizonAngleFromZenith,coord); } else {float coord=2.*unit.y-1.; \ncoord*=coord; \ncosAngleBetweenViewAndZenith=mix(cosHorizonAngleFromZenith,1.,coord); }\n{float coord=unit.x;cosAngleBetweenViewAndLightOnPlane=1.-2.*coord;}}\nvec4 renderSkyView(vec2 uv,sampler2D transmittanceLut,sampler2D multiScatteringLut) {float cosAngleBetweenViewAndZenith;float cosAngleBetweenViewAndLightOnPlane;getSkyViewParametersFromUV(clampedCameraRadius,uv,cosAngleBetweenViewAndZenith,cosAngleBetweenViewAndLightOnPlane);float sinAngleBetweenViewAndZenith=sqrtClamped(1.-cosAngleBetweenViewAndZenith*cosAngleBetweenViewAndZenith);float sinAngleBetweenViewAndLightOnPlane=sqrtClamped(1.-cosAngleBetweenViewAndLightOnPlane*cosAngleBetweenViewAndLightOnPlane);vec3 rayDirection =\nvec3(\nsinAngleBetweenViewAndZenith*cosAngleBetweenViewAndLightOnPlane,\ncosAngleBetweenViewAndZenith,\nsinAngleBetweenViewAndZenith*sinAngleBetweenViewAndLightOnPlane);bool intersectsAtmosphere=false;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=vec3(0.);moveToTopAtmosphere(\nvec3(0.,clampedCameraRadius,0.),\nclampedCameraRadius,\nvec3(0.,1.,0.),\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {return vec4(0.);}\nvec3 transmittance;vec3 radiance;integrateScatteredRadiance(\nfalse,\natmosphereExposure*lightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLightRelativeToCameraGeocentricNormal,\n100000000.,\nSkyViewLutSampleCount,\n-1.,\nradiance,\ntransmittance);float transparency=1.-avg(transmittance);return vec4(radiance,transparency);}\n#endif\n#if RENDER_CAMERA_VOLUME\nvec4 renderCameraVolume(\nvec3 positionOnNearPlane,\nfloat layerIdx,\nsampler2D transmittanceLut,\nsampler2D multiScatteringLut) {vec4 result=vec4(0.);vec3 rayDirection=normalize(positionOnNearPlane);float layer=layerIdxToAerialPerspectiveLayer(layerIdx);float tMax=toAerialPerspectiveDepth(layer);float tMaxMax=tMax;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=clampedCameraPositionGlobal;if (clampedCameraRadius>=atmosphereRadius) {bool intersectsAtmosphere=false;moveToTopAtmosphere(\nclampedCameraPositionGlobal,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {return result;}\nfloat distanceToAtmosphere=distance(clampedCameraPositionGlobal,cameraPositionGlobalClampedToTopOfAtmosphere);if (tMaxMax<distanceToAtmosphere) {return result;}\ntMaxMax=max(0.,tMaxMax-distanceToAtmosphere);}\nfloat sampleCount=min(SkyViewLutSampleCount,2.*layer+2.);vec3 transmittance;vec3 radiance;integrateScatteredRadiance(\ntrue,\nlightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLight,\ntMaxMax,\nsampleCount,\n-1.,\nradiance,\ntransmittance);float transparency=1.-avg(transmittance);result=vec4(radiance,transparency);return result;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const atmosphereFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/depthFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\nimport \"core/Shaders/ShadersInclude/importanceSampling\";\nimport \"core/Shaders/ShadersInclude/pbrBRDFFunctions\";\nimport \"core/Shaders/ShadersInclude/hdrFilteringFunctions\";\n\nconst name = \"diffuseSkyIrradiancePixelShader\";\nconst shader = `precision highp float;const float DiffuseSkyIrradianceLutSampleCount=32.0;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<depthFunctions>\n#include<atmosphereFunctions>\nuniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;vec3 integrateForIrradiance(vec3 directionToLight,vec3 rayDirection,vec3 rayOrigin) {vec3 radiance;vec3 transmittance;integrateScatteredRadiance(\nfalse,\n1.,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\nrayOrigin,\nrayDirection.xzy,\ndirectionToLight.xzy,\n100000000.,\nDiffuseSkyIrradianceLutSampleCount,\n-1.,\nradiance,\ntransmittance);return radiance;}\n#include<importanceSampling>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\nvarying vec2 uv;void main() {vec2 unit=uvToUnit(uv,DiffuseSkyIrradianceLutDomainInUVSpace,DiffuseSkyIrradianceLutHalfTexelSize);float cosLightInclination=2.*unit.x-1.;float sinLightInclination=sqrtClamped(1.-cosLightInclination*cosLightInclination);vec3 directionToLight=normalize(vec3(0.,cosLightInclination,sinLightInclination));float radius=max(planetRadiusWithOffset,unit.y*atmosphereThickness+planetRadius);vec3 swappedDirectionToLight=vec3(directionToLight.x,directionToLight.z,directionToLight.y); \nvec3 irradiance =\nPI *\nirradiance(\nswappedDirectionToLight,\nvec2(radius,0.),\n1.,\nvec3(1.),\nvec3(1.));float averageIrradiance=getLuminance(irradiance);vec3 newIrradiance=mix(irradiance,vec3(averageIrradiance),diffuseSkyIrradianceDesaturationFactor);float newIrradianceScale=getLuminance(newIrradiance);float rescaling=averageIrradiance/max(0.000001,newIrradianceScale);irradiance=newIrradiance*rescaling;gl_FragColor=vec4(irradiance,1.);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const diffuseSkyIrradiancePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\n\nconst name = \"fullscreenTriangleVertexShader\";\nconst shader = `precision highp float;\n#include<__decl__atmosphereFragment>\n#if POSITION_VEC2\nattribute vec2 position;\n#else\nattribute vec3 position;\n#endif\nuniform float depth;varying vec2 uv;\n#if COMPUTE_WORLD_RAY\nvarying vec3 positionOnNearPlane;\n#endif\n#if COMPUTE_WORLD_RAY\nconst float nearPlaneNDC=-1.;\n#endif\nvoid main() {gl_Position=vec4(position.xy,depth,1.);uv=0.5*position.xy+vec2(0.5);\n#if COMPUTE_WORLD_RAY\npositionOnNearPlane=(inverseViewProjectionWithoutTranslation*vec4(position.xy,nearPlaneNDC,1.)).xyz;\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const fullscreenTriangleVertexShader = { name, shader };\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport { Clamp } from \"core/Maths/math.scalar.functions\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport { FromHalfFloat } from \"core/Misc/textureTools\";\r\nimport type { IColor3Like, IColor4Like, IVector2Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { Sample2DRgbaToRef } from \"./sampling\";\r\nimport \"./Shaders/diffuseSkyIrradiance.fragment\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\n\r\nconst RaySamples = 128;\r\nconst LutWidthPx = 64;\r\nconst LutHeightPx = 16;\r\nconst HalfTexelSize = { x: 0.5 / LutWidthPx, y: 0.5 / LutHeightPx };\r\nconst UnitToUVScale = { x: (LutWidthPx - 1.0) / LutWidthPx, y: (LutHeightPx - 1.0) / LutHeightPx };\r\nconst UvTemp = { x: Number.NaN, y: Number.NaN };\r\nconst Color4Temp = { r: Number.NaN, g: Number.NaN, b: Number.NaN, a: Number.NaN } as IColor4Like;\r\n\r\nconst ComputeLutUVToRef = (properties: AtmospherePhysicalProperties, radius: number, cosAngleLightToZenith: number, result: IVector2Like): void => {\r\n const unitX = Clamp(0.5 + 0.5 * cosAngleLightToZenith);\r\n const unitY = Clamp((radius - properties.planetRadius) / properties.atmosphereThickness);\r\n result.x = unitX * UnitToUVScale.x + HalfTexelSize.x;\r\n result.y = unitY * UnitToUVScale.y + HalfTexelSize.y;\r\n};\r\n\r\n/**\r\n * The diffuse sky irradiance LUT is used to query the diffuse irradiance at a specified position.\r\n */\r\nexport class DiffuseSkyIrradianceLut {\r\n private readonly _atmosphere: Atmosphere;\r\n private _renderTarget: Nullable<RenderTargetTexture> = null;\r\n private _effectWrapper: Nullable<EffectWrapper> = null;\r\n private _effectRenderer: Nullable<EffectRenderer> = null;\r\n private _isDirty = true;\r\n private _isDisposed = false;\r\n private _lutData: Uint8Array | Uint16Array = new Uint16Array(0);\r\n\r\n /**\r\n * True if the LUT needs to be rendered.\r\n */\r\n public get isDirty() {\r\n return this._isDirty;\r\n }\r\n\r\n /**\r\n * True if the LUT has been disposed.\r\n */\r\n public get isDisposed(): boolean {\r\n return this._isDisposed;\r\n }\r\n\r\n /**\r\n * The render target used for this LUT.\r\n * @throws if the LUT has been disposed.\r\n */\r\n public get renderTarget(): RenderTargetTexture {\r\n if (this._isDisposed || this._renderTarget === null) {\r\n throw new Error();\r\n }\r\n return this._renderTarget;\r\n }\r\n\r\n /**\r\n * True if the LUT data has been read back from the GPU.\r\n */\r\n public get hasLutData(): boolean {\r\n return this._lutData[0] !== undefined;\r\n }\r\n\r\n /**\r\n * Constructs the {@link DiffuseSkyIrradianceLut}.\r\n * @param atmosphere - The atmosphere to use.\r\n */\r\n constructor(atmosphere: Atmosphere) {\r\n this._atmosphere = atmosphere;\r\n const scene = atmosphere.scene;\r\n const engine = scene.getEngine();\r\n\r\n const name = \"atmo-diffuseSkyIrradiance\";\r\n const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {\r\n generateMipMaps: false,\r\n type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n gammaSpace: false,\r\n }));\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n\r\n const useUbo = atmosphere.uniformBuffer.useUbo;\r\n\r\n this._effectWrapper = new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"diffuseSkyIrradiance\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : atmosphere.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [atmosphere.uniformBuffer.name] : [],\r\n defines: [\r\n \"#define POSITION_VEC2\",\r\n `#define NUM_SAMPLES ${RaySamples}u`,\r\n \"#define CUSTOM_IRRADIANCE_FILTERING_INPUT /* empty */\", // empty, no input texture needed as the radiance is procedurally generated from ray marching.\r\n // The following ray marches the atmosphere to get the radiance.\r\n \"#define CUSTOM_IRRADIANCE_FILTERING_FUNCTION vec3 c = integrateForIrradiance(n, Ls, vec3(0., filteringInfo.x, 0.));\",\r\n ],\r\n samplers: [\"transmittanceLut\", \"multiScatteringLut\"],\r\n useShaderStore: true,\r\n });\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n\r\n // The sky irradiance will also be used for the environment texture.\r\n scene.environmentTexture = renderTarget;\r\n scene.environmentTexture.irradianceTexture = renderTarget;\r\n scene.environmentIntensity = 1.0;\r\n\r\n // Prevent the irradiance LUT from being rendered redundantly at the beginning of the frame.\r\n scene.environmentTexture.isRenderTarget = false;\r\n }\r\n\r\n /**\r\n * Gets the diffuse sky irradiance for a surface oriented along the geocentric normal.\r\n * Resulting color is always in linear space.\r\n * @param directionToLight - The direction to the light in world space.\r\n * @param radius - The position's distance to the planet origin.\r\n * @param cameraGeocentricNormal - The geocentric normal of the camera.\r\n * @param lightIrradiance - The irradiance of the light.\r\n * @param result - The color to store the result in.\r\n * @returns The result color.\r\n */\r\n public getDiffuseSkyIrradianceToRef<T extends IColor3Like>(\r\n directionToLight: IVector3Like,\r\n radius: number,\r\n cameraGeocentricNormal: IVector3Like,\r\n lightIrradiance: number,\r\n result: T\r\n ): T {\r\n const atmosphere = this._atmosphere;\r\n const additionalDiffuseSkyIrradiance = atmosphere.additionalDiffuseSkyIrradiance;\r\n\r\n const properties = atmosphere.physicalProperties;\r\n if (this._lutData[0] === undefined || radius > properties.atmosphereRadius) {\r\n result.r = additionalDiffuseSkyIrradiance.r;\r\n result.g = additionalDiffuseSkyIrradiance.g;\r\n result.b = additionalDiffuseSkyIrradiance.b;\r\n return result;\r\n }\r\n\r\n const cosAngleLightToZenith = directionToLight.x * cameraGeocentricNormal.x + directionToLight.y * cameraGeocentricNormal.y + directionToLight.z * cameraGeocentricNormal.z;\r\n ComputeLutUVToRef(properties, radius, cosAngleLightToZenith, UvTemp);\r\n Sample2DRgbaToRef(UvTemp.x, UvTemp.y, LutWidthPx, LutHeightPx, this._lutData, Color4Temp, FromHalfFloat);\r\n\r\n const intensity = atmosphere.diffuseSkyIrradianceIntensity;\r\n result.r = intensity * (lightIrradiance * Color4Temp.r + additionalDiffuseSkyIrradiance.r);\r\n result.g = intensity * (lightIrradiance * Color4Temp.g + additionalDiffuseSkyIrradiance.g);\r\n result.b = intensity * (lightIrradiance * Color4Temp.b + additionalDiffuseSkyIrradiance.b);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Renders the LUT.\r\n * @returns True if the LUT was rendered.\r\n */\r\n public render(): boolean {\r\n // Only need to render the LUT once.\r\n const effectWrapper = this._effectWrapper;\r\n if (!this._isDirty || !effectWrapper?.isReady() || !this._renderTarget?.isReady()) {\r\n return false;\r\n }\r\n\r\n const engine = this._atmosphere.scene.getEngine();\r\n\r\n engine.bindFramebuffer(this.renderTarget.renderTarget!, undefined, undefined, undefined, true);\r\n\r\n const effectRenderer = this._effectRenderer!;\r\n effectRenderer.applyEffectWrapper(effectWrapper);\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n\r\n const effect = effectWrapper.effect;\r\n effectRenderer.bindBuffers(effect);\r\n\r\n effect.setTexture(\"transmittanceLut\", this._atmosphere.transmittanceLut!.renderTarget);\r\n effect.setTexture(\"multiScatteringLut\", this._atmosphere.multiScatteringLutRenderTarget);\r\n\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n\r\n effect.setFloat(\"depth\", 0.0);\r\n\r\n effectRenderer.draw();\r\n\r\n effectRenderer.restoreStates();\r\n engine.restoreDefaultFramebuffer();\r\n\r\n this._isDirty = false;\r\n\r\n // eslint-disable-next-line github/no-then\r\n void this.renderTarget.readPixels(0, 0, undefined, undefined, true /* noDataConversion */)?.then((value: ArrayBufferView) => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._lutData = value as Uint8Array | Uint16Array;\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Marks the LUT as needing to be rendered.\r\n */\r\n public markDirty(): void {\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * Disposes the LUT.\r\n */\r\n public dispose() {\r\n if (this._renderTarget) {\r\n this._renderTarget.irradianceTexture = null;\r\n this._renderTarget.dispose();\r\n }\r\n this._renderTarget = null;\r\n this._effectWrapper?.dispose();\r\n this._effectWrapper = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._isDisposed = true;\r\n }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"transmittancePixelShader\";\nconst shader = `#define RENDER_TRANSMITTANCE 1\nprecision highp float;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;void main() {gl_FragColor=renderTransmittance(uv);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const transmittancePixelShader = { name, shader };\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport { Clamp, SmoothStep } from \"core/Maths/math.scalar.functions\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { DirectionalLight } from \"core/Lights/directionalLight\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport { FromHalfFloat } from \"core/Misc/textureTools\";\r\nimport type { IColor3Like, IColor4Like, IVector2Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { Sample2DRgbaToRef } from \"./sampling\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\nimport \"./Shaders/transmittance.fragment\";\r\n\r\nconst LutWidthPx = 256;\r\nconst LutHeightPx = 64;\r\nconst EffectiveDomainInUVSpace = { x: (LutWidthPx - 1.0) / LutWidthPx, y: (LutHeightPx - 1.0) / LutHeightPx };\r\nconst HalfTexelSize = { x: 0.5 / LutWidthPx, y: 0.5 / LutHeightPx };\r\nconst TransmittanceHorizonRange = 2.0 * HalfTexelSize.x;\r\nconst TransmittanceMaxUnoccludedU = 1.0 - 0.5 * TransmittanceHorizonRange;\r\n\r\nconst UseHalfFloat = false;\r\n\r\n// Temporary storage.\r\nconst Uv = { x: Number.NaN, y: Number.NaN } as IVector2Like;\r\nconst LightColorTemp = { r: Number.NaN, g: Number.NaN, b: Number.NaN } as IColor3Like;\r\nconst DirectionToLightTemp = { x: Number.NaN, y: Number.NaN, z: Number.NaN } as IVector3Like;\r\nconst Color4Temp = { r: Number.NaN, g: Number.NaN, b: Number.NaN, a: Number.NaN } as IColor4Like;\r\n\r\nconst ComputeLutUVToRef = (properties: AtmospherePhysicalProperties, radius: number, cosAngleLightToZenith: number, uv: IVector2Like): void => {\r\n const radiusSquared = radius * radius;\r\n const distanceToHorizon = Math.sqrt(Math.max(0.0, radiusSquared - properties.planetRadiusSquared));\r\n\r\n const cosAngleLightToZenithSq = cosAngleLightToZenith * cosAngleLightToZenith;\r\n const discriminant = radiusSquared * (cosAngleLightToZenithSq - 1.0) + properties.atmosphereRadiusSquared;\r\n const distanceToAtmosphereEdge = Math.max(0.0, -radius * cosAngleLightToZenith + Math.sqrt(Math.max(0.0, discriminant)));\r\n\r\n const minDistanceToAtmosphereEdge = Math.max(0.0, properties.atmosphereRadius - radius);\r\n const maxDistanceToAtmosphereEdge = distanceToHorizon + properties.horizonDistanceToAtmosphereEdge;\r\n const cosAngleLightToZenithCoordinate =\r\n (distanceToAtmosphereEdge - minDistanceToAtmosphereEdge) / Math.max(0.000001, maxDistanceToAtmosphereEdge - minDistanceToAtmosphereEdge);\r\n const distanceToHorizonCoordinate = distanceToHorizon / Math.max(0.000001, properties.horizonDistanceToAtmosphereEdge);\r\n\r\n // Unit to UV.\r\n uv.x = EffectiveDomainInUVSpace.x * cosAngleLightToZenithCoordinate + HalfTexelSize.x;\r\n uv.y = EffectiveDomainInUVSpace.y * distanceToHorizonCoordinate + HalfTexelSize.y;\r\n};\r\n\r\nconst SampleLutToRef = (\r\n properties: AtmospherePhysicalProperties,\r\n lutData: Uint8Array | Uint16Array,\r\n positionDistanceToOrigin: number,\r\n cosAngleLightToZenith: number,\r\n result: IColor4Like\r\n): void => {\r\n if (positionDistanceToOrigin > properties.atmosphereRadius) {\r\n result.r = result.g = result.b = result.a = 1.0;\r\n return;\r\n }\r\n\r\n ComputeLutUVToRef(properties, positionDistanceToOrigin, cosAngleLightToZenith, Uv);\r\n Sample2DRgbaToRef(Uv.x, Uv.y, LutWidthPx, LutHeightPx, lutData, result, UseHalfFloat ? FromHalfFloat : (value) => value / 255.0);\r\n\r\n const weight = Clamp(SmoothStep(1.0, 0.0, Clamp((Uv.x - TransmittanceMaxUnoccludedU) / TransmittanceHorizonRange)));\r\n result.r *= weight;\r\n result.g *= weight;\r\n result.b *= weight;\r\n result.a *= weight;\r\n};\r\n\r\n/**\r\n * The transmittance LUT can be used to get the radiance from an external light source arriving a given point, accounting for atmospheric scattering.\r\n */\r\nexport class TransmittanceLut {\r\n /**\r\n * Listen to this observer to know when the LUT data has been updated.\r\n * This is typically infrequent (once at startup), but also happens whenever the atmosphere's properties change.\r\n */\r\n public readonly onUpdatedObservable = new Observable<void>();\r\n\r\n private readonly _atmosphere: Atmosphere;\r\n private _lutData: Uint8Array | Uint16Array = new Uint8Array(0);\r\n private _renderTarget: Nullable<RenderTargetTexture>;\r\n private _effectWrapper: Nullable<EffectWrapper>;\r\n private _effectRenderer: Nullable<EffectRenderer>;\r\n private _isDirty = true;\r\n private _isDisposed = false;\r\n\r\n /**\r\n * True if the LUT has been rendered.\r\n */\r\n public get isDirty(): boolean {\r\n return this._isDirty;\r\n }\r\n\r\n /**\r\n * The render target that contains the transmittance LUT.\r\n * @throws if the LUT has been disposed.\r\n */\r\n public get renderTarget(): RenderTargetTexture {\r\n if (this._isDisposed || this._renderTarget === null) {\r\n throw new Error();\r\n }\r\n return this._renderTarget;\r\n }\r\n\r\n /**\r\n * Constructs the {@link TransmittanceLut}.\r\n * @param atmosphere - The atmosphere that owns this LUT.\r\n */\r\n constructor(atmosphere: Atmosphere) {\r\n this._atmosphere = atmosphere;\r\n\r\n const scene = this._atmosphere.scene;\r\n const engine = scene.getEngine();\r\n\r\n const name = \"atmo-transmittance\";\r\n const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {\r\n type: UseHalfFloat ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n gammaSpace: false,\r\n }));\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n\r\n const useUbo = this._atmosphere.uniformBuffer.useUbo;\r\n this._effectWrapper = new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"transmittance\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : this._atmosphere.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [this._atmosphere.uniformBuffer.name] : [],\r\n defines: [\"#define POSITION_VEC2\"],\r\n useShaderStore: true,\r\n });\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n }\r\n\r\n /**\r\n * Gets the transmittance of an external light through the atmosphere to a point specified by its distance to the planet center and its geocentric normal.\r\n * The result is always a linear space color.\r\n * @param directionToLight - The direction to the light source.\r\n * @param pointRadius - The distance from the origin to the point.\r\n * @param pointGeocentricNormal - The normal of the point.\r\n * @param result - The color to write the result to.\r\n * @returns The result color.\r\n */\r\n public getTransmittedColorToRef<T extends IColor3Like>(directionToLight: IVector3Like, pointRadius: number, pointGeocentricNormal: IVector3Like, result: T): T {\r\n if (this._lutData[0] !== undefined) {\r\n const cosAngleLightToZenith =\r\n directionToLight.x * pointGeocentricNormal.x + directionToLight.y * pointGeocentricNormal.y + directionToLight.z * pointGeocentricNormal.z;\r\n SampleLutToRef(this._atmosphere.physicalProperties, this._lutData, pointRadius, cosAngleLightToZenith, Color4Temp);\r\n result.r = Color4Temp.r;\r\n result.g = Color4Temp.g;\r\n result.b = Color4Temp.b;\r\n } else {\r\n // Fallback.\r\n result.r = result.g = result.b = 1.0;\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Derives light color from the transmittance at a point specified by its distance to the planet center and its geocentric normal.\r\n * @param light - The light to update.\r\n * @param pointRadius - The distance from the origin to the point.\r\n * @param pointGeocentricNormal - The normal of the point.\r\n */\r\n public updateLightParameters(light: DirectionalLight, pointRadius: number, pointGeocentricNormal: IVector3Like): void {\r\n const lightDirection = light.direction;\r\n DirectionToLightTemp.x = -lightDirection.x;\r\n DirectionToLightTemp.y = -lightDirection.y;\r\n DirectionToLightTemp.z = -lightDirection.z;\r\n this.getTransmittedColorToRef(DirectionToLightTemp, pointRadius, pointGeocentricNormal, LightColorTemp);\r\n\r\n light.diffuse.copyFromFloats(LightColorTemp.r, LightColorTemp.g, LightColorTemp.b);\r\n light.specular.copyFromFloats(LightColorTemp.r, LightColorTemp.g, LightColorTemp.b);\r\n }\r\n\r\n /**\r\n * Renders the LUT if needed.\r\n * @returns true if the LUT was rendered.\r\n */\r\n public render(): boolean {\r\n // Only need to render the LUT once.\r\n const effectWrapper = this._effectWrapper;\r\n if (!this._isDirty || !effectWrapper?.isReady() || !this._renderTarget?.isReady()) {\r\n return false;\r\n }\r\n\r\n const engine = this._atmosphere.scene.getEngine();\r\n\r\n engine.bindFramebuffer(this.renderTarget.renderTarget!, undefined, undefined, undefined, true);\r\n\r\n const effectRenderer = this._effectRenderer!;\r\n effectRenderer.applyEffectWrapper(effectWrapper);\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n\r\n const effect = effectWrapper.effect;\r\n effectRenderer.bindBuffers(effect);\r\n\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n\r\n effect.setFloat(\"depth\", 0);\r\n\r\n effectRenderer.draw();\r\n\r\n effectRenderer.restoreStates();\r\n engine.restoreDefaultFramebuffer();\r\n\r\n this._isDirty = false;\r\n\r\n // eslint-disable-next-line github/no-then\r\n void this.renderTarget.readPixels(0, 0, undefined, undefined, UseHalfFloat /* noDataConversion */)?.then((value: ArrayBufferView) => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._lutData = value as Uint8Array | Uint16Array;\r\n this.onUpdatedObservable.notifyObservers();\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Marks the LUT as needing to be rendered.\r\n */\r\n public markDirty(): void {\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * Disposes the LUT and its resources.\r\n */\r\n public dispose(): void {\r\n this._renderTarget?.dispose();\r\n this._renderTarget = null;\r\n this._effectWrapper?.dispose();\r\n this._effectWrapper = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._isDisposed = true;\r\n }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/depthFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"compositeAerialPerspectivePixelShader\";\nconst shader = `precision highp float;precision highp sampler2D;precision highp sampler2DArray;\n#include<__decl__atmosphereFragment>\n#if USE_AERIAL_PERSPECTIVE_LUT\nuniform sampler2DArray aerialPerspectiveLut;\n#endif\n#include<helperFunctions>\n#include<depthFunctions>\n#include<atmosphereFunctions>\nuniform sampler2D depthTexture;uniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;varying vec2 uv;varying vec3 positionOnNearPlane;void main() {gl_FragColor=vec4(0.);float depth=textureLod(depthTexture,uv,0.).r;if (depth>=1.) {discard;}\nvec3 rayDirection=normalize(positionOnNearPlane);float distanceFromCamera =\nreconstructDistanceFromCamera(\ndepth,\nrayDirection,\ncameraForward,\ncameraNearPlane);float distanceToSurface=distanceFromCamera/1000.;vec4 aerialPerspective=vec4(0.);if (sampleAerialPerspectiveLut(\nuv,\nfalse,\ndistanceToSurface,\nNumAerialPerspectiveLutLayers,\nAerialPerspectiveLutKMPerSlice,\nAerialPerspectiveLutRangeKM,\naerialPerspective)) {\n#ifndef APPLY_TRANSMITTANCE_BLENDING\naerialPerspective.a=0.;\n#endif\ngl_FragColor=aerialPerspective;} else {bool intersectsAtmosphere=false;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=vec3(0.);moveToTopAtmosphere(\nclampedCameraPositionGlobal,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {gl_FragColor=vec4(0.);return;}\nvec3 transmittance;vec3 radiance;bool isAerialPerspectiveLut=clampedCameraRadius<atmosphereRadius;integrateScatteredRadiance(\nisAerialPerspectiveLut,\natmosphereExposure*lightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLight,\n100000000.,\nSkyViewLutSampleCount,\ndistanceToSurface,\nradiance,\ntransmittance);float transparency=1.-avg(transmittance);gl_FragColor =\napplyAerialPerspectiveRadianceBias(\napplyAerialPerspectiveIntensity(\napplyAerialPerspectiveSaturation(vec4(radiance,transparency))));\n#ifndef APPLY_TRANSMITTANCE_BLENDING\ngl_FragColor.a=0.;\n#endif\n}\n#if OUTPUT_TO_SRGB\ngl_FragColor=toGammaSpace(gl_FragColor);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const compositeAerialPerspectivePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/depthFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"compositeSkyPixelShader\";\nconst shader = `precision highp float;precision highp sampler2D;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<depthFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;varying vec3 positionOnNearPlane;\n#if USE_SKY_VIEW_LUT\nuniform sampler2D skyViewLut;\n#else\nuniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;\n#endif\nvoid main() {gl_FragColor=vec4(0.);vec3 rayDirection=normalize(positionOnNearPlane);\n#if USE_SKY_VIEW_LUT\nfloat cosAngleBetweenViewAndZenith;bool isRayIntersectingGround;vec4 skyColor =\nsampleSkyViewLut(\nskyViewLut,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\ndirectionToLight,\ncosCameraHorizonAngleFromZenith,\ncosAngleBetweenViewAndZenith,\nisRayIntersectingGround);\n#ifndef APPLY_TRANSMITTANCE_BLENDING\nskyColor.a=0.;\n#endif\ngl_FragColor=skyColor;gl_FragColor.a=isRayIntersectingGround ? 1. : gl_FragColor.a;\n#else\nbool intersectsAtmosphere=false;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=vec3(0.);moveToTopAtmosphere(\nclampedCameraPositionGlobal,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {return;}\nvec3 transmittance;vec3 radiance;integrateScatteredRadiance(\nfalse,\natmosphereExposure*lightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLight,\n100000000.,\nSkyViewLutSampleCount,\n-1.,\nradiance,\ntransmittance);\n#if APPLY_TRANSMITTANCE_BLENDING\nfloat transparency=1.-avg(transmittance);\n#else\nfloat transparency=0.;\n#endif\ngl_FragColor=vec4(radiance,transparency);\n#endif\n#if OUTPUT_TO_SRGB\ngl_FragColor=toGammaSpace(gl_FragColor);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const compositeSkyPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/depthFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"compositeGlobeAtmospherePixelShader\";\nconst shader = `precision highp float;precision highp sampler2D;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<depthFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;varying vec3 positionOnNearPlane;\n#if HAS_DEPTH_TEXTURE\nuniform sampler2D depthTexture;\n#endif\n#if USE_SKY_VIEW_LUT\nuniform sampler2D skyViewLut;\n#else\nuniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;\n#endif\nvoid main() {gl_FragColor=vec4(0.);\n#if HAS_DEPTH_TEXTURE\nfloat depth=textureLod(depthTexture,uv,0.).r;\n#endif\nvec3 rayDirection=normalize(positionOnNearPlane);\n#if USE_SKY_VIEW_LUT\nfloat cosAngleBetweenViewAndZenith;bool isRayIntersectingGround;vec4 skyColor =\nsampleSkyViewLut(\nskyViewLut,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\ndirectionToLight,\ncosCameraHorizonAngleFromZenith,\ncosAngleBetweenViewAndZenith,\nisRayIntersectingGround);gl_FragColor=skyColor;if (isRayIntersectingGround) {gl_FragColor =\napplyAerialPerspectiveRadianceBias(\napplyAerialPerspectiveIntensity(\napplyAerialPerspectiveSaturation(gl_FragColor)));\n#if HAS_DEPTH_TEXTURE\ngl_FragColor.a=depth>=1. ? 1. : gl_FragColor.a;\n#endif\n}\n#else\nbool intersectsAtmosphere=false;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=vec3(0.);moveToTopAtmosphere(\nclampedCameraPositionGlobal,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {return;}\n#if HAS_DEPTH_TEXTURE\nfloat distanceFromCamera =\nreconstructDistanceFromCamera(\ndepth,\nrayDirection,\ncameraForward,\ncameraNearPlane);float distanceToSurface=distanceFromCamera/1000.;\n#else\nfloat distanceToSurface=0.;\n#endif\nvec3 transmittance;vec3 radiance;integrateScatteredRadiance(\nfalse,\natmosphereExposure*lightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLight,\n100000000.,\nSkyViewLutSampleCount,\ndistanceToSurface,\nradiance,\ntransmittance);float transparency=1.-avg(transmittance);gl_FragColor=vec4(radiance,transparency);if (distanceToSurface>0.) {gl_FragColor =\napplyAerialPerspectiveRadianceBias(\napplyAerialPerspectiveIntensity(\napplyAerialPerspectiveSaturation(gl_FragColor)));\n#if HAS_DEPTH_TEXTURE\ngl_FragColor.a=depth>=1. ? 1. : gl_FragColor.a;\n#endif\n}\n#endif\n#if OUTPUT_TO_SRGB\ngl_FragColor=toGammaSpace(gl_FragColor);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const compositeGlobeAtmospherePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"multiScatteringPixelShader\";\nconst shader = `#define RENDER_MULTI_SCATTERING 1\nprecision highp float;\n#define COMPUTE_MULTI_SCATTERING 1\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;uniform sampler2D transmittanceLut;void main() {gl_FragColor=renderMultiScattering(uv,transmittanceLut);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const multiScatteringPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"skyViewPixelShader\";\nconst shader = `#define RENDER_SKY_VIEW 1\nprecision highp float;precision highp sampler2D;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;uniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;void main() {gl_FragColor=renderSkyView(uv,transmittanceLut,multiScatteringLut);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const skyViewPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"aerialPerspectivePixelShader\";\nconst shader = `#define RENDER_CAMERA_VOLUME 1\nprecision highp float;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<atmosphereFunctions>\nvarying vec3 positionOnNearPlane;uniform float layerIdx;uniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;void main() {gl_FragColor=renderCameraVolume(\npositionOnNearPlane,\nlayerIdx,\ntransmittanceLut,\nmultiScatteringLut\n);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const aerialPerspectivePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"atmosphereVertexDeclaration\";\nconst shader = `uniform mat4 inverseViewProjectionWithoutTranslation;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const atmosphereVertexDeclaration = { name, shader };\n","import type { IDisposable, Scene } from \"core/scene\";\r\nimport type { BMFontChar } from \"./sdf/bmFont\";\r\nimport type { SdfFont } from \"./sdf/font\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\n\r\nenum CharCode {\r\n SPACE = 32,\r\n TOFU = 0xfffc,\r\n}\r\n\r\n/**\r\n * Class representing a font asset for SDF (Signed Distance Field) rendering.\r\n */\r\nexport class FontAsset implements IDisposable {\r\n private readonly _chars = new Map<number, BMFontChar>();\r\n private readonly _charsRegex: RegExp;\r\n private readonly _kernings = new Map<number, Map<number, number>>();\r\n\r\n /** @internal */\r\n public readonly _font: SdfFont;\r\n\r\n /**\r\n * Gets the font scale value\r\n */\r\n public readonly scale: number;\r\n\r\n /**\r\n * Gets the list of used textures\r\n */\r\n public readonly textures: Texture[];\r\n\r\n /**\r\n * Creates a new FontAsset instance.\r\n * @param definitionData defines the font data in JSON format.\r\n * @param textureUrl defines the url of the texture to use for the font.\r\n * @param scene defines the hosting scene.\r\n */\r\n public constructor(definitionData: string, textureUrl: string, scene?: Scene) {\r\n this._font = JSON.parse(definitionData) as SdfFont;\r\n // So far we only consider one page\r\n this._font.pages = [textureUrl];\r\n\r\n this._font.chars.forEach((char) => this._chars.set(char.id, char));\r\n this._font.kernings.forEach((kerning) => {\r\n let submap = this._kernings.get(kerning.first);\r\n if (!submap) {\r\n submap = new Map();\r\n this._kernings.set(kerning.first, submap);\r\n }\r\n submap.set(kerning.second, kerning.amount);\r\n });\r\n this._charsRegex = new RegExp(`[${this._font.chars.map((c) => c.char.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\")).join(\"\")}]`, \"g\");\r\n\r\n this._updateFallbacks();\r\n\r\n this.scale = 1 / this._font.info.size;\r\n this.textures = this._font.pages.map((page) => {\r\n const texture = new Texture(page, scene, { noMipmap: false, invertY: false });\r\n texture.anisotropicFilteringLevel = 16;\r\n return texture;\r\n });\r\n }\r\n\r\n dispose(): void {\r\n for (const texture of this.textures) {\r\n texture.dispose();\r\n }\r\n this.textures.length = 0;\r\n }\r\n\r\n private _updateFallbacks() {\r\n if (!this._chars.has(CharCode.SPACE)) {\r\n this._chars.set(CharCode.SPACE, {\r\n id: CharCode.SPACE,\r\n x: 0,\r\n y: 0,\r\n width: 0,\r\n height: 0,\r\n xoffset: 0,\r\n yoffset: 0,\r\n xadvance: this._font.info.size * 0.5,\r\n page: -1,\r\n chnl: -1,\r\n index: -1,\r\n char: \" \",\r\n });\r\n }\r\n\r\n if (!this._chars.has(CharCode.TOFU)) {\r\n this._chars.set(CharCode.TOFU, {\r\n id: CharCode.TOFU,\r\n x: 0,\r\n y: 0,\r\n width: this._font.info.size,\r\n height: this._font.info.size,\r\n xoffset: 0,\r\n yoffset: 0,\r\n xadvance: this._font.info.size * 0.5,\r\n page: -1,\r\n chnl: -1,\r\n index: -1,\r\n char: \"￿\",\r\n });\r\n }\r\n }\r\n\r\n /** @internal */\r\n public _getChar(charCode: number) {\r\n return this._chars.get(charCode) || this._chars.get(CharCode.TOFU)!;\r\n }\r\n\r\n /** @internal */\r\n public _getKerning(first: number, second: number) {\r\n return this._kernings.get(first)?.get(second) || 0;\r\n }\r\n\r\n /** @internal */\r\n public _unsupportedChars(text: string) {\r\n return text.replace(this._charsRegex, \"\");\r\n }\r\n}\r\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { AtmospherePBRMaterialPlugin } from \"./atmospherePBRMaterialPlugin\";\r\nimport { AtmospherePerCameraVariables } from \"./atmospherePerCameraVariables\";\r\nimport { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Camera } from \"core/Cameras/camera\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { DeepImmutable, Nullable } from \"core/types\";\r\nimport { DiffuseSkyIrradianceLut } from \"./diffuseSkyIrradianceLut\";\r\nimport type { DirectionalLight } from \"core/Lights/directionalLight\";\r\nimport type { Effect } from \"core/Materials/effect\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport type { IAtmosphereOptions } from \"./atmosphereOptions\";\r\nimport type { IColor3Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { IDisposable, Scene } from \"core/scene\";\r\nimport { Observable, type Observer } from \"core/Misc/observable\";\r\nimport { RegisterMaterialPlugin, UnregisterMaterialPlugin } from \"core/Materials/materialPluginManager\";\r\nimport type { RenderingGroupInfo } from \"core/Rendering/renderingManager\";\r\nimport { RenderTargetTexture, type RenderTargetTextureOptions } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport type { RenderTargetWrapper } from \"core/Engines/renderTargetWrapper\";\r\nimport { TransmittanceLut } from \"./transmittanceLut\";\r\nimport { UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { Vector3 } from \"core/Maths/math.vector\";\r\nimport \"./Shaders/compositeAerialPerspective.fragment\";\r\nimport \"./Shaders/compositeSky.fragment\";\r\nimport \"./Shaders/compositeGlobeAtmosphere.fragment\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\nimport \"./Shaders/multiScattering.fragment\";\r\nimport \"./Shaders/skyView.fragment\";\r\nimport \"./Shaders/aerialPerspective.fragment\";\r\nimport \"./Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\r\nimport \"./Shaders/ShadersInclude/atmosphereFunctions\";\r\nimport \"./Shaders/ShadersInclude/atmosphereUboDeclaration\";\r\nimport \"./Shaders/ShadersInclude/atmosphereVertexDeclaration\";\r\nimport \"./Shaders/ShadersInclude/depthFunctions\";\r\n\r\nconst MaterialPlugin = \"atmo-pbr\";\r\n\r\n/**\r\n * Renders a physically based atmosphere.\r\n * Use {@link IsSupported} to check if the atmosphere is supported before creating an instance.\r\n * @experimental\r\n */\r\nexport class Atmosphere implements IDisposable {\r\n private readonly _directionToLight = Vector3.Zero();\r\n private readonly _tempSceneAmbient = new Color3();\r\n private readonly _engine: AbstractEngine;\r\n private _physicalProperties: AtmospherePhysicalProperties;\r\n private _transmittanceLut: Nullable<TransmittanceLut>;\r\n private _diffuseSkyIrradianceLut: Nullable<DiffuseSkyIrradianceLut>;\r\n private _isSkyViewLutEnabled: boolean;\r\n private _isAerialPerspectiveLutEnabled: boolean;\r\n private _aerialPerspectiveTransmittanceScale: number;\r\n private _aerialPerspectiveSaturation: number;\r\n private _aerialPerspectiveIntensity: number;\r\n private _aerialPerspectiveRadianceBias: number;\r\n private _diffuseSkyIrradianceDesaturationFactor: number;\r\n private _additionalDiffuseSkyIrradianceIntensity: number;\r\n private _additionalDiffuseSkyIrradianceColor: Color3;\r\n private _additionalDiffuseSkyIrradiance = new Color3();\r\n private _diffuseSkyIrradianceIntensity: number;\r\n private _multiScatteringIntensity: number;\r\n private _groundAlbedo: Color3;\r\n private _minimumMultiScatteringColor: Color3;\r\n private _minimumMultiScatteringIntensity: number;\r\n private _lights: DirectionalLight[];\r\n private _atmosphereUbo: Nullable<UniformBuffer> = null;\r\n private _minimumMultiScattering = new Vector3();\r\n private _cameraAtmosphereVariables = new AtmospherePerCameraVariables();\r\n private _isLinearSpaceComposition: boolean;\r\n private _isLinearSpaceLight: boolean;\r\n private _lightRadianceAtCamera = new Vector3();\r\n private _linearLightColor = new Color3();\r\n private _originHeight: number;\r\n private _applyApproximateTransmittance: boolean;\r\n private _exposure: number;\r\n private _atmosphereUniformBufferAsArray: UniformBuffer[] = [];\r\n private _effectRenderer: Nullable<EffectRenderer> = null;\r\n private _skyRenderingGroup: number;\r\n private _aerialPerspectiveRenderingGroup: number;\r\n private _globeAtmosphereRenderingGroup: number;\r\n private _isEnabled = true;\r\n\r\n private _hasRenderedMultiScatteringLut = false;\r\n private _multiScatteringEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _multiScatteringLutRenderTarget: Nullable<RenderTargetTexture> = null;\r\n\r\n private _aerialPerspectiveLutEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _aerialPerspectiveLutEffectRenderer: Nullable<EffectRenderer> = null;\r\n private _aerialPerspectiveLutRenderTarget: Nullable<RenderTargetTexture> = null;\r\n\r\n private _skyViewLutEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _skyViewLutEffectRenderer: Nullable<EffectRenderer> = null;\r\n private _skyViewLutRenderTarget: Nullable<RenderTargetTexture> = null;\r\n\r\n private _aerialPerspectiveCompositorEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _skyCompositorEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _globeAtmosphereCompositorEffectWrapper: Nullable<EffectWrapper> = null;\r\n\r\n private _onBeforeCameraRenderObserver: Nullable<Observer<Camera>> = null;\r\n private _onBeforeDrawPhaseObserver: Nullable<Observer<Scene>> = null;\r\n private _onAfterRenderingGroupObserver: Nullable<Observer<RenderingGroupInfo>> = null;\r\n\r\n /**\r\n * Checks if the {@link Atmosphere} is supported.\r\n * @param engine - The engine to check.\r\n * @returns True if the atmosphere is supported, false otherwise.\r\n */\r\n public static IsSupported(engine: AbstractEngine): boolean {\r\n return !engine._badOS && !engine.isWebGPU && engine.version >= 2;\r\n }\r\n\r\n /**\r\n * Called after the atmosphere variables have been updated for the specified camera.\r\n */\r\n public readonly onAfterUpdateVariablesForCameraObservable = new Observable<Camera>();\r\n\r\n /**\r\n * Called immediately before the light variables are finalized.\r\n */\r\n public readonly onBeforeLightVariablesUpdateObservable = new Observable<void>();\r\n\r\n /**\r\n * Called before the LUTs are rendered for this camera. This happens after the per-camera UBO update.\r\n */\r\n public readonly onBeforeRenderLutsForCameraObservable = new Observable<void>();\r\n\r\n /**\r\n * Called after the LUTs were rendered.\r\n */\r\n public readonly onAfterRenderLutsForCameraObservable = new Observable<void>();\r\n\r\n /**\r\n * If provided, this is the depth texture used for composition passes.\r\n * Expects an infinite far plane on the camera (camera.maxZ = 0) and the non-linear depth accessible in red channel.\r\n * @internal\r\n */\r\n public readonly depthTexture: Nullable<BaseTexture> = null;\r\n\r\n /**\r\n * Controls the overall brightness of the atmosphere rendering.\r\n */\r\n public get exposure(): number {\r\n return this._exposure;\r\n }\r\n\r\n public set exposure(value: number) {\r\n this._exposure = Math.max(0, value);\r\n }\r\n\r\n /**\r\n * Affects the overall intensity of the multiple scattering.\r\n */\r\n public get multiScatteringIntensity(): number {\r\n return this._multiScatteringIntensity;\r\n }\r\n\r\n public set multiScatteringIntensity(value: number) {\r\n const newValue = Math.max(0.0, value);\r\n if (newValue !== this._multiScatteringIntensity) {\r\n this._multiScatteringIntensity = value;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n }\r\n\r\n /**\r\n * Affects the multiply scattered light contribution in the atmosphere by describing the average light color reflected off the ground.\r\n */\r\n public get groundAlbedo(): DeepImmutable<IColor3Like> {\r\n return this._groundAlbedo;\r\n }\r\n\r\n public set groundAlbedo(value: DeepImmutable<IColor3Like>) {\r\n if (!this._groundAlbedo.equals(value)) {\r\n this._groundAlbedo.copyFrom(value);\r\n this._multiScatteringEffectWrapper?.dispose();\r\n this._multiScatteringEffectWrapper = null;\r\n this._hasRenderedMultiScatteringLut = false;\r\n }\r\n }\r\n\r\n /**\r\n * Can be used to clamp the multiple scattering to a minimum value.\r\n */\r\n public get minimumMultiScatteringColor(): DeepImmutable<IColor3Like> {\r\n return this._minimumMultiScatteringColor;\r\n }\r\n\r\n public set minimumMultiScatteringColor(value: DeepImmutable<IColor3Like>) {\r\n if (!this._minimumMultiScatteringColor.equals(value)) {\r\n const minimumScatteringColor = this._minimumMultiScatteringColor.copyFrom(value);\r\n this._minimumMultiScattering.x = minimumScatteringColor.r * this._minimumMultiScatteringIntensity;\r\n this._minimumMultiScattering.y = minimumScatteringColor.g * this._minimumMultiScatteringIntensity;\r\n this._minimumMultiScattering.z = minimumScatteringColor.b * this._minimumMultiScatteringIntensity;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n }\r\n\r\n /**\r\n * This is an additional scaling factor applied to the {@link minimumMultiScatteringColor}.\r\n */\r\n public get minimumMultiScatteringIntensity(): number {\r\n return this._minimumMultiScatteringIntensity;\r\n }\r\n\r\n public set minimumMultiScatteringIntensity(value: number) {\r\n const newValue = Math.max(0.0, value);\r\n if (newValue !== this._minimumMultiScatteringIntensity) {\r\n this._minimumMultiScatteringIntensity = value;\r\n this._minimumMultiScattering.x = this._minimumMultiScatteringColor.r * value;\r\n this._minimumMultiScattering.y = this._minimumMultiScatteringColor.g * value;\r\n this._minimumMultiScattering.z = this._minimumMultiScatteringColor.b * value;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n }\r\n\r\n /**\r\n * Can be used to force the diffuse irradiance towards a gray color.\r\n */\r\n public get diffuseSkyIrradianceDesaturationFactor(): number {\r\n return this._diffuseSkyIrradianceDesaturationFactor;\r\n }\r\n\r\n public set diffuseSkyIrradianceDesaturationFactor(value: number) {\r\n const newValue = Math.max(value, 0.0);\r\n if (newValue !== this._diffuseSkyIrradianceDesaturationFactor) {\r\n this._diffuseSkyIrradianceDesaturationFactor = newValue;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n }\r\n\r\n /**\r\n * This is an additional amount of irradiance added to the diffuse irradiance.\r\n */\r\n public get additionalDiffuseSkyIrradianceIntensity(): number {\r\n return this._additionalDiffuseSkyIrradianceIntensity;\r\n }\r\n\r\n public set additionalDiffuseSkyIrradianceIntensity(value: number) {\r\n value = Math.max(0.0, value);\r\n if (value !== this._additionalDiffuseSkyIrradianceIntensity) {\r\n this._additionalDiffuseSkyIrradianceIntensity = value;\r\n this._additionalDiffuseSkyIrradianceColor.scaleToRef(value, this._additionalDiffuseSkyIrradiance);\r\n }\r\n }\r\n\r\n /**\r\n * This is the color for the additional amount of irradiance added to the diffuse irradiance.\r\n */\r\n public get additionalDiffuseSkyIrradianceColor(): DeepImmutable<IColor3Like> {\r\n return this._additionalDiffuseSkyIrradianceColor;\r\n }\r\n\r\n public set additionalDiffuseSkyIrradianceColor(value: DeepImmutable<IColor3Like>) {\r\n if (!this._additionalDiffuseSkyIrradianceColor.equals(value)) {\r\n this._additionalDiffuseSkyIrradianceColor.copyFrom(value).scaleToRef(this._additionalDiffuseSkyIrradianceIntensity, this._additionalDiffuseSkyIrradiance);\r\n }\r\n }\r\n\r\n /**\r\n * The final additional diffuse irradiance, taking into account the intensity and color.\r\n */\r\n public get additionalDiffuseSkyIrradiance(): DeepImmutable<IColor3Like> {\r\n return this._additionalDiffuseSkyIrradiance;\r\n }\r\n\r\n /**\r\n * The intensity of the diffuse irradiance.\r\n */\r\n public get diffuseSkyIrradianceIntensity(): number {\r\n return this._diffuseSkyIrradianceIntensity;\r\n }\r\n\r\n public set diffuseSkyIrradianceIntensity(value: number) {\r\n this._diffuseSkyIrradianceIntensity = Math.max(value, 0.0);\r\n }\r\n\r\n /**\r\n * True if the sky view LUT should be used for compositing the sky instead of a per-pixel ray march.\r\n */\r\n public get isSkyViewLutEnabled(): boolean {\r\n return this._isSkyViewLutEnabled;\r\n }\r\n\r\n public set isSkyViewLutEnabled(value: boolean) {\r\n this._isSkyViewLutEnabled = value;\r\n this._disposeSkyCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n\r\n /**\r\n * Gets the sky view LUT render target or null if not enabled.\r\n * @returns The render target.\r\n */\r\n public get skyViewLutRenderTarget(): Nullable<RenderTargetTexture> {\r\n if (!this._isSkyViewLutEnabled) {\r\n return null;\r\n }\r\n\r\n if (this._skyViewLutRenderTarget !== null) {\r\n return this._skyViewLutRenderTarget;\r\n }\r\n\r\n const renderTarget = (this._skyViewLutRenderTarget = CreateRenderTargetTexture(\"atmo-skyView\", { width: 128, height: 128 }, this.scene));\r\n renderTarget.coordinatesMode = Constants.TEXTURE_EQUIRECTANGULAR_MODE;\r\n\r\n this._skyViewLutEffectWrapper = CreateSkyViewEffectWrapper(this._engine, this.uniformBuffer);\r\n\r\n return renderTarget;\r\n }\r\n /**\r\n * True if the aerial perspective LUT should be used.\r\n * If false, full ray marching would be used instead.\r\n */\r\n public get isAerialPerspectiveLutEnabled(): boolean {\r\n return this._isAerialPerspectiveLutEnabled;\r\n }\r\n\r\n public set isAerialPerspectiveLutEnabled(value: boolean) {\r\n this._isAerialPerspectiveLutEnabled = value;\r\n this._disposeAerialPerspectiveCompositor();\r\n }\r\n\r\n /**\r\n * Gets the aerial perspective LUT render target or null if not enabled.\r\n * @returns The render target.\r\n */\r\n public get aerialPerspectiveLutRenderTarget(): Nullable<RenderTargetTexture> {\r\n if (!this._isAerialPerspectiveLutEnabled) {\r\n return null;\r\n }\r\n\r\n if (this._aerialPerspectiveLutRenderTarget !== null) {\r\n return this._aerialPerspectiveLutRenderTarget;\r\n }\r\n\r\n const scene = this.scene;\r\n const name = \"atmo-aerialPerspective\";\r\n const renderTarget = (this._aerialPerspectiveLutRenderTarget = CreateRenderTargetTexture(name, { width: 16, height: 64, layers: 32 }, scene, {}));\r\n this._aerialPerspectiveLutEffectWrapper = CreateAerialPerspectiveEffectWrapper(this._engine, this.uniformBuffer);\r\n\r\n return renderTarget;\r\n }\r\n\r\n /**\r\n * The intensity of the aerial perspective.\r\n */\r\n public get aerialPerspectiveIntensity(): number {\r\n return this._aerialPerspectiveIntensity;\r\n }\r\n\r\n public set aerialPerspectiveIntensity(value: number) {\r\n value = Math.max(0.001, value);\r\n if (value !== this._aerialPerspectiveIntensity) {\r\n // Define only needs to change if the value is changing between 1 and not 1.\r\n const hasDefineChanged = (value === 1) !== (this._aerialPerspectiveIntensity === 1);\r\n this._aerialPerspectiveIntensity = value;\r\n if (hasDefineChanged) {\r\n this._disposeAerialPerspectiveCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * The amount of light transmitted into aerial perspective.\r\n * A scale of 1 is physically correct.\r\n */\r\n public get aerialPerspectiveTransmittanceScale(): number {\r\n return this._aerialPerspectiveTransmittanceScale;\r\n }\r\n\r\n public set aerialPerspectiveTransmittanceScale(value: number) {\r\n value = Math.max(0, value);\r\n if (value !== this._aerialPerspectiveTransmittanceScale) {\r\n this._aerialPerspectiveTransmittanceScale = value;\r\n }\r\n }\r\n\r\n /**\r\n * The amount of saturation applied to the aerial perspective.\r\n * Reducing to zero desaturates the aerial perspective completely.\r\n * A value of 1 has no effect.\r\n */\r\n public get aerialPerspectiveSaturation(): number {\r\n return this._aerialPerspectiveSaturation;\r\n }\r\n\r\n public set aerialPerspectiveSaturation(value: number) {\r\n value = Math.max(0.0, value);\r\n if (value !== this._aerialPerspectiveSaturation) {\r\n this._aerialPerspectiveSaturation = value;\r\n }\r\n }\r\n\r\n /**\r\n * A radiance bias applied to aerial perspective.\r\n */\r\n public get aerialPerspectiveRadianceBias(): number {\r\n return this._aerialPerspectiveRadianceBias;\r\n }\r\n\r\n public set aerialPerspectiveRadianceBias(value: number) {\r\n if (value !== this._aerialPerspectiveRadianceBias) {\r\n // Define only needs to change if the value is changing between 0 and not 0.\r\n const hasDefineChanged = (value === 0) !== (this._aerialPerspectiveRadianceBias === 0);\r\n this._aerialPerspectiveRadianceBias = value;\r\n if (hasDefineChanged) {\r\n this._disposeAerialPerspectiveCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * True if the composition should be in linear space (e.g. for HDR rendering).\r\n * Typically linear space is expected when ImageProcessing is enabled via PostProcesses.\r\n * False for non-linear output.\r\n */\r\n public get isLinearSpaceComposition(): boolean {\r\n return this._isLinearSpaceComposition;\r\n }\r\n\r\n public set isLinearSpaceComposition(value: boolean) {\r\n if (value !== this._isLinearSpaceComposition) {\r\n this._isLinearSpaceComposition = value;\r\n // Note, LUTs will remain in linear space. Up to compositors to apply gamma if needed.\r\n this._disposeSkyCompositor();\r\n this._disposeAerialPerspectiveCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n }\r\n\r\n /**\r\n * True if the {@link light} value should be specified in linear space.\r\n * If using PBRMaterials, light value is expected to be linear.\r\n */\r\n public get isLinearSpaceLight(): boolean {\r\n return this._isLinearSpaceLight;\r\n }\r\n\r\n public set isLinearSpaceLight(value: boolean) {\r\n this._isLinearSpaceLight = value;\r\n }\r\n\r\n /**\r\n * The lookup table for transmittance.\r\n */\r\n public get transmittanceLut(): Nullable<TransmittanceLut> {\r\n return this._transmittanceLut;\r\n }\r\n\r\n /**\r\n * Gets the multiple scattering LUT render target.\r\n * @returns The render target.\r\n */\r\n public get multiScatteringLutRenderTarget(): Nullable<RenderTargetTexture> {\r\n return this._multiScatteringLutRenderTarget;\r\n }\r\n\r\n /**\r\n * The lookup table for diffuse sky irradiance, or null if not enabled.\r\n */\r\n public get diffuseSkyIrradianceLut(): Nullable<DiffuseSkyIrradianceLut> {\r\n return this._diffuseSkyIrradianceLut;\r\n }\r\n\r\n /**\r\n * The properties used to describe the size and optical parameters of the atmosphere.\r\n */\r\n public get physicalProperties(): AtmospherePhysicalProperties {\r\n return this._physicalProperties;\r\n }\r\n\r\n /**\r\n * The height in kilometers of the scene's origin.\r\n */\r\n public get originHeight(): number {\r\n return this._originHeight;\r\n }\r\n\r\n public set originHeight(value: number) {\r\n this._originHeight = value;\r\n }\r\n\r\n /**\r\n * When atmospheric scattering is applied to surfaces, if this value is set to true,\r\n * a grayscale approximation of the transmittance is used to dim surfaces.\r\n *\r\n * When set to false, the atmospheric composition does not dim the surfaces behind it.\r\n * It is up to the client application to apply transmittance manually.\r\n */\r\n public get applyApproximateTransmittance(): boolean {\r\n return this._applyApproximateTransmittance;\r\n }\r\n\r\n public set applyApproximateTransmittance(value: boolean) {\r\n if (this._applyApproximateTransmittance !== value) {\r\n this._applyApproximateTransmittance = value;\r\n this._disposeSkyCompositor();\r\n this._disposeAerialPerspectiveCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n }\r\n\r\n /**\r\n * The directional lights in the scene which represent the suns illuminating the atmosphere.\r\n * Each frame, the color and intensity of the lights are updated based on the camera position and the light's direction.\r\n */\r\n public get lights(): ReadonlyArray<DirectionalLight> {\r\n return this._lights;\r\n }\r\n\r\n /**\r\n * The rendering group ID for the sky compositor.\r\n * The sky will only be rendered for this group.\r\n */\r\n public get skyRenderingGroup(): number {\r\n return this._skyRenderingGroup;\r\n }\r\n\r\n public set skyRenderingGroup(value: number) {\r\n this._skyRenderingGroup = value;\r\n this.scene.renderingManager.getRenderingGroup(value);\r\n }\r\n\r\n /**\r\n * The rendering group ID for the aerial perspective compositor.\r\n * Aerial perspective will only be rendered for this group.\r\n */\r\n public get aerialPerspectiveRenderingGroup(): number {\r\n return this._aerialPerspectiveRenderingGroup;\r\n }\r\n\r\n public set aerialPerspectiveRenderingGroup(value: number) {\r\n this._aerialPerspectiveRenderingGroup = value;\r\n this.scene.renderingManager.getRenderingGroup(value);\r\n }\r\n\r\n /**\r\n * The rendering group ID for the globe atmosphere compositor.\r\n * The globe atmosphere will only be rendered for this group.\r\n */\r\n public get globeAtmosphereRenderingGroup(): number {\r\n return this._globeAtmosphereRenderingGroup;\r\n }\r\n\r\n public set globeAtmosphereRenderingGroup(value: number) {\r\n this._globeAtmosphereRenderingGroup = value;\r\n this.scene.renderingManager.getRenderingGroup(value);\r\n }\r\n\r\n /**\r\n * Gets the uniform buffer used to store the atmosphere's physical properties.\r\n */\r\n public get uniformBuffer(): UniformBuffer {\r\n if (this._atmosphereUbo === null) {\r\n const atmosphereUbo = (this._atmosphereUbo = new UniformBuffer(this._engine, undefined, true, \"Atmosphere\"));\r\n atmosphereUbo.addUniform(\"peakRayleighScattering\", 3);\r\n atmosphereUbo.addUniform(\"planetRadius\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"peakMieScattering\", 3);\r\n atmosphereUbo.addUniform(\"atmosphereThickness\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"peakMieAbsorption\", 3);\r\n atmosphereUbo.addUniform(\"planetRadiusSquared\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"peakMieExtinction\", 3);\r\n atmosphereUbo.addUniform(\"atmosphereRadius\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"peakOzoneAbsorption\", 3);\r\n atmosphereUbo.addUniform(\"atmosphereRadiusSquared\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"horizonDistanceToAtmosphereEdge\", 1);\r\n atmosphereUbo.addUniform(\"horizonDistanceToAtmosphereEdgeSquared\", 1);\r\n atmosphereUbo.addUniform(\"planetRadiusWithOffset\", 1);\r\n atmosphereUbo.addUniform(\"planetRadiusOffset\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"atmosphereExposure\", 1);\r\n atmosphereUbo.addUniform(\"aerialPerspectiveRadianceBias\", 1);\r\n atmosphereUbo.addUniform(\"inverseAtmosphereThickness\", 1);\r\n atmosphereUbo.addUniform(\"aerialPerspectiveTransmittanceScale\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"inverseViewProjectionWithoutTranslation\", 16);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"directionToLight\", 3);\r\n atmosphereUbo.addUniform(\"multiScatteringIntensity\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"directionToLightRelativeToCameraGeocentricNormal\", 3);\r\n atmosphereUbo.addUniform(\"cameraRadius\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"lightRadianceAtCamera\", 3);\r\n atmosphereUbo.addUniform(\"diffuseSkyIrradianceDesaturationFactor\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"groundAlbedo\", 3);\r\n atmosphereUbo.addUniform(\"aerialPerspectiveSaturation\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"minMultiScattering\", 3);\r\n atmosphereUbo.addUniform(\"diffuseSkyIrradianceIntensity\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraPositionGlobal\", 3);\r\n atmosphereUbo.addUniform(\"lightIntensity\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"clampedCameraPositionGlobal\", 3);\r\n atmosphereUbo.addUniform(\"aerialPerspectiveIntensity\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraGeocentricNormal\", 3);\r\n atmosphereUbo.addUniform(\"clampedCameraRadius\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraForward\", 3);\r\n atmosphereUbo.addUniform(\"clampedCameraHeight\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraPosition\", 3);\r\n atmosphereUbo.addUniform(\"cosCameraHorizonAngleFromZenith\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"viewport\", 4);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"additionalDiffuseSkyIrradiance\", 3);\r\n atmosphereUbo.addUniform(\"cameraHeight\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraNearPlane\", 1);\r\n atmosphereUbo.addUniform(\"originHeight\", 1);\r\n atmosphereUbo.addUniform(\"sinCameraAtmosphereHorizonAngleFromNadir\", 1);\r\n atmosphereUbo.create();\r\n }\r\n return this._atmosphereUbo;\r\n }\r\n\r\n /**\r\n * Gets the camera-related variables for this atmosphere. Updated each frame.\r\n */\r\n public get cameraAtmosphereVariables(): AtmospherePerCameraVariables {\r\n return this._cameraAtmosphereVariables;\r\n }\r\n\r\n public readonly uniqueId: number;\r\n\r\n /**\r\n * Constructs the {@link Atmosphere}.\r\n * @param name - The name of this instance.\r\n * @param scene - The scene to which the atmosphere will be added.\r\n * @param lights - The light sources that illuminate the atmosphere. Currently only supports one light, and that light should be the first light in the scene.\r\n * @param options - The options used to create the atmosphere.\r\n */\r\n public constructor(\r\n public readonly name: string,\r\n public readonly scene: Scene,\r\n lights: DirectionalLight[],\r\n options?: IAtmosphereOptions\r\n ) {\r\n const engine = (this._engine = scene.getEngine());\r\n this.uniqueId = scene.getUniqueId();\r\n\r\n if (engine.isWebGPU) {\r\n throw new Error(\"Atmosphere is not supported on WebGPU.\");\r\n }\r\n if (engine.version < 2) {\r\n throw new Error(`Atmosphere is not supported on WebGL ${engine.version}.`);\r\n }\r\n\r\n this._physicalProperties = options?.physicalProperties ?? new AtmospherePhysicalProperties();\r\n this._physicalProperties.onChangedObservable.add(() => {\r\n this._transmittanceLut?.markDirty();\r\n });\r\n\r\n if (lights.length !== 1) {\r\n throw new Error(\"Atmosphere only supports one light source currently.\");\r\n }\r\n this._lights = lights;\r\n\r\n this.depthTexture = options?.depthTexture ?? null;\r\n this._exposure = options?.exposure ?? 1.0;\r\n this._isLinearSpaceLight = options?.isLinearSpaceLight ?? false;\r\n this._isLinearSpaceComposition = options?.isLinearSpaceComposition ?? false;\r\n this._applyApproximateTransmittance = options?.applyApproximateTransmittance ?? true;\r\n this._aerialPerspectiveRadianceBias = options?.aerialPerspectiveRadianceBias ?? 0.0;\r\n this._aerialPerspectiveTransmittanceScale = options?.aerialPerspectiveTransmittanceScale ?? 1.0;\r\n this._aerialPerspectiveSaturation = options?.aerialPerspectiveSaturation ?? 1.0;\r\n this._aerialPerspectiveIntensity = options?.aerialPerspectiveIntensity ?? 1.0;\r\n this._diffuseSkyIrradianceDesaturationFactor = options?.diffuseSkyIrradianceDesaturationFactor ?? 0.5;\r\n this._diffuseSkyIrradianceIntensity = options?.diffuseSkyIrradianceIntensity ?? 1.0;\r\n this._additionalDiffuseSkyIrradianceIntensity = options?.additionalDiffuseSkyIrradianceIntensity ?? 0.01;\r\n this._multiScatteringIntensity = options?.multiScatteringIntensity ?? 1.0;\r\n this._minimumMultiScatteringIntensity = options?.minimumMultiScatteringIntensity ?? 0.000618;\r\n this._isSkyViewLutEnabled = options?.isSkyViewLutEnabled ?? true;\r\n this._isAerialPerspectiveLutEnabled = options?.isAerialPerspectiveLutEnabled ?? true;\r\n this._originHeight = options?.originHeight ?? 0;\r\n this._additionalDiffuseSkyIrradianceColor = options?.additionalDiffuseSkyIrradianceColor\r\n ? new Color3().copyFrom(options.additionalDiffuseSkyIrradianceColor)\r\n : new Color3(163 / 255.0, 199 / 255.0, 1.0);\r\n this._groundAlbedo = options?.groundAlbedo ? new Color3().copyFrom(options.groundAlbedo) : new Color3().set(124.0 / 255.0, 165.0 / 255.0, 1.0);\r\n const minimumMultiScatteringColor = (this._minimumMultiScatteringColor = options?.minimumMultiScatteringColor\r\n ? new Color3().copyFrom(options.minimumMultiScatteringColor)\r\n : new Color3(30.0 / 255.0, 40.0 / 255.0, 77.0 / 255.0));\r\n\r\n this._skyRenderingGroup = options?.skyRenderingGroup ?? 0;\r\n this._aerialPerspectiveRenderingGroup = options?.aerialPerspectiveRenderingGroup ?? 0;\r\n this._globeAtmosphereRenderingGroup = options?.globeAtmosphereRenderingGroup ?? 0;\r\n\r\n this._additionalDiffuseSkyIrradianceColor.scaleToRef(this._additionalDiffuseSkyIrradianceIntensity, this._additionalDiffuseSkyIrradiance);\r\n this._minimumMultiScattering.x = minimumMultiScatteringColor.r * this._minimumMultiScatteringIntensity;\r\n this._minimumMultiScattering.y = minimumMultiScatteringColor.g * this._minimumMultiScatteringIntensity;\r\n this._minimumMultiScattering.z = minimumMultiScatteringColor.b * this._minimumMultiScatteringIntensity;\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n\r\n this._transmittanceLut = new TransmittanceLut(this);\r\n this._multiScatteringLutRenderTarget = CreateRenderTargetTexture(\"atmo-multiScattering\", { width: 32, height: 32 }, scene);\r\n if (options?.isDiffuseSkyIrradianceLutEnabled ?? true) {\r\n this._diffuseSkyIrradianceLut = new DiffuseSkyIrradianceLut(this);\r\n }\r\n if (this._isSkyViewLutEnabled) {\r\n this.skyViewLutRenderTarget!;\r\n }\r\n if (this._isAerialPerspectiveLutEnabled) {\r\n this.aerialPerspectiveLutRenderTarget!;\r\n }\r\n\r\n // Before rendering, make sure the per-camera variables have been updated.\r\n this._onBeforeCameraRenderObserver = scene.onBeforeCameraRenderObservable.add((x) => {\r\n this._updatePerCameraVariables(x);\r\n this._renderLutsForCamera();\r\n });\r\n\r\n {\r\n const renderingManager = scene.renderingManager;\r\n if (this._skyRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._skyRenderingGroup);\r\n }\r\n if (this._aerialPerspectiveRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._aerialPerspectiveRenderingGroup);\r\n }\r\n if (this._globeAtmosphereRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._globeAtmosphereRenderingGroup);\r\n }\r\n\r\n // Mark all rendering groups as being \"not empty\" before rendering the corresponding targets.\r\n // This ensures onAfterRenderTargetsRenderObservable is called for empty groups,\r\n // which allows the atmosphere to be rendered even when the groups are otherwise empty e.g.,\r\n // a scene with only the atmosphere in it, and no other Meshes.\r\n this._onBeforeDrawPhaseObserver = scene.onBeforeDrawPhaseObservable.add(() => {\r\n if (this._skyRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._skyRenderingGroup)._empty = false;\r\n }\r\n if (this._aerialPerspectiveRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._aerialPerspectiveRenderingGroup)._empty = false;\r\n }\r\n if (this._globeAtmosphereRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._globeAtmosphereRenderingGroup)._empty = false;\r\n }\r\n });\r\n\r\n // Draw compositors after the respective rendering group.\r\n this._onAfterRenderingGroupObserver = scene.onAfterRenderingGroupObservable.add((group) => {\r\n if (group.renderingManager !== scene.renderingManager) {\r\n return;\r\n }\r\n\r\n const groupId = group.renderingGroupId;\r\n\r\n if (this._skyRenderingGroup === groupId) {\r\n this.drawSkyCompositor();\r\n }\r\n\r\n if (this._aerialPerspectiveRenderingGroup === groupId) {\r\n this.drawAerialPerspectiveCompositor();\r\n }\r\n\r\n if (this._globeAtmosphereRenderingGroup === groupId) {\r\n this.drawGlobeAtmosphereCompositor();\r\n }\r\n });\r\n }\r\n\r\n // Ensure the atmosphere is disposed when the scene is disposed.\r\n scene.onDisposeObservable.addOnce(() => {\r\n scene.removeExternalData(\"atmosphere\");\r\n this.dispose();\r\n });\r\n scene.addExternalData(\"atmosphere\", this);\r\n\r\n // Registers a material plugin which will allow common materials to sample the atmosphere environment maps e.g.,\r\n // sky view LUT for glossy reflections and diffuse sky illiminance LUT for irradiance.\r\n // It also handles aerial perspective application when Atmosphere is not provided with a depth texture.\r\n UnregisterMaterialPlugin(MaterialPlugin);\r\n RegisterMaterialPlugin(MaterialPlugin, (material) => {\r\n if (material.getClassName() === \"PBRMaterial\") {\r\n return new AtmospherePBRMaterialPlugin(material, this, this.depthTexture === null);\r\n }\r\n return null;\r\n });\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public dispose(): void {\r\n this._onBeforeCameraRenderObserver?.remove();\r\n this._onBeforeCameraRenderObserver = null;\r\n this._onBeforeDrawPhaseObserver?.remove();\r\n this._onBeforeDrawPhaseObserver = null;\r\n this._onAfterRenderingGroupObserver?.remove();\r\n this._onAfterRenderingGroupObserver = null;\r\n this._globeAtmosphereCompositorEffectWrapper?.dispose();\r\n this._globeAtmosphereCompositorEffectWrapper = null;\r\n this._skyCompositorEffectWrapper?.dispose();\r\n this._skyCompositorEffectWrapper = null;\r\n this._aerialPerspectiveCompositorEffectWrapper?.dispose();\r\n this._aerialPerspectiveCompositorEffectWrapper = null;\r\n this._skyViewLutRenderTarget?.dispose();\r\n this._skyViewLutRenderTarget = null;\r\n this._skyViewLutEffectWrapper?.dispose();\r\n this._skyViewLutEffectWrapper = null;\r\n this._skyViewLutEffectRenderer?.dispose();\r\n this._skyViewLutEffectRenderer = null;\r\n this._aerialPerspectiveLutRenderTarget?.dispose();\r\n this._aerialPerspectiveLutRenderTarget = null;\r\n this._aerialPerspectiveLutEffectWrapper?.dispose();\r\n this._aerialPerspectiveLutEffectWrapper = null;\r\n this._aerialPerspectiveLutEffectRenderer?.dispose();\r\n this._aerialPerspectiveLutEffectRenderer = null;\r\n this._multiScatteringEffectWrapper?.dispose();\r\n this._multiScatteringEffectWrapper = null;\r\n this._multiScatteringLutRenderTarget?.dispose();\r\n this._multiScatteringLutRenderTarget = null;\r\n this._transmittanceLut?.dispose();\r\n this._transmittanceLut = null;\r\n this._diffuseSkyIrradianceLut?.dispose();\r\n this._diffuseSkyIrradianceLut = null;\r\n this._atmosphereUbo?.dispose();\r\n this._atmosphereUbo = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._atmosphereUniformBufferAsArray.length = 0;\r\n\r\n UnregisterMaterialPlugin(MaterialPlugin);\r\n }\r\n\r\n /**\r\n * True if the atmosphere is enabled.\r\n * @returns - True if the atmosphere is enabled.\r\n */\r\n public isEnabled() {\r\n return this._isEnabled;\r\n }\r\n\r\n /**\r\n * Sets the enabled state of the atmosphere.\r\n * @param enabled - True to enable the atmosphere, false to disable it.\r\n */\r\n public setEnabled(enabled: boolean) {\r\n this._isEnabled = enabled;\r\n }\r\n\r\n /**\r\n * The class name of the {@link Atmosphere}.\r\n * @returns - The class name of the atmosphere.\r\n */\r\n public getClassName(): string {\r\n return \"Atmosphere\";\r\n }\r\n\r\n /**\r\n * Gets the color of a light after being transmitted through the atmosphere to a point specified by its distance to the planet center and its geocentric normal.\r\n * NOTE, the result is always a linear space color.\r\n * @param directionToLight - The direction of the light.\r\n * @param pointRadius - The distance from the planet center to the point in kilometers.\r\n * @param pointGeocentricNormal - The geocentric normal at the point i.e., normalize(point - planet center).\r\n * @param result - The color to store the result in.\r\n * @returns The result color.\r\n */\r\n public getTransmittedColorToRef = <T extends IColor3Like>(directionToLight: IVector3Like, pointRadius: number, pointGeocentricNormal: IVector3Like, result: T): T =>\r\n this._transmittanceLut!.getTransmittedColorToRef(directionToLight, pointRadius, pointGeocentricNormal, result);\r\n\r\n /**\r\n * Gets the diffuse sky irradiance. Result is always in linear space.\r\n * @param directionToLight - The direction of the point to the light.\r\n * @param pointRadius - The distance from the planet center to the point in kilometers.\r\n * @param pointGeocentricNormal - The geocentric normal at the point: normalize(point - planet center).\r\n * @param lightIrradiance - The irradiance of the light.\r\n * @param result - The color to store the result in.\r\n * @returns The result color.\r\n */\r\n public getDiffuseSkyIrradianceToRef = <T extends IColor3Like>(\r\n directionToLight: IVector3Like,\r\n pointRadius: number,\r\n pointGeocentricNormal: IVector3Like,\r\n lightIrradiance: number,\r\n result: T\r\n ): T =>\r\n this._diffuseSkyIrradianceLut?.getDiffuseSkyIrradianceToRef(directionToLight, pointRadius, pointGeocentricNormal, lightIrradiance, result) ??\r\n ((result.r = 0), (result.g = 0), (result.b = 0), result);\r\n\r\n /**\r\n * Creates a new {@link EffectWrapper} for the multiple scattering LUT\r\n * @returns The newly created {@link EffectWrapper}.\r\n */\r\n private _createMultiScatteringEffectWrapper(): EffectWrapper {\r\n const engine = this._engine;\r\n const name = \"atmo-multiScattering\";\r\n const ubo = this.uniformBuffer;\r\n const useUbo = ubo.useUbo;\r\n\r\n const defines: string[] = [\"#define POSITION_VEC2\"];\r\n if (!this._groundAlbedo.equals(Color3.BlackReadOnly)) {\r\n defines.push(\"#define USE_GROUND_ALBEDO\");\r\n }\r\n\r\n return new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"multiScattering\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : this.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [this.uniformBuffer.name] : [],\r\n samplerNames: [\"transmittanceLut\"],\r\n defines,\r\n useShaderStore: true,\r\n });\r\n }\r\n\r\n /**\r\n * Draws the multiple scattering LUT using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n private _drawMultiScatteringLut(): void {\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n DrawEffect(\r\n this._engine,\r\n this._effectRenderer!,\r\n this._multiScatteringEffectWrapper,\r\n this._multiScatteringLutRenderTarget,\r\n (effectRenderer, renderTarget, effect, engine) => {\r\n this.bindUniformBufferToEffect(effect);\r\n engine.bindFramebuffer(renderTarget!, undefined, undefined, undefined, true);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effectRenderer.draw();\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Draws the aerial perspective compositor using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n public drawAerialPerspectiveCompositor(): void {\r\n // Only works if we have a depth texture.\r\n if (this.depthTexture === null) {\r\n return;\r\n }\r\n\r\n const isEnabled = this.isEnabled();\r\n if (!isEnabled) {\r\n return;\r\n }\r\n\r\n // Aerial perspective compositor only renders when inside the atmosphere.\r\n const isOutsideAtmosphere = this._cameraAtmosphereVariables.clampedCameraRadius > this._physicalProperties.atmosphereRadius;\r\n if (isOutsideAtmosphere) {\r\n return;\r\n }\r\n\r\n const engine = this._engine;\r\n this._aerialPerspectiveCompositorEffectWrapper ??= CreateAerialPerspectiveCompositorEffectWrapper(\r\n engine,\r\n this.uniformBuffer,\r\n this._isAerialPerspectiveLutEnabled,\r\n this._isSkyViewLutEnabled,\r\n this._isLinearSpaceComposition,\r\n this._applyApproximateTransmittance,\r\n this._aerialPerspectiveIntensity,\r\n this._aerialPerspectiveRadianceBias\r\n );\r\n\r\n const skyViewLut = this._isSkyViewLutEnabled ? this.skyViewLutRenderTarget : null;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget!;\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n const aerialPerspectiveLut = this._isAerialPerspectiveLutEnabled ? this.aerialPerspectiveLutRenderTarget : null;\r\n if (\r\n !this._aerialPerspectiveCompositorEffectWrapper.isReady() ||\r\n !(skyViewLut?.isReady() ?? true) ||\r\n !multiScatteringLut.isReady() ||\r\n !transmittanceLut.isReady() ||\r\n !(aerialPerspectiveLut?.isReady() ?? true) ||\r\n !this.depthTexture.isReady()\r\n ) {\r\n return;\r\n }\r\n\r\n DrawEffect(\r\n engine,\r\n this._effectRenderer!,\r\n this._aerialPerspectiveCompositorEffectWrapper,\r\n null, // No render target, it will render to the current buffer.\r\n (effectRenderer, _, effect) => {\r\n if (this.depthTexture === null) {\r\n throw new Error(\"Depth texture is required for aerial perspective compositor.\");\r\n }\r\n this.bindUniformBufferToEffect(effect);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n if (this._isSkyViewLutEnabled) {\r\n effect.setTexture(\"skyViewLut\", skyViewLut);\r\n }\r\n if (this._isAerialPerspectiveLutEnabled) {\r\n effect.setTexture(\"aerialPerspectiveLut\", aerialPerspectiveLut);\r\n }\r\n effect.setTexture(\"depthTexture\", this.depthTexture);\r\n effectRenderer.draw();\r\n },\r\n 1, // depth to use in the compositor.\r\n this.applyApproximateTransmittance ? Constants.ALPHA_PREMULTIPLIED_PORTERDUFF : Constants.ALPHA_ONEONE,\r\n true, // depthTest\r\n false, // depthWrite\r\n Constants.ALWAYS, // depthFunction\r\n false // restoreDefaultFramebuffer\r\n );\r\n }\r\n\r\n /**\r\n * Draws the sky compositor using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n public drawSkyCompositor(): void {\r\n const isEnabled = this.isEnabled();\r\n if (!isEnabled) {\r\n return;\r\n }\r\n\r\n // The sky compositor only renders when inside the atmosphere.\r\n const isOutsideAtmosphere = this._cameraAtmosphereVariables.clampedCameraRadius > this._physicalProperties.atmosphereRadius;\r\n if (isOutsideAtmosphere) {\r\n return;\r\n }\r\n\r\n if (this.depthTexture !== null && !this.depthTexture.isReady()) {\r\n return;\r\n }\r\n\r\n const engine = this._engine;\r\n this._skyCompositorEffectWrapper ??= CreateSkyCompositorEffectWrapper(\r\n engine,\r\n this.uniformBuffer,\r\n this._isSkyViewLutEnabled,\r\n this._isLinearSpaceComposition,\r\n this._applyApproximateTransmittance\r\n );\r\n\r\n const skyViewLut = this._isSkyViewLutEnabled ? this.skyViewLutRenderTarget : null;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget!;\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n if (!this._skyCompositorEffectWrapper.isReady() || !(skyViewLut?.isReady() ?? true) || !multiScatteringLut.isReady() || !transmittanceLut.isReady()) {\r\n return;\r\n }\r\n\r\n DrawEffect(\r\n engine,\r\n this._effectRenderer!,\r\n this._skyCompositorEffectWrapper,\r\n null, // No render target, it will render to the current buffer.\r\n (effectRenderer, _, effect) => {\r\n this.bindUniformBufferToEffect(effect);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n if (this._isSkyViewLutEnabled) {\r\n effect.setTexture(\"skyViewLut\", skyViewLut);\r\n }\r\n effectRenderer.draw();\r\n },\r\n 1, // depth to use in the compositor.\r\n this._applyApproximateTransmittance ? Constants.ALPHA_PREMULTIPLIED_PORTERDUFF : Constants.ALPHA_ONEONE,\r\n true, // depthTest\r\n false, // depthWrite\r\n Constants.EQUAL, // depthFunction\r\n false // restoreDefaultFramebuffer\r\n );\r\n }\r\n\r\n /**\r\n * Draws the globe atmosphere compositor using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n public drawGlobeAtmosphereCompositor(): void {\r\n const isEnabled = this.isEnabled();\r\n if (!isEnabled) {\r\n return;\r\n }\r\n\r\n // Globe atmosphere compositor only renders when outside the atmosphere.\r\n const isOutsideAtmosphere = this._cameraAtmosphereVariables.clampedCameraRadius > this._physicalProperties.atmosphereRadius;\r\n if (!isOutsideAtmosphere) {\r\n return;\r\n }\r\n\r\n const engine = this._engine;\r\n this._globeAtmosphereCompositorEffectWrapper ??= CreateGlobeAtmosphereCompositorEffectWrapper(\r\n engine,\r\n this.uniformBuffer,\r\n this._isSkyViewLutEnabled,\r\n this._isLinearSpaceComposition,\r\n this._applyApproximateTransmittance,\r\n this._aerialPerspectiveIntensity,\r\n this._aerialPerspectiveRadianceBias,\r\n this.depthTexture !== null\r\n );\r\n\r\n const skyViewLut = this._isSkyViewLutEnabled ? this.skyViewLutRenderTarget : null;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget!;\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n if (!this._globeAtmosphereCompositorEffectWrapper.isReady() || !(skyViewLut?.isReady() ?? true) || !multiScatteringLut.isReady() || !transmittanceLut.isReady()) {\r\n return;\r\n }\r\n\r\n if (this.depthTexture !== null && !this.depthTexture.isReady()) {\r\n return;\r\n }\r\n\r\n DrawEffect(\r\n engine,\r\n this._effectRenderer!,\r\n this._globeAtmosphereCompositorEffectWrapper,\r\n null, // No render target, it will render to the current buffer.\r\n (effectRenderer, _, effect) => {\r\n this.bindUniformBufferToEffect(effect);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n if (this._isSkyViewLutEnabled) {\r\n effect.setTexture(\"skyViewLut\", skyViewLut);\r\n }\r\n if (this.depthTexture !== null) {\r\n effect.setTexture(\"depthTexture\", this.depthTexture);\r\n }\r\n effectRenderer.draw();\r\n },\r\n 1, // depth to use in the compositor.\r\n this._applyApproximateTransmittance ? Constants.ALPHA_PREMULTIPLIED_PORTERDUFF : Constants.ALPHA_ONEONE,\r\n true, // depthTest\r\n false, // depthWrite\r\n Constants.ALWAYS, // depthFunction\r\n false // restoreDefaultFramebuffer\r\n );\r\n }\r\n\r\n private _disposeSkyCompositor(): void {\r\n this._skyCompositorEffectWrapper?.dispose();\r\n this._skyCompositorEffectWrapper = null;\r\n }\r\n\r\n private _disposeAerialPerspectiveCompositor(): void {\r\n this._aerialPerspectiveCompositorEffectWrapper?.dispose();\r\n this._aerialPerspectiveCompositorEffectWrapper = null;\r\n }\r\n\r\n private _disposeGlobeAtmosphereCompositor(): void {\r\n this._globeAtmosphereCompositorEffectWrapper?.dispose();\r\n this._globeAtmosphereCompositorEffectWrapper = null;\r\n }\r\n\r\n /**\r\n * Updates the camera variables that are specific to the atmosphere.\r\n * @param camera - The camera to update the variables for.\r\n */\r\n private _updatePerCameraVariables(camera: Camera): void {\r\n const light = this._lights[0];\r\n this._directionToLight.copyFrom(light.direction);\r\n this._directionToLight.scaleInPlace(-1);\r\n\r\n const properties = this._physicalProperties;\r\n const cameraAtmosphereVariables = this._cameraAtmosphereVariables;\r\n cameraAtmosphereVariables.update(\r\n camera,\r\n properties.planetRadius,\r\n properties.planetRadiusWithOffset,\r\n properties.atmosphereRadius,\r\n this._directionToLight,\r\n this.originHeight\r\n );\r\n\r\n this._transmittanceLut!.updateLightParameters(light, cameraAtmosphereVariables.clampedCameraRadius, cameraAtmosphereVariables.cameraGeocentricNormal);\r\n this._linearLightColor.copyFrom(light.diffuse);\r\n\r\n this.getDiffuseSkyIrradianceToRef(this._directionToLight, 0, cameraAtmosphereVariables.cameraGeocentricNormal, this.lights[0].intensity, this._tempSceneAmbient);\r\n if (!this.isLinearSpaceLight) {\r\n this._tempSceneAmbient.toGammaSpaceToRef(this._tempSceneAmbient);\r\n }\r\n this.scene.ambientColor = this._tempSceneAmbient;\r\n\r\n this.onAfterUpdateVariablesForCameraObservable.notifyObservers(camera);\r\n }\r\n\r\n /**\r\n * Renders the lookup tables, some of which can vary per-camera.\r\n * It is expected that updatePerCameraVariables was previously called.\r\n */\r\n private _renderLutsForCamera(): void {\r\n {\r\n this.onBeforeLightVariablesUpdateObservable.notifyObservers();\r\n\r\n const light = this.lights[0];\r\n if (!this.isLinearSpaceLight) {\r\n light.diffuse = light.diffuse.toGammaSpaceToRef(light.diffuse);\r\n light.specular = light.specular.toGammaSpaceToRef(light.specular);\r\n }\r\n const intensity = light.intensity;\r\n this._lightRadianceAtCamera.set(intensity * this._linearLightColor.r, intensity * this._linearLightColor.g, intensity * this._linearLightColor.b);\r\n }\r\n\r\n if (this.uniformBuffer.useUbo) {\r\n this.updateUniformBuffer();\r\n }\r\n\r\n // Render the LUTs.\r\n const isEnabled = this.isEnabled();\r\n {\r\n this.onBeforeRenderLutsForCameraObservable.notifyObservers();\r\n\r\n // After UBO update we can render the global LUTs which use some of these values on the GPU.\r\n // TODO: Could break out update and UBOs to global vs. per-camera.\r\n this.renderGlobalLuts();\r\n\r\n // If atmosphere is enabled, render the per-camera LUTs (sky view and aerial perspective).\r\n if (isEnabled && !this._transmittanceLut!.isDirty && this._hasRenderedMultiScatteringLut) {\r\n if (this._isSkyViewLutEnabled) {\r\n this._drawSkyViewLut();\r\n }\r\n\r\n // Only need to render aerial perspective LUT when inside the atmosphere.\r\n if (this._isAerialPerspectiveLutEnabled && this._cameraAtmosphereVariables.clampedCameraRadius <= this._physicalProperties.atmosphereRadius) {\r\n this._drawAerialPerspectiveLut();\r\n }\r\n }\r\n\r\n this.onAfterRenderLutsForCameraObservable.notifyObservers();\r\n }\r\n }\r\n\r\n /**\r\n * Renders the lookup tables that do not depend on a camera position.\r\n */\r\n public renderGlobalLuts(): void {\r\n const hasNewTransmittanceLut = this._transmittanceLut!.render();\r\n if (hasNewTransmittanceLut) {\r\n this._hasRenderedMultiScatteringLut = false;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n\r\n if (!this._transmittanceLut!.isDirty && !this._hasRenderedMultiScatteringLut) {\r\n this._multiScatteringEffectWrapper ??= this._createMultiScatteringEffectWrapper();\r\n if (this._multiScatteringEffectWrapper?.isReady() && this._multiScatteringLutRenderTarget?.isReady()) {\r\n this._drawMultiScatteringLut();\r\n this._hasRenderedMultiScatteringLut = true;\r\n }\r\n }\r\n\r\n if (!this._transmittanceLut!.isDirty && this._hasRenderedMultiScatteringLut) {\r\n this._diffuseSkyIrradianceLut?.render(); // Will only render if needed.\r\n }\r\n }\r\n\r\n /**\r\n * Binds the atmosphere's uniform buffer to an {@link Effect}.\r\n * @param effect - The {@link Effect} to bind the uniform buffer to.\r\n */\r\n public bindUniformBufferToEffect(effect: Effect): void {\r\n const uniformBuffer = this.uniformBuffer;\r\n const name = uniformBuffer.name;\r\n uniformBuffer.bindToEffect(effect, name);\r\n if (uniformBuffer.useUbo) {\r\n uniformBuffer.bindUniformBuffer();\r\n } else {\r\n this.updateUniformBuffer();\r\n }\r\n }\r\n\r\n /**\r\n * Updates the atmosphere's uniform buffer.\r\n */\r\n public updateUniformBuffer(): void {\r\n const physicalProperties = this._physicalProperties;\r\n const cameraAtmosphereVariables = this._cameraAtmosphereVariables;\r\n const ubo = this.uniformBuffer;\r\n\r\n ubo.updateVector3(\"peakRayleighScattering\", physicalProperties.rayleighScattering);\r\n ubo.updateFloat(\"planetRadius\", physicalProperties.planetRadius);\r\n ubo.updateVector3(\"peakMieScattering\", physicalProperties.mieScattering);\r\n ubo.updateFloat(\"atmosphereThickness\", physicalProperties.atmosphereThickness);\r\n ubo.updateVector3(\"peakMieAbsorption\", physicalProperties.mieAbsorption);\r\n ubo.updateFloat(\"planetRadiusSquared\", physicalProperties.planetRadiusSquared);\r\n ubo.updateVector3(\"peakMieExtinction\", physicalProperties.mieExtinction);\r\n ubo.updateFloat(\"atmosphereRadius\", physicalProperties.atmosphereRadius);\r\n ubo.updateVector3(\"peakOzoneAbsorption\", physicalProperties.ozoneAbsorption);\r\n ubo.updateFloat(\"atmosphereRadiusSquared\", physicalProperties.atmosphereRadiusSquared);\r\n ubo.updateFloat(\"horizonDistanceToAtmosphereEdge\", physicalProperties.horizonDistanceToAtmosphereEdge);\r\n ubo.updateFloat(\"horizonDistanceToAtmosphereEdgeSquared\", physicalProperties.horizonDistanceToAtmosphereEdgeSquared);\r\n ubo.updateFloat(\"planetRadiusWithOffset\", physicalProperties.planetRadiusWithOffset);\r\n ubo.updateFloat(\"planetRadiusOffset\", physicalProperties.planetRadiusOffset);\r\n ubo.updateFloat(\"aerialPerspectiveRadianceBias\", this._aerialPerspectiveRadianceBias);\r\n ubo.updateFloat(\"inverseAtmosphereThickness\", 1 / physicalProperties.atmosphereThickness);\r\n ubo.updateFloat(\"aerialPerspectiveTransmittanceScale\", this._aerialPerspectiveTransmittanceScale);\r\n ubo.updateMatrix(\"inverseViewProjectionWithoutTranslation\", cameraAtmosphereVariables.inverseViewProjectionMatrixWithoutTranslation);\r\n ubo.updateVector3(\"directionToLight\", this._directionToLight);\r\n ubo.updateFloat(\"multiScatteringIntensity\", this.multiScatteringIntensity);\r\n ubo.updateVector3(\"directionToLightRelativeToCameraGeocentricNormal\", cameraAtmosphereVariables.directionToLightRelativeToCameraGeocentricNormal);\r\n ubo.updateFloat(\"cameraRadius\", cameraAtmosphereVariables.cameraRadius);\r\n ubo.updateVector3(\"lightRadianceAtCamera\", this._lightRadianceAtCamera);\r\n ubo.updateFloat(\"diffuseSkyIrradianceDesaturationFactor\", this._diffuseSkyIrradianceDesaturationFactor);\r\n ubo.updateColor3(\"groundAlbedo\", this._groundAlbedo);\r\n ubo.updateFloat(\"aerialPerspectiveSaturation\", this._aerialPerspectiveSaturation);\r\n ubo.updateVector3(\"minMultiScattering\", this._minimumMultiScattering);\r\n ubo.updateFloat(\"diffuseSkyIrradianceIntensity\", this._diffuseSkyIrradianceIntensity);\r\n ubo.updateVector3(\"cameraPositionGlobal\", cameraAtmosphereVariables.cameraPositionGlobal);\r\n ubo.updateFloat(\"lightIntensity\", this.lights[0].intensity);\r\n ubo.updateVector3(\"clampedCameraPositionGlobal\", cameraAtmosphereVariables.clampedCameraPositionGlobal);\r\n ubo.updateFloat(\"aerialPerspectiveIntensity\", this._aerialPerspectiveIntensity);\r\n ubo.updateVector3(\"cameraGeocentricNormal\", cameraAtmosphereVariables.cameraGeocentricNormal);\r\n ubo.updateFloat(\"clampedCameraRadius\", cameraAtmosphereVariables.clampedCameraRadius);\r\n ubo.updateVector3(\"cameraForward\", cameraAtmosphereVariables.cameraForward);\r\n ubo.updateFloat(\"clampedCameraHeight\", cameraAtmosphereVariables.clampedCameraHeight);\r\n ubo.updateVector3(\"cameraPosition\", cameraAtmosphereVariables.cameraPosition);\r\n ubo.updateFloat(\"cosCameraHorizonAngleFromZenith\", cameraAtmosphereVariables.cosCameraHorizonAngleFromZenith);\r\n ubo.updateVector4(\"viewport\", cameraAtmosphereVariables.viewport);\r\n ubo.updateColor3(\"additionalDiffuseSkyIrradiance\", this._additionalDiffuseSkyIrradiance);\r\n ubo.updateFloat(\"cameraHeight\", cameraAtmosphereVariables.cameraHeight);\r\n ubo.updateFloat(\"cameraNearPlane\", cameraAtmosphereVariables.cameraNearPlane);\r\n ubo.updateFloat(\"originHeight\", this._originHeight);\r\n ubo.updateFloat(\"sinCameraAtmosphereHorizonAngleFromNadir\", cameraAtmosphereVariables.sinCameraAtmosphereHorizonAngleFromNadir);\r\n ubo.updateFloat(\"atmosphereExposure\", this._exposure);\r\n ubo.update();\r\n }\r\n\r\n /**\r\n * Draws the aerial perspective LUT using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n private _drawAerialPerspectiveLut(): void {\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget;\r\n DrawEffect(\r\n this._engine,\r\n this._effectRenderer!,\r\n this._aerialPerspectiveLutEffectWrapper,\r\n this._aerialPerspectiveLutRenderTarget,\r\n (effectRenderer, renderTarget, effect, engine) => {\r\n this.bindUniformBufferToEffect(effect);\r\n const layers = 32;\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n for (let layer = 0; layer < layers; layer++) {\r\n engine.bindFramebuffer(renderTarget!, undefined, undefined, undefined, true, undefined, layer);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setFloat(\"layerIdx\", layer);\r\n effectRenderer.draw();\r\n }\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Draws the sky view LUT using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n private _drawSkyViewLut(): void {\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget!;\r\n DrawEffect(this._engine, this._effectRenderer!, this._skyViewLutEffectWrapper, this._skyViewLutRenderTarget, (effectRenderer, renderTarget, effect, engine) => {\r\n this.bindUniformBufferToEffect(effect);\r\n engine.bindFramebuffer(renderTarget!, undefined, undefined, undefined, true);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n effectRenderer.draw();\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Creates an {@link EffectWrapper} with the given parameters.\r\n * @param engine - The engine to use.\r\n * @param name - The name of the effect wrapper.\r\n * @param fragmentShader - The fragment shader source.\r\n * @param uniformNames - The uniform names to use.\r\n * @param samplerNames - The sampler names to use.\r\n * @param uniformBuffers - The uniform buffers to use.\r\n * @param defineNames - Array of define names to prepend with \"#define \".\r\n * @returns The effect wrapper.\r\n */\r\nconst CreateEffectWrapper = (\r\n engine: AbstractEngine,\r\n name: string,\r\n fragmentShader: string,\r\n uniformNames?: string[],\r\n samplerNames?: string[],\r\n uniformBuffers?: string[],\r\n defineNames?: string[]\r\n): EffectWrapper => {\r\n const defines = defineNames?.map((defineName) => `#define ${defineName}`) ?? [];\r\n\r\n return new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader,\r\n attributeNames: [\"position\"],\r\n uniformNames,\r\n uniformBuffers,\r\n samplerNames,\r\n defines,\r\n useShaderStore: true,\r\n });\r\n};\r\n\r\nconst CreateRenderTargetTexture = (\r\n name: string,\r\n size: number | { width: number; height: number; layers?: number },\r\n scene: Scene,\r\n options?: RenderTargetTextureOptions\r\n): RenderTargetTexture => {\r\n const rtOptions: RenderTargetTextureOptions = {\r\n generateMipMaps: false,\r\n generateDepthBuffer: false,\r\n generateStencilBuffer: false,\r\n gammaSpace: false,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n format: Constants.TEXTUREFORMAT_RGBA,\r\n ...options,\r\n };\r\n const renderTarget = new RenderTargetTexture(name, size, scene, rtOptions);\r\n\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n return renderTarget;\r\n};\r\n\r\n/**\r\n * Common setup and teardown for drawing LUTs or composition passes.\r\n * @param engine - The engine to use.\r\n * @param effectRenderer - The effect renderer to use.\r\n * @param effectWrapper - The effect wrapper to use.\r\n * @param renderTarget - The render target.\r\n * @param drawCallback - Callback function that performs the drawing.\r\n * @param depth - The depth value to set in the effect.\r\n * @param alphaMode - The alpha mode to set before drawing.\r\n * @param depthTest - Whether to enable depth testing.\r\n * @param depthWrite - Optional depth write state to set before drawing.\r\n * @param depthFunction - The depth function to set before drawing.\r\n * @param restoreDefaultFramebuffer - Whether to restore the default framebuffer after drawing.\r\n */\r\nconst DrawEffect = (\r\n engine: AbstractEngine,\r\n effectRenderer: EffectRenderer,\r\n effectWrapper: Nullable<EffectWrapper>,\r\n renderTarget: Nullable<RenderTargetTexture>,\r\n drawCallback: (effectRenderer: EffectRenderer, renderTarget: Nullable<RenderTargetWrapper>, effect: Effect, engine: AbstractEngine) => void,\r\n depth = 0,\r\n alphaMode = Constants.ALPHA_DISABLE,\r\n depthTest = true,\r\n depthWrite?: boolean,\r\n depthFunction = Constants.LEQUAL,\r\n restoreDefaultFramebuffer = true\r\n): void => {\r\n if ((renderTarget !== null && !renderTarget.isReady()) || !effectWrapper?.isReady()) {\r\n return;\r\n }\r\n\r\n // Set additional depth/stencil states before calling applyEffectWrapper.\r\n const currentDepthWrite = engine.getDepthWrite();\r\n if (depthWrite !== undefined) {\r\n engine.setDepthWrite(depthWrite);\r\n }\r\n const currentDepthFunction = engine.getDepthFunction();\r\n engine.setDepthFunction(depthFunction);\r\n\r\n // Likewise with the alpha mode, which can affect depth state too.\r\n const currentAlphaMode = engine.getAlphaMode();\r\n if (alphaMode !== Constants.ALPHA_DISABLE) {\r\n engine.setAlphaMode(alphaMode);\r\n }\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n effectRenderer.applyEffectWrapper(effectWrapper, depthTest); // Note, stencil is false by default.\r\n\r\n const effect = effectWrapper.effect;\r\n\r\n effect.setFloat(\"depth\", depth);\r\n\r\n // Call the specific drawing logic.\r\n drawCallback(effectRenderer, renderTarget?.renderTarget!, effect, engine);\r\n\r\n // Restore state (order matters!)\r\n engine.setAlphaMode(currentAlphaMode);\r\n if (currentDepthWrite !== undefined) {\r\n engine.setDepthWrite(currentDepthWrite);\r\n }\r\n if (currentDepthFunction) {\r\n engine.setDepthFunction(currentDepthFunction);\r\n }\r\n effectRenderer.restoreStates();\r\n\r\n // And restore the default framebuffer.\r\n if (restoreDefaultFramebuffer) {\r\n engine.restoreDefaultFramebuffer();\r\n }\r\n};\r\n\r\n/**\r\n * Creates an EffectWrapper for the sky compositor.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer to use.\r\n * @param isSkyViewLutEnabled - Whether the sky view LUT is enabled.\r\n * @param isLinearSpaceComposition - Whether composition is in linear space.\r\n * @param applyApproximateTransmittance - Whether to apply approximate transmittance.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateSkyCompositorEffectWrapper = (\r\n engine: AbstractEngine,\r\n uniformBuffer: UniformBuffer,\r\n isSkyViewLutEnabled: boolean,\r\n isLinearSpaceComposition: boolean,\r\n applyApproximateTransmittance: boolean\r\n): EffectWrapper => {\r\n const useUbo = uniformBuffer.useUbo;\r\n const defines = [\"COMPUTE_WORLD_RAY\"];\r\n if (isSkyViewLutEnabled) {\r\n defines.push(\"USE_SKY_VIEW_LUT\");\r\n }\r\n if (!isLinearSpaceComposition) {\r\n defines.push(\"OUTPUT_TO_SRGB\");\r\n }\r\n if (applyApproximateTransmittance) {\r\n defines.push(\"APPLY_TRANSMITTANCE_BLENDING\");\r\n }\r\n const textures = isSkyViewLutEnabled ? [\"skyViewLut\"] : [\"transmittanceLut\", \"multiScatteringLut\"];\r\n return CreateEffectWrapper(\r\n engine,\r\n \"atmo-skyCompositor\",\r\n \"compositeSky\",\r\n [\"depth\", ...(useUbo ? [] : uniformBuffer.getUniformNames())],\r\n textures,\r\n useUbo ? [uniformBuffer.name] : [],\r\n defines\r\n );\r\n};\r\n\r\n/**\r\n * Creates an EffectWrapper for the aerial perspective LUT.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer to use.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateAerialPerspectiveEffectWrapper = (engine: AbstractEngine, uniformBuffer: UniformBuffer): EffectWrapper =>\r\n CreateEffectWrapper(\r\n engine,\r\n \"atmo-aerialPerspective\",\r\n \"aerialPerspective\",\r\n [\"layerIdx\", \"depth\", ...(uniformBuffer.useUbo ? [] : uniformBuffer.getUniformNames())],\r\n [\"transmittanceLut\", \"multiScatteringLut\"],\r\n uniformBuffer.useUbo ? [uniformBuffer.name] : [],\r\n [\"COMPUTE_WORLD_RAY\"]\r\n );\r\n\r\n/**\r\n * Creates an EffectWrapper for the aerial perspective compositor.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer.\r\n * @param isAerialPerspectiveLutEnabled - Whether the aerial perspective LUT is enabled.\r\n * @param isSkyViewLutEnabled - Whether the sky view LUT is enabled.\r\n * @param isLinearSpaceComposition - Whether composition is in linear space.\r\n * @param applyApproximateTransmittance - Whether to apply approximate transmittance.\r\n * @param aerialPerspectiveIntensity - The aerial perspective intensity.\r\n * @param aerialPerspectiveRadianceBias - The aerial perspective radiance bias.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateAerialPerspectiveCompositorEffectWrapper = (\r\n engine: AbstractEngine,\r\n uniformBuffer: UniformBuffer,\r\n isAerialPerspectiveLutEnabled: boolean,\r\n isSkyViewLutEnabled: boolean,\r\n isLinearSpaceComposition: boolean,\r\n applyApproximateTransmittance: boolean,\r\n aerialPerspectiveIntensity: number,\r\n aerialPerspectiveRadianceBias: number\r\n): EffectWrapper => {\r\n const useUbo = uniformBuffer.useUbo;\r\n const defines = [\"COMPUTE_WORLD_RAY\"];\r\n if (isAerialPerspectiveLutEnabled) {\r\n defines.push(\"USE_AERIAL_PERSPECTIVE_LUT\");\r\n }\r\n if (isSkyViewLutEnabled) {\r\n defines.push(\"USE_SKY_VIEW_LUT\");\r\n }\r\n if (aerialPerspectiveIntensity !== 1) {\r\n defines.push(\"APPLY_AERIAL_PERSPECTIVE_INTENSITY\");\r\n }\r\n if (!isLinearSpaceComposition) {\r\n defines.push(\"OUTPUT_TO_SRGB\");\r\n }\r\n if (applyApproximateTransmittance) {\r\n defines.push(\"APPLY_TRANSMITTANCE_BLENDING\");\r\n }\r\n if (aerialPerspectiveRadianceBias !== 0.0) {\r\n defines.push(\"APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\");\r\n }\r\n\r\n const samplers = [\"transmittanceLut\", \"multiScatteringLut\", \"depthTexture\"];\r\n if (isSkyViewLutEnabled) {\r\n samplers.push(\"skyViewLut\");\r\n }\r\n if (isAerialPerspectiveLutEnabled) {\r\n samplers.push(\"aerialPerspectiveLut\");\r\n }\r\n\r\n return CreateEffectWrapper(\r\n engine,\r\n \"atmo-aerialPerspectiveCompositor\",\r\n \"compositeAerialPerspective\",\r\n [\"depth\", ...(useUbo ? [] : uniformBuffer.getUniformNames())],\r\n samplers,\r\n useUbo ? [uniformBuffer.name] : [],\r\n defines\r\n );\r\n};\r\n\r\n/**\r\n * Creates an EffectWrapper for the globe atmosphere compositor.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer to use.\r\n * @param isSkyViewLutEnabled - Whether the sky view LUT is enabled.\r\n * @param isLinearSpaceComposition - Whether composition is in linear space.\r\n * @param applyApproximateTransmittance - Whether to apply approximate transmittance.\r\n * @param aerialPerspectiveIntensity - The aerial perspective intensity.\r\n * @param aerialPerspectiveRadianceBias - The aerial perspective radiance bias.\r\n * @param hasDepthTexture - Whether a depth texture is available.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateGlobeAtmosphereCompositorEffectWrapper = (\r\n engine: AbstractEngine,\r\n uniformBuffer: UniformBuffer,\r\n isSkyViewLutEnabled: boolean,\r\n isLinearSpaceComposition: boolean,\r\n applyApproximateTransmittance: boolean,\r\n aerialPerspectiveIntensity: number,\r\n aerialPerspectiveRadianceBias: number,\r\n hasDepthTexture: boolean\r\n): EffectWrapper => {\r\n const useUbo = uniformBuffer.useUbo;\r\n const defines = [\"COMPUTE_WORLD_RAY\"];\r\n if (isSkyViewLutEnabled) {\r\n defines.push(\"USE_SKY_VIEW_LUT\");\r\n }\r\n if (aerialPerspectiveIntensity !== 1) {\r\n defines.push(\"APPLY_AERIAL_PERSPECTIVE_INTENSITY\");\r\n }\r\n if (!isLinearSpaceComposition) {\r\n defines.push(\"OUTPUT_TO_SRGB\");\r\n }\r\n if (hasDepthTexture) {\r\n defines.push(\"HAS_DEPTH_TEXTURE\");\r\n }\r\n if (applyApproximateTransmittance) {\r\n defines.push(\"APPLY_TRANSMITTANCE_BLENDING\");\r\n }\r\n if (aerialPerspectiveRadianceBias !== 0.0) {\r\n defines.push(\"APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\");\r\n }\r\n\r\n const samplers = [\"transmittanceLut\", \"multiScatteringLut\"];\r\n if (isSkyViewLutEnabled) {\r\n samplers.push(\"skyViewLut\");\r\n }\r\n if (hasDepthTexture) {\r\n samplers.push(\"depthTexture\");\r\n }\r\n\r\n return CreateEffectWrapper(\r\n engine,\r\n \"atmo-globeAtmosphereCompositor\",\r\n \"compositeGlobeAtmosphere\",\r\n [\"depth\", ...(useUbo ? [] : uniformBuffer.getUniformNames())],\r\n samplers,\r\n useUbo ? [uniformBuffer.name] : [],\r\n defines\r\n );\r\n};\r\n\r\n/**\r\n * Creates an EffectWrapper for the sky view LUT.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer to use.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateSkyViewEffectWrapper = (engine: AbstractEngine, uniformBuffer: UniformBuffer): EffectWrapper =>\r\n CreateEffectWrapper(\r\n engine,\r\n \"atmo-skyView\",\r\n \"skyView\",\r\n [\"depth\", ...(uniformBuffer.useUbo ? [] : uniformBuffer.getUniformNames())],\r\n [\"transmittanceLut\", \"multiScatteringLut\"],\r\n uniformBuffer.useUbo ? [uniformBuffer.name] : []\r\n );\r\n","import type { Scene } from \"core/scene\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math\";\r\n\r\nimport type { HtmlMesh } from \"./htmlMesh\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport type { SubMesh } from \"core/Meshes/subMesh\";\r\nimport { RenderingGroup } from \"core/Rendering/renderingGroup\";\r\n\r\nimport type { Observer } from \"core/Misc/observable\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport type { AbstractEngine } from \"core/Engines\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\n\r\nconst PositionUpdateFailMessage = \"Failed to update html mesh renderer position due to failure to get canvas rect. HtmlMesh instances may not render correctly\";\r\nconst BabylonUnitsToPixels = 100;\r\n\r\n/**\r\n * A function that compares two submeshes and returns a number indicating which\r\n * should be rendered first.\r\n */\r\ntype RenderOrderFunction = (subMeshA: SubMesh, subMeshB: SubMesh) => number;\r\n\r\ntype RenderLayerElements = {\r\n container: HTMLElement;\r\n domElement: HTMLElement;\r\n cameraElement: HTMLElement;\r\n};\r\n\r\n// Returns a function that ensures that HtmlMeshes are rendered before all other meshes.\r\n// Note this will only be applied to group 0.\r\n// If neither mesh is an HtmlMesh, then the default render order is used\r\n// This prevents HtmlMeshes from appearing in front of other meshes when they are behind them\r\nconst RenderOrderFunc = (defaultRenderOrder: RenderOrderFunction): RenderOrderFunction => {\r\n return (subMeshA: SubMesh, subMeshB: SubMesh) => {\r\n const meshA = subMeshA.getMesh();\r\n const meshB = subMeshB.getMesh();\r\n\r\n // Use property check instead of instanceof since it is less expensive and\r\n // this will be called many times per frame\r\n const meshIsHtmlMeshA = (meshA as any)[\"isHtmlMesh\"];\r\n const meshIsHtmlMeshB = (meshB as any)[\"isHtmlMesh\"];\r\n if (meshIsHtmlMeshA) {\r\n return meshIsHtmlMeshB ? (meshA.absolutePosition.z <= meshB.absolutePosition.z ? 1 : -1) : -1;\r\n } else {\r\n return meshIsHtmlMeshB ? 1 : defaultRenderOrder(subMeshA, subMeshB);\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * An instance of this is required to render HtmlMeshes in the scene.\r\n * if using HtmlMeshes, you must not set render order for group 0 using\r\n * scene.setRenderingOrder. You must instead pass the compare functions\r\n * to the HtmlMeshRenderer constructor. If you do not, then your render\r\n * order will be overwritten if the HtmlMeshRenderer is created after and\r\n * the HtmlMeshes will not render correctly (they will appear in front of\r\n * meshes that are actually in front of them) if the HtmlMeshRenderer is\r\n * created before.\r\n */\r\nexport class HtmlMeshRenderer {\r\n /**\r\n * Global scale factor applied to the homogeneous `w` component (m[15]) of the\r\n * transformation matrix when projecting 3D objects into pixel space.\r\n *\r\n * This value is used to balance Babylon units against screen pixels, ensuring\r\n * that HTML-mapped or screen-space objects appear with the correct relative\r\n * size. Adjust with care, as changing it affects the projection scale of all\r\n * transformed objects.\r\n *\r\n * The default value is `0.00001`, which works well when 1 Babylon unit\r\n * corresponds to 1 meter, and the typical screen resolution is around\r\n * 100 pixels per meter (i.e., 1 pixel per centimeter).\r\n */\r\n public static PROJECTION_SCALE_FACTOR = 0.00001;\r\n\r\n private _containerId?: string;\r\n private _inSceneElements?: RenderLayerElements | null;\r\n private _overlayElements?: RenderLayerElements | null;\r\n private _engine: AbstractEngine;\r\n\r\n private _cache = {\r\n cameraData: { fov: 0, position: new Vector3(), style: \"\" },\r\n htmlMeshData: new WeakMap<object, { style: string }>(),\r\n };\r\n private _width = 0;\r\n private _height = 0;\r\n private _heightHalf = 0;\r\n\r\n private _cameraWorldMatrix?: Matrix;\r\n\r\n // Create some refs to avoid creating new objects every frame\r\n private _temp = {\r\n scaleTransform: new Vector3(),\r\n rotationTransform: new Quaternion(),\r\n positionTransform: new Vector3(),\r\n objectMatrix: Matrix.Identity(),\r\n cameraWorldMatrix: Matrix.Identity(),\r\n cameraRotationMatrix: Matrix.Identity(),\r\n cameraWorldMatrixAsArray: new Array(16),\r\n };\r\n\r\n // Keep track of DPR so we can resize if DPR changes\r\n // Otherwise the DOM content will scale, but the mesh won't\r\n private _lastDevicePixelRatio = window.devicePixelRatio;\r\n\r\n // Keep track of camera matrix changes so we only update the\r\n // DOM element styles when necessary\r\n private _cameraMatrixUpdated = true;\r\n\r\n // Keep track of position changes so we only update the DOM element\r\n // styles when necessary\r\n private _previousCanvasDocumentPosition = {\r\n top: 0,\r\n left: 0,\r\n };\r\n\r\n private _renderObserver: Observer<Scene> | null = null;\r\n\r\n /**\r\n * Contruct an instance of HtmlMeshRenderer\r\n * @param scene\r\n * @param options object containing the following optional properties:\r\n * @returns\r\n */\r\n constructor(\r\n scene: Scene,\r\n {\r\n parentContainerId = null,\r\n _containerId = \"css-container\",\r\n enableOverlayRender = true,\r\n defaultOpaqueRenderOrder = RenderingGroup.PainterSortCompare,\r\n defaultAlphaTestRenderOrder = RenderingGroup.PainterSortCompare,\r\n defaultTransparentRenderOrder = RenderingGroup.defaultTransparentSortCompare,\r\n }: {\r\n parentContainerId?: string | null;\r\n _containerId?: string;\r\n defaultOpaqueRenderOrder?: RenderOrderFunction;\r\n defaultAlphaTestRenderOrder?: RenderOrderFunction;\r\n defaultTransparentRenderOrder?: RenderOrderFunction;\r\n enableOverlayRender?: boolean;\r\n } = {}\r\n ) {\r\n // Requires a browser to work. Only init if we are in a browser\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n this._containerId = _containerId;\r\n this._init(scene, parentContainerId, enableOverlayRender, defaultOpaqueRenderOrder, defaultAlphaTestRenderOrder, defaultTransparentRenderOrder);\r\n }\r\n\r\n /**\r\n * Dispose of the HtmlMeshRenderer\r\n */\r\n public dispose() {\r\n if (this._renderObserver) {\r\n this._renderObserver.remove();\r\n this._renderObserver = null;\r\n }\r\n\r\n this._overlayElements?.container.remove();\r\n this._overlayElements = null;\r\n\r\n this._inSceneElements?.container.remove();\r\n this._inSceneElements = null;\r\n }\r\n\r\n protected _init(\r\n scene: Scene,\r\n parentContainerId: string | null,\r\n enableOverlayRender: boolean,\r\n defaultOpaqueRenderOrder: RenderOrderFunction,\r\n defaultAlphaTestRenderOrder: RenderOrderFunction,\r\n defaultTransparentRenderOrder: RenderOrderFunction\r\n ): void {\r\n // Requires a browser to work. Only init if we are in a browser\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n\r\n // Create the DOM containers\r\n let parentContainer = parentContainerId ? document.getElementById(parentContainerId) : document.body;\r\n\r\n if (!parentContainer) {\r\n parentContainer = document.body;\r\n }\r\n\r\n // if the container already exists, then remove it\r\n const inSceneContainerId = `${this._containerId}_in_scene`;\r\n this._inSceneElements = this._createRenderLayerElements(inSceneContainerId);\r\n\r\n parentContainer.insertBefore(this._inSceneElements.container, parentContainer.firstChild);\r\n\r\n if (enableOverlayRender) {\r\n const overlayContainerId = `${this._containerId}_overlay`;\r\n this._overlayElements = this._createRenderLayerElements(overlayContainerId);\r\n const zIndex = +(scene.getEngine().getRenderingCanvas()!.style.zIndex ?? \"0\") + 1;\r\n this._overlayElements.container.style.zIndex = `${zIndex}`;\r\n this._overlayElements.container.style.pointerEvents = \"none\";\r\n parentContainer.insertBefore(this._overlayElements.container, parentContainer.firstChild);\r\n }\r\n this._engine = scene.getEngine();\r\n const clientRect = this._engine.getRenderingCanvasClientRect();\r\n if (!clientRect) {\r\n throw new Error(\"Failed to get client rect for rendering canvas\");\r\n }\r\n\r\n // Set the size and resize behavior\r\n this._setSize(clientRect.width, clientRect.height);\r\n\r\n this._engine.onResizeObservable.add(() => {\r\n const clientRect = this._engine.getRenderingCanvasClientRect();\r\n if (clientRect) {\r\n this._setSize(clientRect.width, clientRect.height);\r\n }\r\n });\r\n\r\n let projectionObs: Observer<Camera>;\r\n let matrixObs: Observer<Camera>;\r\n\r\n const observeCamera = () => {\r\n const camera = scene.activeCamera;\r\n if (camera) {\r\n projectionObs = camera.onProjectionMatrixChangedObservable.add(() => {\r\n this._onCameraMatrixChanged(camera);\r\n });\r\n matrixObs = camera.onViewMatrixChangedObservable.add(() => {\r\n this._onCameraMatrixChanged(camera);\r\n });\r\n }\r\n };\r\n\r\n observeCamera();\r\n\r\n scene.onActiveCameraChanged.add(() => {\r\n if (projectionObs) {\r\n scene.activeCamera?.onProjectionMatrixChangedObservable.remove(projectionObs);\r\n }\r\n if (matrixObs) {\r\n scene.activeCamera?.onViewMatrixChangedObservable.remove(matrixObs);\r\n }\r\n observeCamera();\r\n });\r\n\r\n // We need to make sure that HtmlMeshes are rendered before all other meshes\r\n // so that they don't appear in front of meshes that are actually in front of them\r\n // Updating the render order isn't ideal, but it is the only way to acheive this\r\n // The implication is that an app using the HtmlMeshRendered must set the scene render order\r\n // via the HtmlMeshRendered constructor\r\n const opaqueRenderOrder = RenderOrderFunc(defaultOpaqueRenderOrder);\r\n const alphaTestRenderOrder = RenderOrderFunc(defaultAlphaTestRenderOrder);\r\n const transparentRenderOrder = RenderOrderFunc(defaultTransparentRenderOrder);\r\n scene.setRenderingOrder(0, opaqueRenderOrder, alphaTestRenderOrder, transparentRenderOrder);\r\n\r\n this._renderObserver = scene.onBeforeRenderObservable.add(() => {\r\n this._render(scene, scene.activeCamera as Camera);\r\n });\r\n }\r\n\r\n private _createRenderLayerElements(containerId: string): RenderLayerElements {\r\n const existingContainer = document.getElementById(containerId);\r\n if (existingContainer) {\r\n existingContainer.remove();\r\n }\r\n const container = document.createElement(\"div\");\r\n container.id = containerId;\r\n container.style.position = \"absolute\";\r\n container.style.width = \"100%\";\r\n container.style.height = \"100%\";\r\n container.style.zIndex = \"-1\";\r\n\r\n const domElement = document.createElement(\"div\");\r\n domElement.style.overflow = \"hidden\";\r\n\r\n const cameraElement = document.createElement(\"div\");\r\n\r\n cameraElement.style.webkitTransformStyle = \"preserve-3d\";\r\n cameraElement.style.transformStyle = \"preserve-3d\";\r\n\r\n cameraElement.style.pointerEvents = \"none\";\r\n\r\n domElement.appendChild(cameraElement);\r\n container.appendChild(domElement);\r\n return {\r\n container,\r\n domElement,\r\n cameraElement,\r\n };\r\n }\r\n\r\n protected _getSize(): { width: number; height: number } {\r\n return {\r\n width: this._width,\r\n height: this._height,\r\n };\r\n }\r\n\r\n protected _setSize(width: number, height: number): void {\r\n this._width = width;\r\n this._height = height;\r\n this._heightHalf = this._height / 2;\r\n\r\n if (!this._inSceneElements || !this._overlayElements) {\r\n return;\r\n }\r\n\r\n const domElements = [this._inSceneElements.domElement, this._overlayElements.domElement, this._inSceneElements.cameraElement, this._overlayElements.cameraElement];\r\n for (const dom of domElements) {\r\n if (dom) {\r\n dom.style.width = `${width}px`;\r\n dom.style.height = `${height}px`;\r\n }\r\n }\r\n }\r\n\r\n // prettier-ignore\r\n protected _getCameraCssMatrix(matrix: Matrix): string {\r\n const elements = matrix.m;\r\n return `matrix3d(${\r\n this._epsilon( elements[0] )\r\n },${\r\n this._epsilon( - elements[1] )\r\n },${\r\n this._epsilon( elements[2] )\r\n },${\r\n this._epsilon( elements[3] )\r\n },${\r\n this._epsilon( elements[4] )\r\n },${\r\n this._epsilon( - elements[5] )\r\n },${\r\n this._epsilon( elements[6] )\r\n },${\r\n this._epsilon( elements[7] )\r\n },${\r\n this._epsilon( elements[8] )\r\n },${\r\n this._epsilon( - elements[9] )\r\n },${\r\n this._epsilon( elements[10] )\r\n },${\r\n this._epsilon( elements[11] )\r\n },${\r\n this._epsilon( elements[12] )\r\n },${\r\n this._epsilon( - elements[13] )\r\n },${\r\n this._epsilon( elements[14] )\r\n },${\r\n this._epsilon( elements[15] )\r\n })`;\r\n }\r\n\r\n // Convert a Babylon world matrix to a CSS matrix\r\n // This also handles conversion from BJS left handed coords\r\n // to CSS right handed coords\r\n // prettier-ignore\r\n protected _getHtmlContentCssMatrix(matrix: Matrix, useRightHandedSystem: boolean): string {\r\n const elements = matrix.m;\r\n // In a right handed coordinate system, the elements 11 to 14 have to change their direction\r\n const direction = useRightHandedSystem ? -1 : 1;\r\n const matrix3d = `matrix3d(${\r\n this._epsilon( elements[0] )\r\n },${\r\n this._epsilon( elements[1] )\r\n },${\r\n this._epsilon( elements[2] * -direction )\r\n },${\r\n this._epsilon( elements[3] )\r\n },${\r\n this._epsilon( - elements[4] )\r\n },${\r\n this._epsilon( - elements[5] )\r\n },${\r\n this._epsilon( elements[6] * direction )\r\n },${\r\n this._epsilon( - elements[7] )\r\n },${\r\n this._epsilon( elements[8] * -direction )\r\n },${\r\n this._epsilon( elements[9] * -direction )\r\n },${\r\n this._epsilon( elements[10] )\r\n },${\r\n this._epsilon( elements[11] * direction )\r\n },${\r\n this._epsilon( elements[12] * direction )\r\n },${\r\n this._epsilon( elements[13] * direction )\r\n },${\r\n this._epsilon( elements[14] * direction )\r\n },${\r\n this._epsilon( elements[15] )\r\n })`;\r\n return matrix3d;\r\n }\r\n\r\n protected _getTransformationMatrix(htmlMesh: HtmlMesh, useRightHandedSystem: boolean): Matrix {\r\n // Get the camera world matrix\r\n // Make sure the camera world matrix is up to date\r\n if (!this._cameraWorldMatrix) {\r\n this._cameraWorldMatrix = htmlMesh.getScene().activeCamera?.getWorldMatrix();\r\n }\r\n if (!this._cameraWorldMatrix) {\r\n return Matrix.Identity();\r\n }\r\n\r\n const objectWorldMatrix = htmlMesh.getWorldMatrix();\r\n\r\n // Scale the object matrix by the base scale factor for the mesh\r\n // which is the ratio of the mesh width/height to the renderer\r\n // width/height divided by the babylon units to pixels ratio\r\n let widthScaleFactor = 1;\r\n let heightScaleFactor = 1;\r\n if (htmlMesh.sourceWidth && htmlMesh.sourceHeight) {\r\n widthScaleFactor = htmlMesh.width! / (htmlMesh.sourceWidth / BabylonUnitsToPixels);\r\n heightScaleFactor = htmlMesh.height! / (htmlMesh.sourceHeight / BabylonUnitsToPixels);\r\n }\r\n\r\n // Apply the scale to the object's world matrix. Note we aren't scaling\r\n // the object, just getting a matrix as though it were scaled, so we can\r\n // scale the content\r\n const scaleTransform = this._temp.scaleTransform;\r\n const rotationTransform = this._temp.rotationTransform;\r\n const positionTransform = this._temp.positionTransform;\r\n const scaledAndTranslatedObjectMatrix = this._temp.objectMatrix;\r\n\r\n objectWorldMatrix.decompose(scaleTransform, rotationTransform, positionTransform);\r\n scaleTransform.x *= widthScaleFactor;\r\n scaleTransform.y *= heightScaleFactor;\r\n\r\n Matrix.ComposeToRef(scaleTransform, rotationTransform, positionTransform, scaledAndTranslatedObjectMatrix);\r\n\r\n // Adjust direction of 12 and 13 of the transformation matrix based on the handedness of the system\r\n const direction = useRightHandedSystem ? -1 : 1;\r\n // Adjust translation values to be from camera vs world origin\r\n // Note that we are also adjusting these values to be pixels vs Babylon units\r\n const position = htmlMesh.getAbsolutePosition();\r\n scaledAndTranslatedObjectMatrix.setRowFromFloats(\r\n 3,\r\n (-this._cameraWorldMatrix.m[12] + position.x) * BabylonUnitsToPixels * direction,\r\n (-this._cameraWorldMatrix.m[13] + position.y) * BabylonUnitsToPixels * direction,\r\n (this._cameraWorldMatrix.m[14] - position.z) * BabylonUnitsToPixels,\r\n this._cameraWorldMatrix.m[15] * HtmlMeshRenderer.PROJECTION_SCALE_FACTOR * BabylonUnitsToPixels\r\n );\r\n\r\n // Adjust other values to be pixels vs Babylon units\r\n scaledAndTranslatedObjectMatrix.multiplyAtIndex(3, BabylonUnitsToPixels);\r\n scaledAndTranslatedObjectMatrix.multiplyAtIndex(7, BabylonUnitsToPixels);\r\n scaledAndTranslatedObjectMatrix.multiplyAtIndex(11, BabylonUnitsToPixels);\r\n\r\n return scaledAndTranslatedObjectMatrix;\r\n }\r\n\r\n protected _renderHtmlMesh(htmlMesh: HtmlMesh, useRightHandedSystem: boolean) {\r\n if (!htmlMesh.element || !htmlMesh.element.firstElementChild) {\r\n // nothing to render, so bail\r\n return;\r\n }\r\n\r\n // We need to ensure html mesh data is initialized before\r\n // computing the base scale factor\r\n let htmlMeshData = this._cache.htmlMeshData.get(htmlMesh);\r\n if (!htmlMeshData) {\r\n htmlMeshData = { style: \"\" };\r\n this._cache.htmlMeshData.set(htmlMesh, htmlMeshData);\r\n }\r\n\r\n const cameraElement = htmlMesh._isCanvasOverlay ? this._overlayElements?.cameraElement : this._inSceneElements?.cameraElement;\r\n\r\n if (htmlMesh.element.parentNode !== cameraElement) {\r\n cameraElement!.appendChild(htmlMesh.element);\r\n }\r\n\r\n // If the htmlMesh content has changed, update the base scale factor\r\n if (htmlMesh.requiresUpdate) {\r\n this._updateBaseScaleFactor(htmlMesh);\r\n }\r\n\r\n // Get the transformation matrix for the html mesh\r\n const scaledAndTranslatedObjectMatrix = this._getTransformationMatrix(htmlMesh, useRightHandedSystem);\r\n\r\n let style = `translate(-50%, -50%) ${this._getHtmlContentCssMatrix(scaledAndTranslatedObjectMatrix, useRightHandedSystem)}`;\r\n // In a right handed system, screens are on the wrong side of the mesh, so we have to rotate by Math.PI which results in the matrix3d seen below\r\n // Also in RH + billboard mode, we cancel the handedness so we do not need to scale on x\r\n style += `${useRightHandedSystem ? `matrix3d(${htmlMesh.billboardMode !== TransformNode.BILLBOARDMODE_NONE ? 1 : -1}, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1)` : \"\"}`;\r\n\r\n if (htmlMeshData.style !== style) {\r\n htmlMesh.element.style.webkitTransform = style;\r\n htmlMesh.element.style.transform = style;\r\n }\r\n\r\n htmlMesh._markAsUpdated();\r\n }\r\n\r\n protected _render(scene: Scene, camera: Camera) {\r\n let needsUpdate = false;\r\n\r\n const useRightHandedSystem = scene.useRightHandedSystem;\r\n\r\n // Update the container position and size if necessary\r\n this._updateContainerPositionIfNeeded();\r\n\r\n // Check for a camera change\r\n if (this._cameraMatrixUpdated) {\r\n this._cameraMatrixUpdated = false;\r\n needsUpdate = true;\r\n }\r\n\r\n // If the camera position has changed, then we also need to update\r\n if (\r\n camera.position.x !== this._cache.cameraData.position.x ||\r\n camera.position.y !== this._cache.cameraData.position.y ||\r\n camera.position.z !== this._cache.cameraData.position.z\r\n ) {\r\n this._cache.cameraData.position.copyFrom(camera.position);\r\n needsUpdate = true;\r\n }\r\n\r\n // Check for a dpr change\r\n if (window.devicePixelRatio !== this._lastDevicePixelRatio) {\r\n this._lastDevicePixelRatio = window.devicePixelRatio;\r\n Logger.Log(\"In render - dpr changed: \", this._lastDevicePixelRatio);\r\n needsUpdate = true;\r\n }\r\n\r\n // Check if any meshes need to be updated\r\n const meshesNeedingUpdate = scene.meshes.filter((mesh) => (mesh as any)[\"isHtmlMesh\"] && (needsUpdate || (mesh as HtmlMesh).requiresUpdate));\r\n needsUpdate = needsUpdate || meshesNeedingUpdate.length > 0;\r\n\r\n if (!needsUpdate) {\r\n return;\r\n }\r\n\r\n // Get a projection matrix for the camera\r\n const projectionMatrix = camera.getProjectionMatrix();\r\n const fov = projectionMatrix.m[5] * this._heightHalf;\r\n\r\n if (this._cache.cameraData.fov !== fov) {\r\n const source = [this._overlayElements?.domElement, this._inSceneElements?.domElement];\r\n if (camera.mode == Camera.PERSPECTIVE_CAMERA) {\r\n for (const el of source) {\r\n if (el) {\r\n el.style.webkitPerspective = fov + \"px\";\r\n el.style.perspective = fov + \"px\";\r\n }\r\n }\r\n } else {\r\n for (const el of source) {\r\n if (el) {\r\n el.style.webkitPerspective = \"\";\r\n el.style.perspective = \"\";\r\n }\r\n }\r\n }\r\n this._cache.cameraData.fov = fov;\r\n }\r\n\r\n // Get the CSS matrix for the camera (which will include any camera rotation)\r\n if (camera.parent === null) {\r\n camera.computeWorldMatrix();\r\n }\r\n\r\n const cameraMatrixWorld = this._temp.cameraWorldMatrix;\r\n cameraMatrixWorld.copyFrom(camera.getWorldMatrix());\r\n const cameraRotationMatrix = this._temp.cameraRotationMatrix;\r\n cameraMatrixWorld.getRotationMatrix().transposeToRef(cameraRotationMatrix);\r\n\r\n const cameraMatrixWorldAsArray = this._temp.cameraWorldMatrixAsArray;\r\n cameraMatrixWorld.copyToArray(cameraMatrixWorldAsArray);\r\n\r\n // For a few values, we have to adjust the direction based on the handedness of the system\r\n const direction = useRightHandedSystem ? 1 : -1;\r\n\r\n cameraMatrixWorldAsArray[1] = cameraRotationMatrix.m[1];\r\n cameraMatrixWorldAsArray[2] = cameraRotationMatrix.m[2] * direction;\r\n cameraMatrixWorldAsArray[4] = cameraRotationMatrix.m[4] * direction;\r\n cameraMatrixWorldAsArray[6] = cameraRotationMatrix.m[6] * direction;\r\n cameraMatrixWorldAsArray[8] = cameraRotationMatrix.m[8] * direction;\r\n cameraMatrixWorldAsArray[9] = cameraRotationMatrix.m[9] * direction;\r\n\r\n Matrix.FromArrayToRef(cameraMatrixWorldAsArray, 0, cameraMatrixWorld);\r\n\r\n const cameraCSSMatrix = this._getCameraCssMatrix(cameraMatrixWorld);\r\n const style = cameraCSSMatrix;\r\n\r\n if (this._cache.cameraData.style !== style) {\r\n const source = [this._inSceneElements?.cameraElement, this._overlayElements?.cameraElement];\r\n for (const el of source) {\r\n if (el) {\r\n el.style.webkitTransform = style;\r\n el.style.transform = style;\r\n }\r\n }\r\n this._cache.cameraData.style = style;\r\n }\r\n\r\n // _Render objects if necessary\r\n for (const mesh of meshesNeedingUpdate) {\r\n this._renderHtmlMesh(mesh as HtmlMesh, useRightHandedSystem);\r\n }\r\n }\r\n\r\n protected _updateBaseScaleFactor(htmlMesh: HtmlMesh) {\r\n // Get screen width and height\r\n let screenWidth = this._width;\r\n let screenHeight = this._height;\r\n\r\n // Calculate aspect ratios\r\n const htmlMeshAspectRatio = (htmlMesh.width || 1) / (htmlMesh.height || 1);\r\n const screenAspectRatio = screenWidth / screenHeight;\r\n\r\n // Adjust screen dimensions based on aspect ratios\r\n if (htmlMeshAspectRatio > screenAspectRatio) {\r\n // If the HTML mesh is wider relative to its height than the screen, adjust the screen width\r\n screenWidth = screenHeight * htmlMeshAspectRatio;\r\n } else {\r\n // If the HTML mesh is taller relative to its width than the screen, adjust the screen height\r\n screenHeight = screenWidth / htmlMeshAspectRatio;\r\n }\r\n\r\n // Set content to fill screen so we get max resolution when it is shrunk to fit the mesh\r\n htmlMesh.setContentSizePx(screenWidth, screenHeight);\r\n }\r\n\r\n protected _updateContainerPositionIfNeeded() {\r\n // Determine if the canvas has moved on the screen\r\n const canvasRect = this._engine.getRenderingCanvasClientRect();\r\n\r\n // canvas rect may be null if layout not complete\r\n if (!canvasRect) {\r\n Logger.Warn(PositionUpdateFailMessage);\r\n return;\r\n }\r\n const scrollTop = window.scrollY;\r\n const scrollLeft = window.scrollX;\r\n const canvasDocumentTop = canvasRect.top + scrollTop;\r\n const canvasDocumentLeft = canvasRect.left + scrollLeft;\r\n\r\n if (this._previousCanvasDocumentPosition.top !== canvasDocumentTop || this._previousCanvasDocumentPosition.left !== canvasDocumentLeft) {\r\n this._previousCanvasDocumentPosition.top = canvasDocumentTop;\r\n this._previousCanvasDocumentPosition.left = canvasDocumentLeft;\r\n\r\n const source = [this._inSceneElements?.container, this._overlayElements?.container];\r\n for (const container of source) {\r\n if (!container) {\r\n continue;\r\n }\r\n // set the top and left of the css container to match the canvas\r\n const containerParent = container.offsetParent as HTMLElement;\r\n const parentRect = containerParent.getBoundingClientRect();\r\n const parentDocumentTop = parentRect.top + scrollTop;\r\n const parentDocumentLeft = parentRect.left + scrollLeft;\r\n\r\n const ancestorMarginsAndPadding = this._getAncestorMarginsAndPadding(containerParent);\r\n\r\n // Add the body margin\r\n const bodyStyle = window.getComputedStyle(document.body);\r\n const bodyMarginTop = parseInt(bodyStyle.marginTop, 10);\r\n const bodyMarginLeft = parseInt(bodyStyle.marginLeft, 10);\r\n\r\n container.style.top = `${canvasDocumentTop - parentDocumentTop - ancestorMarginsAndPadding.marginTop + ancestorMarginsAndPadding.paddingTop + bodyMarginTop}px`;\r\n container.style.left = `${\r\n canvasDocumentLeft - parentDocumentLeft - ancestorMarginsAndPadding.marginLeft + ancestorMarginsAndPadding.paddingLeft + bodyMarginLeft\r\n }px`;\r\n }\r\n }\r\n }\r\n\r\n protected _onCameraMatrixChanged = (camera: Camera) => {\r\n this._cameraWorldMatrix = camera.getWorldMatrix();\r\n this._cameraMatrixUpdated = true;\r\n };\r\n\r\n private _epsilon(value: number) {\r\n return Math.abs(value) < 1e-10 ? 0 : value;\r\n }\r\n\r\n // Get total margins and padding for an element, excluding the body and document margins\r\n private _getAncestorMarginsAndPadding(element: HTMLElement) {\r\n let marginTop = 0;\r\n let marginLeft = 0;\r\n let paddingTop = 0;\r\n let paddingLeft = 0;\r\n\r\n while (element && element !== document.body && element !== document.documentElement) {\r\n const style = window.getComputedStyle(element);\r\n marginTop += parseInt(style.marginTop, 10);\r\n marginLeft += parseInt(style.marginLeft, 10);\r\n paddingTop += parseInt(style.paddingTop, 10);\r\n paddingLeft += parseInt(style.paddingLeft, 10);\r\n element = element.offsetParent as HTMLElement;\r\n }\r\n\r\n return { marginTop, marginLeft, paddingTop, paddingLeft };\r\n }\r\n}\r\n","import { Tools } from \"core/Misc/tools\";\r\n\r\n// A capture management system to ensure that the correct object has the pointer\r\n// events by eliminating race conditions that can cause the pointer events to be\r\n// released by a different object after they are captured leaving no object\r\n// as the owner. It does this by queueing requests and only allowing\r\n// capture when the current capture owner releases pointer events.\r\n\r\ntype CaptureReleaseCallback = () => void;\r\n\r\ntype CaptureReleaseCallbacks = {\r\n capture: CaptureReleaseCallback;\r\n release: CaptureReleaseCallback;\r\n};\r\n\r\nlet CaptureRequestQueue: string[] = [];\r\n\r\n// Key is request id, value is object with capture and release callbacks\r\nconst PendingRequestCallbacks: Map<string, CaptureReleaseCallbacks> = new Map();\r\n\r\n// Keep track of release requests with no matching capture request\r\n// in case the release request arrived before the capture to avoid\r\n// the capture request never getting released.\r\nlet UnmatchedReleaseRequests: string[] = [];\r\n\r\nlet CurrentOwner: string | null = null; // Called on first capture or release request\r\n\r\n/**\r\n * Get the id of the object currently capturing pointer events\r\n * @returns The id of the object currently capturing pointer events\r\n * or null if no object is capturing pointer events\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const getCapturingId = () => {\r\n return CurrentOwner;\r\n};\r\n\r\n/**\r\n * Request that the object with the given id capture pointer events. If there is no current\r\n * owner, then the request is granted immediately. If there is a current owner, then the request\r\n * is queued until the current owner releases pointer events.\r\n * @param requestId An id to identify the request. This id will be used to match the capture\r\n * request with the release request.\r\n * @param captureCallback The callback to call when the request is granted and the object is capturing\r\n * @param releaseCallback The callback to call when the object is no longer capturing pointer events\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const requestCapture = (requestId: string, captureCallback: CaptureReleaseCallback, releaseCallback: CaptureReleaseCallback) => {\r\n DebugLog(`In pointerEventsCapture.requestCapture - Pointer events capture requested for ${requestId}`);\r\n\r\n // If there is a release for this request, then ignore the request\r\n if (RemoveUnmatchedRequest(requestId)) {\r\n DebugLog(`In pointerEventsCapture.requestCapture - Capture request matched previous release request ${requestId}. Cancelling capture request`);\r\n return;\r\n } else if (requestId !== CurrentOwner) {\r\n // if the request is not already in the queue, add it to the queue\r\n EnqueueCaptureRequest(requestId, captureCallback, releaseCallback);\r\n }\r\n\r\n if (!CurrentOwner) {\r\n // If there is no current owner, go ahead and grant the request\r\n TransferPointerEventsOwnership();\r\n }\r\n // If the request id is the current owner, do nothing\r\n};\r\n\r\n/**\r\n * Release pointer events from the object with the given id. If the object is the current owner\r\n * then pointer events are released immediately. If the object is not the current owner, then the\r\n * associated capture request is removed from the queue. If there is no matching capture request\r\n * in the queue, then the release request is added to a list of unmatched release requests and will\r\n * negate the next capture request with the same id. This is to guard against the possibility that\r\n * the release request arrived before the capture request.\r\n * @param requestId The id which should match the id of the capture request\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const requestRelease = (requestId: string | null) => {\r\n DebugLog(`In pointerEventsCapture.requestRelease - Pointer events release requested for ${requestId}`);\r\n\r\n // if the requestId is the current capture holder release it\r\n if (!requestId || requestId === CurrentOwner) {\r\n TransferPointerEventsOwnership();\r\n } else if (CancelRequest(requestId)) {\r\n // if the request is in the queue, but not the current capture holder, remove it and it's callbacks\r\n PendingRequestCallbacks.delete(requestId);\r\n } else {\r\n DebugLog(`In pointerEventsCapture.requestRelease - Received release request ${requestId} but no matching capture request was received`);\r\n // request was not current and not in queue, likely because we received a release\r\n // request before the capture. Add it to the unmatched list to guard against this possibility\r\n if (!UnmatchedReleaseRequests.includes(requestId)) {\r\n UnmatchedReleaseRequests.push(requestId);\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Release pointer events from the current owner\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const releaseCurrent = () => {\r\n requestRelease(CurrentOwner);\r\n};\r\n\r\nconst EnqueueCaptureRequest = (requestId: string, capture: CaptureReleaseCallback, release: CaptureReleaseCallback) => {\r\n DebugLog(`In pointerEventsCapture.enqueueCaptureRequest - Enqueueing capture request for ${requestId}`);\r\n if (!CaptureRequestQueue.includes(requestId)) {\r\n CaptureRequestQueue.push(requestId);\r\n PendingRequestCallbacks.set(requestId, { capture, release });\r\n }\r\n};\r\n\r\n// Removes the request from the queue if it exists. Returns true\r\n// if the request was found and removed, otherwise false\r\nconst CancelRequest = (requestId: string | null) => {\r\n let removed = false;\r\n CaptureRequestQueue = CaptureRequestQueue.filter((id) => {\r\n if (id !== requestId) {\r\n return true;\r\n } else {\r\n removed = true;\r\n DebugLog(`In pointerEventsCapture.cancelRequest - Canceling pointer events capture request ${requestId}`);\r\n return false;\r\n }\r\n });\r\n return removed;\r\n};\r\n\r\nconst RemoveUnmatchedRequest = (requestId: string) => {\r\n let removed = false;\r\n UnmatchedReleaseRequests = UnmatchedReleaseRequests.filter((id) => {\r\n if (id !== requestId) {\r\n return true;\r\n } else {\r\n removed = true;\r\n return false;\r\n }\r\n });\r\n return removed;\r\n};\r\n\r\nconst TransferPointerEventsOwnership = () => {\r\n const newOwnerId = NextCaptureRequest();\r\n DebugLog(`In pointerEventsCapture.transferPointerEventsOwnership - Transferrring pointer events from ${CurrentOwner} to ${newOwnerId}`);\r\n // Release the current owner\r\n DoRelease();\r\n if (newOwnerId) {\r\n DoCapture(newOwnerId);\r\n }\r\n};\r\n\r\nconst DoRelease = () => {\r\n DebugLog(`In pointerEventsCapture.doRelease - Releasing pointer events from ${CurrentOwner}`);\r\n if (CurrentOwner) {\r\n // call the release callback\r\n PendingRequestCallbacks.get(CurrentOwner)?.release();\r\n // And remove the callbacks\r\n PendingRequestCallbacks.delete(CurrentOwner);\r\n CurrentOwner = null;\r\n }\r\n};\r\n\r\nconst DoCapture = (newOwnerId: string) => {\r\n if (newOwnerId) {\r\n // call the capture callback\r\n PendingRequestCallbacks.get(newOwnerId)?.capture();\r\n }\r\n CurrentOwner = newOwnerId;\r\n DebugLog(`In pointerEventsCapture.doCapture - Pointer events now captured by ${newOwnerId}`);\r\n};\r\n\r\nconst NextCaptureRequest = () => {\r\n return CaptureRequestQueue.length > 0 ? CaptureRequestQueue.shift() : null;\r\n};\r\n\r\n// #region Debugging support\r\ndeclare global {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n interface Window {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n \"pointer-events-capture-debug\": boolean | null;\r\n }\r\n}\r\n\r\nconst DebugLog = (message: string) => {\r\n // If we are runnning in a test runner (in node, so window is not defined)\r\n // or if the debug flag is set, then log the message\r\n if (typeof window === \"undefined\" || window[\"pointer-events-capture-debug\"]) {\r\n Tools.Log(\r\n `${performance.now()} - game.scene.pointerEvents - ${message}\\ncurrentOwner: ${CurrentOwner}\\nqueue: ${CaptureRequestQueue}\\nunmatched: ${UnmatchedReleaseRequests}`\r\n );\r\n }\r\n};\r\n// #endregion Debugging support\r\n","import type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport type { Behavior } from \"core/Behaviors/behavior\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { requestCapture, requestRelease, releaseCurrent, getCapturingId } from \"./pointerEventsCapture\";\r\n\r\n// Module level variable for holding the current scene\r\nlet LocalScene: Scene | null = null;\r\n\r\n// Module level variable to hold the count of behavior instances that are currently capturing pointer events\r\n// on entry. This is used to determine if we need to start or stop observing pointer movement.\r\nlet CaptureOnEnterCount = 0;\r\n\r\n// Map used to store instance of the PointerEventsCaptureBehavior for a mesh\r\n// We do this because this gets checked on pointer move and we don't want to\r\n// use getBehaviorByName() because that is a linear search\r\nconst MeshToBehaviorMap = new WeakMap<AbstractMesh, PointerEventsCaptureBehavior>();\r\n\r\nconst StartCaptureOnEnter = (scene: Scene) => {\r\n // If we are not in a browser, do nothing\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n if (CaptureOnEnterCount === 0) {\r\n document.addEventListener(\"pointermove\", OnPointerMove);\r\n document.addEventListener(\"touchstart\", OnPointerMove);\r\n LocalScene = LocalScene ?? scene;\r\n Logger.Log(\"PointerEventsCaptureBehavior: Starting observation of pointer move events.\");\r\n LocalScene.onDisposeObservable.add(DoStopCaptureOnEnter);\r\n }\r\n CaptureOnEnterCount++;\r\n};\r\n\r\nconst DoStopCaptureOnEnter = () => {\r\n document.removeEventListener(\"pointermove\", OnPointerMove);\r\n document.removeEventListener(\"touchstart\", OnPointerMove);\r\n LocalScene = null;\r\n Logger.Log(\"PointerEventsCaptureBehavior: Stopping observation of pointer move events.\");\r\n CaptureOnEnterCount = 0;\r\n};\r\n\r\nconst StopCaptureOnEnter = () => {\r\n // If we are not in a browser, do nothing\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n\r\n // If we are not observing pointer movement, do nothing\r\n if (!LocalScene) {\r\n return;\r\n }\r\n\r\n CaptureOnEnterCount--;\r\n if (CaptureOnEnterCount <= 0) {\r\n DoStopCaptureOnEnter();\r\n }\r\n};\r\n\r\n// Module level function used to determine if an entered mesh should capture pointer events\r\nconst OnPointerMove = (evt: PointerEvent | TouchEvent) => {\r\n if (!LocalScene) {\r\n return;\r\n }\r\n\r\n const canvasRect = LocalScene.getEngine().getRenderingCanvasClientRect();\r\n if (!canvasRect) {\r\n return;\r\n }\r\n\r\n // Get the object that contains the client X and Y from either the pointer event or from the\r\n // TouchEvent touch\r\n const { clientX, clientY } = \"touches\" in evt ? evt.touches[0] : evt;\r\n\r\n // get the picked mesh, if any\r\n const pointerScreenX = clientX - canvasRect.left;\r\n const pointerScreenY = clientY - canvasRect.top;\r\n\r\n let pointerCaptureBehavior: PointerEventsCaptureBehavior | undefined;\r\n const pickResult = LocalScene.pick(pointerScreenX, pointerScreenY, (mesh) => {\r\n // If the mesh has an instance of PointerEventsCaptureBehavior attached to it,\r\n // and capture on pointer enter is true, then we want to pick it\r\n const pointerCaptureBehavior = MeshToBehaviorMap.get(mesh);\r\n return mesh.isEnabled() && typeof pointerCaptureBehavior !== \"undefined\" && pointerCaptureBehavior._captureOnPointerEnter;\r\n });\r\n\r\n let pickedMesh: AbstractMesh | null;\r\n if (pickResult.hit) {\r\n pickedMesh = pickResult.pickedMesh;\r\n } else {\r\n pickedMesh = null;\r\n }\r\n\r\n const capturingIdAsInt = parseInt(getCapturingId() || \"\");\r\n\r\n // if the picked mesh is the current capturing mesh, do nothing\r\n if (pickedMesh && pickedMesh.uniqueId === capturingIdAsInt) {\r\n return;\r\n }\r\n\r\n // If there is a capturing mesh and it is not the current picked mesh, or no\r\n // mesh is picked, release the capturing mesh\r\n if (capturingIdAsInt && (!pickedMesh || pickedMesh.uniqueId !== capturingIdAsInt)) {\r\n releaseCurrent();\r\n }\r\n\r\n // If there is a picked mesh and it is not the current capturing mesh, capture\r\n // the pointer events. Note that the current capturing mesh has already been\r\n // released above\r\n if (pickedMesh) {\r\n pointerCaptureBehavior = MeshToBehaviorMap.get(pickedMesh);\r\n pointerCaptureBehavior!.capturePointerEvents();\r\n }\r\n};\r\n\r\n/**\r\n * Behavior for any content that can capture pointer events, i.e. bypass the Babylon pointer event handling\r\n * and receive pointer events directly. It will register the capture triggers and negotiate the capture and\r\n * release of pointer events. Curerntly this applies only to HtmlMesh\r\n */\r\nexport class PointerEventsCaptureBehavior implements Behavior<AbstractMesh> {\r\n /** gets or sets behavior's name */\r\n public name = \"PointerEventsCaptureBehavior\";\r\n\r\n private _attachedMesh: AbstractMesh | null;\r\n /** @internal */\r\n public _captureOnPointerEnter: boolean;\r\n\r\n /**\r\n * Gets or sets the mesh that the behavior is attached to\r\n */\r\n public get attachedMesh() {\r\n return this._attachedMesh;\r\n }\r\n\r\n public set attachedMesh(value: AbstractMesh | null) {\r\n this._attachedMesh = value;\r\n }\r\n\r\n constructor(\r\n private _captureCallback: () => void,\r\n private _releaseCallback: () => void,\r\n { captureOnPointerEnter = true } = {}\r\n ) {\r\n this._attachedMesh = null;\r\n this._captureOnPointerEnter = captureOnPointerEnter;\r\n\r\n // Warn if we are not in a browser\r\n if (typeof document === \"undefined\") {\r\n Logger.Warn(`Creating an instance of PointerEventsCaptureBehavior outside of a browser. The behavior will not work.`);\r\n }\r\n }\r\n\r\n /**\r\n * Set if the behavior should capture pointer events when the pointer enters the mesh\r\n */\r\n public set captureOnPointerEnter(captureOnPointerEnter: boolean) {\r\n if (this._captureOnPointerEnter === captureOnPointerEnter) {\r\n return;\r\n }\r\n this._captureOnPointerEnter = captureOnPointerEnter;\r\n if (this._attachedMesh) {\r\n if (this._captureOnPointerEnter) {\r\n StartCaptureOnEnter(this._attachedMesh.getScene());\r\n } else {\r\n StopCaptureOnEnter();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Function called when the behavior needs to be initialized (before attaching it to a target)\r\n */\r\n public init() {}\r\n\r\n /**\r\n * Called when the behavior is attached to a target\r\n * @param mesh defines the target where the behavior is attached to\r\n */\r\n public attach(mesh: AbstractMesh) {\r\n // Add a reference to this behavior on the mesh. We do this so we can get a\r\n // reference to the behavior in the onPointerMove function without relying on\r\n // getBehaviorByName(), which does a linear search of the behaviors array.\r\n this.attachedMesh = mesh;\r\n MeshToBehaviorMap.set(mesh, this);\r\n if (this._captureOnPointerEnter) {\r\n StartCaptureOnEnter(mesh.getScene());\r\n }\r\n }\r\n\r\n /**\r\n * Called when the behavior is detached from its target\r\n */\r\n public detach() {\r\n if (!this.attachedMesh) {\r\n return;\r\n }\r\n // Remove the reference to this behavior from the mesh\r\n MeshToBehaviorMap.delete(this.attachedMesh);\r\n if (this._captureOnPointerEnter) {\r\n StopCaptureOnEnter();\r\n }\r\n this.attachedMesh = null;\r\n }\r\n\r\n /**\r\n * Dispose the behavior\r\n */\r\n public dispose() {\r\n this.detach();\r\n }\r\n\r\n // Release pointer events\r\n public releasePointerEvents() {\r\n if (!this.attachedMesh) {\r\n return;\r\n }\r\n requestRelease(this.attachedMesh.uniqueId.toString());\r\n }\r\n\r\n // Capture pointer events\r\n public capturePointerEvents() {\r\n if (!this.attachedMesh) {\r\n return;\r\n }\r\n requestCapture(this.attachedMesh.uniqueId.toString(), this._captureCallback, this._releaseCallback);\r\n }\r\n}\r\n","export type FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement;\r\n updateSize(sizingElement: HTMLElement, width: number, height: number): void;\r\n};\r\n\r\nconst FitStrategyContain: FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement {\r\n const sizingElement = document.createElement(\"div\");\r\n sizingElement.style.display = \"flex\";\r\n sizingElement.style.justifyContent = \"center\";\r\n sizingElement.style.alignItems = \"center\";\r\n const scalingElement = document.createElement(\"div\");\r\n scalingElement.style.visibility = \"hidden\";\r\n scalingElement.appendChild(element);\r\n sizingElement.appendChild(scalingElement);\r\n return sizingElement;\r\n },\r\n updateSize(sizingElement: HTMLElement, width: number, height: number) {\r\n const scalingElement = sizingElement.firstElementChild! as HTMLElement;\r\n sizingElement.style.width = `${width}px`;\r\n sizingElement.style.height = `${height}px`;\r\n\r\n const [childWidth, childHeight] = [scalingElement.offsetWidth, scalingElement.offsetHeight];\r\n const scale = Math.min(width / childWidth, height / childHeight);\r\n scalingElement.style.transform = `scale(${scale})`;\r\n scalingElement.style.visibility = \"visible\";\r\n },\r\n};\r\n\r\nconst FitStrategyCover: FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement {\r\n const sizingElement = document.createElement(\"div\");\r\n sizingElement.style.display = \"flex\";\r\n sizingElement.style.justifyContent = \"center\";\r\n sizingElement.style.alignItems = \"center\";\r\n sizingElement.style.overflow = \"hidden\";\r\n const scalingElement = document.createElement(\"div\");\r\n scalingElement.style.visibility = \"hidden\";\r\n scalingElement.appendChild(element);\r\n sizingElement.appendChild(scalingElement);\r\n return sizingElement;\r\n },\r\n updateSize(sizingElement: HTMLElement, width: number, height: number) {\r\n const scalingElement = sizingElement.firstElementChild! as HTMLElement;\r\n sizingElement.style.width = `${width}px`;\r\n sizingElement.style.height = `${height}px`;\r\n\r\n const [childWidth, childHeight] = [scalingElement.offsetWidth, scalingElement.offsetHeight];\r\n const scale = Math.max(width / childWidth, height / childHeight);\r\n scalingElement.style.transform = `scale(${scale})`;\r\n scalingElement.style.visibility = \"visible\";\r\n },\r\n};\r\n\r\nconst FitStrategyStretch: FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement {\r\n const sizingElement = document.createElement(\"div\");\r\n sizingElement.style.display = \"flex\";\r\n sizingElement.style.justifyContent = \"center\";\r\n sizingElement.style.alignItems = \"center\";\r\n const scalingElement = document.createElement(\"div\");\r\n scalingElement.style.visibility = \"hidden\";\r\n scalingElement.appendChild(element);\r\n sizingElement.appendChild(scalingElement);\r\n return sizingElement;\r\n },\r\n updateSize(sizingElement: HTMLElement, width: number, height: number) {\r\n const scalingElement = sizingElement.firstElementChild! as HTMLElement;\r\n sizingElement.style.width = `${width}px`;\r\n sizingElement.style.height = `${height}px`;\r\n\r\n const [childWidth, childHeight] = [scalingElement.offsetWidth, scalingElement.offsetHeight];\r\n scalingElement.style.transform = `scale(${width / childWidth}, ${height / childHeight})`;\r\n scalingElement.style.visibility = \"visible\";\r\n },\r\n};\r\n\r\nconst FitStrategyNone: FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement {\r\n return element;\r\n },\r\n updateSize(sizingElement: HTMLElement, width: number, height: number) {\r\n if (sizingElement) {\r\n sizingElement.style.width = `${width}px`;\r\n sizingElement.style.height = `${height}px`;\r\n }\r\n },\r\n};\r\n\r\nexport const FitStrategy = {\r\n CONTAIN: FitStrategyContain,\r\n COVER: FitStrategyCover,\r\n STRETCH: FitStrategyStretch,\r\n NONE: FitStrategyNone,\r\n};\r\n","import { Mesh } from \"core/Meshes/mesh\";\r\nimport { CreatePlaneVertexData } from \"core/Meshes/Builders/planeBuilder\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport { Matrix } from \"core/Maths/math\";\r\nimport { PointerEventsCaptureBehavior } from \"./pointerEventsCaptureBehavior\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport type { FitStrategyType } from \"./fitStrategy\";\r\nimport { FitStrategy } from \"./fitStrategy\";\r\n\r\n/**\r\n * This class represents HTML content that we want to render as though it is part of the scene. The HTML content is actually\r\n * rendered below the canvas, but a depth mask is created by this class that writes to the depth buffer but does not\r\n * write to the color buffer, effectively punching a hole in the canvas. CSS transforms are used to scale, translate, and rotate\r\n * the HTML content so that it matches the camera and mesh orientation. The class supports interactions in editable and non-editable mode.\r\n * In non-editable mode (the default), events are passed to the HTML content when the pointer is over the mask (and not occluded by other meshes\r\n * in the scene).\r\n * @see https://playground.babylonjs.com/#HVHYJC#5\r\n * @see https://playground.babylonjs.com/#B17TC7#112\r\n */\r\nexport class HtmlMesh extends Mesh {\r\n /**\r\n * Helps identifying a html mesh from a regular mesh\r\n */\r\n public get isHtmlMesh() {\r\n return true;\r\n }\r\n\r\n // Override the super class's _isEnabled property so we can control when the mesh\r\n // is enabled. I.e., we don't want to render the mesh until there is content to show.\r\n private _enabled = false;\r\n\r\n // The mesh is ready when content has been set and the content size has been set\r\n // The former is done by the user, the latter is done by the renderer.\r\n private _ready = false;\r\n\r\n /**\r\n * @internal\r\n */\r\n public _isCanvasOverlay = false;\r\n\r\n private _requiresUpdate = true;\r\n\r\n private _element?: HTMLElement;\r\n private _width?: number;\r\n private _height?: number;\r\n\r\n private _inverseScaleMatrix: Matrix | null = null;\r\n\r\n private _captureOnPointerEnter: boolean = true;\r\n private _pointerEventCaptureBehavior: PointerEventsCaptureBehavior | null = null;\r\n\r\n private _sourceWidth: number | null = null;\r\n private _sourceHeight: number | null = null;\r\n\r\n /**\r\n * Return the source width of the content in pixels\r\n */\r\n public get sourceWidth() {\r\n return this._sourceWidth;\r\n }\r\n\r\n /**\r\n * Return the source height of the content in pixels\r\n */\r\n public get sourceHeight() {\r\n return this._sourceHeight;\r\n }\r\n\r\n private _worldMatrixUpdateObserver: any;\r\n\r\n private _fitStrategy: FitStrategyType = FitStrategy.NONE;\r\n\r\n /**\r\n * Contruct an instance of HtmlMesh\r\n * @param scene\r\n * @param id The id of the mesh. Will be used as the id of the HTML element as well.\r\n * @param options object with optional parameters\r\n */\r\n constructor(scene: Scene, id: string, { captureOnPointerEnter = true, isCanvasOverlay = false, fitStrategy = FitStrategy.NONE } = {}) {\r\n super(id, scene);\r\n\r\n // Requires a browser to work. Bail if we aren't running in a browser\r\n if (typeof document === \"undefined\") {\r\n Logger.Warn(`Creating an instance of an HtmlMesh with id ${id} outside of a browser. The mesh will not be visible.`);\r\n return;\r\n }\r\n\r\n this._fitStrategy = fitStrategy;\r\n this._isCanvasOverlay = isCanvasOverlay;\r\n this._createMask();\r\n this._element = this._createElement();\r\n\r\n // Set enabled by default, so this will show as soon as it's ready\r\n this.setEnabled(true);\r\n\r\n this._captureOnPointerEnter = captureOnPointerEnter;\r\n\r\n // Create a behavior to capture pointer events\r\n this._pointerEventCaptureBehavior = new PointerEventsCaptureBehavior(this.capturePointerEvents.bind(this), this.releasePointerEvents.bind(this), {\r\n captureOnPointerEnter: this._captureOnPointerEnter,\r\n });\r\n this.addBehavior(this._pointerEventCaptureBehavior);\r\n }\r\n\r\n /**\r\n * The width of the content in pixels\r\n */\r\n public get width() {\r\n return this._width;\r\n }\r\n\r\n /**\r\n * The height of the content in pixels\r\n */\r\n public get height() {\r\n return this._height;\r\n }\r\n\r\n /**\r\n * The HTML element that is being rendered as a mesh\r\n */\r\n public get element() {\r\n return this._element;\r\n }\r\n\r\n /**\r\n * True if the mesh has been moved, rotated, or scaled since the last time this\r\n * property was read. This property is reset to false after reading.\r\n */\r\n public get requiresUpdate() {\r\n return this._requiresUpdate;\r\n }\r\n\r\n /**\r\n * Enable capture for the pointer when entering the mesh area\r\n */\r\n public set captureOnPointerEnter(captureOnPointerEnter: boolean) {\r\n this._captureOnPointerEnter = captureOnPointerEnter;\r\n if (this._pointerEventCaptureBehavior) {\r\n this._pointerEventCaptureBehavior.captureOnPointerEnter = captureOnPointerEnter;\r\n }\r\n }\r\n\r\n /**\r\n * Disposes of the mesh and the HTML element\r\n */\r\n public override dispose() {\r\n super.dispose();\r\n this._element?.remove();\r\n this._element = undefined;\r\n if (this._pointerEventCaptureBehavior) {\r\n this._pointerEventCaptureBehavior.dispose();\r\n this._pointerEventCaptureBehavior = null;\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _markAsUpdated() {\r\n this._requiresUpdate = false;\r\n }\r\n\r\n /**\r\n * Sets the content of the element to the specified content adjusting the mesh scale to match and making it visible.\r\n * If the the specified content is undefined, then it will make the mesh invisible. In either case it will clear the\r\n * element content first.\r\n * @param element The element to render as a mesh\r\n * @param width The width of the mesh in Babylon units\r\n * @param height The height of the mesh in Babylon units\r\n */\r\n setContent(element: HTMLElement, width: number, height: number) {\r\n // If content is changed, we are no longer ready\r\n this._setAsReady(false);\r\n\r\n // Also invalidate the source width and height\r\n this._sourceWidth = null;\r\n this._sourceHeight = null;\r\n\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n this._width = width;\r\n this._height = height;\r\n this._requiresUpdate = true;\r\n\r\n this.scaling.setAll(1);\r\n\r\n if (element) {\r\n this._element.appendChild(this._fitStrategy.wrapElement(element));\r\n\r\n this._updateScaleIfNecessary();\r\n }\r\n\r\n if (this.sourceWidth && this.sourceHeight) {\r\n this._setAsReady(true);\r\n }\r\n }\r\n\r\n // Overides BABYLON.Mesh.setEnabled\r\n public override setEnabled(enabled: boolean) {\r\n // Capture requested enabled state\r\n this._enabled = enabled;\r\n\r\n // If disabling or enabling and we are ready\r\n if (!enabled || this._ready) {\r\n this._doSetEnabled(enabled);\r\n }\r\n }\r\n\r\n /**\r\n * Sets the content size in pixels\r\n * @param width width of the source\r\n * @param height height of the source\r\n */\r\n public setContentSizePx(width: number, height: number) {\r\n this._sourceWidth = width;\r\n this._sourceHeight = height;\r\n\r\n if (!this._element || !this._element.firstElementChild) {\r\n return;\r\n }\r\n\r\n this._fitStrategy.updateSize(this._element.firstElementChild as HTMLElement, width, height);\r\n\r\n this._updateScaleIfNecessary();\r\n\r\n if (this.width && this.height) {\r\n this._setAsReady(true);\r\n }\r\n }\r\n\r\n protected _setAsReady(ready: boolean) {\r\n this._ready = ready;\r\n if (ready) {\r\n this._doSetEnabled(this._enabled);\r\n } else {\r\n this._doSetEnabled(false);\r\n }\r\n }\r\n\r\n protected _doSetEnabled(enabled: boolean) {\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n //if enabled, then start listening for changes to the\r\n // scaling, rotation, and position. otherwise stop listening\r\n if (enabled && !this._worldMatrixUpdateObserver) {\r\n this._worldMatrixUpdateObserver = this.onAfterWorldMatrixUpdateObservable.add(() => {\r\n this._requiresUpdate = true;\r\n });\r\n } else if (!enabled) {\r\n this._worldMatrixUpdateObserver?.remove();\r\n this._worldMatrixUpdateObserver = null;\r\n }\r\n\r\n // If enabled, then revert the content element display\r\n // otherwise hide it\r\n this._element.style.display = enabled ? \"\" : \"none\";\r\n // Capture the content z index\r\n this._setElementzIndex(this.position.z * -10000);\r\n super.setEnabled(enabled);\r\n }\r\n\r\n protected _updateScaleIfNecessary() {\r\n // If we have setContent before, the content scale is baked into the mesh. If we don't reset the vertices to\r\n // the original size, then we will multiply the scale when we bake the scale below. By applying the inverse, we back out\r\n // the scaling that has been done so we are starting from the same point.\r\n // First reset the scale to 1\r\n this.scaling.setAll(1);\r\n // Then back out the original vertices changes to match the content scale\r\n if (this._inverseScaleMatrix) {\r\n this.bakeTransformIntoVertices(this._inverseScaleMatrix);\r\n // Clear out the matrix so it doesn't get applied again unless we scale\r\n this._inverseScaleMatrix = null;\r\n }\r\n\r\n // Set scale to match content. Note we can't just scale the mesh, because that will scale the content as well\r\n // What we need to do is compute a scale matrix and then bake that into the mesh vertices. This will leave the\r\n // mesh scale at 1, so our content will stay it's original width and height until we scale the mesh.\r\n const scaleX = this._width || 1;\r\n const scaleY = this._height || 1;\r\n const scaleMatrix = Matrix.Scaling(scaleX, scaleY, 1);\r\n this.bakeTransformIntoVertices(scaleMatrix);\r\n\r\n // Get an inverse of the scale matrix that we can use to back out the scale changes we have made so\r\n // we don't multiply the scale.\r\n this._inverseScaleMatrix = new Matrix();\r\n scaleMatrix.invertToRef(this._inverseScaleMatrix);\r\n }\r\n\r\n protected _createMask() {\r\n const vertexData = CreatePlaneVertexData({ width: 1, height: 1 });\r\n vertexData.applyToMesh(this);\r\n\r\n const scene = this.getScene();\r\n this.checkCollisions = true;\r\n\r\n const depthMask = new StandardMaterial(`${this.id}-mat`, scene);\r\n if (!this._isCanvasOverlay) {\r\n depthMask.backFaceCulling = false;\r\n depthMask.disableColorWrite = true;\r\n depthMask.disableLighting = true;\r\n }\r\n\r\n this.material = depthMask;\r\n\r\n // Optimization - Freeze material since it never needs to change\r\n this.material.freeze();\r\n }\r\n\r\n protected _setElementzIndex(zIndex: number) {\r\n if (this._element) {\r\n this._element.style.zIndex = `${zIndex}`;\r\n }\r\n }\r\n\r\n /**\r\n * Callback used by the PointerEventsCaptureBehavior to capture pointer events\r\n */\r\n capturePointerEvents() {\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n // Enable dom content to capture pointer events\r\n this._element.style.pointerEvents = \"auto\";\r\n\r\n // Supress events outside of the dom content\r\n document.getElementsByTagName(\"body\")[0].style.pointerEvents = \"none\";\r\n }\r\n\r\n /**\r\n * Callback used by the PointerEventsCaptureBehavior to release pointer events\r\n */\r\n releasePointerEvents() {\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n // Enable pointer events on canvas\r\n document.getElementsByTagName(\"body\")[0].style.pointerEvents = \"auto\";\r\n\r\n // Disable pointer events on dom content\r\n this._element.style.pointerEvents = \"none\";\r\n }\r\n\r\n protected _createElement() {\r\n // Requires a browser to work. Bail if we aren't running in a browser\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n const div = document.createElement(\"div\");\r\n div.id = this.id;\r\n div.style.backgroundColor = this._isCanvasOverlay ? \"transparent\" : \"#000\";\r\n div.style.zIndex = \"1\";\r\n div.style.position = \"absolute\";\r\n div.style.pointerEvents = \"none\";\r\n div.style.backfaceVisibility = \"hidden\";\r\n\r\n return div;\r\n }\r\n}\r\n","/* eslint-disable jsdoc/require-jsdoc */\r\n\r\nimport type { IVector2Like } from \"core/Maths/math.like\";\r\n\r\n/** @internal */\r\nexport type ParagraphOptions = {\r\n maxWidth: number;\r\n lineHeight: number;\r\n letterSpacing: number;\r\n tabSize: number;\r\n whiteSpace: /* 'normal' | 'nowrap' | 'pre' | 'pre-wrap' | */ \"pre-line\" /* | 'break-spaces'*/;\r\n textAlign: \"left\" | \"right\" | \"center\" /* | 'justify'*/;\r\n translate: IVector2Like | undefined;\r\n};\r\n\r\n/** @internal */\r\nexport const DefaultParagraphOptions: ParagraphOptions = {\r\n maxWidth: Infinity,\r\n lineHeight: 1,\r\n letterSpacing: 1,\r\n tabSize: 4,\r\n whiteSpace: \"pre-line\",\r\n textAlign: \"center\",\r\n translate: { x: -0.5, y: -0.5 },\r\n};\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport type { FontAsset } from \"../fontAsset\";\r\nimport { DefaultParagraphOptions, type ParagraphOptions } from \"../paragraphOptions\";\r\nimport type { BMFontChar } from \"./bmFont\";\r\nimport type { SdfGlyph } from \"./glyph\";\r\nimport type { SdfTextLine } from \"./line\";\r\n\r\n/** @internal */\r\nexport class SdfTextParagraph {\r\n public readonly options: ParagraphOptions;\r\n\r\n get lineHeight() {\r\n return this.fontAsset._font.common.lineHeight * this.options.lineHeight;\r\n }\r\n\r\n readonly paragraph;\r\n readonly lines;\r\n readonly width;\r\n readonly height;\r\n readonly glyphs;\r\n\r\n constructor(\r\n public readonly text: string,\r\n public readonly fontAsset: FontAsset,\r\n options?: Partial<ParagraphOptions>\r\n ) {\r\n this.options = { ...DefaultParagraphOptions, ...options };\r\n\r\n const { paragraph, lines, glyphs, width, height } = this._computeMetrics(text);\r\n\r\n this.paragraph = paragraph;\r\n this.lines = lines;\r\n this.glyphs = glyphs;\r\n this.width = width;\r\n this.height = height;\r\n }\r\n\r\n private _computeMetrics(text: string) {\r\n const collapsed = this._collapse(text);\r\n const breaked = this._breakLines(collapsed);\r\n const trimmed = breaked.map((line) => line.trim());\r\n\r\n const lines: SdfTextLine[] = [];\r\n for (const line of trimmed) {\r\n lines.push(...this._wrap(line, lines.length));\r\n }\r\n\r\n const width = Math.max(...lines.map((line) => line.width));\r\n const height = this.lineHeight * lines.length;\r\n\r\n if (this.options.textAlign !== \"left\" || this.options.translate) {\r\n lines.forEach((line) => {\r\n const anchor = (() => {\r\n switch (this.options.textAlign) {\r\n case \"right\":\r\n return width - line.width;\r\n case \"center\":\r\n return (width - line.width) / 2;\r\n case \"left\":\r\n default:\r\n return 0;\r\n }\r\n })();\r\n\r\n const x = this.options.translate ? this.options.translate.x * width : 0;\r\n const y = this.options.translate ? this.options.translate.y * height : 0;\r\n for (const glyph of line.glyphs) {\r\n glyph.x += anchor;\r\n glyph.x += x;\r\n glyph.y += y;\r\n }\r\n });\r\n }\r\n\r\n const glyphs = lines.flatMap((line) => line.glyphs);\r\n\r\n return {\r\n paragraph: trimmed.join(\"\\n\"),\r\n lines,\r\n glyphs,\r\n width,\r\n height,\r\n };\r\n }\r\n\r\n private _breakLines(text: string) {\r\n return text.split(\"\\n\");\r\n }\r\n\r\n private _collapse(text: string) {\r\n return text.replace(/\\t/g, \" \".repeat(this.options.tabSize)).replace(/ +/g, \" \");\r\n }\r\n\r\n private _wrap(text: string, lineOffset = 0) {\r\n const lines = new Array<SdfTextLine>();\r\n\r\n let currentLine = lineOffset;\r\n let currentGlyphs = new Array<SdfGlyph>();\r\n let currentCursor = 0;\r\n let currentWidth = 0;\r\n let lastChar: BMFontChar | undefined;\r\n let start = 0;\r\n let end = start;\r\n\r\n const pushCurrentLine = () => {\r\n lines.push({\r\n text: text.slice(start, end),\r\n glyphs: currentGlyphs,\r\n start: start,\r\n end: end,\r\n width: currentWidth,\r\n });\r\n };\r\n\r\n while (end < text.length) {\r\n const i = end;\r\n const charCode = text.charCodeAt(i);\r\n const char = this.fontAsset._getChar(charCode);\r\n const charWidth = char.width;\r\n const kerning = lastChar ? this.fontAsset._getKerning(lastChar.id, char.id) : 0;\r\n\r\n currentCursor += kerning;\r\n const newWidth = currentCursor + charWidth;\r\n const cursorProgress = char.xadvance + this.options.letterSpacing;\r\n const nextPosition = currentCursor + cursorProgress;\r\n\r\n const shouldBreak = nextPosition > this.options.maxWidth || newWidth > this.options.maxWidth;\r\n\r\n if (shouldBreak) {\r\n pushCurrentLine();\r\n\r\n currentLine++;\r\n lastChar = undefined;\r\n currentCursor = 0;\r\n currentWidth = 0;\r\n start = end;\r\n end = start + 1;\r\n currentGlyphs = [];\r\n }\r\n\r\n const x = currentCursor;\r\n const y = currentLine * this.lineHeight;\r\n\r\n currentGlyphs.push({\r\n char,\r\n line: currentLine,\r\n position: currentGlyphs.length,\r\n x: x,\r\n y: y,\r\n });\r\n\r\n if (!shouldBreak) {\r\n lastChar = char;\r\n currentCursor = nextPosition;\r\n currentWidth = newWidth;\r\n end++;\r\n } else {\r\n currentCursor = cursorProgress;\r\n }\r\n }\r\n\r\n if (currentGlyphs.length > 0) {\r\n if (lastChar) {\r\n // currentWidth += lastChar.xadvance;\r\n }\r\n pushCurrentLine();\r\n }\r\n\r\n return lines;\r\n }\r\n}\r\n","import type { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Buffer } from \"core/Buffers/buffer\";\r\nimport type { AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { ThinEngine } from \"core/Engines/thinEngine\";\r\nimport { DrawWrapper } from \"core/Materials/drawWrapper\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport type { IDisposable } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { SdfTextParagraph } from \"./sdf/paragraph\";\r\nimport type { FontAsset } from \"./fontAsset\";\r\nimport type { ParagraphOptions } from \"./paragraphOptions\";\r\nimport { ThinMatrix } from \"core/Maths/ThinMaths/thinMath.matrix\";\r\nimport {\r\n CopyMatrixToArray,\r\n CopyMatrixToRef,\r\n IdentityMatrixToRef,\r\n MultiplyMatricesToRef,\r\n ScalingMatrixToRef,\r\n TranslationMatrixToRef,\r\n} from \"core/Maths/ThinMaths/thinMath.matrix.functions\";\r\nimport type { IColor4Like, IMatrixLike } from \"core/Maths/math.like\";\r\n\r\n/**\r\n * Abstract Node class from Babylon.js\r\n */\r\nexport interface INodeLike {\r\n getWorldMatrix(): IMatrixLike;\r\n}\r\n\r\n/**\r\n * Class used to render text using MSDF (Multi-channel Signed Distance Field) technique\r\n * Thanks a lot to the work of Bhushan_Wagh and zb_sj for their amazing work on MSDF for Babylon.js\r\n * #6RLCWP#16\r\n * Star wars scroller: #6RLCWP#29\r\n * With metrics: #6RLCWP#35\r\n * Thickness: #IABMEZ#3\r\n * Solar system: #9YCDYC#9\r\n * Stroke: #6RLCWP#37\r\n */\r\nexport class TextRenderer implements IDisposable {\r\n private readonly _useVAO: boolean = false;\r\n private _engine: AbstractEngine;\r\n private _shaderLanguage: ShaderLanguage;\r\n private _vertexBuffers: { [key: string]: VertexBuffer } = {};\r\n private _spriteBuffer: Nullable<Buffer>;\r\n private _worldBuffer: Nullable<Buffer>;\r\n private _uvBuffer: Nullable<Buffer>;\r\n private _drawWrapperBase: DrawWrapper;\r\n private _vertexArrayObject: WebGLVertexArrayObject;\r\n private _font: FontAsset;\r\n private _charMatrices = new Array<number>();\r\n private _charUvs = new Array<number>();\r\n private _isDirty = true;\r\n private _baseLine = 0;\r\n\r\n // Cache\r\n private _scalingMatrix = new ThinMatrix();\r\n private _fontScaleMatrix = new ThinMatrix();\r\n private _offsetMatrix = new ThinMatrix();\r\n private _translationMatrix = new ThinMatrix();\r\n private _baseMatrix = new ThinMatrix();\r\n private _scaledMatrix = new ThinMatrix();\r\n private _localMatrix = new ThinMatrix();\r\n private _finalMatrix = new ThinMatrix();\r\n private _lineMatrix = new ThinMatrix();\r\n private _parentWorldMatrix = new ThinMatrix();\r\n\r\n /**\r\n * Gets or sets the color of the text\r\n */\r\n public color: IColor4Like = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };\r\n\r\n /**\r\n * Gets or sets the color of the stroke around the text\r\n */\r\n public strokeColor: IColor4Like = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };\r\n\r\n /**\r\n * Gets or sets the width of the stroke around the text (inset)\r\n */\r\n public strokeInsetWidth = 0;\r\n\r\n /**\r\n * Gets or sets the width of the stroke around the text (outset)\r\n */\r\n public strokeOutsetWidth = 0;\r\n\r\n /**\r\n * Gets or sets the thickness of the text (0 means as defined in the font)\r\n * Value must be between -0.5 and 0.5\r\n */\r\n public thicknessControl = 0;\r\n\r\n private _parent: Nullable<INodeLike> = null;\r\n\r\n /**\r\n * Gets or sets the parent of the text renderer\r\n */\r\n public get parent(): Nullable<INodeLike> {\r\n return this._parent;\r\n }\r\n\r\n public set parent(value: Nullable<INodeLike>) {\r\n this._parent = value;\r\n }\r\n\r\n private _transformMatrix: IMatrixLike = new ThinMatrix();\r\n\r\n /**\r\n * Gets or sets the transform matrix of the text renderer\r\n * It will be applied in that order:\r\n * parent x transform x paragraph world\r\n */\r\n public get transformMatrix(): IMatrixLike {\r\n return this._transformMatrix;\r\n }\r\n\r\n public set transformMatrix(value: IMatrixLike) {\r\n this._transformMatrix = value;\r\n }\r\n\r\n /**\r\n * Gets or sets if the text is billboarded\r\n */\r\n public isBillboard = false;\r\n\r\n /**\r\n * Gets or sets if the text is screen projected\r\n * This will work only if the text is billboarded\r\n */\r\n public isBillboardScreenProjected = false;\r\n\r\n /**\r\n * Gets the number of characters in the text renderer\r\n */\r\n public get characterCount(): number {\r\n return this._charMatrices.length / 16;\r\n }\r\n\r\n /**\r\n * Gets or sets if the text renderer should ignore the depth buffer\r\n * Default is false\r\n */\r\n public ignoreDepthBuffer = false;\r\n\r\n private constructor(engine: AbstractEngine, shaderLanguage: ShaderLanguage = ShaderLanguage.GLSL, font: FontAsset) {\r\n this._engine = engine;\r\n this._shaderLanguage = shaderLanguage;\r\n this._font = font;\r\n this._baseLine = font._font.common.lineHeight * font.scale;\r\n\r\n this._useVAO = engine.getCaps().vertexArrayObject && !engine.disableVertexArrayObjects;\r\n\r\n // Main vertex buffer\r\n const spriteData = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);\r\n this._spriteBuffer = new Buffer(engine, spriteData, false, 2);\r\n this._vertexBuffers[\"offsets\"] = this._spriteBuffer.createVertexBuffer(\"offsets\", 0, 2);\r\n\r\n // Instances\r\n this._resizeBuffers(128);\r\n }\r\n\r\n private _resizeBuffers(capacity: number) {\r\n if (this._worldBuffer) {\r\n this._worldBuffer.dispose();\r\n this._worldBuffer = null;\r\n }\r\n\r\n if (this._uvBuffer) {\r\n this._uvBuffer.dispose();\r\n this._uvBuffer = null;\r\n }\r\n\r\n this._worldBuffer = new Buffer(this._engine, new Float32Array(capacity * 16), true, 16);\r\n this._vertexBuffers[\"world0\"] = this._worldBuffer.createVertexBuffer(\"world0\", 0, 4, 16, true);\r\n this._vertexBuffers[\"world1\"] = this._worldBuffer.createVertexBuffer(\"world1\", 4, 4, 16, true);\r\n this._vertexBuffers[\"world2\"] = this._worldBuffer.createVertexBuffer(\"world2\", 8, 4, 16, true);\r\n this._vertexBuffers[\"world3\"] = this._worldBuffer.createVertexBuffer(\"world3\", 12, 4, 16, true);\r\n\r\n this._uvBuffer = new Buffer(this._engine, new Float32Array(capacity * 4), true, 4);\r\n this._vertexBuffers[\"uvs\"] = this._uvBuffer.createVertexBuffer(\"uvs\", 0, 4, 4, true);\r\n }\r\n\r\n private _setShaders(vertex: string, fragment: string) {\r\n this._drawWrapperBase?.dispose();\r\n\r\n this._drawWrapperBase = new DrawWrapper(this._engine);\r\n\r\n if (this._drawWrapperBase.drawContext) {\r\n this._drawWrapperBase.drawContext.useInstancing = true;\r\n }\r\n\r\n const defines = \"\";\r\n\r\n this._drawWrapperBase.effect = this._engine.createEffect(\r\n {\r\n vertexSource: vertex,\r\n fragmentSource: fragment,\r\n },\r\n [\"offsets\", \"world0\", \"world1\", \"world2\", \"world3\", \"uvs\"],\r\n [\"parentWorld\", \"view\", \"projection\", \"uColor\", \"thickness\", \"uStrokeColor\", \"uStrokeInsetWidth\", \"uStrokeOutsetWidth\", \"mode\", \"transform\"],\r\n [\"fontAtlas\"],\r\n defines,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n this._shaderLanguage\r\n );\r\n\r\n this._drawWrapperBase.effect._refCount++;\r\n }\r\n\r\n /**\r\n * Add a paragraph of text to the renderer\r\n * @param text define the text to add\r\n * @param options define the options to use for the paragraph (optional)\r\n * @param worldMatrix define the world matrix to use for the paragraph (optional)\r\n */\r\n public addParagraph(text: string, options?: Partial<ParagraphOptions>, worldMatrix?: IMatrixLike) {\r\n const paragraph = new SdfTextParagraph(text, this._font, options);\r\n\r\n const fontScale = this._font.scale;\r\n\r\n const texWidth = this._font._font.common.scaleW;\r\n const texHeight = this._font._font.common.scaleH;\r\n const glyphs = paragraph.glyphs.filter((g) => g.char.page >= 0);\r\n\r\n let worldMatrixToUse = worldMatrix;\r\n\r\n if (!worldMatrixToUse) {\r\n const lineHeight = paragraph.lineHeight * fontScale;\r\n const lineOffset = (paragraph.lines.length * lineHeight) / 2;\r\n TranslationMatrixToRef(0, this._baseLine - lineOffset, 0, this._lineMatrix);\r\n worldMatrixToUse = this._lineMatrix;\r\n }\r\n\r\n ScalingMatrixToRef(fontScale, fontScale, 1.0, this._fontScaleMatrix);\r\n TranslationMatrixToRef(0.5, -0.5, 0, this._offsetMatrix);\r\n\r\n const charsUvsBase = this._charUvs.length;\r\n const matricesBase = this._charMatrices.length;\r\n glyphs.forEach((g, i) => {\r\n this._charUvs[charsUvsBase + i * 4 + 0] = g.char.x / texWidth;\r\n this._charUvs[charsUvsBase + i * 4 + 1] = g.char.y / texHeight;\r\n this._charUvs[charsUvsBase + i * 4 + 2] = g.char.width / texWidth;\r\n this._charUvs[charsUvsBase + i * 4 + 3] = g.char.height / texHeight;\r\n\r\n const x = g.x + g.char.xoffset;\r\n const y = 1.0 - (g.y + g.char.yoffset);\r\n\r\n ScalingMatrixToRef(g.char.width, g.char.height, 1.0, this._scalingMatrix);\r\n MultiplyMatricesToRef(this._offsetMatrix, this._scalingMatrix, this._baseMatrix);\r\n\r\n TranslationMatrixToRef(x * fontScale, y * fontScale, 0.0, this._translationMatrix);\r\n MultiplyMatricesToRef(this._baseMatrix, this._fontScaleMatrix, this._scaledMatrix);\r\n MultiplyMatricesToRef(this._scaledMatrix, this._translationMatrix, this._localMatrix);\r\n\r\n MultiplyMatricesToRef(this._localMatrix, worldMatrixToUse, this._finalMatrix);\r\n CopyMatrixToArray(this._finalMatrix, this._charMatrices, matricesBase + i * 16);\r\n });\r\n\r\n this._isDirty = true;\r\n\r\n this._baseLine -= paragraph.lineHeight * fontScale * paragraph.lines.length;\r\n }\r\n\r\n /**\r\n * Render the text using the provided view and projection matrices\r\n * @param viewMatrix define the view matrix to use\r\n * @param projectionMatrix define the projection matrix to use\r\n */\r\n public render(viewMatrix: IMatrixLike, projectionMatrix: IMatrixLike): void {\r\n const drawWrapper = this._drawWrapperBase;\r\n\r\n const effect = drawWrapper.effect!;\r\n\r\n // Check\r\n if (!effect.isReady()) {\r\n return;\r\n }\r\n const engine = this._engine;\r\n\r\n engine.setState(false);\r\n engine.enableEffect(drawWrapper);\r\n\r\n if (this.ignoreDepthBuffer) {\r\n engine.setDepthBuffer(false);\r\n }\r\n\r\n if (this._parent) {\r\n CopyMatrixToRef(this._parent.getWorldMatrix(), this._parentWorldMatrix);\r\n } else {\r\n IdentityMatrixToRef(this._parentWorldMatrix);\r\n }\r\n\r\n effect.setInt(\"mode\", this.isBillboard ? (this.isBillboardScreenProjected ? 2 : 1) : 0);\r\n effect.setMatrix(\"parentWorld\", this._parentWorldMatrix);\r\n effect.setMatrix(\"view\", viewMatrix);\r\n effect.setMatrix(\"projection\", projectionMatrix);\r\n effect.setMatrix(\"transform\", this.transformMatrix);\r\n\r\n // Texture\r\n effect.setTexture(\"fontAtlas\", this._font.textures[0]);\r\n effect.setDirectColor4(\"uColor\", this.color);\r\n effect.setDirectColor4(\"uStrokeColor\", this.strokeColor);\r\n effect.setFloat(\"thickness\", this.thicknessControl * 0.9);\r\n effect.setFloat(\"uStrokeInsetWidth\", this.strokeInsetWidth);\r\n effect.setFloat(\"uStrokeOutsetWidth\", this.strokeOutsetWidth);\r\n\r\n const instanceCount = this._charMatrices.length / 16;\r\n\r\n // Need update?\r\n if (this._isDirty) {\r\n this._isDirty = false;\r\n\r\n if (this._worldBuffer!.getBuffer()!.capacity / 4 < instanceCount * 16) {\r\n this._resizeBuffers(instanceCount);\r\n }\r\n\r\n this._worldBuffer!.update(this._charMatrices);\r\n this._uvBuffer!.update(this._charUvs);\r\n }\r\n\r\n if (this._useVAO) {\r\n if (!this._vertexArrayObject) {\r\n this._vertexArrayObject = (engine as ThinEngine).recordVertexArrayObject(this._vertexBuffers, null, effect);\r\n }\r\n (engine as ThinEngine).bindVertexArrayObject(this._vertexArrayObject, null);\r\n } else {\r\n // VBOs\r\n engine.bindBuffers(this._vertexBuffers, null, effect);\r\n }\r\n\r\n engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, instanceCount);\r\n engine.unbindInstanceAttributes();\r\n engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n\r\n if (this.ignoreDepthBuffer) {\r\n engine.setDepthBuffer(true);\r\n }\r\n }\r\n\r\n /**\r\n * Release associated resources\r\n */\r\n public dispose(): void {\r\n if (this._worldBuffer) {\r\n this._worldBuffer.dispose();\r\n this._worldBuffer = null;\r\n }\r\n\r\n if (this._uvBuffer) {\r\n this._uvBuffer.dispose();\r\n this._uvBuffer = null;\r\n }\r\n\r\n if (this._spriteBuffer) {\r\n this._spriteBuffer.dispose();\r\n this._spriteBuffer = null;\r\n }\r\n\r\n if (this._vertexArrayObject) {\r\n (this._engine as ThinEngine).releaseVertexArrayObject(this._vertexArrayObject);\r\n (<any>this._vertexArrayObject) = null;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new TextRenderer instance asynchronously\r\n * @param font define the font asset to use\r\n * @param engine define the engine to use\r\n * @returns a promise that resolves to the created TextRenderer instance\r\n */\r\n public static async CreateTextRendererAsync(font: FontAsset, engine: AbstractEngine) {\r\n if (!engine.getCaps().instancedArrays || !engine._features.supportSpriteInstancing) {\r\n throw new Error(\"Instanced arrays are required for MSDF text rendering.\");\r\n }\r\n\r\n let shaderLanguage = ShaderLanguage.GLSL;\r\n let vertex: string = \"\";\r\n let fragment: string = \"\";\r\n if (engine.isWebGPU) {\r\n shaderLanguage = ShaderLanguage.WGSL;\r\n vertex = (await import(\"./shadersWGSL/msdf.vertex\")).msdfVertexShaderWGSL.shader;\r\n fragment = (await import(\"./shadersWGSL/msdf.fragment\")).msdfPixelShaderWGSL.shader;\r\n } else {\r\n vertex = (await import(\"./shaders/msdf.vertex\")).msdfVertexShader.shader;\r\n fragment = (await import(\"./shaders/msdf.fragment\")).msdfPixelShader.shader;\r\n }\r\n\r\n const textRenderer = new TextRenderer(engine, shaderLanguage, font);\r\n textRenderer._setShaders(vertex, fragment);\r\n\r\n return textRenderer;\r\n }\r\n}\r\n","import * as addons from \"addons/index\";\r\n\r\nexport { addons };\r\nexport default addons;\r\n"],"names":["root","factory","exports","module","require","define","amd","self","global","this","__WEBPACK_EXTERNAL_MODULE__597__","name","shader","ShaderStore","ShadersStore","msdfVertexShader","ShadersStoreWGSL","msdfPixelShaderWGSL","msdfPixelShader","msdfVertexShaderWGSL","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","n","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","extendStatics","b","setPrototypeOf","__proto__","Array","p","__extends","TypeError","String","__","constructor","create","__assign","assign","t","s","i","arguments","length","apply","__spreadArray","to","from","pack","ar","l","slice","concat","SuppressedError","UboArray","useAerialPerspectiveLut","APPLY_AERIAL_PERSPECTIVE_INTENSITY","APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS","USE_AERIAL_PERSPECTIVE_LUT","MaterialDefines","size","type","material","_atmosphere","_isAerialPerspectiveEnabled","USE_CUSTOM_REFLECTION","diffuseSkyIrradianceLut","CUSTOM_FRAGMENT_BEFORE_FOG","isAerialPerspectiveLutEnabled","aerialPerspectiveIntensity","aerialPerspectiveRadianceBias","doNotSerialize","_pluginManager","_addPlugin","getUniformBuffersNames","_ubos","uniformBuffer","useUbo","push","getUniforms","atmosphere","ubo","fragment","externalUniforms","getUniformNames","isReadyForSubMesh","isReady","aerialPerspectiveLutRenderTarget","transmittanceLutRenderTarget","transmittanceLut","renderTarget","getActiveTextures","_activeTextures","bindForSubMesh","engine","scene","getEngine","effect","currentEffect","bindUniformBufferToEffect","width","getRenderWidth","height","getRenderHeight","updateFloat2","setTexture","prepareDefines","defines","lastUseAerialPerspectiveLut","lastApplyAerialPerspectiveIntensity","lastApplyAerialPerspectiveRadianceBias","markAllAsDirty","getSamplers","samplers","getCustomCode","shaderType","directionToLightSnippet","supportsUniformBuffers","atmosphereImportSnippet","CUSTOM_FRAGMENT_DEFINITIONS","CUSTOM_LIGHT0_COLOR","CUSTOM_REFLECTION","MaterialPluginBase","TempRay","Ray","Vector3","Zero","_inverseViewProjectionMatrixWithoutTranslation","Matrix","Identity","_directionToLightRelativeToCameraGeocentricNormal","Up","_cosAngleLightToZenith","_cameraRadius","_clampedCameraRadius","_cameraHeight","_clampedCameraHeight","_cameraPositionGlobal","_clampedCameraPositionGlobal","_cosCameraHorizonAngleFromZenith","_sinCameraAtmosphereHorizonAngleFromNadir","_cameraGeocentricNormal","_cameraForward","Down","_cameraNearPlane","_cameraPosition","_viewport","Vector4","_lastViewMatrix","_lastProjectionMatrix","_inverseViewMatrixWithoutTranslation","_inverseProjectionMatrix","update","camera","planetRadius","planetRadiusWithOffset","atmosphereRadius","directionToLight","originHeight","minZ","copyFrom","getForwardRayToRef","direction","getScene","copyFromFloats","viewMatrix","getViewMatrix","projectionMatrix","getProjectionMatrix","equals","setTranslation","ZeroReadOnly","invertToRef","multiplyToRef","globalPosition","scaleToRef","y","normalizeToRef","ComputeCosHorizonAngleFromZenith","Math","min","Vector3Dot","lightZenithSinAngle","sqrt","max","normalize","radius","sinHorizonAngleFromNadir","DefaultPeakRayleighScattering","DefaultPeakMieScattering","DefaultPeakMieAbsorption","DefaultPeakOzoneAbsorption","options","onChangedObservable","Observable","_peakRayleighScattering","_peakMieScattering","_peakMieAbsorption","_peakOzoneAbsorption","_planetRadiusWithOffset","_planetRadiusSquared","_atmosphereRadius","_atmosphereRadiusSquared","_horizonDistanceToAtmosphereEdge","_horizonDistanceToAtmosphereEdgeSquared","_rayleighScattering","_mieScattering","_mieAbsorption","_mieExtinction","_ozoneAbsorption","_planetRadius","_planetRadiusOffset","planetRadiusOffset","_atmosphereThickness","atmosphereThickness","_rayleighScatteringScale","rayleighScatteringScale","peakRayleighScattering","_mieScatteringScale","mieScatteringScale","peakMieScattering","_mieAbsorptionScale","mieAbsorptionScale","peakMieAbsorption","_ozoneAbsorptionScale","ozoneAbsorptionScale","peakOzoneAbsorption","_recomputeDimensionalParameters","_recomputeRayleighScattering","_recomputeMieScattering","_recomputeMieAbsorption","_recomputeOzoneAbsorption","notifyObservers","_recomputeMieExtinction","addToRef","MakeTempColor4Like","Number","NaN","g","TmpColor1","TmpColor2","TmpColor3","TmpColor4","Sample2DRgbaToRef","u","v","widthPx","heightPx","data","result","normalizeFunc","Error","expectedLength","Clamp","fractionalTexelX","fractionalTexelY","xLeft","floor","xRight","yBottom","yTop","lowerLeftColor","TexelFetch2DRgbaToRef","upperLeftColor","lowerRightColor","upperRightColor","tX","tY","oneMinusTX","oneMinusTY","w0","w1","w2","w3","x","clampedTexelX","index","IncludesShadersStore","UvTemp","Color4Temp","_renderTarget","_effectWrapper","_effectRenderer","_isDirty","_isDisposed","_lutData","Uint16Array","RenderTargetTexture","generateMipMaps","Constants","TEXTURETYPE_HALF_FLOAT","samplingMode","TEXTURE_BILINEAR_SAMPLINGMODE","generateDepthBuffer","gammaSpace","wrapU","TEXTURE_CLAMP_ADDRESSMODE","wrapV","anisotropicFilteringLevel","skipInitialClear","EffectWrapper","vertexShader","fragmentShader","attributeNames","uniformNames","uniformBuffers","useShaderStore","EffectRenderer","indices","positions","environmentTexture","irradianceTexture","environmentIntensity","isRenderTarget","getDiffuseSkyIrradianceToRef","cameraGeocentricNormal","lightIrradiance","additionalDiffuseSkyIrradiance","properties","physicalProperties","cosAngleLightToZenith","unitX","unitY","ComputeLutUVToRef","z","FromHalfFloat","intensity","diffuseSkyIrradianceIntensity","render","effectWrapper","bindFramebuffer","effectRenderer","applyEffectWrapper","saveStates","setViewport","bindBuffers","multiScatteringLutRenderTarget","setFloat","draw","restoreStates","restoreDefaultFramebuffer","readPixels","then","markDirty","dispose","TransmittanceHorizonRange","Uv","LightColorTemp","DirectionToLightTemp","onUpdatedObservable","Uint8Array","TEXTURETYPE_UNSIGNED_BYTE","getTransmittedColorToRef","pointRadius","pointGeocentricNormal","lutData","positionDistanceToOrigin","uv","radiusSquared","distanceToHorizon","planetRadiusSquared","discriminant","atmosphereRadiusSquared","distanceToAtmosphereEdge","minDistanceToAtmosphereEdge","maxDistanceToAtmosphereEdge","horizonDistanceToAtmosphereEdge","cosAngleLightToZenithCoordinate","distanceToHorizonCoordinate","weight","SmoothStep","SampleLutToRef","updateLightParameters","light","lightDirection","diffuse","specular","CharCode","MaterialPlugin","lights","_directionToLight","_tempSceneAmbient","Color3","_additionalDiffuseSkyIrradiance","_atmosphereUbo","_minimumMultiScattering","_cameraAtmosphereVariables","AtmospherePerCameraVariables","_lightRadianceAtCamera","_linearLightColor","_atmosphereUniformBufferAsArray","_isEnabled","_hasRenderedMultiScatteringLut","_multiScatteringEffectWrapper","_multiScatteringLutRenderTarget","_aerialPerspectiveLutEffectWrapper","_aerialPerspectiveLutEffectRenderer","_aerialPerspectiveLutRenderTarget","_skyViewLutEffectWrapper","_skyViewLutEffectRenderer","_skyViewLutRenderTarget","_aerialPerspectiveCompositorEffectWrapper","_skyCompositorEffectWrapper","_globeAtmosphereCompositorEffectWrapper","_onBeforeCameraRenderObserver","_onBeforeDrawPhaseObserver","_onAfterRenderingGroupObserver","onAfterUpdateVariablesForCameraObservable","onBeforeLightVariablesUpdateObservable","onBeforeRenderLutsForCameraObservable","onAfterRenderLutsForCameraObservable","depthTexture","_transmittanceLut","_diffuseSkyIrradianceLut","_engine","uniqueId","getUniqueId","isWebGPU","version","_physicalProperties","AtmospherePhysicalProperties","add","_lights","_exposure","exposure","_isLinearSpaceLight","isLinearSpaceLight","_isLinearSpaceComposition","isLinearSpaceComposition","_applyApproximateTransmittance","applyApproximateTransmittance","_aerialPerspectiveRadianceBias","_aerialPerspectiveTransmittanceScale","aerialPerspectiveTransmittanceScale","_aerialPerspectiveSaturation","aerialPerspectiveSaturation","_aerialPerspectiveIntensity","_diffuseSkyIrradianceDesaturationFactor","diffuseSkyIrradianceDesaturationFactor","_diffuseSkyIrradianceIntensity","_additionalDiffuseSkyIrradianceIntensity","additionalDiffuseSkyIrradianceIntensity","_multiScatteringIntensity","multiScatteringIntensity","_minimumMultiScatteringIntensity","minimumMultiScatteringIntensity","_isSkyViewLutEnabled","isSkyViewLutEnabled","_isAerialPerspectiveLutEnabled","_originHeight","_additionalDiffuseSkyIrradianceColor","additionalDiffuseSkyIrradianceColor","_groundAlbedo","groundAlbedo","set","minimumMultiScatteringColor","_minimumMultiScatteringColor","_skyRenderingGroup","skyRenderingGroup","_aerialPerspectiveRenderingGroup","aerialPerspectiveRenderingGroup","_globeAtmosphereRenderingGroup","globeAtmosphereRenderingGroup","TransmittanceLut","CreateRenderTargetTexture","isDiffuseSkyIrradianceLutEnabled","DiffuseSkyIrradianceLut","skyViewLutRenderTarget","onBeforeCameraRenderObservable","_updatePerCameraVariables","_renderLutsForCamera","renderingManager","getRenderingGroup","onBeforeDrawPhaseObservable","_empty","onAfterRenderingGroupObservable","group","groupId","renderingGroupId","drawSkyCompositor","drawAerialPerspectiveCompositor","drawGlobeAtmosphereCompositor","onDisposeObservable","addOnce","removeExternalData","addExternalData","UnregisterMaterialPlugin","RegisterMaterialPlugin","getClassName","AtmospherePBRMaterialPlugin","IsSupported","_badOS","minimumScatteringColor","newValue","_disposeSkyCompositor","_disposeGlobeAtmosphereCompositor","coordinatesMode","TEXTURE_EQUIRECTANGULAR_MODE","CreateSkyViewEffectWrapper","_disposeAerialPerspectiveCompositor","layers","CreateAerialPerspectiveEffectWrapper","hasDefineChanged","atmosphereUbo","UniformBuffer","addUniform","remove","isEnabled","setEnabled","enabled","_createMultiScatteringEffectWrapper","BlackReadOnly","samplerNames","_drawMultiScatteringLut","DrawEffect","clampedCameraRadius","CreateAerialPerspectiveCompositorEffectWrapper","skyViewLut","multiScatteringLut","aerialPerspectiveLut","_","ALPHA_PREMULTIPLIED_PORTERDUFF","ALPHA_ONEONE","ALWAYS","CreateSkyCompositorEffectWrapper","EQUAL","CreateGlobeAtmosphereCompositorEffectWrapper","scaleInPlace","cameraAtmosphereVariables","toGammaSpaceToRef","ambientColor","updateUniformBuffer","renderGlobalLuts","isDirty","_drawSkyViewLut","_drawAerialPerspectiveLut","bindToEffect","bindUniformBuffer","updateVector3","rayleighScattering","updateFloat","mieScattering","mieAbsorption","mieExtinction","ozoneAbsorption","horizonDistanceToAtmosphereEdgeSquared","updateMatrix","inverseViewProjectionMatrixWithoutTranslation","directionToLightRelativeToCameraGeocentricNormal","cameraRadius","updateColor3","cameraPositionGlobal","clampedCameraPositionGlobal","cameraForward","clampedCameraHeight","cameraPosition","cosCameraHorizonAngleFromZenith","updateVector4","viewport","cameraHeight","cameraNearPlane","sinCameraAtmosphereHorizonAngleFromNadir","layer","CreateEffectWrapper","defineNames","map","defineName","rtOptions","generateStencilBuffer","format","TEXTUREFORMAT_RGBA","drawCallback","depth","alphaMode","depthTest","depthWrite","depthFunction","ALPHA_DISABLE","LEQUAL","currentDepthWrite","getDepthWrite","setDepthWrite","currentDepthFunction","getDepthFunction","setDepthFunction","currentAlphaMode","getAlphaMode","setAlphaMode","textures","hasDepthTexture","BabylonUnitsToPixels","RenderOrderFunc","defaultRenderOrder","subMeshA","subMeshB","meshA","getMesh","meshB","meshIsHtmlMeshA","meshIsHtmlMeshB","absolutePosition","parentContainerId","_containerId","enableOverlayRender","defaultOpaqueRenderOrder","RenderingGroup","PainterSortCompare","defaultAlphaTestRenderOrder","defaultTransparentRenderOrder","defaultTransparentSortCompare","_cache","cameraData","fov","position","style","htmlMeshData","WeakMap","_width","_height","_heightHalf","_temp","scaleTransform","rotationTransform","Quaternion","positionTransform","objectMatrix","cameraWorldMatrix","cameraRotationMatrix","cameraWorldMatrixAsArray","_lastDevicePixelRatio","window","devicePixelRatio","_cameraMatrixUpdated","_previousCanvasDocumentPosition","top","left","_renderObserver","_onCameraMatrixChanged","_cameraWorldMatrix","getWorldMatrix","document","_init","_overlayElements","container","_inSceneElements","parentContainer","getElementById","body","inSceneContainerId","_createRenderLayerElements","insertBefore","firstChild","overlayContainerId","zIndex","getRenderingCanvas","pointerEvents","projectionObs","matrixObs","clientRect","getRenderingCanvasClientRect","_setSize","onResizeObservable","observeCamera","activeCamera","onProjectionMatrixChangedObservable","onViewMatrixChangedObservable","onActiveCameraChanged","opaqueRenderOrder","alphaTestRenderOrder","transparentRenderOrder","setRenderingOrder","onBeforeRenderObservable","_render","containerId","existingContainer","createElement","id","domElement","overflow","cameraElement","webkitTransformStyle","transformStyle","appendChild","_getSize","dom","_getCameraCssMatrix","matrix","elements","m","_epsilon","_getHtmlContentCssMatrix","useRightHandedSystem","_getTransformationMatrix","htmlMesh","objectWorldMatrix","widthScaleFactor","heightScaleFactor","sourceWidth","sourceHeight","scaledAndTranslatedObjectMatrix","decompose","ComposeToRef","getAbsolutePosition","setRowFromFloats","HtmlMeshRenderer","PROJECTION_SCALE_FACTOR","multiplyAtIndex","_renderHtmlMesh","element","firstElementChild","_isCanvasOverlay","parentNode","requiresUpdate","_updateBaseScaleFactor","billboardMode","TransformNode","BILLBOARDMODE_NONE","webkitTransform","transform","_markAsUpdated","needsUpdate","_updateContainerPositionIfNeeded","Logger","Log","meshesNeedingUpdate","meshes","filter","mesh","source","mode","Camera","PERSPECTIVE_CAMERA","el","webkitPerspective","perspective","parent","computeWorldMatrix","cameraMatrixWorld","getRotationMatrix","transposeToRef","cameraMatrixWorldAsArray","copyToArray","FromArrayToRef","screenWidth","screenHeight","htmlMeshAspectRatio","setContentSizePx","canvasRect","scrollTop","scrollY","scrollLeft","scrollX","canvasDocumentTop","canvasDocumentLeft","containerParent","offsetParent","parentRect","getBoundingClientRect","parentDocumentTop","parentDocumentLeft","ancestorMarginsAndPadding","_getAncestorMarginsAndPadding","bodyStyle","getComputedStyle","bodyMarginTop","parseInt","marginTop","bodyMarginLeft","marginLeft","paddingTop","paddingLeft","Warn","abs","documentElement","CaptureRequestQueue","PendingRequestCallbacks","Map","UnmatchedReleaseRequests","CurrentOwner","requestRelease","requestId","DebugLog","CancelRequest","delete","includes","TransferPointerEventsOwnership","removed","newOwnerId","NextCaptureRequest","DoRelease","DoCapture","release","capture","shift","message","Tools","performance","now","LocalScene","CaptureOnEnterCount","MeshToBehaviorMap","StartCaptureOnEnter","addEventListener","OnPointerMove","DoStopCaptureOnEnter","removeEventListener","StopCaptureOnEnter","evt","pickedMesh","touches","clientX","clientY","pointerScreenX","pointerScreenY","pickResult","pick","pointerCaptureBehavior","_captureOnPointerEnter","hit","capturingIdAsInt","capturePointerEvents","_captureCallback","_releaseCallback","captureOnPointerEnter","_attachedMesh","init","attach","attachedMesh","detach","releasePointerEvents","toString","captureCallback","releaseCallback","RemoveUnmatchedRequest","EnqueueCaptureRequest","FitStrategy","CONTAIN","wrapElement","sizingElement","display","justifyContent","alignItems","scalingElement","visibility","updateSize","offsetWidth","offsetHeight","childWidth","childHeight","scale","COVER","STRETCH","NONE","isCanvasOverlay","fitStrategy","_enabled","_ready","_requiresUpdate","_inverseScaleMatrix","_pointerEventCaptureBehavior","_sourceWidth","_sourceHeight","_fitStrategy","_createMask","_element","_createElement","PointerEventsCaptureBehavior","bind","addBehavior","setContent","_setAsReady","scaling","setAll","_updateScaleIfNecessary","_doSetEnabled","ready","_worldMatrixUpdateObserver","onAfterWorldMatrixUpdateObservable","_setElementzIndex","bakeTransformIntoVertices","scaleX","scaleY","scaleMatrix","Scaling","CreatePlaneVertexData","applyToMesh","checkCollisions","depthMask","StandardMaterial","backFaceCulling","disableColorWrite","disableLighting","freeze","getElementsByTagName","div","backgroundColor","backfaceVisibility","Mesh","definitionData","textureUrl","_chars","_kernings","_font","JSON","parse","pages","chars","forEach","char","kernings","kerning","submap","first","second","amount","_charsRegex","RegExp","c","replace","join","_updateFallbacks","info","page","texture","Texture","noMipmap","invertY","has","SPACE","xoffset","yoffset","xadvance","chnl","TOFU","_getChar","charCode","_getKerning","_unsupportedChars","text","DefaultParagraphOptions","maxWidth","Infinity","lineHeight","letterSpacing","tabSize","whiteSpace","textAlign","translate","fontAsset","_computeMetrics","paragraph","lines","glyphs","common","collapsed","_collapse","trimmed","_breakLines","line","trim","_wrap","anchor","glyph","flatMap","split","repeat","lineOffset","lastChar","currentLine","currentGlyphs","currentCursor","currentWidth","start","end","pushCurrentLine","charCodeAt","charWidth","newWidth","cursorProgress","nextPosition","shouldBreak","shaderLanguage","font","_useVAO","_vertexBuffers","_charMatrices","_charUvs","_baseLine","_scalingMatrix","ThinMatrix","_fontScaleMatrix","_offsetMatrix","_translationMatrix","_baseMatrix","_scaledMatrix","_localMatrix","_finalMatrix","_lineMatrix","_parentWorldMatrix","color","strokeColor","strokeInsetWidth","strokeOutsetWidth","thicknessControl","_parent","_transformMatrix","isBillboard","isBillboardScreenProjected","ignoreDepthBuffer","_shaderLanguage","getCaps","vertexArrayObject","disableVertexArrayObjects","spriteData","Float32Array","_spriteBuffer","Buffer","createVertexBuffer","_resizeBuffers","capacity","_worldBuffer","_uvBuffer","_setShaders","vertex","_drawWrapperBase","DrawWrapper","drawContext","useInstancing","createEffect","vertexSource","fragmentSource","_refCount","addParagraph","worldMatrix","SdfTextParagraph","fontScale","texWidth","scaleW","texHeight","scaleH","worldMatrixToUse","TranslationMatrixToRef","ScalingMatrixToRef","charsUvsBase","matricesBase","MultiplyMatricesToRef","CopyMatrixToArray","drawWrapper","setState","enableEffect","setDepthBuffer","CopyMatrixToRef","IdentityMatrixToRef","setInt","setMatrix","transformMatrix","setDirectColor4","instanceCount","getBuffer","_vertexArrayObject","recordVertexArrayObject","bindVertexArrayObject","ALPHA_COMBINE","drawArraysType","MATERIAL_TriangleStripDrawMode","unbindInstanceAttributes","releaseVertexArrayObject","CreateTextRendererAsync","thisArg","_arguments","generator","f","label","sent","trys","ops","Iterator","next","verb","iterator","op","done","pop","e","step","instancedArrays","_features","supportSpriteInstancing","textRenderer","TextRenderer","P","Promise","resolve","reject","fulfilled","rejected"],"sourceRoot":""}
1
+ {"version":3,"file":"babylonjs.addons.min.js","mappings":"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","sources":["webpack://ADDONS/webpack/universalModuleDefinition","webpack://ADDONS/../../../dev/addons/src/msdfText/shaders/msdf.vertex.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/shadersWGSL/msdf.fragment.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/shaders/msdf.fragment.ts","webpack://ADDONS/external umd {\"root\":\"BABYLON\",\"commonjs\":\"babylonjs\",\"commonjs2\":\"babylonjs\",\"amd\":\"babylonjs\"}","webpack://ADDONS/../../../dev/addons/src/msdfText/shadersWGSL/msdf.vertex.ts","webpack://ADDONS/webpack/bootstrap","webpack://ADDONS/webpack/runtime/compat get default export","webpack://ADDONS/webpack/runtime/define property getters","webpack://ADDONS/webpack/runtime/hasOwnProperty shorthand","webpack://ADDONS/webpack/runtime/make namespace object","webpack://ADDONS/../../../../node_modules/tslib/tslib.es6.mjs","webpack://ADDONS/../../../dev/addons/src/atmosphere/atmospherePBRMaterialPlugin.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/atmospherePerCameraVariables.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/atmospherePhysicalProperties.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/sampling.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/atmosphereFragmentDeclaration.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/atmosphereUboDeclaration.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/depthFunctions.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/atmosphereFunctions.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/diffuseSkyIrradiance.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/fullscreenTriangle.vertex.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/diffuseSkyIrradianceLut.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/transmittance.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/transmittanceLut.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/compositeAerialPerspective.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/compositeSky.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/compositeGlobeAtmosphere.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/multiScattering.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/skyView.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/aerialPerspective.fragment.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/Shaders/ShadersInclude/atmosphereVertexDeclaration.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/fontAsset.ts","webpack://ADDONS/../../../dev/addons/src/atmosphere/atmosphere.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/htmlMeshRenderer.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/pointerEventsCapture.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/pointerEventsCaptureBehavior.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/fitStrategy.ts","webpack://ADDONS/../../../dev/addons/src/htmlMesh/htmlMesh.ts","webpack://ADDONS/../../../dev/addons/src/navigation/factory/common.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/paragraphOptions.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/sdf/paragraph.ts","webpack://ADDONS/../../../dev/addons/src/msdfText/textRenderer.ts","webpack://ADDONS/../../../dev/addons/src/navigation/common/tile-cache.ts","webpack://ADDONS/../../../dev/addons/src/navigation/common/config.ts","webpack://ADDONS/../../../dev/addons/src/navigation/plugin/RecastJSCrowd.ts","webpack://ADDONS/../../../dev/addons/src/navigation/common/convert.ts","webpack://ADDONS/../../../dev/addons/src/navigation/types.ts","webpack://ADDONS/../../../dev/addons/src/navigation/common/smooth-path.ts","webpack://ADDONS/../../../dev/addons/src/navigation/common/getters.ts","webpack://ADDONS/../../../dev/addons/src/navigation/debug/simple-debug.ts","webpack://ADDONS/../../../dev/addons/src/navigation/generator/generator.single-thread.ts","webpack://ADDONS/../../../dev/addons/src/navigation/generator/injection.ts","webpack://ADDONS/../../../dev/addons/src/navigation/plugin/RecastNavigationJSPlugin.ts","webpack://ADDONS/../../../dev/addons/src/navigation/factory/factory.single-thread.ts","webpack://ADDONS/../../../dev/addons/src/navigation/common/utils.ts","webpack://ADDONS/../../../dev/addons/src/navigation/generator/generator.common.ts","webpack://ADDONS/../../../dev/addons/src/navigation/debug/NavigationDebugger.ts","webpack://ADDONS/./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"babylonjs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"babylonjs-addons\", [\"babylonjs\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"babylonjs-addons\"] = factory(require(\"babylonjs\"));\n\telse\n\t\troot[\"ADDONS\"] = factory(root[\"BABYLON\"]);\n})((typeof self !== \"undefined\" ? self : typeof global !== \"undefined\" ? global : this), (__WEBPACK_EXTERNAL_MODULE__597__) => {\nreturn ","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfVertexShader\";\nconst shader = `#define BILLBOARD 1\n#define BILLBOARDSCREENPROJECTED 2\nattribute vec2 offsets;attribute vec4 world0;attribute vec4 world1;attribute vec4 world2;attribute vec4 world3;attribute vec4 uvs;uniform mat4 transform;uniform mat4 parentWorld;uniform mat4 view;uniform mat4 projection;uniform vec3 center;uniform int mode;varying vec2 atlasUV;void main(void) {mat4 world=mat4(world0,world1,world2,world3);vec4 worldPos=transform*(world*vec4(offsets.xy-vec2(0.5,0.5),0.,1.0));if (mode>=BILLBOARD) {vec3 viewPos=(view*parentWorld*vec4(0.,0.,0.,1.0)).xyz; \nif (mode==BILLBOARDSCREENPROJECTED) {viewPos.x/=viewPos.z;viewPos.y/=viewPos.z;viewPos.z=1.0;}\ngl_Position=projection*vec4(viewPos+worldPos.xyz,1.0); } else {vec3 viewPos=(view*parentWorld*worldPos).xyz; \ngl_Position=projection*vec4(viewPos,1.0); }\natlasUV=vec2(uvs.x+offsets.x*uvs.z,uvs.y+(1.0-offsets.y)*uvs.w);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const msdfVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfPixelShader\";\nconst shader = `var fontAtlas: texture_2d<f32>;var fontAtlasSampler: sampler;uniform uColor: vec4f;uniform thickness: f32;uniform uStrokeColor: vec4f;uniform uStrokeInsetWidth: f32;uniform uStrokeOutsetWidth: f32;varying atlasUV: vec2f;fn median(msdf: vec3<f32>)->f32 {let a=min(msdf.r,msdf.g);let b=max(msdf.r,msdf.g);return max(a,min(b,msdf.b));}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let s=textureSample(fontAtlas,fontAtlasSampler,input.atlasUV).rgb;let sigDist=median(s)-0.5+uniforms.thickness;let afwidth=length(vec2<f32>(dpdx(sigDist),dpdy(sigDist)));let alpha=clamp(sigDist/afwidth+0.5,0.0,1.0);let sigDistOutset=sigDist+uniforms.uStrokeOutsetWidth*0.5;let sigDistInset=sigDist-uniforms.uStrokeInsetWidth*0.5;let afwidthOutset=length(vec2<f32>(dpdx(sigDistOutset),dpdy(sigDistOutset)));let afwidthInset=length(vec2<f32>(dpdx(sigDistInset),dpdy(sigDistInset)));let outset=clamp(sigDistOutset/afwidthOutset+0.5,0.0,1.0);let inset=1.0-clamp(sigDistInset/afwidthInset+0.5,0.0,1.0);let border=outset*inset;let filledFragColor=vec4<f32>(uniforms.uColor.rgb,alpha*uniforms.uColor.a);let strokedFragColor=vec4<f32>(uniforms.uStrokeColor.rgb,border*uniforms.uStrokeColor.a);fragmentOutputs.color=mix(filledFragColor,strokedFragColor,border);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const msdfPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfPixelShader\";\nconst shader = `#extension GL_OES_standard_derivatives : enable\nprecision highp float;uniform sampler2D fontAtlas;uniform vec4 uColor;uniform vec4 uStrokeColor;uniform float uStrokeInsetWidth;uniform float uStrokeOutsetWidth;uniform float thickness;varying vec2 atlasUV;float median(vec3 msdf) {return max(min(msdf.r,msdf.g),min(max(msdf.r,msdf.g),msdf.b));}\nvoid main(void)\n{vec3 s=texture2D(fontAtlas,atlasUV).rgb;float sigDist=median(s)-0.5+thickness;float alpha=clamp(sigDist/fwidth(sigDist)+0.5,0.0,1.0);float sigDistOutset=sigDist+uStrokeOutsetWidth*0.5;float sigDistInset=sigDist-uStrokeInsetWidth*0.5;float outset=clamp(sigDistOutset/fwidth(sigDistOutset)+0.5,0.0,1.0);float inset=1.0-clamp(sigDistInset/fwidth(sigDistInset)+0.5,0.0,1.0);float border=outset*inset;vec4 filledFragColor=vec4(uColor.rgb,alpha*uColor.a);vec4 strokedFragColor=vec4(uStrokeColor.rgb,border*uStrokeColor.a);gl_FragColor=mix(filledFragColor,strokedFragColor,border);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const msdfPixelShader = { name, shader };\n","module.exports = __WEBPACK_EXTERNAL_MODULE__597__;","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfVertexShader\";\nconst shader = `#define BILLBOARD 1\n#define BILLBOARDSCREENPROJECTED 2\nattribute offsets: vec2f;attribute world0: vec4f;attribute world1: vec4f;attribute world2: vec4f;attribute world3: vec4f;attribute uvs: vec4f;uniform transform: mat4x4f;uniform parentWorld: mat4x4f;uniform view: mat4x4f;uniform projection: mat4x4f;uniform mode: u32;varying atlasUV: vec2f;@vertex\nfn main(input: VertexInputs)->FragmentInputs {let world=mat4x4<f32>(input.world0,input.world1,input.world2,input.world3);let localOffset=vec4<f32>(input.offsets-vec2<f32>(0.5,0.5),0.0,1.0);let worldPos=uniforms.transform*world*localOffset;if (uniforms.mode>=BILLBOARD) { \nvar viewPos=(uniforms.view*uniforms.parentWorld*vec4f(0.,0.,0.,1.0)).xyz;if (uniforms.mode==BILLBOARDSCREENPROJECTED) {viewPos=vec3f(viewPos.x/viewPos.z,viewPos.y/viewPos.z,1.0);} \nvertexOutputs.position=uniforms.projection*vec4<f32>(viewPos+worldPos.xyz,1.0);} else { \nlet viewPos=(uniforms.view*uniforms.parentWorld*worldPos).xyz;vertexOutputs.position=uniforms.projection*vec4<f32>(viewPos,1.0);}\nvertexOutputs.atlasUV=vec2<f32>(\ninput.uvs.x+input.offsets.x*input.uvs.z,\ninput.uvs.y+(1.0-input.offsets.y)*input.uvs.w\n);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const msdfVertexShaderWGSL = { name, shader };\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { MaterialDefines } from \"core/Materials/materialDefines\";\r\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { UniformBuffer } from \"core/Materials/uniformBuffer\";\r\n\r\nclass AtmospherePBRMaterialDefines extends MaterialDefines {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public USE_AERIAL_PERSPECTIVE_LUT: boolean;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public APPLY_AERIAL_PERSPECTIVE_INTENSITY = false;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS = false;\r\n\r\n /**\r\n * Constructs the {@link AtmospherePBRMaterialDefines}.\r\n * @param useAerialPerspectiveLut - Whether to use the aerial perspective LUT.\r\n */\r\n constructor(useAerialPerspectiveLut: boolean) {\r\n super();\r\n this.USE_AERIAL_PERSPECTIVE_LUT = useAerialPerspectiveLut;\r\n }\r\n}\r\n\r\nconst UboArray = [{ name: \"inverseViewportSize\", size: 2, type: \"vec2\" }];\r\nconst MakeUniforms = (atmosphere: Atmosphere) => ({\r\n ubo: UboArray,\r\n fragment: \"uniform vec2 inverseViewportSize;\\n\",\r\n externalUniforms: atmosphere.uniformBuffer.getUniformNames(),\r\n});\r\n\r\nconst PluginName = \"AtmospherePBRMaterialPlugin\";\r\nconst PluginPriority = 600;\r\n\r\n/**\r\n * Adds shading logic to a PBRMaterial that provides radiance, diffuse sky irradiance, and aerial perspective from the atmosphere.\r\n */\r\nexport class AtmospherePBRMaterialPlugin extends MaterialPluginBase {\r\n /**\r\n * Constructs the {@link AtmospherePBRMaterialPlugin}.\r\n * @param material - The material to apply the plugin to.\r\n * @param _atmosphere - The atmosphere to use for shading.\r\n * @param _isAerialPerspectiveEnabled - Whether to apply aerial perspective.\r\n */\r\n constructor(\r\n material: Material,\r\n private readonly _atmosphere: Atmosphere,\r\n private readonly _isAerialPerspectiveEnabled = false\r\n ) {\r\n super(\r\n material,\r\n PluginName,\r\n PluginPriority,\r\n {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n USE_CUSTOM_REFLECTION: _atmosphere.diffuseSkyIrradianceLut !== null,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n CUSTOM_FRAGMENT_BEFORE_FOG: _isAerialPerspectiveEnabled,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n USE_AERIAL_PERSPECTIVE_LUT: _isAerialPerspectiveEnabled && _atmosphere.isAerialPerspectiveLutEnabled,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n APPLY_AERIAL_PERSPECTIVE_INTENSITY: _isAerialPerspectiveEnabled && _atmosphere.aerialPerspectiveIntensity !== 1.0,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS: _isAerialPerspectiveEnabled && _atmosphere.aerialPerspectiveRadianceBias !== 0.0,\r\n },\r\n false, // addPluginToList -- false because we need to control when this is added to the list\r\n true, // enable\r\n true // resolveIncludes\r\n );\r\n\r\n this.doNotSerialize = true;\r\n\r\n // This calls `getCode` so we need to do this after having initialized the class fields.\r\n this._pluginManager._addPlugin(this);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getUniformBuffersNames(_ubos: string[]): void {\r\n const uniformBuffer = this._atmosphere.uniformBuffer;\r\n if (uniformBuffer.useUbo) {\r\n _ubos.push(uniformBuffer.name);\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getUniforms() {\r\n return MakeUniforms(this._atmosphere);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override isReadyForSubMesh(): boolean {\r\n let isReady = true;\r\n const atmosphere = this._atmosphere;\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n isReady = isReady && !!aerialPerspectiveLutRenderTarget?.isReady();\r\n }\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n isReady = isReady && !!transmittanceLutRenderTarget?.isReady();\r\n return isReady;\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getActiveTextures(_activeTextures: BaseTexture[]): void {\r\n const atmosphere = this._atmosphere;\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n if (aerialPerspectiveLutRenderTarget) {\r\n _activeTextures.push(aerialPerspectiveLutRenderTarget);\r\n }\r\n }\r\n\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n if (transmittanceLutRenderTarget) {\r\n _activeTextures.push(transmittanceLutRenderTarget);\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override bindForSubMesh(uniformBuffer: UniformBuffer): void {\r\n const atmosphere = this._atmosphere;\r\n const engine = atmosphere.scene.getEngine();\r\n\r\n // Bind the atmosphere's uniform buffer to the effect.\r\n const effect = uniformBuffer.currentEffect;\r\n if (effect) {\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n }\r\n\r\n const width = engine.getRenderWidth();\r\n const height = engine.getRenderHeight();\r\n uniformBuffer.updateFloat2(\"inverseViewportSize\", 1.0 / width, 1.0 / height);\r\n\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n uniformBuffer.setTexture(\"aerialPerspectiveLut\", aerialPerspectiveLutRenderTarget);\r\n }\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n uniformBuffer.setTexture(\"transmittanceLut\", transmittanceLutRenderTarget);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override prepareDefines(defines: AtmospherePBRMaterialDefines): void {\r\n const lastUseAerialPerspectiveLut = defines.USE_AERIAL_PERSPECTIVE_LUT;\r\n const lastApplyAerialPerspectiveIntensity = defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY;\r\n const lastApplyAerialPerspectiveRadianceBias = defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS;\r\n defines.USE_AERIAL_PERSPECTIVE_LUT = this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled;\r\n defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY = this._isAerialPerspectiveEnabled && this._atmosphere.aerialPerspectiveIntensity !== 1.0;\r\n defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS = this._isAerialPerspectiveEnabled && this._atmosphere.aerialPerspectiveRadianceBias !== 0.0;\r\n if (\r\n lastUseAerialPerspectiveLut !== defines.USE_AERIAL_PERSPECTIVE_LUT ||\r\n lastApplyAerialPerspectiveIntensity !== defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY ||\r\n lastApplyAerialPerspectiveRadianceBias !== defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\r\n ) {\r\n defines.markAllAsDirty();\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getSamplers(samplers: string[]): void {\r\n samplers.push(\"transmittanceLut\");\r\n if (this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled) {\r\n samplers.push(\"aerialPerspectiveLut\");\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getCustomCode(shaderType: string): Nullable<Record<string, string>> {\r\n // Assumed inputs are light0, vPositionW, normalW.\r\n // Only works for directional lights.\r\n if (shaderType !== \"fragment\") {\r\n return null;\r\n }\r\n\r\n const useUbo = this._atmosphere.scene.getEngine().supportsUniformBuffers;\r\n const directionToLightSnippet = useUbo ? \"-light0.vLightData.xyz\" : \"-vLightData0.xyz\";\r\n\r\n const useAtmosphereUbo = this._atmosphere.uniformBuffer.useUbo;\r\n const atmosphereImportSnippet = useAtmosphereUbo ? \"#include<atmosphereUboDeclaration>\" : \"#include<atmosphereFragmentDeclaration>\";\r\n\r\n return {\r\n CUSTOM_FRAGMENT_DEFINITIONS:\r\n this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled\r\n ? `uniform sampler2D transmittanceLut;\\r\\nprecision highp sampler2DArray;\\r\\nuniform sampler2DArray aerialPerspectiveLut;\\r\\n${atmosphereImportSnippet}\\r\\n#include<atmosphereFunctions>`\r\n : `uniform sampler2D transmittanceLut;\\r\\n${atmosphereImportSnippet}\\r\\n#include<atmosphereFunctions>`,\r\n CUSTOM_LIGHT0_COLOR: `\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + vec3(0., planetRadius, 0.);\r\n float positionRadius = length(positionGlobal);\r\n vec3 geocentricNormal = positionGlobal / positionRadius;\r\n vec3 directionToLight = ${directionToLightSnippet};\r\n float cosAngleLightToZenith = dot(directionToLight, geocentricNormal);\r\n diffuse0 = lightIntensity * sampleTransmittanceLut(transmittanceLut, positionRadius, cosAngleLightToZenith);\r\n }\r\n`,\r\n CUSTOM_REFLECTION: `\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + vec3(0., planetRadius, 0.);\r\n float positionRadius = length(positionGlobal);\r\n vec3 geocentricNormal = positionGlobal / positionRadius;\r\n\r\n vec3 directionToLight = ${directionToLightSnippet};\r\n float cosAngleLightToZenith = dot(directionToLight, geocentricNormal);\r\n\r\n vec2 uv = vec2(0.5 + 0.5 * cosAngleLightToZenith, (positionRadius - planetRadius) / atmosphereThickness);\r\n float irradianceScaleT = 0.5 * dot(normalW, geocentricNormal) + 0.5;\r\n float irradianceScale = ((-0.6652 * irradianceScaleT) + 1.5927) * irradianceScaleT + 0.1023;\r\n vec3 environmentIrradiance = lightIntensity * sampleReflection(irradianceSampler, uv).rgb;\r\n\r\n // Add a contribution here to estimate indirect lighting.\r\n const float r = 0.2;\r\n float indirect = getLuminance(environmentIrradiance) / max(0.00001, 1. - r);\r\n environmentIrradiance *= irradianceScale;\r\n environmentIrradiance += indirect;\r\n\r\n environmentIrradiance += additionalDiffuseSkyIrradiance;\r\n\r\n const float diffuseBrdf = 1. / PI;\r\n environmentIrradiance *= diffuseBrdf * diffuseSkyIrradianceIntensity;\r\n\r\n reflectionOut.environmentIrradiance = environmentIrradiance;\r\n reflectionOut.environmentRadiance.rgb = reflectionOut.environmentIrradiance;\r\n }\r\n`,\r\n // TODO: Support full ray marching if USE_AERIAL_PERSPECTIVE_LUT is disabled.\r\n CUSTOM_FRAGMENT_BEFORE_FOG: `\r\n #if USE_AERIAL_PERSPECTIVE_LUT\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + vec3(0., planetRadius, 0.);\r\n float distanceFromCamera = distance(positionGlobal, cameraPositionGlobal);\r\n\r\n vec4 aerialPerspective = vec4(0.);\r\n if (sampleAerialPerspectiveLut(\r\n gl_FragCoord.xy * inverseViewportSize,\r\n true,\r\n distanceFromCamera,\r\n NumAerialPerspectiveLutLayers,\r\n AerialPerspectiveLutKMPerSlice,\r\n AerialPerspectiveLutRangeKM,\r\n aerialPerspective)) {\r\n finalColor = aerialPerspective + (1. - aerialPerspective.a) * finalColor;\r\n }\r\n }\r\n #endif\r\n`,\r\n };\r\n }\r\n}\r\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Camera } from \"core/Cameras/camera\";\r\nimport type { IMatrixLike, IVector3Like, IVector4Like } from \"core/Maths/math.like\";\r\nimport { Matrix, Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Ray } from \"core/Culling/ray.core\";\r\nimport { Vector3Dot } from \"core/Maths/math.vector.functions\";\r\n\r\nconst TempRay = new Ray(Vector3.Zero(), Vector3.Zero());\r\n\r\n/**\r\n * Variables that are used to render the atmosphere and are computed per-camera.\r\n */\r\nexport class AtmospherePerCameraVariables {\r\n private _inverseViewProjectionMatrixWithoutTranslation = Matrix.Identity();\r\n private _directionToLightRelativeToCameraGeocentricNormal = Vector3.Up();\r\n private _cosAngleLightToZenith = 0;\r\n private _cameraRadius = 0;\r\n private _clampedCameraRadius = 0;\r\n private _cameraHeight = 0;\r\n private _clampedCameraHeight = 0;\r\n private _cameraPositionGlobal = new Vector3();\r\n private _clampedCameraPositionGlobal = new Vector3();\r\n private _cosCameraHorizonAngleFromZenith = 0;\r\n private _sinCameraAtmosphereHorizonAngleFromNadir = 0;\r\n private _cameraGeocentricNormal = Vector3.Up();\r\n private _cameraForward = Vector3.Down();\r\n private _cameraNearPlane = 0;\r\n private _cameraPosition = new Vector3();\r\n private _viewport = new Vector4();\r\n private _lastViewMatrix = Matrix.Identity();\r\n private _lastProjectionMatrix = Matrix.Identity();\r\n private _inverseViewMatrixWithoutTranslation = Matrix.Identity();\r\n private _inverseProjectionMatrix = Matrix.Identity();\r\n\r\n /**\r\n * The inverse view projection matrix is used to unproject rays.\r\n * To avoid precision issues, the translation part of the matrix has been removed.\r\n */\r\n public get inverseViewProjectionMatrixWithoutTranslation(): IMatrixLike {\r\n return this._inverseViewProjectionMatrixWithoutTranslation;\r\n }\r\n\r\n /**\r\n * The direction to the light relative to the geocentric normal under the camera.\r\n */\r\n public get directionToLightRelativeToCameraGeocentricNormal(): IVector3Like {\r\n return this._directionToLightRelativeToCameraGeocentricNormal;\r\n }\r\n\r\n /**\r\n * The cosine of the angle between the light direction and zenith.\r\n */\r\n public get cosAngleLightToZenith(): number {\r\n return this._cosAngleLightToZenith;\r\n }\r\n\r\n /**\r\n * The distance from the camera to the planet origin in kilometers.\r\n */\r\n public get cameraRadius(): number {\r\n return this._cameraRadius;\r\n }\r\n\r\n /**\r\n * The distance from the camera to the planet origin, clamped to the planet radius offset, in kilometers.\r\n */\r\n public get clampedCameraRadius(): number {\r\n return this._clampedCameraRadius;\r\n }\r\n\r\n /**\r\n * The height of the camera above the planet surface in kilometers.\r\n */\r\n public get cameraHeight(): number {\r\n return this._cameraHeight;\r\n }\r\n\r\n /**\r\n * The height of the camera above the planet surface, clamped to the planet radius offset, in kilometers.\r\n */\r\n public get clampedCameraHeight(): number {\r\n return this._clampedCameraHeight;\r\n }\r\n\r\n /**\r\n * The camera position in global space kilometers.\r\n */\r\n public get cameraPositionGlobal(): IVector3Like {\r\n return this._cameraPositionGlobal;\r\n }\r\n\r\n /**\r\n * The camera position, clamped to the planet radius offset, in global space kilometers.\r\n */\r\n public get clampedCameraPositionGlobal(): IVector3Like {\r\n return this._clampedCameraPositionGlobal;\r\n }\r\n\r\n /**\r\n * The cosine of the angle from the zenith to the horizon of the planet, measured from the camera position.\r\n */\r\n public get cosCameraHorizonAngleFromZenith(): number {\r\n return this._cosCameraHorizonAngleFromZenith;\r\n }\r\n\r\n /**\r\n * The sine of the angle from the nadir to the horizon of the atmosphere, measured from the camera position.\r\n */\r\n public get sinCameraAtmosphereHorizonAngleFromNadir(): number {\r\n return this._sinCameraAtmosphereHorizonAngleFromNadir;\r\n }\r\n\r\n /**\r\n * The geocentric normal of the camera in global space i.e., the normalization of {@link cameraPositionGlobal}.\r\n */\r\n public get cameraGeocentricNormal(): IVector3Like {\r\n return this._cameraGeocentricNormal;\r\n }\r\n\r\n /**\r\n * The camera's forward direction in world space.\r\n */\r\n public get cameraForward(): IVector3Like {\r\n return this._cameraForward;\r\n }\r\n\r\n /**\r\n * The distance to the near plane of the camera.\r\n */\r\n public get cameraNearPlane(): number {\r\n return this._cameraNearPlane;\r\n }\r\n\r\n /**\r\n * The camera's position in world space.\r\n */\r\n public get cameraPosition(): IVector3Like {\r\n return this._cameraPosition;\r\n }\r\n\r\n /**\r\n * The viewport for the camera.\r\n */\r\n public get viewport(): IVector4Like {\r\n return this._viewport;\r\n }\r\n\r\n /**\r\n * Updates the variables.\r\n * @param camera - The camera to update the variables for.\r\n * @param planetRadius - The radius of the planet in kilometers.\r\n * @param planetRadiusWithOffset - The radius of the planet with the offset in kilometers.\r\n * @param atmosphereRadius - The radius of the atmosphere in kilometers.\r\n * @param directionToLight - The direction to the light in world space.\r\n * @param originHeight - The height of the origin (distance from planet's surface) in kilometers.\r\n */\r\n public update(camera: Camera, planetRadius: number, planetRadiusWithOffset: number, atmosphereRadius: number, directionToLight: IVector3Like, originHeight: number): void {\r\n this._cameraNearPlane = camera.minZ;\r\n this._cameraForward.copyFrom(camera.getForwardRayToRef(TempRay, 1).direction);\r\n\r\n const engine = camera.getScene().getEngine();\r\n this._viewport.copyFromFloats(0.0, 0.0, engine.getRenderWidth(), engine.getRenderHeight());\r\n\r\n // Compute inverse view projection matrix, but remove the translational component to increase precision.\r\n const viewMatrix = camera.getViewMatrix();\r\n const projectionMatrix = camera.getProjectionMatrix();\r\n if (!this._lastViewMatrix.equals(viewMatrix) || !this._lastProjectionMatrix.equals(projectionMatrix)) {\r\n this._lastViewMatrix.copyFrom(viewMatrix);\r\n this._lastViewMatrix.setTranslation(Vector3.ZeroReadOnly);\r\n this._lastViewMatrix.invertToRef(this._inverseViewMatrixWithoutTranslation);\r\n\r\n this._lastProjectionMatrix.copyFrom(projectionMatrix);\r\n this._lastProjectionMatrix.invertToRef(this._inverseProjectionMatrix);\r\n this._inverseProjectionMatrix.multiplyToRef(this._inverseViewMatrixWithoutTranslation, this._inverseViewProjectionMatrixWithoutTranslation);\r\n }\r\n\r\n // Compute the global space position of the camera in kilometers.\r\n this._cameraPosition.copyFrom(camera.globalPosition);\r\n this._cameraPosition.scaleToRef(1.0 / 1000.0, this._cameraPositionGlobal);\r\n this._cameraPositionGlobal.y += planetRadius + originHeight;\r\n this._cameraHeight = this._cameraPositionGlobal.y - planetRadius;\r\n\r\n // Clamp the camera parameters.\r\n this._cameraRadius = this._cameraPositionGlobal.length();\r\n this._clampedCameraRadius = this._cameraRadius;\r\n this._cameraPositionGlobal.normalizeToRef(this._cameraGeocentricNormal);\r\n if (this._clampedCameraRadius < planetRadiusWithOffset) {\r\n this._clampedCameraRadius = planetRadiusWithOffset;\r\n this._cameraGeocentricNormal.scaleToRef(planetRadiusWithOffset, this._clampedCameraPositionGlobal);\r\n } else {\r\n this._clampedCameraPositionGlobal.copyFrom(this._cameraPositionGlobal);\r\n }\r\n\r\n this._cosCameraHorizonAngleFromZenith = ComputeCosHorizonAngleFromZenith(planetRadius, this._clampedCameraRadius);\r\n this._sinCameraAtmosphereHorizonAngleFromNadir = Math.min(1.0, atmosphereRadius / this._clampedCameraRadius);\r\n this._clampedCameraHeight = this._clampedCameraRadius - planetRadius;\r\n\r\n // Compute the direction to the light relative to the camera's geocentric normal.\r\n {\r\n this._cosAngleLightToZenith = Vector3Dot(directionToLight, this._cameraGeocentricNormal);\r\n const lightZenithSinAngle = Math.sqrt(Math.max(0.0, 1.0 - this._cosAngleLightToZenith * this._cosAngleLightToZenith));\r\n this._directionToLightRelativeToCameraGeocentricNormal.copyFromFloats(lightZenithSinAngle, this._cosAngleLightToZenith, 0.0);\r\n this._directionToLightRelativeToCameraGeocentricNormal.normalize();\r\n }\r\n }\r\n}\r\n\r\nconst ComputeCosHorizonAngleFromZenith = (planetRadius: number, radius: number): number => {\r\n const sinHorizonAngleFromNadir = Math.min(1, planetRadius / radius);\r\n const cosHorizonAngleFromNadir = Math.sqrt(1 - sinHorizonAngleFromNadir * sinHorizonAngleFromNadir);\r\n const cosHorizonAngleFromZenith = -cosHorizonAngleFromNadir;\r\n return cosHorizonAngleFromZenith;\r\n};\r\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { IAtmospherePhysicalPropertiesOptions } from \"./atmospherePhysicalPropertiesOptions\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { Vector3 } from \"core/Maths/math.vector\";\r\n\r\nconst DefaultPlanetRadius = 6360.0;\r\nconst DefaultPlanetRadiusOffset = 0.01;\r\nconst DefaultAtmosphereThickness = 100.0;\r\n\r\n// The scattering and absorption values are per kilometer measured at sea level.\r\nconst DefaultPeakRayleighScattering = new Vector3(0.005802, 0.013558, 0.0331);\r\nconst DefaultPeakMieScattering = new Vector3(0.003996, 0.003996, 0.003996);\r\nconst DefaultPeakMieAbsorption = new Vector3(0.000444, 0.000444, 0.000444);\r\nconst DefaultPeakOzoneAbsorption = new Vector3(0.00065, 0.001881, 0.000085);\r\n\r\n/**\r\n * Describes the physical properties of the atmosphere. Assumes a spherical planet.\r\n * - \"radius\" values describe a distance from the planet's center.\r\n * - \"height\" values describe a distance from the planet's surface.\r\n * - Distances are in kilometers unless otherwise specified. Angles are in radians.\r\n */\r\nexport class AtmospherePhysicalProperties {\r\n /**\r\n * Notification for when properties of the {@link AtmospherePhysicalProperties} are changed.\r\n */\r\n public readonly onChangedObservable = new Observable<AtmospherePhysicalProperties>();\r\n\r\n private _planetRadius: number;\r\n private _planetRadiusOffset: number;\r\n private _atmosphereThickness: number;\r\n private _rayleighScatteringScale: number;\r\n private _peakRayleighScattering = new Vector3();\r\n private _mieScatteringScale: number;\r\n private _peakMieScattering = new Vector3();\r\n private _mieAbsorptionScale: number;\r\n private _peakMieAbsorption = new Vector3();\r\n private _ozoneAbsorptionScale: number;\r\n private _peakOzoneAbsorption = new Vector3();\r\n\r\n // Inferred values.\r\n private _planetRadiusWithOffset = 0;\r\n private _planetRadiusSquared = 0;\r\n private _atmosphereRadius = 0;\r\n private _atmosphereRadiusSquared = 0;\r\n private _horizonDistanceToAtmosphereEdge = 0;\r\n private _horizonDistanceToAtmosphereEdgeSquared = 0;\r\n private _rayleighScattering = new Vector3();\r\n private _mieScattering = new Vector3();\r\n private _mieAbsorption = new Vector3();\r\n private _mieExtinction = new Vector3();\r\n private _ozoneAbsorption = new Vector3();\r\n\r\n /**\r\n * The radius of the planet in kilometers.\r\n */\r\n public get planetRadius(): number {\r\n return this._planetRadius;\r\n }\r\n public set planetRadius(value: number) {\r\n if (this._planetRadius !== value) {\r\n this._planetRadius = value;\r\n this._recomputeDimensionalParameters();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The squared radius of the planet in kilometers.\r\n */\r\n public get planetRadiusSquared(): number {\r\n return this._planetRadiusSquared;\r\n }\r\n\r\n /**\r\n * Offset applied to view points near the planet's surface. This should be greater than 0.\r\n * It prevents rendering issues close to the planet's surface.\r\n */\r\n public get planetRadiusOffset(): number {\r\n return this._planetRadiusOffset;\r\n }\r\n public set planetRadiusOffset(value: number) {\r\n if (this._planetRadiusOffset !== value) {\r\n this._planetRadiusOffset = value;\r\n this._recomputeDimensionalParameters();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * This is the {@link planetRadius} with the additional {@link planetRadiusOffset}, in kilometers.\r\n */\r\n public get planetRadiusWithOffset(): number {\r\n return this._planetRadiusWithOffset;\r\n }\r\n\r\n /**\r\n * The thickness of the atmosphere measured in kilometers.\r\n */\r\n public get atmosphereThickness(): number {\r\n return this._atmosphereThickness;\r\n }\r\n public set atmosphereThickness(value: number) {\r\n if (this._atmosphereThickness !== value) {\r\n this._atmosphereThickness = value;\r\n this._recomputeDimensionalParameters();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The combined planet radius and atmosphere thickness in kilometers.\r\n */\r\n public get atmosphereRadius(): number {\r\n return this._atmosphereRadius;\r\n }\r\n\r\n /**\r\n * The atmosphere radius squared in kilometers.\r\n */\r\n public get atmosphereRadiusSquared(): number {\r\n return this._atmosphereRadiusSquared;\r\n }\r\n\r\n /**\r\n * Horizon distance from the planet's surface to the outer edge of the atmosphere in kilometers.\r\n */\r\n public get horizonDistanceToAtmosphereEdge(): number {\r\n return this._horizonDistanceToAtmosphereEdge;\r\n }\r\n\r\n /**\r\n * Horizon distance from the planet's surface to the outer edge of the atmosphere, squared, in kilometers.\r\n */\r\n public get horizonDistanceToAtmosphereEdgeSquared(): number {\r\n return this._horizonDistanceToAtmosphereEdgeSquared;\r\n }\r\n\r\n /**\r\n * The scale applied to {@link peakRayleighScattering}.\r\n */\r\n public get rayleighScatteringScale(): number {\r\n return this._rayleighScatteringScale;\r\n }\r\n public set rayleighScatteringScale(value: number) {\r\n if (this._rayleighScatteringScale !== value) {\r\n this._rayleighScatteringScale = value;\r\n this._recomputeRayleighScattering();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Rayleigh scattering per kilometer at sea level for red, green, and blue wavelengths.\r\n */\r\n public get peakRayleighScattering(): Vector3 {\r\n return this._peakRayleighScattering;\r\n }\r\n public set peakRayleighScattering(value: Vector3) {\r\n if (!this._peakRayleighScattering.equals(value)) {\r\n this._peakRayleighScattering.copyFrom(value);\r\n this._recomputeRayleighScattering();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Rayleigh scattering per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by scaling {@link peakRayleighScattering} by {@link rayleighScatteringScale}.\r\n */\r\n public get rayleighScattering(): Vector3 {\r\n return this._rayleighScattering;\r\n }\r\n\r\n /**\r\n * The scale applied to {@link peakMieScattering}.\r\n */\r\n public get mieScatteringScale(): number {\r\n return this._mieScatteringScale;\r\n }\r\n public set mieScatteringScale(value: number) {\r\n if (this._mieScatteringScale !== value) {\r\n this._mieScatteringScale = value;\r\n this._recomputeMieScattering();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Mie scattering per kilometer at sea level for red, green, and blue wavelengths.\r\n */\r\n public get peakMieScattering(): Vector3 {\r\n return this._peakMieScattering;\r\n }\r\n public set peakMieScattering(value: Vector3) {\r\n if (!this._peakMieScattering.equals(value)) {\r\n this._peakMieScattering.copyFrom(value);\r\n this._recomputeMieScattering();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Mie scattering per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by scaling {@link mieScatteringScale} by {@link peakMieScattering}.\r\n */\r\n public get mieScattering(): Vector3 {\r\n return this._mieScattering;\r\n }\r\n\r\n /**\r\n * The scale applied to {@link peakMieAbsorption}.\r\n */\r\n public get mieAbsorptionScale(): number {\r\n return this._mieAbsorptionScale;\r\n }\r\n public set mieAbsorptionScale(value: number) {\r\n if (this._mieAbsorptionScale !== value) {\r\n this._mieAbsorptionScale = value;\r\n this._recomputeMieAbsorption();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Mie absorption per kilometer at sea level for red, green, and blue wavelengths.\r\n */\r\n public get peakMieAbsorption(): Vector3 {\r\n return this._peakMieAbsorption;\r\n }\r\n public set peakMieAbsorption(value: Vector3) {\r\n if (!this._peakMieAbsorption.equals(value)) {\r\n this._peakMieAbsorption.copyFrom(value);\r\n this._recomputeMieAbsorption();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The Mie absorption per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by scaling {@link mieAbsorptionScale} by {@link peakMieAbsorption}.\r\n */\r\n public get mieAbsorption(): Vector3 {\r\n return this._mieAbsorption;\r\n }\r\n\r\n /**\r\n * The Mie extinction per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by adding the {@link mieAbsorption} to the {@link mieScattering}.\r\n */\r\n public get mieExtinction(): Vector3 {\r\n return this._mieExtinction;\r\n }\r\n\r\n /**\r\n * The scale applied to {@link peakOzoneAbsorption}.\r\n */\r\n public get ozoneAbsorptionScale(): number {\r\n return this._ozoneAbsorptionScale;\r\n }\r\n public set ozoneAbsorptionScale(value: number) {\r\n if (this._ozoneAbsorptionScale !== value) {\r\n this._ozoneAbsorptionScale = value;\r\n this._recomputeOzoneAbsorption();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The ozone absorption per kilometer measured at a height corresponding to it's peak concentration,\r\n * for red, green, and blue wavelengths.\r\n */\r\n public get peakOzoneAbsorption(): Vector3 {\r\n return this._peakOzoneAbsorption;\r\n }\r\n public set peakOzoneAbsorption(value: Vector3) {\r\n if (!this._peakOzoneAbsorption.equals(value)) {\r\n this._peakOzoneAbsorption.copyFrom(value);\r\n this._recomputeOzoneAbsorption();\r\n this.onChangedObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * The ozone absorption per kilometer at sea level for red, green, and blue wavelengths.\r\n * This value cannot be set directly. It is inferred by scaling {@link peakOzoneAbsorption} by {@link ozoneAbsorptionScale}.\r\n */\r\n public get ozoneAbsorption(): Vector3 {\r\n return this._ozoneAbsorption;\r\n }\r\n\r\n /**\r\n * Constructs the {@link AtmospherePhysicalProperties}.\r\n * @param options - The options for the {@link AtmospherePhysicalProperties}.\r\n */\r\n constructor(options?: IAtmospherePhysicalPropertiesOptions) {\r\n this._planetRadius = options?.planetRadius ?? DefaultPlanetRadius;\r\n this._planetRadiusOffset = options?.planetRadiusOffset ?? DefaultPlanetRadiusOffset;\r\n this._atmosphereThickness = options?.atmosphereThickness ?? DefaultAtmosphereThickness;\r\n this._rayleighScatteringScale = options?.rayleighScatteringScale ?? 1.0;\r\n this._peakRayleighScattering.copyFrom(options?.peakRayleighScattering ?? DefaultPeakRayleighScattering);\r\n this._mieScatteringScale = options?.mieScatteringScale ?? 1.0;\r\n this._peakMieScattering.copyFrom(options?.peakMieScattering ?? DefaultPeakMieScattering);\r\n this._mieAbsorptionScale = options?.mieAbsorptionScale ?? 1.0;\r\n this._peakMieAbsorption.copyFrom(options?.peakMieAbsorption ?? DefaultPeakMieAbsorption);\r\n this._ozoneAbsorptionScale = options?.ozoneAbsorptionScale ?? 1.0;\r\n this._peakOzoneAbsorption.copyFrom(options?.peakOzoneAbsorption ?? DefaultPeakOzoneAbsorption);\r\n\r\n // Compute inferred values.\r\n this._recomputeDimensionalParameters();\r\n this._recomputeRayleighScattering();\r\n this._recomputeMieScattering();\r\n this._recomputeMieAbsorption();\r\n this._recomputeOzoneAbsorption();\r\n }\r\n\r\n private _recomputeDimensionalParameters(): void {\r\n this._planetRadiusWithOffset = this._planetRadius + this._planetRadiusOffset;\r\n this._planetRadiusSquared = this._planetRadius * this._planetRadius;\r\n this._atmosphereRadius = this._planetRadius + this._atmosphereThickness;\r\n this._atmosphereRadiusSquared = this._atmosphereRadius * this._atmosphereRadius;\r\n this._horizonDistanceToAtmosphereEdgeSquared = this._atmosphereRadiusSquared - this._planetRadiusSquared;\r\n this._horizonDistanceToAtmosphereEdge = Math.sqrt(this._horizonDistanceToAtmosphereEdgeSquared);\r\n }\r\n\r\n private _recomputeRayleighScattering(): void {\r\n this._peakRayleighScattering.scaleToRef(this._rayleighScatteringScale, this._rayleighScattering);\r\n }\r\n\r\n private _recomputeMieScattering(): void {\r\n this._peakMieScattering.scaleToRef(this._mieScatteringScale, this._mieScattering);\r\n this._recomputeMieExtinction();\r\n }\r\n\r\n private _recomputeMieAbsorption(): void {\r\n this._peakMieAbsorption.scaleToRef(this._mieAbsorptionScale, this._mieAbsorption);\r\n this._recomputeMieExtinction();\r\n }\r\n\r\n private _recomputeMieExtinction(): void {\r\n this._mieAbsorption.addToRef(this._mieScattering, this._mieExtinction);\r\n }\r\n\r\n private _recomputeOzoneAbsorption(): void {\r\n this._peakOzoneAbsorption.scaleToRef(this._ozoneAbsorptionScale, this._ozoneAbsorption);\r\n }\r\n}\r\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport { Clamp } from \"core/Maths/math.scalar.functions\";\r\nimport type { IColor4Like } from \"core/Maths/math.like\";\r\n\r\nconst MakeTempColor4Like = (): IColor4Like => {\r\n return {\r\n r: Number.NaN,\r\n g: Number.NaN,\r\n b: Number.NaN,\r\n a: Number.NaN,\r\n };\r\n};\r\n\r\nconst TmpColor1 = MakeTempColor4Like();\r\nconst TmpColor2 = MakeTempColor4Like();\r\nconst TmpColor3 = MakeTempColor4Like();\r\nconst TmpColor4 = MakeTempColor4Like();\r\n\r\n/**\r\n * Samples the texture data at the given uv coordinate using bilinear interpolation.\r\n * Note this will not match GPU sampling behavior exactly.\r\n * Currently assumes clamping behavior.\r\n * @param u - The u coordinate to sample.\r\n * @param v - The v coordinate to sample.\r\n * @param widthPx - The width of the texture in texels.\r\n * @param heightPx - The height of the texture in texels.\r\n * @param data - The texture data to sample.\r\n * @param result - The color to store the sample.\r\n * @param normalizeFunc - The function to normalize the texel values. Default is to divide by 255.\r\n * @returns The result color.\r\n */\r\nexport function Sample2DRgbaToRef<T extends IColor4Like>(\r\n u: number,\r\n v: number,\r\n widthPx: number,\r\n heightPx: number,\r\n data: Uint8Array | Uint16Array | Float32Array,\r\n result: T,\r\n normalizeFunc = (value: number) => value / 255.0\r\n): T {\r\n if (widthPx <= 0 || heightPx <= 0) {\r\n throw new Error(\"Sample2DRgbaToRef: widthPx and heightPx must be positive.\");\r\n }\r\n\r\n const expectedLength = widthPx * heightPx * 4;\r\n if (data.length < expectedLength) {\r\n throw new Error(`Sample2DRgbaToRef: data length (${data.length}) is less than required (${expectedLength}).`);\r\n }\r\n\r\n // Default to clamping behavior, but could support others.\r\n u = Clamp(u);\r\n v = Clamp(v);\r\n\r\n // Compute 4 nearest neighbor texels.\r\n const fractionalTexelX = Math.max(u * widthPx - 0.5, 0);\r\n const fractionalTexelY = Math.max(v * heightPx - 0.5, 0);\r\n const xLeft = Math.floor(fractionalTexelX);\r\n const xRight = Math.min(xLeft + 1, widthPx - 1);\r\n const yBottom = Math.floor(fractionalTexelY);\r\n const yTop = Math.min(yBottom + 1, heightPx - 1);\r\n\r\n // Sample nearest neighbor texels.\r\n const lowerLeftColor = TexelFetch2DRgbaToRef(xLeft, yBottom, widthPx, heightPx, data, TmpColor1, normalizeFunc);\r\n const upperLeftColor = TexelFetch2DRgbaToRef(xLeft, yTop, widthPx, heightPx, data, TmpColor2, normalizeFunc);\r\n const lowerRightColor = TexelFetch2DRgbaToRef(xRight, yBottom, widthPx, heightPx, data, TmpColor3, normalizeFunc);\r\n const upperRightColor = TexelFetch2DRgbaToRef(xRight, yTop, widthPx, heightPx, data, TmpColor4, normalizeFunc);\r\n\r\n // Compute weights.\r\n const tX = fractionalTexelX - xLeft;\r\n const tY = fractionalTexelY - yBottom;\r\n const oneMinusTX = 1.0 - tX;\r\n const oneMinusTY = 1.0 - tY;\r\n const w0 = oneMinusTX * oneMinusTY;\r\n const w1 = tX * oneMinusTY;\r\n const w2 = oneMinusTX * tY;\r\n const w3 = tX * tY;\r\n\r\n // Compute the result.\r\n result.r = lowerLeftColor.r * w0 + lowerRightColor.r * w1 + upperLeftColor.r * w2 + upperRightColor.r * w3;\r\n result.g = lowerLeftColor.g * w0 + lowerRightColor.g * w1 + upperLeftColor.g * w2 + upperRightColor.g * w3;\r\n result.b = lowerLeftColor.b * w0 + lowerRightColor.b * w1 + upperLeftColor.b * w2 + upperRightColor.b * w3;\r\n result.a = lowerLeftColor.a * w0 + lowerRightColor.a * w1 + upperLeftColor.a * w2 + upperRightColor.a * w3;\r\n return result;\r\n}\r\n\r\n/**\r\n * Fetches a texel from a 2D texture and stores the result in the given color.\r\n * @param x - The x coordinate in texels.\r\n * @param y - The y coordinate in texels.\r\n * @param width - The width of the texture in texels.\r\n * @param height - The height of the texture in texels.\r\n * @param data - The texture data to sample from.\r\n * @param result - The color to store the sampled color in.\r\n * @param normalizeFunc - The function to normalize the texel values. Default is to divide by 255.\r\n * @returns The result color.\r\n */\r\nconst TexelFetch2DRgbaToRef = <T extends IColor4Like>(\r\n x: number,\r\n y: number,\r\n width: number,\r\n height: number,\r\n data: Uint8Array | Uint16Array | Float32Array,\r\n result: T,\r\n normalizeFunc = (value: number) => value / 255.0\r\n): T => {\r\n const clampedTexelX = Clamp(x, 0, width - 1);\r\n const clampedTexelY = Clamp(y, 0, height - 1);\r\n const index = 4 * (clampedTexelY * width + clampedTexelX);\r\n result.r = normalizeFunc(data[index]);\r\n result.g = normalizeFunc(data[index + 1]);\r\n result.b = normalizeFunc(data[index + 2]);\r\n result.a = normalizeFunc(data[index + 3]);\r\n return result;\r\n};\r\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"atmosphereFragmentDeclaration\";\nconst shader = `uniform vec3 peakRayleighScattering;uniform float planetRadius;uniform vec3 peakMieScattering;uniform float atmosphereThickness;uniform vec3 peakMieAbsorption;uniform float planetRadiusSquared;uniform vec3 peakMieExtinction;uniform float atmosphereRadius;uniform vec3 peakOzoneAbsorption;uniform float atmosphereRadiusSquared;uniform float horizonDistanceToAtmosphereEdge;uniform float horizonDistanceToAtmosphereEdgeSquared;uniform float planetRadiusWithOffset;uniform float planetRadiusOffset;uniform float atmosphereExposure;uniform float aerialPerspectiveRadianceBias;uniform float inverseAtmosphereThickness;uniform float aerialPerspectiveTransmittanceScale;uniform mat4 inverseViewProjectionWithoutTranslation;uniform vec3 directionToLight;uniform float multiScatteringIntensity;uniform vec3 directionToLightRelativeToCameraGeocentricNormal;uniform float cameraRadius;uniform vec3 lightRadianceAtCamera;uniform float diffuseSkyIrradianceDesaturationFactor;uniform vec3 groundAlbedo;uniform float aerialPerspectiveSaturation;uniform vec3 minMultiScattering;uniform float diffuseSkyIrradianceIntensity;uniform vec3 cameraPositionGlobal;uniform float lightIntensity;uniform vec3 clampedCameraPositionGlobal;uniform float aerialPerspectiveIntensity;uniform vec3 cameraGeocentricNormal;uniform float clampedCameraRadius;uniform vec3 cameraForward;uniform float clampedCameraHeight;uniform vec3 cameraPosition;uniform float cosCameraHorizonAngleFromZenith;uniform vec4 viewport;uniform vec3 additionalDiffuseSkyIrradiance;uniform float cameraHeight;uniform float cameraNearPlane;uniform float originHeight;uniform float sinCameraAtmosphereHorizonAngleFromNadir;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const atmosphereFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"atmosphereUboDeclaration\";\nconst shader = `layout(std140,column_major) uniform;uniform Atmosphere {vec3 peakRayleighScattering;float planetRadius;vec3 peakMieScattering;float atmosphereThickness;vec3 peakMieAbsorption;float planetRadiusSquared;vec3 peakMieExtinction;float atmosphereRadius;vec3 peakOzoneAbsorption;float atmosphereRadiusSquared;float horizonDistanceToAtmosphereEdge;float horizonDistanceToAtmosphereEdgeSquared;float planetRadiusWithOffset;float planetRadiusOffset;float atmosphereExposure;float aerialPerspectiveRadianceBias;float inverseAtmosphereThickness;float aerialPerspectiveTransmittanceScale;mat4 inverseViewProjectionWithoutTranslation;vec3 directionToLight;float multiScatteringIntensity;vec3 directionToLightRelativeToCameraGeocentricNormal;float cameraRadius;vec3 lightRadianceAtCamera;float diffuseSkyIrradianceDesaturationFactor;vec3 groundAlbedo;float aerialPerspectiveSaturation;vec3 minMultiScattering;float diffuseSkyIrradianceIntensity;vec3 cameraPositionGlobal;float lightIntensity;vec3 clampedCameraPositionGlobal;float aerialPerspectiveIntensity;vec3 cameraGeocentricNormal;float clampedCameraRadius;vec3 cameraForward;float clampedCameraHeight;vec3 cameraPosition;float cosCameraHorizonAngleFromZenith;vec4 viewport;vec3 additionalDiffuseSkyIrradiance;float cameraHeight;float cameraNearPlane;float originHeight;float sinCameraAtmosphereHorizonAngleFromNadir;};\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const atmosphereUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"depthFunctions\";\nconst shader = `float reconstructDistanceFromCameraPlane(float depth,float cameraNearPlane) {return cameraNearPlane/(1.0-depth);}\nfloat sampleDistanceFromCameraPlane(sampler2D depthTexture,vec2 uv,float cameraNearPlane) {float depth=textureLod(depthTexture,uv,0.).r;return depth>=1. ? 0. : reconstructDistanceFromCameraPlane(depth,cameraNearPlane);}\nfloat reconstructDistanceFromCamera(float depth,vec3 cameraRayDirection,vec3 cameraForward,float cameraNearPlane) {float distanceFromCameraPlane=reconstructDistanceFromCameraPlane(depth,cameraNearPlane);return distanceFromCameraPlane/max(0.00001,dot(cameraForward,cameraRayDirection));}\nfloat reconstructDistanceFromCamera(\nsampler2D depthTexture,\nvec2 uv,\nvec3 cameraRayDirection,\nvec3 cameraForward,\nfloat cameraNearPlane) {float depth=textureLod(depthTexture,uv,0.).r;return depth>=1. ? 0. : reconstructDistanceFromCamera(depth,cameraRayDirection,cameraForward,cameraNearPlane);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const depthFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"core/Shaders/ShadersInclude/intersectionFunctions\";\n\nconst name = \"atmosphereFunctions\";\nconst shader = `#include<intersectionFunctions>\nconst vec2 MultiScatteringLutSize=vec2(32.0,32.0);const vec2 MultiScatteringLutDomainInUVSpace=(MultiScatteringLutSize-vec2(1.0))/MultiScatteringLutSize;const vec2 MultiScatteringLutHalfTexelSize=vec2(0.5)/MultiScatteringLutSize;const float NumAerialPerspectiveLutLayers=32.0;const vec3 AerialPerspectiveLutSize=vec3(16.0,64.0,NumAerialPerspectiveLutLayers);const vec2 DiffuseSkyIrradianceLutSize=vec2(64.0,16.0);const vec2 DiffuseSkyIrradianceLutDomainInUVSpace=(DiffuseSkyIrradianceLutSize-vec2(1.0))/DiffuseSkyIrradianceLutSize;const vec2 DiffuseSkyIrradianceLutHalfTexelSize=vec2(0.5)/DiffuseSkyIrradianceLutSize;const vec2 SkyViewLutSize=vec2(128.0,128.0);const vec2 SkyViewLutDomainInUVSpace=(SkyViewLutSize-vec2(1.0))/SkyViewLutSize;const vec2 SkyViewLutHalfTexelSize=vec2(0.5)/SkyViewLutSize;const float AerialPerspectiveLutKMPerSlice=4.0;const float AerialPerspectiveLutRangeKM=AerialPerspectiveLutKMPerSlice*NumAerialPerspectiveLutLayers;const float TransmittanceSampleCount=128.0;const float SkyViewLutSampleCount=30.0;const vec2 TransmittanceLutSize=vec2(256.,64.);const vec2 TransmittanceLutDomainInUVSpace=(TransmittanceLutSize-vec2(1.))/TransmittanceLutSize;const vec2 TransmittanceLutHalfTexelSize=vec2(0.5)/TransmittanceLutSize;const float TransmittanceHorizonRange=2.*TransmittanceLutHalfTexelSize.x;const float TransmittanceMaxUnoccludedU=1.-0.5*TransmittanceHorizonRange;const float TransmittanceMinOccludedU=1.+0.5*TransmittanceHorizonRange;vec2 uvToUnit(vec2 uv,vec2 domainInUVSpace,vec2 halfTexelSize) {return (uv-halfTexelSize)/domainInUVSpace;}\nvec2 unitToUV(vec2 unit,vec2 domainInUVSpace,vec2 halfTexelSize) {return unit*domainInUVSpace+halfTexelSize;}\nfloat sphereIntersectNearest(vec3 rayOrigin,vec3 rayDirection,float sphereRadius) {vec2 result=sphereIntersectFromOrigin(rayOrigin,rayDirection,sphereRadius);float c=dot(rayOrigin,rayOrigin)-sphereRadius*sphereRadius;return c>=0.0 ?\nresult.y :\nresult.x;}\nvoid moveToTopAtmosphere(\nvec3 cameraPosition,\nfloat positionRadius,\nvec3 positionGeocentricNormal,\nvec3 rayDirection,\nout bool intersectsAtmosphere,\nout vec3 cameraPositionClampedToTopOfAtmosphere) {intersectsAtmosphere=true;cameraPositionClampedToTopOfAtmosphere=cameraPosition;if (positionRadius>atmosphereRadius) {float tTop=sphereIntersectNearest(cameraPosition,rayDirection,atmosphereRadius);if (tTop>=0.0) {vec3 upOffset=-planetRadiusOffset*positionGeocentricNormal;cameraPositionClampedToTopOfAtmosphere=cameraPosition+rayDirection*tTop+upOffset;} else {intersectsAtmosphere=false;}}}\nvoid getSkyViewUVFromParameters(\nbool intersectsGround,\nfloat cosHorizonAngleFromZenith,\nfloat cosAngleBetweenViewAndZenith,\nfloat cosAngleBetweenViewAndLightOnPlane,\nout vec2 uv)\n{vec2 unit=vec2(0.0);if (intersectsGround) {float coord=(cosAngleBetweenViewAndZenith+1.0)/(cosHorizonAngleFromZenith+1.0);coord=sqrtClamped(coord); \nunit.y=0.5*coord; } else {float coord=(cosAngleBetweenViewAndZenith-cosHorizonAngleFromZenith)/(1.0-cosHorizonAngleFromZenith);coord=sqrtClamped(coord); \nunit.y=0.5*coord+0.5; }\n{float coord=0.5-0.5*cosAngleBetweenViewAndLightOnPlane;unit.x=coord;}\nuv=unitToUV(unit,SkyViewLutDomainInUVSpace,SkyViewLutHalfTexelSize);}\nvec4 sampleSkyViewLut(\nsampler2D skyViewLut,\nfloat positionRadius,\nvec3 geocentricNormal,\nvec3 rayDirection,\nvec3 directionToLight,\nfloat cosHorizonAngleFromZenith,\nout float cosAngleBetweenViewAndZenith,\nout bool isRayIntersectingGround) {cosAngleBetweenViewAndZenith=dot(rayDirection,geocentricNormal);if (positionRadius>atmosphereRadius) {float sinAngleBetweenViewAndNadir=sqrtClamped(1.-cosAngleBetweenViewAndZenith*cosAngleBetweenViewAndZenith);if (sinAngleBetweenViewAndNadir>sinCameraAtmosphereHorizonAngleFromNadir) {isRayIntersectingGround=false;return vec4(0.);}}\nvec3 sideVector=normalize(cross(geocentricNormal,rayDirection));vec3 forwardVector=normalize(cross(sideVector,geocentricNormal));vec2 lightOnPlane=normalize(vec2(dot(directionToLight,forwardVector),dot(directionToLight,sideVector)));float cosAngleBetweenViewAndLightOnPlane=lightOnPlane.x;float rayIntersectionScale=mix(0.95,1.,saturate((positionRadius-planetRadius)/atmosphereThickness));isRayIntersectingGround =\npositionRadius>planetRadius &&\n(rayIntersectionScale*cosAngleBetweenViewAndZenith)<=cosHorizonAngleFromZenith;vec2 uv;getSkyViewUVFromParameters(\nisRayIntersectingGround,\ncosHorizonAngleFromZenith,\ncosAngleBetweenViewAndZenith,\ncosAngleBetweenViewAndLightOnPlane,\nuv);return textureLod(skyViewLut,uv,0.);}\nfloat computeRayleighPhase(float onePlusCosThetaSq) {return 0.0596831037*onePlusCosThetaSq;}\nfloat computeMiePhaseCornetteShanks(float cosTheta,float onePlusCosThetaSq) {const float g=0.8;const float gSquared=g*g;const float oneMinusGSquared=1.-gSquared;const float onePlusGSquared=1.+gSquared;const float twoPlusGSquared=2.+gSquared;const float twoG=2.*g;const float threeOverEightPi=3./(8.*PI);return threeOverEightPi*oneMinusGSquared*onePlusCosThetaSq/(twoPlusGSquared*pow(onePlusGSquared-twoG*cosTheta,1.5));}\nfloat computeOzoneDensity(float normalizedViewHeight) {const float MinOzoneDensity=0.135;const float OneMinusMinOzoneDensity=1.-MinOzoneDensity;const float OzoneStartHeight=.15; \nconst float PeakOzoneHeight=.25;const float MaxOzoneHeight=0.6;const float InverseRampupDistance=1./(PeakOzoneHeight-OzoneStartHeight);const float InverseRampdownDistance=1./(MaxOzoneHeight-PeakOzoneHeight);float lowerAtmosphereDensity=MinOzoneDensity+OneMinusMinOzoneDensity*max(0.,normalizedViewHeight-OzoneStartHeight)*InverseRampupDistance;float sqrtUpperAtmosphereDensity=max(0.,1.-(normalizedViewHeight-PeakOzoneHeight)*InverseRampdownDistance);float upperAtmosphereDensity=sqrtUpperAtmosphereDensity*sqrtUpperAtmosphereDensity;float densityOzone=normalizedViewHeight<PeakOzoneHeight ? lowerAtmosphereDensity : upperAtmosphereDensity;return densityOzone;}\nvoid sampleMediumRGB(\nfloat viewHeight,\nout vec3 scatteringRayleigh,\nout vec3 scatteringMie,\nout vec3 extinction,\nout vec3 scattering) {float normalizedViewHeight=saturate(viewHeight*inverseAtmosphereThickness);float densityMie=exp(-83.333*normalizedViewHeight);float densityRayleigh=exp(-12.5*normalizedViewHeight);float densityOzone=computeOzoneDensity(normalizedViewHeight);scatteringRayleigh=densityRayleigh*peakRayleighScattering;scatteringMie=densityMie*peakMieScattering;scattering=scatteringMie+scatteringRayleigh;vec3 extinctionRayleigh=scatteringRayleigh;vec3 extinctionMie=densityMie*peakMieExtinction;vec3 extinctionOzone=densityOzone*peakOzoneAbsorption;extinction=extinctionRayleigh+extinctionMie+extinctionOzone;}\nvec3 computeTransmittance(vec3 rayOriginGlobal,vec3 rayDirection,float tMax,float sampleCount) {vec3 opticalDepth=vec3(0.);float t=0.;float sampleSegmentWeight=tMax/sampleCount;const float sampleSegmentT=0.3;for (float s=0.; s<sampleCount; s+=1.) {float newT=sampleSegmentWeight*(s+sampleSegmentT);float dt=newT-t;t=newT;vec3 scatteringRayleigh,scatteringMie,extinction,scattering;vec3 samplePositionGlobal=rayOriginGlobal+t*rayDirection;sampleMediumRGB(length(samplePositionGlobal)-planetRadius,scatteringRayleigh,scatteringMie,extinction,scattering);opticalDepth+=extinction*dt;}\nreturn exp(-opticalDepth);}\nvec2 getTransmittanceUV(float radius,float cosAngleLightToZenith,out float distanceToHorizon) {float radiusSquared=radius*radius;distanceToHorizon=sqrtClamped(radiusSquared-planetRadiusSquared);float cosAngleLightToZenithSquared=cosAngleLightToZenith*cosAngleLightToZenith;float discriminant=radiusSquared*(cosAngleLightToZenithSquared-1.)+atmosphereRadiusSquared;float distanceToAtmosphereEdge=max(0.,-radius*cosAngleLightToZenith+sqrtClamped(discriminant));float minDistanceToAtmosphereEdge=max(0.,atmosphereRadius-radius);float maxDistanceToAtmosphereEdge=distanceToHorizon+horizonDistanceToAtmosphereEdge;float cosAngleLightToZenithCoordinate=(distanceToAtmosphereEdge-minDistanceToAtmosphereEdge)/max(0.000001,maxDistanceToAtmosphereEdge-minDistanceToAtmosphereEdge);float distanceToHorizonCoordinate=distanceToHorizon/max(0.000001,horizonDistanceToAtmosphereEdge);vec2 unit=vec2(cosAngleLightToZenithCoordinate,distanceToHorizonCoordinate);return unit*TransmittanceLutDomainInUVSpace+TransmittanceLutHalfTexelSize; }\nvec4 sampleTransmittanceLut(sampler2D transmittanceLut,float positionRadius,float cosAngleLightToZenith) {float distanceToHorizon;vec2 uv=getTransmittanceUV(positionRadius,cosAngleLightToZenith,distanceToHorizon);float weight=smoothstep(TransmittanceMinOccludedU,TransmittanceMaxUnoccludedU,uv.x);return weight*textureLod(transmittanceLut,uv,0.);}\nvec3 sampleMultiScatteringLut(sampler2D multiScatteringLut,float radius,float cosAngleLightToZenith) {vec2 unit=vec2(0.5+0.5*cosAngleLightToZenith,(radius-planetRadius)/atmosphereThickness);vec2 uv=unitToUV(unit,MultiScatteringLutDomainInUVSpace,MultiScatteringLutHalfTexelSize);vec3 multiScattering=textureLod(multiScatteringLut,uv,0.).rgb;return max(minMultiScattering,multiScattering);}\nconst float uniformPhase=RECIPROCAL_PI4;void integrateScatteredRadiance(\nbool isAerialPerspectiveLut,\nfloat lightIntensity,\nsampler2D transmittanceLut,\n#ifndef COMPUTE_MULTI_SCATTERING\nsampler2D multiScatteringLut,\nfloat multiScatteringIntensity,\n#endif\nvec3 rayOriginGlobal,\nvec3 rayDirection,\nvec3 directionToLight,\nfloat tMaxMax,\nfloat sampleCount,\nfloat distanceToSurface,\nout vec3 radiance,\nout vec3 transmittance\n#if COMPUTE_MULTI_SCATTERING\n,out vec3 multiScattering\n#endif\n) {radiance=vec3(0.);transmittance=vec3(1.);\n#if COMPUTE_MULTI_SCATTERING\nmultiScattering=vec3(0.);\n#endif\nfloat tBottom=sphereIntersectNearest(rayOriginGlobal,rayDirection,planetRadius);float tTop=sphereIntersectNearest(rayOriginGlobal,rayDirection,atmosphereRadius);float tMax=0.;if (tBottom<0.) {if (tTop<0.) {return;} else {tMax=tTop;}} else {if (tTop>0.) {if (isAerialPerspectiveLut) {tMax=tTop;} else {tMax=min(tBottom,tTop);}}}\nif (distanceToSurface>0. && distanceToSurface<tMax) {tMax=distanceToSurface;}\ntMax=min(tMax,tMaxMax);\n#ifndef COMPUTE_MULTI_SCATTERING\nfloat cosTheta=dot(rayDirection,directionToLight);float onePlusCosThetaSq=1.+cosTheta*cosTheta;float rayleighPhase=computeRayleighPhase(onePlusCosThetaSq);float miePhase=computeMiePhaseCornetteShanks(cosTheta,onePlusCosThetaSq);\n#endif\nfloat transmittanceScale=isAerialPerspectiveLut ? aerialPerspectiveTransmittanceScale : 1.;float t=0.;float sampleSegmentWeight=tMax/sampleCount;const float sampleSegmentT=0.3;for (float s=0.; s<sampleCount; s+=1.) {float newT=sampleSegmentWeight*(s+sampleSegmentT);float dt=newT-t;t=newT;vec3 samplePositionGlobal=rayOriginGlobal+t*rayDirection;float sampleRadiusGlobal=length(samplePositionGlobal);vec3 sampleGeocentricNormal=samplePositionGlobal/sampleRadiusGlobal;float sampleCosAngleLightToZenith=dot(directionToLight,sampleGeocentricNormal);vec3 scatteringRayleigh,scatteringMie,extinction,scattering;sampleMediumRGB(sampleRadiusGlobal-planetRadius,scatteringRayleigh,scatteringMie,extinction,scattering);vec3 transmittanceToLight=sampleTransmittanceLut(transmittanceLut,sampleRadiusGlobal,sampleCosAngleLightToZenith).rgb;\n#if COMPUTE_MULTI_SCATTERING\nvec3 phaseTimesScattering=uniformPhase*scattering;vec3 S=transmittanceToLight*phaseTimesScattering;\n#else\nvec3 phaseTimesScattering=scatteringMie*miePhase+scatteringRayleigh*rayleighPhase;vec3 multiScatteredRadiance=sampleMultiScatteringLut(multiScatteringLut,sampleRadiusGlobal,sampleCosAngleLightToZenith);vec3 S=transmittanceScale*transmittanceToLight*phaseTimesScattering+multiScatteringIntensity*multiScatteredRadiance*scattering;\n#endif\nvec3 sampleOpticalDepth=extinction*dt;vec3 sampleTransmittance=exp(-sampleOpticalDepth);vec3 clampedExtinction=max(vec3(0.0000001),extinction);vec3 SInt=(S-S*sampleTransmittance)/clampedExtinction;radiance+=transmittance*SInt;\n#if COMPUTE_MULTI_SCATTERING\nvec3 MSInt=(scattering-scattering*sampleTransmittance)/clampedExtinction;multiScattering+=transmittance*MSInt;\n#endif\ntransmittance*=sampleTransmittance;}\n#if USE_GROUND_ALBEDO\nif (tMax==tBottom && tBottom>0.) {vec3 planetPos=rayOriginGlobal+tBottom*rayDirection;float planetPosRadius=length(planetPos);vec3 planetPosGeocentricNormal=planetPos/planetPosRadius;float nDotL=dot(directionToLight,planetPosGeocentricNormal);vec3 lightTransmittance=sampleTransmittanceLut(transmittanceLut,planetPosRadius,nDotL).rgb;const float diffuseBrdf=RECIPROCAL_PI;radiance+=lightTransmittance*transmittance*groundAlbedo*(nDotL*diffuseBrdf);}\n#endif\nradiance*=lightIntensity;}\nfloat layerIdxToAerialPerspectiveLayer(float layerIdx) {float layer=(layerIdx+1.)/NumAerialPerspectiveLutLayers;layer*=layer; \nlayer*=NumAerialPerspectiveLutLayers;return layer;}\nfloat toAerialPerspectiveDepth(float layer) {return layer*AerialPerspectiveLutKMPerSlice;}\nfloat toAerialPerspectiveLayer(float distance,float aerialPerspectiveLutDistancePerSlice) {return distance/aerialPerspectiveLutDistancePerSlice;}\nvec4 applyAerialPerspectiveSaturation(vec4 aerialPerspective) {float previousRadiance=getLuminance(aerialPerspective.rgb);aerialPerspective.rgb=mix(vec3(previousRadiance),aerialPerspective.rgb,aerialPerspectiveSaturation);return aerialPerspective;}\nvec4 applyAerialPerspectiveIntensity(vec4 aerialPerspective) {\n#if APPLY_AERIAL_PERSPECTIVE_INTENSITY\nif (aerialPerspectiveIntensity==0.) {aerialPerspective=vec4(0.);} else {float previousAlpha=aerialPerspective.a;aerialPerspective/=max(0.00001,previousAlpha);aerialPerspective*=pow(previousAlpha,1./aerialPerspectiveIntensity);}\n#endif\nreturn aerialPerspective;}\nvec4 applyAerialPerspectiveRadianceBias(vec4 aerialPerspective) {\n#if APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\nfloat originalRadiance=dot(aerialPerspective.rgb,LuminanceEncodeApprox);float targetRadiance=originalRadiance+aerialPerspectiveRadianceBias;if (originalRadiance>0.) {aerialPerspective*=max(0.,targetRadiance/originalRadiance);} else {aerialPerspective=max(vec4(0.),vec4(vec3(aerialPerspectiveRadianceBias),aerialPerspectiveRadianceBias));}\naerialPerspective.a=min(aerialPerspective.a,1.);\n#endif\nreturn aerialPerspective;}\nbool sampleAerialPerspectiveLut(\nvec2 screenUV,\nbool clampToLutRange,\nfloat distanceFromCamera,\nfloat numAerialPerspectiveLutLayers,\nfloat aerialPerspectiveLutKMPerSlice,\nfloat aerialPerspectiveLutRangeKM,\nout vec4 aerialPerspective) {aerialPerspective=vec4(0.);\n#if USE_AERIAL_PERSPECTIVE_LUT\nif (distanceFromCamera>0. &&\n(clampToLutRange || distanceFromCamera<aerialPerspectiveLutRangeKM) &&\nclampedCameraRadius<=atmosphereRadius) {float layer=toAerialPerspectiveLayer(distanceFromCamera,aerialPerspectiveLutKMPerSlice);float normalizedLayer=sqrt(layer/numAerialPerspectiveLutLayers); \nlayer=min(normalizedLayer*numAerialPerspectiveLutLayers,numAerialPerspectiveLutLayers);float weight=min(layer,1.);float layerIdx=max(0.,layer-1.);float floorLayerIdx=floor(layerIdx);vec4 aerialPerspectiveLayer0=textureLod(aerialPerspectiveLut,vec3(screenUV,floorLayerIdx),0.);vec4 aerialPerspectiveLayer1=textureLod(aerialPerspectiveLut,vec3(screenUV,floorLayerIdx+1.),0.);aerialPerspective=mix(aerialPerspectiveLayer0,aerialPerspectiveLayer1,layerIdx-floorLayerIdx);aerialPerspective.rgb*=atmosphereExposure;aerialPerspective=applyAerialPerspectiveSaturation(aerialPerspective);aerialPerspective=weight*applyAerialPerspectiveIntensity(aerialPerspective);aerialPerspective=applyAerialPerspectiveRadianceBias(aerialPerspective);return true;}\n#endif\nreturn false;}\n#if RENDER_TRANSMITTANCE\nvoid getTransmittanceParameters(vec2 uv,out float radius,out float cosAngleLightToZenith,out float distanceToAtmosphereEdge) {vec2 unit=uvToUnit(uv,TransmittanceLutDomainInUVSpace,TransmittanceLutHalfTexelSize);float distanceToHorizon=unit.y*horizonDistanceToAtmosphereEdge;float distanceToHorizonSquared=distanceToHorizon*distanceToHorizon;radius=sqrtClamped(distanceToHorizonSquared+planetRadiusSquared);float minDistanceToAtmosphereEdge=atmosphereRadius-radius;float maxDistanceToAtmosphereEdge=distanceToHorizon+horizonDistanceToAtmosphereEdge;distanceToAtmosphereEdge=minDistanceToAtmosphereEdge+unit.x*(maxDistanceToAtmosphereEdge-minDistanceToAtmosphereEdge);float distanceToAtmosphereEdgeSquared=distanceToAtmosphereEdge*distanceToAtmosphereEdge;cosAngleLightToZenith =\ndistanceToAtmosphereEdge<=0. ?\n1. :\n(horizonDistanceToAtmosphereEdgeSquared-distanceToAtmosphereEdgeSquared-distanceToHorizonSquared)/(2.*radius*distanceToAtmosphereEdge);cosAngleLightToZenith=clamp(cosAngleLightToZenith,-1.,1.);}\nvec4 renderTransmittance(vec2 uv) {float radius,cosAngleLightToZenith,distanceToAtmosphereEdgeAlongAngle;getTransmittanceParameters(uv,radius,cosAngleLightToZenith,distanceToAtmosphereEdgeAlongAngle);float sinAngleLightToZenith=sqrtClamped(1.-cosAngleLightToZenith*cosAngleLightToZenith);vec3 directionToLight=normalize(vec3(0.,cosAngleLightToZenith,sinAngleLightToZenith));vec3 transmittance=computeTransmittance(vec3(0.,radius,0.),directionToLight,distanceToAtmosphereEdgeAlongAngle,TransmittanceSampleCount);return vec4(transmittance,avg(transmittance));}\n#endif\n#if RENDER_MULTI_SCATTERING\nvec3 getSphereSample(float azimuth,float inclination,out float sinInclination) {sinInclination=sin(inclination);return vec3(sinInclination*sin(azimuth),cos(inclination),sinInclination*cos(azimuth));}\nconst float MultiScatteringInclinationSampleCount=8.;const float MultiScatteringAzimuthSampleCount=2.*MultiScatteringInclinationSampleCount;const float MultiScatteringLutSampleCount=64.;const float MultiScatteringAzimuthIterationAngle=TWO_PI/MultiScatteringAzimuthSampleCount;const float MultiScatteringInclinationIterationAngle=PI/MultiScatteringInclinationSampleCount;const float MultiScatteringAngleStepProduct=MultiScatteringAzimuthIterationAngle*MultiScatteringInclinationIterationAngle;vec4 renderMultiScattering(vec2 uv,sampler2D transmittanceLut) {vec2 unit=uvToUnit(uv,MultiScatteringLutDomainInUVSpace,MultiScatteringLutHalfTexelSize);float cosAngleLightToZenith=2.*unit.x-1.;float sinAngleLightToZenith=sqrtClamped(1.-cosAngleLightToZenith*cosAngleLightToZenith);vec3 directionToLight=normalize(vec3(0.,cosAngleLightToZenith,sinAngleLightToZenith));float rayOriginRadius=planetRadius+max(unit.y,0.001)*atmosphereThickness;vec3 rayOrigin=vec3(0.,rayOriginRadius,0.);vec3 inscattered=vec3(0.);vec3 multiScatteringTotal=vec3(0.);for (float i=0.5; i<MultiScatteringAzimuthSampleCount; ++i) {float azimuth=MultiScatteringAzimuthIterationAngle*i;for (float j=0.5; j<MultiScatteringInclinationSampleCount; ++j) {float inclination=MultiScatteringInclinationIterationAngle*j;float sinInclination;vec3 rayDirection=getSphereSample(azimuth,inclination,sinInclination);vec3 radiance;vec3 transmittance;vec3 multiScattering;integrateScatteredRadiance(\nfalse,\n1.,\ntransmittanceLut,\nrayOrigin,\nrayDirection,\ndirectionToLight,\n100000000.,\nMultiScatteringLutSampleCount,\n-1.,\nradiance,\ntransmittance,\nmultiScattering);float weight=RECIPROCAL_PI4*abs(sinInclination)*MultiScatteringAngleStepProduct;multiScatteringTotal+=multiScattering*weight;inscattered+=radiance*weight;}}\nvec3 multiScattering=inscattered/max(vec3(0.000001),vec3(1.)-multiScatteringTotal);return vec4(multiScattering,1.);}\n#endif\nfloat computeCosHorizonAngleFromZenith(float radius) {float sinAngleBetweenHorizonAndNadir=min(1.,planetRadius/radius);float cosHorizonAngleFromNadir=sqrt(1.-sinAngleBetweenHorizonAndNadir*sinAngleBetweenHorizonAndNadir);float cosHorizonAngleFromZenith=-cosHorizonAngleFromNadir;return cosHorizonAngleFromZenith;}\n#if RENDER_SKY_VIEW\nvoid getSkyViewParametersFromUV(\nfloat radius,\nvec2 uv,\nout float cosAngleBetweenViewAndZenith,\nout float cosAngleBetweenViewAndLightOnPlane) {vec2 unit=uvToUnit(uv,SkyViewLutDomainInUVSpace,SkyViewLutHalfTexelSize);float cosHorizonAngleFromZenith=computeCosHorizonAngleFromZenith(radius);if (unit.y<0.5) {float coord=2.*unit.y; \ncoord*=coord; \ncosAngleBetweenViewAndZenith=mix(-1.,cosHorizonAngleFromZenith,coord); } else {float coord=2.*unit.y-1.; \ncoord*=coord; \ncosAngleBetweenViewAndZenith=mix(cosHorizonAngleFromZenith,1.,coord); }\n{float coord=unit.x;cosAngleBetweenViewAndLightOnPlane=1.-2.*coord;}}\nvec4 renderSkyView(vec2 uv,sampler2D transmittanceLut,sampler2D multiScatteringLut) {float cosAngleBetweenViewAndZenith;float cosAngleBetweenViewAndLightOnPlane;getSkyViewParametersFromUV(clampedCameraRadius,uv,cosAngleBetweenViewAndZenith,cosAngleBetweenViewAndLightOnPlane);float sinAngleBetweenViewAndZenith=sqrtClamped(1.-cosAngleBetweenViewAndZenith*cosAngleBetweenViewAndZenith);float sinAngleBetweenViewAndLightOnPlane=sqrtClamped(1.-cosAngleBetweenViewAndLightOnPlane*cosAngleBetweenViewAndLightOnPlane);vec3 rayDirection =\nvec3(\nsinAngleBetweenViewAndZenith*cosAngleBetweenViewAndLightOnPlane,\ncosAngleBetweenViewAndZenith,\nsinAngleBetweenViewAndZenith*sinAngleBetweenViewAndLightOnPlane);bool intersectsAtmosphere=false;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=vec3(0.);moveToTopAtmosphere(\nvec3(0.,clampedCameraRadius,0.),\nclampedCameraRadius,\nvec3(0.,1.,0.),\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {return vec4(0.);}\nvec3 transmittance;vec3 radiance;integrateScatteredRadiance(\nfalse,\natmosphereExposure*lightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLightRelativeToCameraGeocentricNormal,\n100000000.,\nSkyViewLutSampleCount,\n-1.,\nradiance,\ntransmittance);float transparency=1.-avg(transmittance);return vec4(radiance,transparency);}\n#endif\n#if RENDER_CAMERA_VOLUME\nvec4 renderCameraVolume(\nvec3 positionOnNearPlane,\nfloat layerIdx,\nsampler2D transmittanceLut,\nsampler2D multiScatteringLut) {vec4 result=vec4(0.);vec3 rayDirection=normalize(positionOnNearPlane);float layer=layerIdxToAerialPerspectiveLayer(layerIdx);float tMax=toAerialPerspectiveDepth(layer);float tMaxMax=tMax;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=clampedCameraPositionGlobal;if (clampedCameraRadius>=atmosphereRadius) {bool intersectsAtmosphere=false;moveToTopAtmosphere(\nclampedCameraPositionGlobal,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {return result;}\nfloat distanceToAtmosphere=distance(clampedCameraPositionGlobal,cameraPositionGlobalClampedToTopOfAtmosphere);if (tMaxMax<distanceToAtmosphere) {return result;}\ntMaxMax=max(0.,tMaxMax-distanceToAtmosphere);}\nfloat sampleCount=min(SkyViewLutSampleCount,2.*layer+2.);vec3 transmittance;vec3 radiance;integrateScatteredRadiance(\ntrue,\nlightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLight,\ntMaxMax,\nsampleCount,\n-1.,\nradiance,\ntransmittance);float transparency=1.-avg(transmittance);result=vec4(radiance,transparency);return result;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const atmosphereFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/depthFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\nimport \"core/Shaders/ShadersInclude/importanceSampling\";\nimport \"core/Shaders/ShadersInclude/pbrBRDFFunctions\";\nimport \"core/Shaders/ShadersInclude/hdrFilteringFunctions\";\n\nconst name = \"diffuseSkyIrradiancePixelShader\";\nconst shader = `precision highp float;const float DiffuseSkyIrradianceLutSampleCount=32.0;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<depthFunctions>\n#include<atmosphereFunctions>\nuniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;vec3 integrateForIrradiance(vec3 directionToLight,vec3 rayDirection,vec3 rayOrigin) {vec3 radiance;vec3 transmittance;integrateScatteredRadiance(\nfalse,\n1.,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\nrayOrigin,\nrayDirection.xzy,\ndirectionToLight.xzy,\n100000000.,\nDiffuseSkyIrradianceLutSampleCount,\n-1.,\nradiance,\ntransmittance);return radiance;}\n#include<importanceSampling>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\nvarying vec2 uv;void main() {vec2 unit=uvToUnit(uv,DiffuseSkyIrradianceLutDomainInUVSpace,DiffuseSkyIrradianceLutHalfTexelSize);float cosLightInclination=2.*unit.x-1.;float sinLightInclination=sqrtClamped(1.-cosLightInclination*cosLightInclination);vec3 directionToLight=normalize(vec3(0.,cosLightInclination,sinLightInclination));float radius=max(planetRadiusWithOffset,unit.y*atmosphereThickness+planetRadius);vec3 swappedDirectionToLight=vec3(directionToLight.x,directionToLight.z,directionToLight.y); \nvec3 irradiance =\nPI *\nirradiance(\nswappedDirectionToLight,\nvec2(radius,0.),\n1.,\nvec3(1.),\nvec3(1.));float averageIrradiance=getLuminance(irradiance);vec3 newIrradiance=mix(irradiance,vec3(averageIrradiance),diffuseSkyIrradianceDesaturationFactor);float newIrradianceScale=getLuminance(newIrradiance);float rescaling=averageIrradiance/max(0.000001,newIrradianceScale);irradiance=newIrradiance*rescaling;gl_FragColor=vec4(irradiance,1.);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const diffuseSkyIrradiancePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\n\nconst name = \"fullscreenTriangleVertexShader\";\nconst shader = `precision highp float;\n#include<__decl__atmosphereFragment>\n#if POSITION_VEC2\nattribute vec2 position;\n#else\nattribute vec3 position;\n#endif\nuniform float depth;varying vec2 uv;\n#if COMPUTE_WORLD_RAY\nvarying vec3 positionOnNearPlane;\n#endif\n#if COMPUTE_WORLD_RAY\nconst float nearPlaneNDC=-1.;\n#endif\nvoid main() {gl_Position=vec4(position.xy,depth,1.);uv=0.5*position.xy+vec2(0.5);\n#if COMPUTE_WORLD_RAY\npositionOnNearPlane=(inverseViewProjectionWithoutTranslation*vec4(position.xy,nearPlaneNDC,1.)).xyz;\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const fullscreenTriangleVertexShader = { name, shader };\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport { Clamp } from \"core/Maths/math.scalar.functions\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport { FromHalfFloat } from \"core/Misc/textureTools\";\r\nimport type { IColor3Like, IColor4Like, IVector2Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { Sample2DRgbaToRef } from \"./sampling\";\r\nimport \"./Shaders/diffuseSkyIrradiance.fragment\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\n\r\nconst RaySamples = 128;\r\nconst LutWidthPx = 64;\r\nconst LutHeightPx = 16;\r\nconst HalfTexelSize = { x: 0.5 / LutWidthPx, y: 0.5 / LutHeightPx };\r\nconst UnitToUVScale = { x: (LutWidthPx - 1.0) / LutWidthPx, y: (LutHeightPx - 1.0) / LutHeightPx };\r\nconst UvTemp = { x: Number.NaN, y: Number.NaN };\r\nconst Color4Temp = { r: Number.NaN, g: Number.NaN, b: Number.NaN, a: Number.NaN } as IColor4Like;\r\n\r\nconst ComputeLutUVToRef = (properties: AtmospherePhysicalProperties, radius: number, cosAngleLightToZenith: number, result: IVector2Like): void => {\r\n const unitX = Clamp(0.5 + 0.5 * cosAngleLightToZenith);\r\n const unitY = Clamp((radius - properties.planetRadius) / properties.atmosphereThickness);\r\n result.x = unitX * UnitToUVScale.x + HalfTexelSize.x;\r\n result.y = unitY * UnitToUVScale.y + HalfTexelSize.y;\r\n};\r\n\r\n/**\r\n * The diffuse sky irradiance LUT is used to query the diffuse irradiance at a specified position.\r\n */\r\nexport class DiffuseSkyIrradianceLut {\r\n private readonly _atmosphere: Atmosphere;\r\n private _renderTarget: Nullable<RenderTargetTexture> = null;\r\n private _effectWrapper: Nullable<EffectWrapper> = null;\r\n private _effectRenderer: Nullable<EffectRenderer> = null;\r\n private _isDirty = true;\r\n private _isDisposed = false;\r\n private _lutData: Uint8Array | Uint16Array = new Uint16Array(0);\r\n\r\n /**\r\n * True if the LUT needs to be rendered.\r\n */\r\n public get isDirty() {\r\n return this._isDirty;\r\n }\r\n\r\n /**\r\n * True if the LUT has been disposed.\r\n */\r\n public get isDisposed(): boolean {\r\n return this._isDisposed;\r\n }\r\n\r\n /**\r\n * The render target used for this LUT.\r\n * @throws if the LUT has been disposed.\r\n */\r\n public get renderTarget(): RenderTargetTexture {\r\n if (this._isDisposed || this._renderTarget === null) {\r\n throw new Error();\r\n }\r\n return this._renderTarget;\r\n }\r\n\r\n /**\r\n * True if the LUT data has been read back from the GPU.\r\n */\r\n public get hasLutData(): boolean {\r\n return this._lutData[0] !== undefined;\r\n }\r\n\r\n /**\r\n * Constructs the {@link DiffuseSkyIrradianceLut}.\r\n * @param atmosphere - The atmosphere to use.\r\n */\r\n constructor(atmosphere: Atmosphere) {\r\n this._atmosphere = atmosphere;\r\n const scene = atmosphere.scene;\r\n const engine = scene.getEngine();\r\n\r\n const name = \"atmo-diffuseSkyIrradiance\";\r\n const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {\r\n generateMipMaps: false,\r\n type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n gammaSpace: false,\r\n }));\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n\r\n const useUbo = atmosphere.uniformBuffer.useUbo;\r\n\r\n this._effectWrapper = new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"diffuseSkyIrradiance\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : atmosphere.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [atmosphere.uniformBuffer.name] : [],\r\n defines: [\r\n \"#define POSITION_VEC2\",\r\n `#define NUM_SAMPLES ${RaySamples}u`,\r\n \"#define CUSTOM_IRRADIANCE_FILTERING_INPUT /* empty */\", // empty, no input texture needed as the radiance is procedurally generated from ray marching.\r\n // The following ray marches the atmosphere to get the radiance.\r\n \"#define CUSTOM_IRRADIANCE_FILTERING_FUNCTION vec3 c = integrateForIrradiance(n, Ls, vec3(0., filteringInfo.x, 0.));\",\r\n ],\r\n samplers: [\"transmittanceLut\", \"multiScatteringLut\"],\r\n useShaderStore: true,\r\n });\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n\r\n // The sky irradiance will also be used for the environment texture.\r\n scene.environmentTexture = renderTarget;\r\n scene.environmentTexture.irradianceTexture = renderTarget;\r\n scene.environmentIntensity = 1.0;\r\n\r\n // Prevent the irradiance LUT from being rendered redundantly at the beginning of the frame.\r\n scene.environmentTexture.isRenderTarget = false;\r\n }\r\n\r\n /**\r\n * Gets the diffuse sky irradiance for a surface oriented along the geocentric normal.\r\n * Resulting color is always in linear space.\r\n * @param directionToLight - The direction to the light in world space.\r\n * @param radius - The position's distance to the planet origin.\r\n * @param cameraGeocentricNormal - The geocentric normal of the camera.\r\n * @param lightIrradiance - The irradiance of the light.\r\n * @param result - The color to store the result in.\r\n * @returns The result color.\r\n */\r\n public getDiffuseSkyIrradianceToRef<T extends IColor3Like>(\r\n directionToLight: IVector3Like,\r\n radius: number,\r\n cameraGeocentricNormal: IVector3Like,\r\n lightIrradiance: number,\r\n result: T\r\n ): T {\r\n const atmosphere = this._atmosphere;\r\n const additionalDiffuseSkyIrradiance = atmosphere.additionalDiffuseSkyIrradiance;\r\n\r\n const properties = atmosphere.physicalProperties;\r\n if (this._lutData[0] === undefined || radius > properties.atmosphereRadius) {\r\n result.r = additionalDiffuseSkyIrradiance.r;\r\n result.g = additionalDiffuseSkyIrradiance.g;\r\n result.b = additionalDiffuseSkyIrradiance.b;\r\n return result;\r\n }\r\n\r\n const cosAngleLightToZenith = directionToLight.x * cameraGeocentricNormal.x + directionToLight.y * cameraGeocentricNormal.y + directionToLight.z * cameraGeocentricNormal.z;\r\n ComputeLutUVToRef(properties, radius, cosAngleLightToZenith, UvTemp);\r\n Sample2DRgbaToRef(UvTemp.x, UvTemp.y, LutWidthPx, LutHeightPx, this._lutData, Color4Temp, FromHalfFloat);\r\n\r\n const intensity = atmosphere.diffuseSkyIrradianceIntensity;\r\n result.r = intensity * (lightIrradiance * Color4Temp.r + additionalDiffuseSkyIrradiance.r);\r\n result.g = intensity * (lightIrradiance * Color4Temp.g + additionalDiffuseSkyIrradiance.g);\r\n result.b = intensity * (lightIrradiance * Color4Temp.b + additionalDiffuseSkyIrradiance.b);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Renders the LUT.\r\n * @returns True if the LUT was rendered.\r\n */\r\n public render(): boolean {\r\n // Only need to render the LUT once.\r\n const effectWrapper = this._effectWrapper;\r\n if (!this._isDirty || !effectWrapper?.isReady() || !this._renderTarget?.isReady()) {\r\n return false;\r\n }\r\n\r\n const engine = this._atmosphere.scene.getEngine();\r\n\r\n engine.bindFramebuffer(this.renderTarget.renderTarget!, undefined, undefined, undefined, true);\r\n\r\n const effectRenderer = this._effectRenderer!;\r\n effectRenderer.applyEffectWrapper(effectWrapper);\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n\r\n const effect = effectWrapper.effect;\r\n effectRenderer.bindBuffers(effect);\r\n\r\n effect.setTexture(\"transmittanceLut\", this._atmosphere.transmittanceLut!.renderTarget);\r\n effect.setTexture(\"multiScatteringLut\", this._atmosphere.multiScatteringLutRenderTarget);\r\n\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n\r\n effect.setFloat(\"depth\", 0.0);\r\n\r\n effectRenderer.draw();\r\n\r\n effectRenderer.restoreStates();\r\n engine.restoreDefaultFramebuffer();\r\n\r\n this._isDirty = false;\r\n\r\n // eslint-disable-next-line github/no-then\r\n void this.renderTarget.readPixels(0, 0, undefined, undefined, true /* noDataConversion */)?.then((value: ArrayBufferView) => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._lutData = value as Uint8Array | Uint16Array;\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Marks the LUT as needing to be rendered.\r\n */\r\n public markDirty(): void {\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * Disposes the LUT.\r\n */\r\n public dispose() {\r\n if (this._renderTarget) {\r\n this._renderTarget.irradianceTexture = null;\r\n this._renderTarget.dispose();\r\n }\r\n this._renderTarget = null;\r\n this._effectWrapper?.dispose();\r\n this._effectWrapper = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._isDisposed = true;\r\n }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"transmittancePixelShader\";\nconst shader = `#define RENDER_TRANSMITTANCE 1\nprecision highp float;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;void main() {gl_FragColor=renderTransmittance(uv);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const transmittancePixelShader = { name, shader };\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport { Clamp, SmoothStep } from \"core/Maths/math.scalar.functions\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { DirectionalLight } from \"core/Lights/directionalLight\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport { FromHalfFloat } from \"core/Misc/textureTools\";\r\nimport type { IColor3Like, IColor4Like, IVector2Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { Sample2DRgbaToRef } from \"./sampling\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\nimport \"./Shaders/transmittance.fragment\";\r\n\r\nconst LutWidthPx = 256;\r\nconst LutHeightPx = 64;\r\nconst EffectiveDomainInUVSpace = { x: (LutWidthPx - 1.0) / LutWidthPx, y: (LutHeightPx - 1.0) / LutHeightPx };\r\nconst HalfTexelSize = { x: 0.5 / LutWidthPx, y: 0.5 / LutHeightPx };\r\nconst TransmittanceHorizonRange = 2.0 * HalfTexelSize.x;\r\nconst TransmittanceMaxUnoccludedU = 1.0 - 0.5 * TransmittanceHorizonRange;\r\n\r\nconst UseHalfFloat = false;\r\n\r\n// Temporary storage.\r\nconst Uv = { x: Number.NaN, y: Number.NaN } as IVector2Like;\r\nconst LightColorTemp = { r: Number.NaN, g: Number.NaN, b: Number.NaN } as IColor3Like;\r\nconst DirectionToLightTemp = { x: Number.NaN, y: Number.NaN, z: Number.NaN } as IVector3Like;\r\nconst Color4Temp = { r: Number.NaN, g: Number.NaN, b: Number.NaN, a: Number.NaN } as IColor4Like;\r\n\r\nconst ComputeLutUVToRef = (properties: AtmospherePhysicalProperties, radius: number, cosAngleLightToZenith: number, uv: IVector2Like): void => {\r\n const radiusSquared = radius * radius;\r\n const distanceToHorizon = Math.sqrt(Math.max(0.0, radiusSquared - properties.planetRadiusSquared));\r\n\r\n const cosAngleLightToZenithSq = cosAngleLightToZenith * cosAngleLightToZenith;\r\n const discriminant = radiusSquared * (cosAngleLightToZenithSq - 1.0) + properties.atmosphereRadiusSquared;\r\n const distanceToAtmosphereEdge = Math.max(0.0, -radius * cosAngleLightToZenith + Math.sqrt(Math.max(0.0, discriminant)));\r\n\r\n const minDistanceToAtmosphereEdge = Math.max(0.0, properties.atmosphereRadius - radius);\r\n const maxDistanceToAtmosphereEdge = distanceToHorizon + properties.horizonDistanceToAtmosphereEdge;\r\n const cosAngleLightToZenithCoordinate =\r\n (distanceToAtmosphereEdge - minDistanceToAtmosphereEdge) / Math.max(0.000001, maxDistanceToAtmosphereEdge - minDistanceToAtmosphereEdge);\r\n const distanceToHorizonCoordinate = distanceToHorizon / Math.max(0.000001, properties.horizonDistanceToAtmosphereEdge);\r\n\r\n // Unit to UV.\r\n uv.x = EffectiveDomainInUVSpace.x * cosAngleLightToZenithCoordinate + HalfTexelSize.x;\r\n uv.y = EffectiveDomainInUVSpace.y * distanceToHorizonCoordinate + HalfTexelSize.y;\r\n};\r\n\r\nconst SampleLutToRef = (\r\n properties: AtmospherePhysicalProperties,\r\n lutData: Uint8Array | Uint16Array,\r\n positionDistanceToOrigin: number,\r\n cosAngleLightToZenith: number,\r\n result: IColor4Like\r\n): void => {\r\n if (positionDistanceToOrigin > properties.atmosphereRadius) {\r\n result.r = result.g = result.b = result.a = 1.0;\r\n return;\r\n }\r\n\r\n ComputeLutUVToRef(properties, positionDistanceToOrigin, cosAngleLightToZenith, Uv);\r\n Sample2DRgbaToRef(Uv.x, Uv.y, LutWidthPx, LutHeightPx, lutData, result, UseHalfFloat ? FromHalfFloat : (value) => value / 255.0);\r\n\r\n const weight = Clamp(SmoothStep(1.0, 0.0, Clamp((Uv.x - TransmittanceMaxUnoccludedU) / TransmittanceHorizonRange)));\r\n result.r *= weight;\r\n result.g *= weight;\r\n result.b *= weight;\r\n result.a *= weight;\r\n};\r\n\r\n/**\r\n * The transmittance LUT can be used to get the radiance from an external light source arriving a given point, accounting for atmospheric scattering.\r\n */\r\nexport class TransmittanceLut {\r\n /**\r\n * Listen to this observer to know when the LUT data has been updated.\r\n * This is typically infrequent (once at startup), but also happens whenever the atmosphere's properties change.\r\n */\r\n public readonly onUpdatedObservable = new Observable<void>();\r\n\r\n private readonly _atmosphere: Atmosphere;\r\n private _lutData: Uint8Array | Uint16Array = new Uint8Array(0);\r\n private _renderTarget: Nullable<RenderTargetTexture>;\r\n private _effectWrapper: Nullable<EffectWrapper>;\r\n private _effectRenderer: Nullable<EffectRenderer>;\r\n private _isDirty = true;\r\n private _isDisposed = false;\r\n\r\n /**\r\n * True if the LUT has been rendered.\r\n */\r\n public get isDirty(): boolean {\r\n return this._isDirty;\r\n }\r\n\r\n /**\r\n * The render target that contains the transmittance LUT.\r\n * @throws if the LUT has been disposed.\r\n */\r\n public get renderTarget(): RenderTargetTexture {\r\n if (this._isDisposed || this._renderTarget === null) {\r\n throw new Error();\r\n }\r\n return this._renderTarget;\r\n }\r\n\r\n /**\r\n * Constructs the {@link TransmittanceLut}.\r\n * @param atmosphere - The atmosphere that owns this LUT.\r\n */\r\n constructor(atmosphere: Atmosphere) {\r\n this._atmosphere = atmosphere;\r\n\r\n const scene = this._atmosphere.scene;\r\n const engine = scene.getEngine();\r\n\r\n const name = \"atmo-transmittance\";\r\n const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {\r\n type: UseHalfFloat ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n gammaSpace: false,\r\n }));\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n\r\n const useUbo = this._atmosphere.uniformBuffer.useUbo;\r\n this._effectWrapper = new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"transmittance\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : this._atmosphere.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [this._atmosphere.uniformBuffer.name] : [],\r\n defines: [\"#define POSITION_VEC2\"],\r\n useShaderStore: true,\r\n });\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n }\r\n\r\n /**\r\n * Gets the transmittance of an external light through the atmosphere to a point specified by its distance to the planet center and its geocentric normal.\r\n * The result is always a linear space color.\r\n * @param directionToLight - The direction to the light source.\r\n * @param pointRadius - The distance from the origin to the point.\r\n * @param pointGeocentricNormal - The normal of the point.\r\n * @param result - The color to write the result to.\r\n * @returns The result color.\r\n */\r\n public getTransmittedColorToRef<T extends IColor3Like>(directionToLight: IVector3Like, pointRadius: number, pointGeocentricNormal: IVector3Like, result: T): T {\r\n if (this._lutData[0] !== undefined) {\r\n const cosAngleLightToZenith =\r\n directionToLight.x * pointGeocentricNormal.x + directionToLight.y * pointGeocentricNormal.y + directionToLight.z * pointGeocentricNormal.z;\r\n SampleLutToRef(this._atmosphere.physicalProperties, this._lutData, pointRadius, cosAngleLightToZenith, Color4Temp);\r\n result.r = Color4Temp.r;\r\n result.g = Color4Temp.g;\r\n result.b = Color4Temp.b;\r\n } else {\r\n // Fallback.\r\n result.r = result.g = result.b = 1.0;\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Derives light color from the transmittance at a point specified by its distance to the planet center and its geocentric normal.\r\n * @param light - The light to update.\r\n * @param pointRadius - The distance from the origin to the point.\r\n * @param pointGeocentricNormal - The normal of the point.\r\n */\r\n public updateLightParameters(light: DirectionalLight, pointRadius: number, pointGeocentricNormal: IVector3Like): void {\r\n const lightDirection = light.direction;\r\n DirectionToLightTemp.x = -lightDirection.x;\r\n DirectionToLightTemp.y = -lightDirection.y;\r\n DirectionToLightTemp.z = -lightDirection.z;\r\n this.getTransmittedColorToRef(DirectionToLightTemp, pointRadius, pointGeocentricNormal, LightColorTemp);\r\n\r\n light.diffuse.copyFromFloats(LightColorTemp.r, LightColorTemp.g, LightColorTemp.b);\r\n light.specular.copyFromFloats(LightColorTemp.r, LightColorTemp.g, LightColorTemp.b);\r\n }\r\n\r\n /**\r\n * Renders the LUT if needed.\r\n * @returns true if the LUT was rendered.\r\n */\r\n public render(): boolean {\r\n // Only need to render the LUT once.\r\n const effectWrapper = this._effectWrapper;\r\n if (!this._isDirty || !effectWrapper?.isReady() || !this._renderTarget?.isReady()) {\r\n return false;\r\n }\r\n\r\n const engine = this._atmosphere.scene.getEngine();\r\n\r\n engine.bindFramebuffer(this.renderTarget.renderTarget!, undefined, undefined, undefined, true);\r\n\r\n const effectRenderer = this._effectRenderer!;\r\n effectRenderer.applyEffectWrapper(effectWrapper);\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n\r\n const effect = effectWrapper.effect;\r\n effectRenderer.bindBuffers(effect);\r\n\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n\r\n effect.setFloat(\"depth\", 0);\r\n\r\n effectRenderer.draw();\r\n\r\n effectRenderer.restoreStates();\r\n engine.restoreDefaultFramebuffer();\r\n\r\n this._isDirty = false;\r\n\r\n // eslint-disable-next-line github/no-then\r\n void this.renderTarget.readPixels(0, 0, undefined, undefined, UseHalfFloat /* noDataConversion */)?.then((value: ArrayBufferView) => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._lutData = value as Uint8Array | Uint16Array;\r\n this.onUpdatedObservable.notifyObservers();\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Marks the LUT as needing to be rendered.\r\n */\r\n public markDirty(): void {\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * Disposes the LUT and its resources.\r\n */\r\n public dispose(): void {\r\n this._renderTarget?.dispose();\r\n this._renderTarget = null;\r\n this._effectWrapper?.dispose();\r\n this._effectWrapper = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._isDisposed = true;\r\n }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/depthFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"compositeAerialPerspectivePixelShader\";\nconst shader = `precision highp float;precision highp sampler2D;precision highp sampler2DArray;\n#include<__decl__atmosphereFragment>\n#if USE_AERIAL_PERSPECTIVE_LUT\nuniform sampler2DArray aerialPerspectiveLut;\n#endif\n#include<helperFunctions>\n#include<depthFunctions>\n#include<atmosphereFunctions>\nuniform sampler2D depthTexture;uniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;varying vec2 uv;varying vec3 positionOnNearPlane;void main() {gl_FragColor=vec4(0.);float depth=textureLod(depthTexture,uv,0.).r;if (depth>=1.) {discard;}\nvec3 rayDirection=normalize(positionOnNearPlane);float distanceFromCamera =\nreconstructDistanceFromCamera(\ndepth,\nrayDirection,\ncameraForward,\ncameraNearPlane);float distanceToSurface=distanceFromCamera/1000.;vec4 aerialPerspective=vec4(0.);if (sampleAerialPerspectiveLut(\nuv,\nfalse,\ndistanceToSurface,\nNumAerialPerspectiveLutLayers,\nAerialPerspectiveLutKMPerSlice,\nAerialPerspectiveLutRangeKM,\naerialPerspective)) {\n#ifndef APPLY_TRANSMITTANCE_BLENDING\naerialPerspective.a=0.;\n#endif\ngl_FragColor=aerialPerspective;} else {bool intersectsAtmosphere=false;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=vec3(0.);moveToTopAtmosphere(\nclampedCameraPositionGlobal,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {gl_FragColor=vec4(0.);return;}\nvec3 transmittance;vec3 radiance;bool isAerialPerspectiveLut=clampedCameraRadius<atmosphereRadius;integrateScatteredRadiance(\nisAerialPerspectiveLut,\natmosphereExposure*lightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLight,\n100000000.,\nSkyViewLutSampleCount,\ndistanceToSurface,\nradiance,\ntransmittance);float transparency=1.-avg(transmittance);gl_FragColor =\napplyAerialPerspectiveRadianceBias(\napplyAerialPerspectiveIntensity(\napplyAerialPerspectiveSaturation(vec4(radiance,transparency))));\n#ifndef APPLY_TRANSMITTANCE_BLENDING\ngl_FragColor.a=0.;\n#endif\n}\n#if OUTPUT_TO_SRGB\ngl_FragColor=toGammaSpace(gl_FragColor);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const compositeAerialPerspectivePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/depthFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"compositeSkyPixelShader\";\nconst shader = `precision highp float;precision highp sampler2D;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<depthFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;varying vec3 positionOnNearPlane;\n#if USE_SKY_VIEW_LUT\nuniform sampler2D skyViewLut;\n#else\nuniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;\n#endif\nvoid main() {gl_FragColor=vec4(0.);vec3 rayDirection=normalize(positionOnNearPlane);\n#if USE_SKY_VIEW_LUT\nfloat cosAngleBetweenViewAndZenith;bool isRayIntersectingGround;vec4 skyColor =\nsampleSkyViewLut(\nskyViewLut,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\ndirectionToLight,\ncosCameraHorizonAngleFromZenith,\ncosAngleBetweenViewAndZenith,\nisRayIntersectingGround);\n#ifndef APPLY_TRANSMITTANCE_BLENDING\nskyColor.a=0.;\n#endif\ngl_FragColor=skyColor;gl_FragColor.a=isRayIntersectingGround ? 1. : gl_FragColor.a;\n#else\nbool intersectsAtmosphere=false;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=vec3(0.);moveToTopAtmosphere(\nclampedCameraPositionGlobal,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {return;}\nvec3 transmittance;vec3 radiance;integrateScatteredRadiance(\nfalse,\natmosphereExposure*lightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLight,\n100000000.,\nSkyViewLutSampleCount,\n-1.,\nradiance,\ntransmittance);\n#if APPLY_TRANSMITTANCE_BLENDING\nfloat transparency=1.-avg(transmittance);\n#else\nfloat transparency=0.;\n#endif\ngl_FragColor=vec4(radiance,transparency);\n#endif\n#if OUTPUT_TO_SRGB\ngl_FragColor=toGammaSpace(gl_FragColor);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const compositeSkyPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/depthFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"compositeGlobeAtmospherePixelShader\";\nconst shader = `precision highp float;precision highp sampler2D;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<depthFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;varying vec3 positionOnNearPlane;\n#if HAS_DEPTH_TEXTURE\nuniform sampler2D depthTexture;\n#endif\n#if USE_SKY_VIEW_LUT\nuniform sampler2D skyViewLut;\n#else\nuniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;\n#endif\nvoid main() {gl_FragColor=vec4(0.);\n#if HAS_DEPTH_TEXTURE\nfloat depth=textureLod(depthTexture,uv,0.).r;\n#endif\nvec3 rayDirection=normalize(positionOnNearPlane);\n#if USE_SKY_VIEW_LUT\nfloat cosAngleBetweenViewAndZenith;bool isRayIntersectingGround;vec4 skyColor =\nsampleSkyViewLut(\nskyViewLut,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\ndirectionToLight,\ncosCameraHorizonAngleFromZenith,\ncosAngleBetweenViewAndZenith,\nisRayIntersectingGround);gl_FragColor=skyColor;if (isRayIntersectingGround) {gl_FragColor =\napplyAerialPerspectiveRadianceBias(\napplyAerialPerspectiveIntensity(\napplyAerialPerspectiveSaturation(gl_FragColor)));\n#if HAS_DEPTH_TEXTURE\ngl_FragColor.a=depth>=1. ? 1. : gl_FragColor.a;\n#endif\n}\n#else\nbool intersectsAtmosphere=false;vec3 cameraPositionGlobalClampedToTopOfAtmosphere=vec3(0.);moveToTopAtmosphere(\nclampedCameraPositionGlobal,\nclampedCameraRadius,\ncameraGeocentricNormal,\nrayDirection,\nintersectsAtmosphere,\ncameraPositionGlobalClampedToTopOfAtmosphere);if (!intersectsAtmosphere) {return;}\n#if HAS_DEPTH_TEXTURE\nfloat distanceFromCamera =\nreconstructDistanceFromCamera(\ndepth,\nrayDirection,\ncameraForward,\ncameraNearPlane);float distanceToSurface=distanceFromCamera/1000.;\n#else\nfloat distanceToSurface=0.;\n#endif\nvec3 transmittance;vec3 radiance;integrateScatteredRadiance(\nfalse,\natmosphereExposure*lightIntensity,\ntransmittanceLut,\nmultiScatteringLut,\nmultiScatteringIntensity,\ncameraPositionGlobalClampedToTopOfAtmosphere,\nrayDirection,\ndirectionToLight,\n100000000.,\nSkyViewLutSampleCount,\ndistanceToSurface,\nradiance,\ntransmittance);float transparency=1.-avg(transmittance);gl_FragColor=vec4(radiance,transparency);if (distanceToSurface>0.) {gl_FragColor =\napplyAerialPerspectiveRadianceBias(\napplyAerialPerspectiveIntensity(\napplyAerialPerspectiveSaturation(gl_FragColor)));\n#if HAS_DEPTH_TEXTURE\ngl_FragColor.a=depth>=1. ? 1. : gl_FragColor.a;\n#endif\n}\n#endif\n#if OUTPUT_TO_SRGB\ngl_FragColor=toGammaSpace(gl_FragColor);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const compositeGlobeAtmospherePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"multiScatteringPixelShader\";\nconst shader = `#define RENDER_MULTI_SCATTERING 1\nprecision highp float;\n#define COMPUTE_MULTI_SCATTERING 1\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;uniform sampler2D transmittanceLut;void main() {gl_FragColor=renderMultiScattering(uv,transmittanceLut);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const multiScatteringPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"skyViewPixelShader\";\nconst shader = `#define RENDER_SKY_VIEW 1\nprecision highp float;precision highp sampler2D;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<atmosphereFunctions>\nvarying vec2 uv;uniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;void main() {gl_FragColor=renderSkyView(uv,transmittanceLut,multiScatteringLut);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const skyViewPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\nimport \"../Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\nimport \"../Shaders/ShadersInclude/atmosphereUboDeclaration\";\nimport \"core/Shaders/ShadersInclude/helperFunctions\";\nimport \"../Shaders/ShadersInclude/atmosphereFunctions\";\n\nconst name = \"aerialPerspectivePixelShader\";\nconst shader = `#define RENDER_CAMERA_VOLUME 1\nprecision highp float;\n#include<__decl__atmosphereFragment>\n#include<helperFunctions>\n#include<atmosphereFunctions>\nvarying vec3 positionOnNearPlane;uniform float layerIdx;uniform sampler2D transmittanceLut;uniform sampler2D multiScatteringLut;void main() {gl_FragColor=renderCameraVolume(\npositionOnNearPlane,\nlayerIdx,\ntransmittanceLut,\nmultiScatteringLut\n);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const aerialPerspectivePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"atmosphereVertexDeclaration\";\nconst shader = `uniform mat4 inverseViewProjectionWithoutTranslation;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const atmosphereVertexDeclaration = { name, shader };\n","import type { IDisposable, Scene } from \"core/scene\";\r\nimport type { BMFontChar } from \"./sdf/bmFont\";\r\nimport type { SdfFont } from \"./sdf/font\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\n\r\nenum CharCode {\r\n SPACE = 32,\r\n TOFU = 0xfffc,\r\n}\r\n\r\n/**\r\n * Class representing a font asset for SDF (Signed Distance Field) rendering.\r\n */\r\nexport class FontAsset implements IDisposable {\r\n private readonly _chars = new Map<number, BMFontChar>();\r\n private readonly _charsRegex: RegExp;\r\n private readonly _kernings = new Map<number, Map<number, number>>();\r\n\r\n /** @internal */\r\n public readonly _font: SdfFont;\r\n\r\n /**\r\n * Gets the font scale value\r\n */\r\n public readonly scale: number;\r\n\r\n /**\r\n * Gets the list of used textures\r\n */\r\n public readonly textures: Texture[];\r\n\r\n /**\r\n * Creates a new FontAsset instance.\r\n * @param definitionData defines the font data in JSON format.\r\n * @param textureUrl defines the url of the texture to use for the font.\r\n * @param scene defines the hosting scene.\r\n */\r\n public constructor(definitionData: string, textureUrl: string, scene?: Scene) {\r\n this._font = JSON.parse(definitionData) as SdfFont;\r\n // So far we only consider one page\r\n this._font.pages = [textureUrl];\r\n\r\n this._font.chars.forEach((char) => this._chars.set(char.id, char));\r\n this._font.kernings.forEach((kerning) => {\r\n let submap = this._kernings.get(kerning.first);\r\n if (!submap) {\r\n submap = new Map();\r\n this._kernings.set(kerning.first, submap);\r\n }\r\n submap.set(kerning.second, kerning.amount);\r\n });\r\n this._charsRegex = new RegExp(`[${this._font.chars.map((c) => c.char.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\")).join(\"\")}]`, \"g\");\r\n\r\n this._updateFallbacks();\r\n\r\n this.scale = 1 / this._font.info.size;\r\n this.textures = this._font.pages.map((page) => {\r\n const texture = new Texture(page, scene, { noMipmap: false, invertY: false });\r\n texture.anisotropicFilteringLevel = 16;\r\n return texture;\r\n });\r\n }\r\n\r\n dispose(): void {\r\n for (const texture of this.textures) {\r\n texture.dispose();\r\n }\r\n this.textures.length = 0;\r\n }\r\n\r\n private _updateFallbacks() {\r\n if (!this._chars.has(CharCode.SPACE)) {\r\n this._chars.set(CharCode.SPACE, {\r\n id: CharCode.SPACE,\r\n x: 0,\r\n y: 0,\r\n width: 0,\r\n height: 0,\r\n xoffset: 0,\r\n yoffset: 0,\r\n xadvance: this._font.info.size * 0.5,\r\n page: -1,\r\n chnl: -1,\r\n index: -1,\r\n char: \" \",\r\n });\r\n }\r\n\r\n if (!this._chars.has(CharCode.TOFU)) {\r\n this._chars.set(CharCode.TOFU, {\r\n id: CharCode.TOFU,\r\n x: 0,\r\n y: 0,\r\n width: this._font.info.size,\r\n height: this._font.info.size,\r\n xoffset: 0,\r\n yoffset: 0,\r\n xadvance: this._font.info.size * 0.5,\r\n page: -1,\r\n chnl: -1,\r\n index: -1,\r\n char: \"￿\",\r\n });\r\n }\r\n }\r\n\r\n /** @internal */\r\n public _getChar(charCode: number) {\r\n return this._chars.get(charCode) || this._chars.get(CharCode.TOFU)!;\r\n }\r\n\r\n /** @internal */\r\n public _getKerning(first: number, second: number) {\r\n return this._kernings.get(first)?.get(second) || 0;\r\n }\r\n\r\n /** @internal */\r\n public _unsupportedChars(text: string) {\r\n return text.replace(this._charsRegex, \"\");\r\n }\r\n}\r\n","// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { AtmospherePBRMaterialPlugin } from \"./atmospherePBRMaterialPlugin\";\r\nimport { AtmospherePerCameraVariables } from \"./atmospherePerCameraVariables\";\r\nimport { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Camera } from \"core/Cameras/camera\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { DeepImmutable, Nullable } from \"core/types\";\r\nimport { DiffuseSkyIrradianceLut } from \"./diffuseSkyIrradianceLut\";\r\nimport type { DirectionalLight } from \"core/Lights/directionalLight\";\r\nimport type { Effect } from \"core/Materials/effect\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport type { IAtmosphereOptions } from \"./atmosphereOptions\";\r\nimport type { IColor3Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { IDisposable, Scene } from \"core/scene\";\r\nimport { Observable, type Observer } from \"core/Misc/observable\";\r\nimport { RegisterMaterialPlugin, UnregisterMaterialPlugin } from \"core/Materials/materialPluginManager\";\r\nimport type { RenderingGroupInfo } from \"core/Rendering/renderingManager\";\r\nimport { RenderTargetTexture, type RenderTargetTextureOptions } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport type { RenderTargetWrapper } from \"core/Engines/renderTargetWrapper\";\r\nimport { TransmittanceLut } from \"./transmittanceLut\";\r\nimport { UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { Vector3 } from \"core/Maths/math.vector\";\r\nimport \"./Shaders/compositeAerialPerspective.fragment\";\r\nimport \"./Shaders/compositeSky.fragment\";\r\nimport \"./Shaders/compositeGlobeAtmosphere.fragment\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\nimport \"./Shaders/multiScattering.fragment\";\r\nimport \"./Shaders/skyView.fragment\";\r\nimport \"./Shaders/aerialPerspective.fragment\";\r\nimport \"./Shaders/ShadersInclude/atmosphereFragmentDeclaration\";\r\nimport \"./Shaders/ShadersInclude/atmosphereFunctions\";\r\nimport \"./Shaders/ShadersInclude/atmosphereUboDeclaration\";\r\nimport \"./Shaders/ShadersInclude/atmosphereVertexDeclaration\";\r\nimport \"./Shaders/ShadersInclude/depthFunctions\";\r\n\r\nconst MaterialPlugin = \"atmo-pbr\";\r\n\r\n/**\r\n * Renders a physically based atmosphere.\r\n * Use {@link IsSupported} to check if the atmosphere is supported before creating an instance.\r\n * @experimental\r\n */\r\nexport class Atmosphere implements IDisposable {\r\n private readonly _directionToLight = Vector3.Zero();\r\n private readonly _tempSceneAmbient = new Color3();\r\n private readonly _engine: AbstractEngine;\r\n private _physicalProperties: AtmospherePhysicalProperties;\r\n private _transmittanceLut: Nullable<TransmittanceLut>;\r\n private _diffuseSkyIrradianceLut: Nullable<DiffuseSkyIrradianceLut>;\r\n private _isSkyViewLutEnabled: boolean;\r\n private _isAerialPerspectiveLutEnabled: boolean;\r\n private _aerialPerspectiveTransmittanceScale: number;\r\n private _aerialPerspectiveSaturation: number;\r\n private _aerialPerspectiveIntensity: number;\r\n private _aerialPerspectiveRadianceBias: number;\r\n private _diffuseSkyIrradianceDesaturationFactor: number;\r\n private _additionalDiffuseSkyIrradianceIntensity: number;\r\n private _additionalDiffuseSkyIrradianceColor: Color3;\r\n private _additionalDiffuseSkyIrradiance = new Color3();\r\n private _diffuseSkyIrradianceIntensity: number;\r\n private _multiScatteringIntensity: number;\r\n private _groundAlbedo: Color3;\r\n private _minimumMultiScatteringColor: Color3;\r\n private _minimumMultiScatteringIntensity: number;\r\n private _lights: DirectionalLight[];\r\n private _atmosphereUbo: Nullable<UniformBuffer> = null;\r\n private _minimumMultiScattering = new Vector3();\r\n private _cameraAtmosphereVariables = new AtmospherePerCameraVariables();\r\n private _isLinearSpaceComposition: boolean;\r\n private _isLinearSpaceLight: boolean;\r\n private _lightRadianceAtCamera = new Vector3();\r\n private _linearLightColor = new Color3();\r\n private _originHeight: number;\r\n private _applyApproximateTransmittance: boolean;\r\n private _exposure: number;\r\n private _atmosphereUniformBufferAsArray: UniformBuffer[] = [];\r\n private _effectRenderer: Nullable<EffectRenderer> = null;\r\n private _skyRenderingGroup: number;\r\n private _aerialPerspectiveRenderingGroup: number;\r\n private _globeAtmosphereRenderingGroup: number;\r\n private _isEnabled = true;\r\n\r\n private _hasRenderedMultiScatteringLut = false;\r\n private _multiScatteringEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _multiScatteringLutRenderTarget: Nullable<RenderTargetTexture> = null;\r\n\r\n private _aerialPerspectiveLutEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _aerialPerspectiveLutEffectRenderer: Nullable<EffectRenderer> = null;\r\n private _aerialPerspectiveLutRenderTarget: Nullable<RenderTargetTexture> = null;\r\n\r\n private _skyViewLutEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _skyViewLutEffectRenderer: Nullable<EffectRenderer> = null;\r\n private _skyViewLutRenderTarget: Nullable<RenderTargetTexture> = null;\r\n\r\n private _aerialPerspectiveCompositorEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _skyCompositorEffectWrapper: Nullable<EffectWrapper> = null;\r\n private _globeAtmosphereCompositorEffectWrapper: Nullable<EffectWrapper> = null;\r\n\r\n private _onBeforeCameraRenderObserver: Nullable<Observer<Camera>> = null;\r\n private _onBeforeDrawPhaseObserver: Nullable<Observer<Scene>> = null;\r\n private _onAfterRenderingGroupObserver: Nullable<Observer<RenderingGroupInfo>> = null;\r\n\r\n /**\r\n * Checks if the {@link Atmosphere} is supported.\r\n * @param engine - The engine to check.\r\n * @returns True if the atmosphere is supported, false otherwise.\r\n */\r\n public static IsSupported(engine: AbstractEngine): boolean {\r\n return !engine._badOS && !engine.isWebGPU && engine.version >= 2;\r\n }\r\n\r\n /**\r\n * Called after the atmosphere variables have been updated for the specified camera.\r\n */\r\n public readonly onAfterUpdateVariablesForCameraObservable = new Observable<Camera>();\r\n\r\n /**\r\n * Called immediately before the light variables are finalized.\r\n */\r\n public readonly onBeforeLightVariablesUpdateObservable = new Observable<void>();\r\n\r\n /**\r\n * Called before the LUTs are rendered for this camera. This happens after the per-camera UBO update.\r\n */\r\n public readonly onBeforeRenderLutsForCameraObservable = new Observable<void>();\r\n\r\n /**\r\n * Called after the LUTs were rendered.\r\n */\r\n public readonly onAfterRenderLutsForCameraObservable = new Observable<void>();\r\n\r\n /**\r\n * If provided, this is the depth texture used for composition passes.\r\n * Expects an infinite far plane on the camera (camera.maxZ = 0) and the non-linear depth accessible in red channel.\r\n * @internal\r\n */\r\n public readonly depthTexture: Nullable<BaseTexture> = null;\r\n\r\n /**\r\n * Controls the overall brightness of the atmosphere rendering.\r\n */\r\n public get exposure(): number {\r\n return this._exposure;\r\n }\r\n\r\n public set exposure(value: number) {\r\n this._exposure = Math.max(0, value);\r\n }\r\n\r\n /**\r\n * Affects the overall intensity of the multiple scattering.\r\n */\r\n public get multiScatteringIntensity(): number {\r\n return this._multiScatteringIntensity;\r\n }\r\n\r\n public set multiScatteringIntensity(value: number) {\r\n const newValue = Math.max(0.0, value);\r\n if (newValue !== this._multiScatteringIntensity) {\r\n this._multiScatteringIntensity = value;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n }\r\n\r\n /**\r\n * Affects the multiply scattered light contribution in the atmosphere by describing the average light color reflected off the ground.\r\n */\r\n public get groundAlbedo(): DeepImmutable<IColor3Like> {\r\n return this._groundAlbedo;\r\n }\r\n\r\n public set groundAlbedo(value: DeepImmutable<IColor3Like>) {\r\n if (!this._groundAlbedo.equals(value)) {\r\n this._groundAlbedo.copyFrom(value);\r\n this._multiScatteringEffectWrapper?.dispose();\r\n this._multiScatteringEffectWrapper = null;\r\n this._hasRenderedMultiScatteringLut = false;\r\n }\r\n }\r\n\r\n /**\r\n * Can be used to clamp the multiple scattering to a minimum value.\r\n */\r\n public get minimumMultiScatteringColor(): DeepImmutable<IColor3Like> {\r\n return this._minimumMultiScatteringColor;\r\n }\r\n\r\n public set minimumMultiScatteringColor(value: DeepImmutable<IColor3Like>) {\r\n if (!this._minimumMultiScatteringColor.equals(value)) {\r\n const minimumScatteringColor = this._minimumMultiScatteringColor.copyFrom(value);\r\n this._minimumMultiScattering.x = minimumScatteringColor.r * this._minimumMultiScatteringIntensity;\r\n this._minimumMultiScattering.y = minimumScatteringColor.g * this._minimumMultiScatteringIntensity;\r\n this._minimumMultiScattering.z = minimumScatteringColor.b * this._minimumMultiScatteringIntensity;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n }\r\n\r\n /**\r\n * This is an additional scaling factor applied to the {@link minimumMultiScatteringColor}.\r\n */\r\n public get minimumMultiScatteringIntensity(): number {\r\n return this._minimumMultiScatteringIntensity;\r\n }\r\n\r\n public set minimumMultiScatteringIntensity(value: number) {\r\n const newValue = Math.max(0.0, value);\r\n if (newValue !== this._minimumMultiScatteringIntensity) {\r\n this._minimumMultiScatteringIntensity = value;\r\n this._minimumMultiScattering.x = this._minimumMultiScatteringColor.r * value;\r\n this._minimumMultiScattering.y = this._minimumMultiScatteringColor.g * value;\r\n this._minimumMultiScattering.z = this._minimumMultiScatteringColor.b * value;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n }\r\n\r\n /**\r\n * Can be used to force the diffuse irradiance towards a gray color.\r\n */\r\n public get diffuseSkyIrradianceDesaturationFactor(): number {\r\n return this._diffuseSkyIrradianceDesaturationFactor;\r\n }\r\n\r\n public set diffuseSkyIrradianceDesaturationFactor(value: number) {\r\n const newValue = Math.max(value, 0.0);\r\n if (newValue !== this._diffuseSkyIrradianceDesaturationFactor) {\r\n this._diffuseSkyIrradianceDesaturationFactor = newValue;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n }\r\n\r\n /**\r\n * This is an additional amount of irradiance added to the diffuse irradiance.\r\n */\r\n public get additionalDiffuseSkyIrradianceIntensity(): number {\r\n return this._additionalDiffuseSkyIrradianceIntensity;\r\n }\r\n\r\n public set additionalDiffuseSkyIrradianceIntensity(value: number) {\r\n value = Math.max(0.0, value);\r\n if (value !== this._additionalDiffuseSkyIrradianceIntensity) {\r\n this._additionalDiffuseSkyIrradianceIntensity = value;\r\n this._additionalDiffuseSkyIrradianceColor.scaleToRef(value, this._additionalDiffuseSkyIrradiance);\r\n }\r\n }\r\n\r\n /**\r\n * This is the color for the additional amount of irradiance added to the diffuse irradiance.\r\n */\r\n public get additionalDiffuseSkyIrradianceColor(): DeepImmutable<IColor3Like> {\r\n return this._additionalDiffuseSkyIrradianceColor;\r\n }\r\n\r\n public set additionalDiffuseSkyIrradianceColor(value: DeepImmutable<IColor3Like>) {\r\n if (!this._additionalDiffuseSkyIrradianceColor.equals(value)) {\r\n this._additionalDiffuseSkyIrradianceColor.copyFrom(value).scaleToRef(this._additionalDiffuseSkyIrradianceIntensity, this._additionalDiffuseSkyIrradiance);\r\n }\r\n }\r\n\r\n /**\r\n * The final additional diffuse irradiance, taking into account the intensity and color.\r\n */\r\n public get additionalDiffuseSkyIrradiance(): DeepImmutable<IColor3Like> {\r\n return this._additionalDiffuseSkyIrradiance;\r\n }\r\n\r\n /**\r\n * The intensity of the diffuse irradiance.\r\n */\r\n public get diffuseSkyIrradianceIntensity(): number {\r\n return this._diffuseSkyIrradianceIntensity;\r\n }\r\n\r\n public set diffuseSkyIrradianceIntensity(value: number) {\r\n this._diffuseSkyIrradianceIntensity = Math.max(value, 0.0);\r\n }\r\n\r\n /**\r\n * True if the sky view LUT should be used for compositing the sky instead of a per-pixel ray march.\r\n */\r\n public get isSkyViewLutEnabled(): boolean {\r\n return this._isSkyViewLutEnabled;\r\n }\r\n\r\n public set isSkyViewLutEnabled(value: boolean) {\r\n this._isSkyViewLutEnabled = value;\r\n this._disposeSkyCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n\r\n /**\r\n * Gets the sky view LUT render target or null if not enabled.\r\n * @returns The render target.\r\n */\r\n public get skyViewLutRenderTarget(): Nullable<RenderTargetTexture> {\r\n if (!this._isSkyViewLutEnabled) {\r\n return null;\r\n }\r\n\r\n if (this._skyViewLutRenderTarget !== null) {\r\n return this._skyViewLutRenderTarget;\r\n }\r\n\r\n const renderTarget = (this._skyViewLutRenderTarget = CreateRenderTargetTexture(\"atmo-skyView\", { width: 128, height: 128 }, this.scene));\r\n renderTarget.coordinatesMode = Constants.TEXTURE_EQUIRECTANGULAR_MODE;\r\n\r\n this._skyViewLutEffectWrapper = CreateSkyViewEffectWrapper(this._engine, this.uniformBuffer);\r\n\r\n return renderTarget;\r\n }\r\n /**\r\n * True if the aerial perspective LUT should be used.\r\n * If false, full ray marching would be used instead.\r\n */\r\n public get isAerialPerspectiveLutEnabled(): boolean {\r\n return this._isAerialPerspectiveLutEnabled;\r\n }\r\n\r\n public set isAerialPerspectiveLutEnabled(value: boolean) {\r\n this._isAerialPerspectiveLutEnabled = value;\r\n this._disposeAerialPerspectiveCompositor();\r\n }\r\n\r\n /**\r\n * Gets the aerial perspective LUT render target or null if not enabled.\r\n * @returns The render target.\r\n */\r\n public get aerialPerspectiveLutRenderTarget(): Nullable<RenderTargetTexture> {\r\n if (!this._isAerialPerspectiveLutEnabled) {\r\n return null;\r\n }\r\n\r\n if (this._aerialPerspectiveLutRenderTarget !== null) {\r\n return this._aerialPerspectiveLutRenderTarget;\r\n }\r\n\r\n const scene = this.scene;\r\n const name = \"atmo-aerialPerspective\";\r\n const renderTarget = (this._aerialPerspectiveLutRenderTarget = CreateRenderTargetTexture(name, { width: 16, height: 64, layers: 32 }, scene, {}));\r\n this._aerialPerspectiveLutEffectWrapper = CreateAerialPerspectiveEffectWrapper(this._engine, this.uniformBuffer);\r\n\r\n return renderTarget;\r\n }\r\n\r\n /**\r\n * The intensity of the aerial perspective.\r\n */\r\n public get aerialPerspectiveIntensity(): number {\r\n return this._aerialPerspectiveIntensity;\r\n }\r\n\r\n public set aerialPerspectiveIntensity(value: number) {\r\n value = Math.max(0.001, value);\r\n if (value !== this._aerialPerspectiveIntensity) {\r\n // Define only needs to change if the value is changing between 1 and not 1.\r\n const hasDefineChanged = (value === 1) !== (this._aerialPerspectiveIntensity === 1);\r\n this._aerialPerspectiveIntensity = value;\r\n if (hasDefineChanged) {\r\n this._disposeAerialPerspectiveCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * The amount of light transmitted into aerial perspective.\r\n * A scale of 1 is physically correct.\r\n */\r\n public get aerialPerspectiveTransmittanceScale(): number {\r\n return this._aerialPerspectiveTransmittanceScale;\r\n }\r\n\r\n public set aerialPerspectiveTransmittanceScale(value: number) {\r\n value = Math.max(0, value);\r\n if (value !== this._aerialPerspectiveTransmittanceScale) {\r\n this._aerialPerspectiveTransmittanceScale = value;\r\n }\r\n }\r\n\r\n /**\r\n * The amount of saturation applied to the aerial perspective.\r\n * Reducing to zero desaturates the aerial perspective completely.\r\n * A value of 1 has no effect.\r\n */\r\n public get aerialPerspectiveSaturation(): number {\r\n return this._aerialPerspectiveSaturation;\r\n }\r\n\r\n public set aerialPerspectiveSaturation(value: number) {\r\n value = Math.max(0.0, value);\r\n if (value !== this._aerialPerspectiveSaturation) {\r\n this._aerialPerspectiveSaturation = value;\r\n }\r\n }\r\n\r\n /**\r\n * A radiance bias applied to aerial perspective.\r\n */\r\n public get aerialPerspectiveRadianceBias(): number {\r\n return this._aerialPerspectiveRadianceBias;\r\n }\r\n\r\n public set aerialPerspectiveRadianceBias(value: number) {\r\n if (value !== this._aerialPerspectiveRadianceBias) {\r\n // Define only needs to change if the value is changing between 0 and not 0.\r\n const hasDefineChanged = (value === 0) !== (this._aerialPerspectiveRadianceBias === 0);\r\n this._aerialPerspectiveRadianceBias = value;\r\n if (hasDefineChanged) {\r\n this._disposeAerialPerspectiveCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * True if the composition should be in linear space (e.g. for HDR rendering).\r\n * Typically linear space is expected when ImageProcessing is enabled via PostProcesses.\r\n * False for non-linear output.\r\n */\r\n public get isLinearSpaceComposition(): boolean {\r\n return this._isLinearSpaceComposition;\r\n }\r\n\r\n public set isLinearSpaceComposition(value: boolean) {\r\n if (value !== this._isLinearSpaceComposition) {\r\n this._isLinearSpaceComposition = value;\r\n // Note, LUTs will remain in linear space. Up to compositors to apply gamma if needed.\r\n this._disposeSkyCompositor();\r\n this._disposeAerialPerspectiveCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n }\r\n\r\n /**\r\n * True if the {@link light} value should be specified in linear space.\r\n * If using PBRMaterials, light value is expected to be linear.\r\n */\r\n public get isLinearSpaceLight(): boolean {\r\n return this._isLinearSpaceLight;\r\n }\r\n\r\n public set isLinearSpaceLight(value: boolean) {\r\n this._isLinearSpaceLight = value;\r\n }\r\n\r\n /**\r\n * The lookup table for transmittance.\r\n */\r\n public get transmittanceLut(): Nullable<TransmittanceLut> {\r\n return this._transmittanceLut;\r\n }\r\n\r\n /**\r\n * Gets the multiple scattering LUT render target.\r\n * @returns The render target.\r\n */\r\n public get multiScatteringLutRenderTarget(): Nullable<RenderTargetTexture> {\r\n return this._multiScatteringLutRenderTarget;\r\n }\r\n\r\n /**\r\n * The lookup table for diffuse sky irradiance, or null if not enabled.\r\n */\r\n public get diffuseSkyIrradianceLut(): Nullable<DiffuseSkyIrradianceLut> {\r\n return this._diffuseSkyIrradianceLut;\r\n }\r\n\r\n /**\r\n * The properties used to describe the size and optical parameters of the atmosphere.\r\n */\r\n public get physicalProperties(): AtmospherePhysicalProperties {\r\n return this._physicalProperties;\r\n }\r\n\r\n /**\r\n * The height in kilometers of the scene's origin.\r\n */\r\n public get originHeight(): number {\r\n return this._originHeight;\r\n }\r\n\r\n public set originHeight(value: number) {\r\n this._originHeight = value;\r\n }\r\n\r\n /**\r\n * When atmospheric scattering is applied to surfaces, if this value is set to true,\r\n * a grayscale approximation of the transmittance is used to dim surfaces.\r\n *\r\n * When set to false, the atmospheric composition does not dim the surfaces behind it.\r\n * It is up to the client application to apply transmittance manually.\r\n */\r\n public get applyApproximateTransmittance(): boolean {\r\n return this._applyApproximateTransmittance;\r\n }\r\n\r\n public set applyApproximateTransmittance(value: boolean) {\r\n if (this._applyApproximateTransmittance !== value) {\r\n this._applyApproximateTransmittance = value;\r\n this._disposeSkyCompositor();\r\n this._disposeAerialPerspectiveCompositor();\r\n this._disposeGlobeAtmosphereCompositor();\r\n }\r\n }\r\n\r\n /**\r\n * The directional lights in the scene which represent the suns illuminating the atmosphere.\r\n * Each frame, the color and intensity of the lights are updated based on the camera position and the light's direction.\r\n */\r\n public get lights(): ReadonlyArray<DirectionalLight> {\r\n return this._lights;\r\n }\r\n\r\n /**\r\n * The rendering group ID for the sky compositor.\r\n * The sky will only be rendered for this group.\r\n */\r\n public get skyRenderingGroup(): number {\r\n return this._skyRenderingGroup;\r\n }\r\n\r\n public set skyRenderingGroup(value: number) {\r\n this._skyRenderingGroup = value;\r\n this.scene.renderingManager.getRenderingGroup(value);\r\n }\r\n\r\n /**\r\n * The rendering group ID for the aerial perspective compositor.\r\n * Aerial perspective will only be rendered for this group.\r\n */\r\n public get aerialPerspectiveRenderingGroup(): number {\r\n return this._aerialPerspectiveRenderingGroup;\r\n }\r\n\r\n public set aerialPerspectiveRenderingGroup(value: number) {\r\n this._aerialPerspectiveRenderingGroup = value;\r\n this.scene.renderingManager.getRenderingGroup(value);\r\n }\r\n\r\n /**\r\n * The rendering group ID for the globe atmosphere compositor.\r\n * The globe atmosphere will only be rendered for this group.\r\n */\r\n public get globeAtmosphereRenderingGroup(): number {\r\n return this._globeAtmosphereRenderingGroup;\r\n }\r\n\r\n public set globeAtmosphereRenderingGroup(value: number) {\r\n this._globeAtmosphereRenderingGroup = value;\r\n this.scene.renderingManager.getRenderingGroup(value);\r\n }\r\n\r\n /**\r\n * Gets the uniform buffer used to store the atmosphere's physical properties.\r\n */\r\n public get uniformBuffer(): UniformBuffer {\r\n if (this._atmosphereUbo === null) {\r\n const atmosphereUbo = (this._atmosphereUbo = new UniformBuffer(this._engine, undefined, true, \"Atmosphere\"));\r\n atmosphereUbo.addUniform(\"peakRayleighScattering\", 3);\r\n atmosphereUbo.addUniform(\"planetRadius\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"peakMieScattering\", 3);\r\n atmosphereUbo.addUniform(\"atmosphereThickness\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"peakMieAbsorption\", 3);\r\n atmosphereUbo.addUniform(\"planetRadiusSquared\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"peakMieExtinction\", 3);\r\n atmosphereUbo.addUniform(\"atmosphereRadius\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"peakOzoneAbsorption\", 3);\r\n atmosphereUbo.addUniform(\"atmosphereRadiusSquared\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"horizonDistanceToAtmosphereEdge\", 1);\r\n atmosphereUbo.addUniform(\"horizonDistanceToAtmosphereEdgeSquared\", 1);\r\n atmosphereUbo.addUniform(\"planetRadiusWithOffset\", 1);\r\n atmosphereUbo.addUniform(\"planetRadiusOffset\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"atmosphereExposure\", 1);\r\n atmosphereUbo.addUniform(\"aerialPerspectiveRadianceBias\", 1);\r\n atmosphereUbo.addUniform(\"inverseAtmosphereThickness\", 1);\r\n atmosphereUbo.addUniform(\"aerialPerspectiveTransmittanceScale\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"inverseViewProjectionWithoutTranslation\", 16);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"directionToLight\", 3);\r\n atmosphereUbo.addUniform(\"multiScatteringIntensity\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"directionToLightRelativeToCameraGeocentricNormal\", 3);\r\n atmosphereUbo.addUniform(\"cameraRadius\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"lightRadianceAtCamera\", 3);\r\n atmosphereUbo.addUniform(\"diffuseSkyIrradianceDesaturationFactor\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"groundAlbedo\", 3);\r\n atmosphereUbo.addUniform(\"aerialPerspectiveSaturation\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"minMultiScattering\", 3);\r\n atmosphereUbo.addUniform(\"diffuseSkyIrradianceIntensity\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraPositionGlobal\", 3);\r\n atmosphereUbo.addUniform(\"lightIntensity\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"clampedCameraPositionGlobal\", 3);\r\n atmosphereUbo.addUniform(\"aerialPerspectiveIntensity\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraGeocentricNormal\", 3);\r\n atmosphereUbo.addUniform(\"clampedCameraRadius\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraForward\", 3);\r\n atmosphereUbo.addUniform(\"clampedCameraHeight\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraPosition\", 3);\r\n atmosphereUbo.addUniform(\"cosCameraHorizonAngleFromZenith\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"viewport\", 4);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"additionalDiffuseSkyIrradiance\", 3);\r\n atmosphereUbo.addUniform(\"cameraHeight\", 1);\r\n // 16-byte boundary\r\n atmosphereUbo.addUniform(\"cameraNearPlane\", 1);\r\n atmosphereUbo.addUniform(\"originHeight\", 1);\r\n atmosphereUbo.addUniform(\"sinCameraAtmosphereHorizonAngleFromNadir\", 1);\r\n atmosphereUbo.create();\r\n }\r\n return this._atmosphereUbo;\r\n }\r\n\r\n /**\r\n * Gets the camera-related variables for this atmosphere. Updated each frame.\r\n */\r\n public get cameraAtmosphereVariables(): AtmospherePerCameraVariables {\r\n return this._cameraAtmosphereVariables;\r\n }\r\n\r\n public readonly uniqueId: number;\r\n\r\n /**\r\n * Constructs the {@link Atmosphere}.\r\n * @param name - The name of this instance.\r\n * @param scene - The scene to which the atmosphere will be added.\r\n * @param lights - The light sources that illuminate the atmosphere. Currently only supports one light, and that light should be the first light in the scene.\r\n * @param options - The options used to create the atmosphere.\r\n */\r\n public constructor(\r\n public readonly name: string,\r\n public readonly scene: Scene,\r\n lights: DirectionalLight[],\r\n options?: IAtmosphereOptions\r\n ) {\r\n const engine = (this._engine = scene.getEngine());\r\n this.uniqueId = scene.getUniqueId();\r\n\r\n if (engine.isWebGPU) {\r\n throw new Error(\"Atmosphere is not supported on WebGPU.\");\r\n }\r\n if (engine.version < 2) {\r\n throw new Error(`Atmosphere is not supported on WebGL ${engine.version}.`);\r\n }\r\n\r\n this._physicalProperties = options?.physicalProperties ?? new AtmospherePhysicalProperties();\r\n this._physicalProperties.onChangedObservable.add(() => {\r\n this._transmittanceLut?.markDirty();\r\n });\r\n\r\n if (lights.length !== 1) {\r\n throw new Error(\"Atmosphere only supports one light source currently.\");\r\n }\r\n this._lights = lights;\r\n\r\n this.depthTexture = options?.depthTexture ?? null;\r\n this._exposure = options?.exposure ?? 1.0;\r\n this._isLinearSpaceLight = options?.isLinearSpaceLight ?? false;\r\n this._isLinearSpaceComposition = options?.isLinearSpaceComposition ?? false;\r\n this._applyApproximateTransmittance = options?.applyApproximateTransmittance ?? true;\r\n this._aerialPerspectiveRadianceBias = options?.aerialPerspectiveRadianceBias ?? 0.0;\r\n this._aerialPerspectiveTransmittanceScale = options?.aerialPerspectiveTransmittanceScale ?? 1.0;\r\n this._aerialPerspectiveSaturation = options?.aerialPerspectiveSaturation ?? 1.0;\r\n this._aerialPerspectiveIntensity = options?.aerialPerspectiveIntensity ?? 1.0;\r\n this._diffuseSkyIrradianceDesaturationFactor = options?.diffuseSkyIrradianceDesaturationFactor ?? 0.5;\r\n this._diffuseSkyIrradianceIntensity = options?.diffuseSkyIrradianceIntensity ?? 1.0;\r\n this._additionalDiffuseSkyIrradianceIntensity = options?.additionalDiffuseSkyIrradianceIntensity ?? 0.01;\r\n this._multiScatteringIntensity = options?.multiScatteringIntensity ?? 1.0;\r\n this._minimumMultiScatteringIntensity = options?.minimumMultiScatteringIntensity ?? 0.000618;\r\n this._isSkyViewLutEnabled = options?.isSkyViewLutEnabled ?? true;\r\n this._isAerialPerspectiveLutEnabled = options?.isAerialPerspectiveLutEnabled ?? true;\r\n this._originHeight = options?.originHeight ?? 0;\r\n this._additionalDiffuseSkyIrradianceColor = options?.additionalDiffuseSkyIrradianceColor\r\n ? new Color3().copyFrom(options.additionalDiffuseSkyIrradianceColor)\r\n : new Color3(163 / 255.0, 199 / 255.0, 1.0);\r\n this._groundAlbedo = options?.groundAlbedo ? new Color3().copyFrom(options.groundAlbedo) : new Color3().set(124.0 / 255.0, 165.0 / 255.0, 1.0);\r\n const minimumMultiScatteringColor = (this._minimumMultiScatteringColor = options?.minimumMultiScatteringColor\r\n ? new Color3().copyFrom(options.minimumMultiScatteringColor)\r\n : new Color3(30.0 / 255.0, 40.0 / 255.0, 77.0 / 255.0));\r\n\r\n this._skyRenderingGroup = options?.skyRenderingGroup ?? 0;\r\n this._aerialPerspectiveRenderingGroup = options?.aerialPerspectiveRenderingGroup ?? 0;\r\n this._globeAtmosphereRenderingGroup = options?.globeAtmosphereRenderingGroup ?? 0;\r\n\r\n this._additionalDiffuseSkyIrradianceColor.scaleToRef(this._additionalDiffuseSkyIrradianceIntensity, this._additionalDiffuseSkyIrradiance);\r\n this._minimumMultiScattering.x = minimumMultiScatteringColor.r * this._minimumMultiScatteringIntensity;\r\n this._minimumMultiScattering.y = minimumMultiScatteringColor.g * this._minimumMultiScatteringIntensity;\r\n this._minimumMultiScattering.z = minimumMultiScatteringColor.b * this._minimumMultiScatteringIntensity;\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n\r\n this._transmittanceLut = new TransmittanceLut(this);\r\n this._multiScatteringLutRenderTarget = CreateRenderTargetTexture(\"atmo-multiScattering\", { width: 32, height: 32 }, scene);\r\n if (options?.isDiffuseSkyIrradianceLutEnabled ?? true) {\r\n this._diffuseSkyIrradianceLut = new DiffuseSkyIrradianceLut(this);\r\n }\r\n if (this._isSkyViewLutEnabled) {\r\n this.skyViewLutRenderTarget!;\r\n }\r\n if (this._isAerialPerspectiveLutEnabled) {\r\n this.aerialPerspectiveLutRenderTarget!;\r\n }\r\n\r\n // Before rendering, make sure the per-camera variables have been updated.\r\n this._onBeforeCameraRenderObserver = scene.onBeforeCameraRenderObservable.add((x) => {\r\n this._updatePerCameraVariables(x);\r\n this._renderLutsForCamera();\r\n });\r\n\r\n {\r\n const renderingManager = scene.renderingManager;\r\n if (this._skyRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._skyRenderingGroup);\r\n }\r\n if (this._aerialPerspectiveRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._aerialPerspectiveRenderingGroup);\r\n }\r\n if (this._globeAtmosphereRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._globeAtmosphereRenderingGroup);\r\n }\r\n\r\n // Mark all rendering groups as being \"not empty\" before rendering the corresponding targets.\r\n // This ensures onAfterRenderTargetsRenderObservable is called for empty groups,\r\n // which allows the atmosphere to be rendered even when the groups are otherwise empty e.g.,\r\n // a scene with only the atmosphere in it, and no other Meshes.\r\n this._onBeforeDrawPhaseObserver = scene.onBeforeDrawPhaseObservable.add(() => {\r\n if (this._skyRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._skyRenderingGroup)._empty = false;\r\n }\r\n if (this._aerialPerspectiveRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._aerialPerspectiveRenderingGroup)._empty = false;\r\n }\r\n if (this._globeAtmosphereRenderingGroup >= 0) {\r\n renderingManager.getRenderingGroup(this._globeAtmosphereRenderingGroup)._empty = false;\r\n }\r\n });\r\n\r\n // Draw compositors after the respective rendering group.\r\n this._onAfterRenderingGroupObserver = scene.onAfterRenderingGroupObservable.add((group) => {\r\n if (group.renderingManager !== scene.renderingManager) {\r\n return;\r\n }\r\n\r\n const groupId = group.renderingGroupId;\r\n\r\n if (this._skyRenderingGroup === groupId) {\r\n this.drawSkyCompositor();\r\n }\r\n\r\n if (this._aerialPerspectiveRenderingGroup === groupId) {\r\n this.drawAerialPerspectiveCompositor();\r\n }\r\n\r\n if (this._globeAtmosphereRenderingGroup === groupId) {\r\n this.drawGlobeAtmosphereCompositor();\r\n }\r\n });\r\n }\r\n\r\n // Ensure the atmosphere is disposed when the scene is disposed.\r\n scene.onDisposeObservable.addOnce(() => {\r\n scene.removeExternalData(\"atmosphere\");\r\n this.dispose();\r\n });\r\n scene.addExternalData(\"atmosphere\", this);\r\n\r\n // Registers a material plugin which will allow common materials to sample the atmosphere environment maps e.g.,\r\n // sky view LUT for glossy reflections and diffuse sky illiminance LUT for irradiance.\r\n // It also handles aerial perspective application when Atmosphere is not provided with a depth texture.\r\n UnregisterMaterialPlugin(MaterialPlugin);\r\n RegisterMaterialPlugin(MaterialPlugin, (material) => {\r\n if (material.getClassName() === \"PBRMaterial\") {\r\n return new AtmospherePBRMaterialPlugin(material, this, this.depthTexture === null);\r\n }\r\n return null;\r\n });\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public dispose(): void {\r\n this._onBeforeCameraRenderObserver?.remove();\r\n this._onBeforeCameraRenderObserver = null;\r\n this._onBeforeDrawPhaseObserver?.remove();\r\n this._onBeforeDrawPhaseObserver = null;\r\n this._onAfterRenderingGroupObserver?.remove();\r\n this._onAfterRenderingGroupObserver = null;\r\n this._globeAtmosphereCompositorEffectWrapper?.dispose();\r\n this._globeAtmosphereCompositorEffectWrapper = null;\r\n this._skyCompositorEffectWrapper?.dispose();\r\n this._skyCompositorEffectWrapper = null;\r\n this._aerialPerspectiveCompositorEffectWrapper?.dispose();\r\n this._aerialPerspectiveCompositorEffectWrapper = null;\r\n this._skyViewLutRenderTarget?.dispose();\r\n this._skyViewLutRenderTarget = null;\r\n this._skyViewLutEffectWrapper?.dispose();\r\n this._skyViewLutEffectWrapper = null;\r\n this._skyViewLutEffectRenderer?.dispose();\r\n this._skyViewLutEffectRenderer = null;\r\n this._aerialPerspectiveLutRenderTarget?.dispose();\r\n this._aerialPerspectiveLutRenderTarget = null;\r\n this._aerialPerspectiveLutEffectWrapper?.dispose();\r\n this._aerialPerspectiveLutEffectWrapper = null;\r\n this._aerialPerspectiveLutEffectRenderer?.dispose();\r\n this._aerialPerspectiveLutEffectRenderer = null;\r\n this._multiScatteringEffectWrapper?.dispose();\r\n this._multiScatteringEffectWrapper = null;\r\n this._multiScatteringLutRenderTarget?.dispose();\r\n this._multiScatteringLutRenderTarget = null;\r\n this._transmittanceLut?.dispose();\r\n this._transmittanceLut = null;\r\n this._diffuseSkyIrradianceLut?.dispose();\r\n this._diffuseSkyIrradianceLut = null;\r\n this._atmosphereUbo?.dispose();\r\n this._atmosphereUbo = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._atmosphereUniformBufferAsArray.length = 0;\r\n\r\n UnregisterMaterialPlugin(MaterialPlugin);\r\n }\r\n\r\n /**\r\n * True if the atmosphere is enabled.\r\n * @returns - True if the atmosphere is enabled.\r\n */\r\n public isEnabled() {\r\n return this._isEnabled;\r\n }\r\n\r\n /**\r\n * Sets the enabled state of the atmosphere.\r\n * @param enabled - True to enable the atmosphere, false to disable it.\r\n */\r\n public setEnabled(enabled: boolean) {\r\n this._isEnabled = enabled;\r\n }\r\n\r\n /**\r\n * The class name of the {@link Atmosphere}.\r\n * @returns - The class name of the atmosphere.\r\n */\r\n public getClassName(): string {\r\n return \"Atmosphere\";\r\n }\r\n\r\n /**\r\n * Gets the color of a light after being transmitted through the atmosphere to a point specified by its distance to the planet center and its geocentric normal.\r\n * NOTE, the result is always a linear space color.\r\n * @param directionToLight - The direction of the light.\r\n * @param pointRadius - The distance from the planet center to the point in kilometers.\r\n * @param pointGeocentricNormal - The geocentric normal at the point i.e., normalize(point - planet center).\r\n * @param result - The color to store the result in.\r\n * @returns The result color.\r\n */\r\n public getTransmittedColorToRef = <T extends IColor3Like>(directionToLight: IVector3Like, pointRadius: number, pointGeocentricNormal: IVector3Like, result: T): T =>\r\n this._transmittanceLut!.getTransmittedColorToRef(directionToLight, pointRadius, pointGeocentricNormal, result);\r\n\r\n /**\r\n * Gets the diffuse sky irradiance. Result is always in linear space.\r\n * @param directionToLight - The direction of the point to the light.\r\n * @param pointRadius - The distance from the planet center to the point in kilometers.\r\n * @param pointGeocentricNormal - The geocentric normal at the point: normalize(point - planet center).\r\n * @param lightIrradiance - The irradiance of the light.\r\n * @param result - The color to store the result in.\r\n * @returns The result color.\r\n */\r\n public getDiffuseSkyIrradianceToRef = <T extends IColor3Like>(\r\n directionToLight: IVector3Like,\r\n pointRadius: number,\r\n pointGeocentricNormal: IVector3Like,\r\n lightIrradiance: number,\r\n result: T\r\n ): T =>\r\n this._diffuseSkyIrradianceLut?.getDiffuseSkyIrradianceToRef(directionToLight, pointRadius, pointGeocentricNormal, lightIrradiance, result) ??\r\n ((result.r = 0), (result.g = 0), (result.b = 0), result);\r\n\r\n /**\r\n * Creates a new {@link EffectWrapper} for the multiple scattering LUT\r\n * @returns The newly created {@link EffectWrapper}.\r\n */\r\n private _createMultiScatteringEffectWrapper(): EffectWrapper {\r\n const engine = this._engine;\r\n const name = \"atmo-multiScattering\";\r\n const ubo = this.uniformBuffer;\r\n const useUbo = ubo.useUbo;\r\n\r\n const defines: string[] = [\"#define POSITION_VEC2\"];\r\n if (!this._groundAlbedo.equals(Color3.BlackReadOnly)) {\r\n defines.push(\"#define USE_GROUND_ALBEDO\");\r\n }\r\n\r\n return new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"multiScattering\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : this.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [this.uniformBuffer.name] : [],\r\n samplerNames: [\"transmittanceLut\"],\r\n defines,\r\n useShaderStore: true,\r\n });\r\n }\r\n\r\n /**\r\n * Draws the multiple scattering LUT using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n private _drawMultiScatteringLut(): void {\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n DrawEffect(\r\n this._engine,\r\n this._effectRenderer!,\r\n this._multiScatteringEffectWrapper,\r\n this._multiScatteringLutRenderTarget,\r\n (effectRenderer, renderTarget, effect, engine) => {\r\n this.bindUniformBufferToEffect(effect);\r\n engine.bindFramebuffer(renderTarget!, undefined, undefined, undefined, true);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effectRenderer.draw();\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Draws the aerial perspective compositor using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n public drawAerialPerspectiveCompositor(): void {\r\n // Only works if we have a depth texture.\r\n if (this.depthTexture === null) {\r\n return;\r\n }\r\n\r\n const isEnabled = this.isEnabled();\r\n if (!isEnabled) {\r\n return;\r\n }\r\n\r\n // Aerial perspective compositor only renders when inside the atmosphere.\r\n const isOutsideAtmosphere = this._cameraAtmosphereVariables.clampedCameraRadius > this._physicalProperties.atmosphereRadius;\r\n if (isOutsideAtmosphere) {\r\n return;\r\n }\r\n\r\n const engine = this._engine;\r\n this._aerialPerspectiveCompositorEffectWrapper ??= CreateAerialPerspectiveCompositorEffectWrapper(\r\n engine,\r\n this.uniformBuffer,\r\n this._isAerialPerspectiveLutEnabled,\r\n this._isSkyViewLutEnabled,\r\n this._isLinearSpaceComposition,\r\n this._applyApproximateTransmittance,\r\n this._aerialPerspectiveIntensity,\r\n this._aerialPerspectiveRadianceBias\r\n );\r\n\r\n const skyViewLut = this._isSkyViewLutEnabled ? this.skyViewLutRenderTarget : null;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget!;\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n const aerialPerspectiveLut = this._isAerialPerspectiveLutEnabled ? this.aerialPerspectiveLutRenderTarget : null;\r\n if (\r\n !this._aerialPerspectiveCompositorEffectWrapper.isReady() ||\r\n !(skyViewLut?.isReady() ?? true) ||\r\n !multiScatteringLut.isReady() ||\r\n !transmittanceLut.isReady() ||\r\n !(aerialPerspectiveLut?.isReady() ?? true) ||\r\n !this.depthTexture.isReady()\r\n ) {\r\n return;\r\n }\r\n\r\n DrawEffect(\r\n engine,\r\n this._effectRenderer!,\r\n this._aerialPerspectiveCompositorEffectWrapper,\r\n null, // No render target, it will render to the current buffer.\r\n (effectRenderer, _, effect) => {\r\n if (this.depthTexture === null) {\r\n throw new Error(\"Depth texture is required for aerial perspective compositor.\");\r\n }\r\n this.bindUniformBufferToEffect(effect);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n if (this._isSkyViewLutEnabled) {\r\n effect.setTexture(\"skyViewLut\", skyViewLut);\r\n }\r\n if (this._isAerialPerspectiveLutEnabled) {\r\n effect.setTexture(\"aerialPerspectiveLut\", aerialPerspectiveLut);\r\n }\r\n effect.setTexture(\"depthTexture\", this.depthTexture);\r\n effectRenderer.draw();\r\n },\r\n 1, // depth to use in the compositor.\r\n this.applyApproximateTransmittance ? Constants.ALPHA_PREMULTIPLIED_PORTERDUFF : Constants.ALPHA_ONEONE,\r\n true, // depthTest\r\n false, // depthWrite\r\n Constants.ALWAYS, // depthFunction\r\n false // restoreDefaultFramebuffer\r\n );\r\n }\r\n\r\n /**\r\n * Draws the sky compositor using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n public drawSkyCompositor(): void {\r\n const isEnabled = this.isEnabled();\r\n if (!isEnabled) {\r\n return;\r\n }\r\n\r\n // The sky compositor only renders when inside the atmosphere.\r\n const isOutsideAtmosphere = this._cameraAtmosphereVariables.clampedCameraRadius > this._physicalProperties.atmosphereRadius;\r\n if (isOutsideAtmosphere) {\r\n return;\r\n }\r\n\r\n if (this.depthTexture !== null && !this.depthTexture.isReady()) {\r\n return;\r\n }\r\n\r\n const engine = this._engine;\r\n this._skyCompositorEffectWrapper ??= CreateSkyCompositorEffectWrapper(\r\n engine,\r\n this.uniformBuffer,\r\n this._isSkyViewLutEnabled,\r\n this._isLinearSpaceComposition,\r\n this._applyApproximateTransmittance\r\n );\r\n\r\n const skyViewLut = this._isSkyViewLutEnabled ? this.skyViewLutRenderTarget : null;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget!;\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n if (!this._skyCompositorEffectWrapper.isReady() || !(skyViewLut?.isReady() ?? true) || !multiScatteringLut.isReady() || !transmittanceLut.isReady()) {\r\n return;\r\n }\r\n\r\n DrawEffect(\r\n engine,\r\n this._effectRenderer!,\r\n this._skyCompositorEffectWrapper,\r\n null, // No render target, it will render to the current buffer.\r\n (effectRenderer, _, effect) => {\r\n this.bindUniformBufferToEffect(effect);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n if (this._isSkyViewLutEnabled) {\r\n effect.setTexture(\"skyViewLut\", skyViewLut);\r\n }\r\n effectRenderer.draw();\r\n },\r\n 1, // depth to use in the compositor.\r\n this._applyApproximateTransmittance ? Constants.ALPHA_PREMULTIPLIED_PORTERDUFF : Constants.ALPHA_ONEONE,\r\n true, // depthTest\r\n false, // depthWrite\r\n Constants.EQUAL, // depthFunction\r\n false // restoreDefaultFramebuffer\r\n );\r\n }\r\n\r\n /**\r\n * Draws the globe atmosphere compositor using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n public drawGlobeAtmosphereCompositor(): void {\r\n const isEnabled = this.isEnabled();\r\n if (!isEnabled) {\r\n return;\r\n }\r\n\r\n // Globe atmosphere compositor only renders when outside the atmosphere.\r\n const isOutsideAtmosphere = this._cameraAtmosphereVariables.clampedCameraRadius > this._physicalProperties.atmosphereRadius;\r\n if (!isOutsideAtmosphere) {\r\n return;\r\n }\r\n\r\n const engine = this._engine;\r\n this._globeAtmosphereCompositorEffectWrapper ??= CreateGlobeAtmosphereCompositorEffectWrapper(\r\n engine,\r\n this.uniformBuffer,\r\n this._isSkyViewLutEnabled,\r\n this._isLinearSpaceComposition,\r\n this._applyApproximateTransmittance,\r\n this._aerialPerspectiveIntensity,\r\n this._aerialPerspectiveRadianceBias,\r\n this.depthTexture !== null\r\n );\r\n\r\n const skyViewLut = this._isSkyViewLutEnabled ? this.skyViewLutRenderTarget : null;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget!;\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n if (!this._globeAtmosphereCompositorEffectWrapper.isReady() || !(skyViewLut?.isReady() ?? true) || !multiScatteringLut.isReady() || !transmittanceLut.isReady()) {\r\n return;\r\n }\r\n\r\n if (this.depthTexture !== null && !this.depthTexture.isReady()) {\r\n return;\r\n }\r\n\r\n DrawEffect(\r\n engine,\r\n this._effectRenderer!,\r\n this._globeAtmosphereCompositorEffectWrapper,\r\n null, // No render target, it will render to the current buffer.\r\n (effectRenderer, _, effect) => {\r\n this.bindUniformBufferToEffect(effect);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n if (this._isSkyViewLutEnabled) {\r\n effect.setTexture(\"skyViewLut\", skyViewLut);\r\n }\r\n if (this.depthTexture !== null) {\r\n effect.setTexture(\"depthTexture\", this.depthTexture);\r\n }\r\n effectRenderer.draw();\r\n },\r\n 1, // depth to use in the compositor.\r\n this._applyApproximateTransmittance ? Constants.ALPHA_PREMULTIPLIED_PORTERDUFF : Constants.ALPHA_ONEONE,\r\n true, // depthTest\r\n false, // depthWrite\r\n Constants.ALWAYS, // depthFunction\r\n false // restoreDefaultFramebuffer\r\n );\r\n }\r\n\r\n private _disposeSkyCompositor(): void {\r\n this._skyCompositorEffectWrapper?.dispose();\r\n this._skyCompositorEffectWrapper = null;\r\n }\r\n\r\n private _disposeAerialPerspectiveCompositor(): void {\r\n this._aerialPerspectiveCompositorEffectWrapper?.dispose();\r\n this._aerialPerspectiveCompositorEffectWrapper = null;\r\n }\r\n\r\n private _disposeGlobeAtmosphereCompositor(): void {\r\n this._globeAtmosphereCompositorEffectWrapper?.dispose();\r\n this._globeAtmosphereCompositorEffectWrapper = null;\r\n }\r\n\r\n /**\r\n * Updates the camera variables that are specific to the atmosphere.\r\n * @param camera - The camera to update the variables for.\r\n */\r\n private _updatePerCameraVariables(camera: Camera): void {\r\n const light = this._lights[0];\r\n this._directionToLight.copyFrom(light.direction);\r\n this._directionToLight.scaleInPlace(-1);\r\n\r\n const properties = this._physicalProperties;\r\n const cameraAtmosphereVariables = this._cameraAtmosphereVariables;\r\n cameraAtmosphereVariables.update(\r\n camera,\r\n properties.planetRadius,\r\n properties.planetRadiusWithOffset,\r\n properties.atmosphereRadius,\r\n this._directionToLight,\r\n this.originHeight\r\n );\r\n\r\n this._transmittanceLut!.updateLightParameters(light, cameraAtmosphereVariables.clampedCameraRadius, cameraAtmosphereVariables.cameraGeocentricNormal);\r\n this._linearLightColor.copyFrom(light.diffuse);\r\n\r\n this.getDiffuseSkyIrradianceToRef(this._directionToLight, 0, cameraAtmosphereVariables.cameraGeocentricNormal, this.lights[0].intensity, this._tempSceneAmbient);\r\n if (!this.isLinearSpaceLight) {\r\n this._tempSceneAmbient.toGammaSpaceToRef(this._tempSceneAmbient);\r\n }\r\n this.scene.ambientColor = this._tempSceneAmbient;\r\n\r\n this.onAfterUpdateVariablesForCameraObservable.notifyObservers(camera);\r\n }\r\n\r\n /**\r\n * Renders the lookup tables, some of which can vary per-camera.\r\n * It is expected that updatePerCameraVariables was previously called.\r\n */\r\n private _renderLutsForCamera(): void {\r\n {\r\n this.onBeforeLightVariablesUpdateObservable.notifyObservers();\r\n\r\n const light = this.lights[0];\r\n if (!this.isLinearSpaceLight) {\r\n light.diffuse = light.diffuse.toGammaSpaceToRef(light.diffuse);\r\n light.specular = light.specular.toGammaSpaceToRef(light.specular);\r\n }\r\n const intensity = light.intensity;\r\n this._lightRadianceAtCamera.set(intensity * this._linearLightColor.r, intensity * this._linearLightColor.g, intensity * this._linearLightColor.b);\r\n }\r\n\r\n if (this.uniformBuffer.useUbo) {\r\n this.updateUniformBuffer();\r\n }\r\n\r\n // Render the LUTs.\r\n const isEnabled = this.isEnabled();\r\n {\r\n this.onBeforeRenderLutsForCameraObservable.notifyObservers();\r\n\r\n // After UBO update we can render the global LUTs which use some of these values on the GPU.\r\n // TODO: Could break out update and UBOs to global vs. per-camera.\r\n this.renderGlobalLuts();\r\n\r\n // If atmosphere is enabled, render the per-camera LUTs (sky view and aerial perspective).\r\n if (isEnabled && !this._transmittanceLut!.isDirty && this._hasRenderedMultiScatteringLut) {\r\n if (this._isSkyViewLutEnabled) {\r\n this._drawSkyViewLut();\r\n }\r\n\r\n // Only need to render aerial perspective LUT when inside the atmosphere.\r\n if (this._isAerialPerspectiveLutEnabled && this._cameraAtmosphereVariables.clampedCameraRadius <= this._physicalProperties.atmosphereRadius) {\r\n this._drawAerialPerspectiveLut();\r\n }\r\n }\r\n\r\n this.onAfterRenderLutsForCameraObservable.notifyObservers();\r\n }\r\n }\r\n\r\n /**\r\n * Renders the lookup tables that do not depend on a camera position.\r\n */\r\n public renderGlobalLuts(): void {\r\n const hasNewTransmittanceLut = this._transmittanceLut!.render();\r\n if (hasNewTransmittanceLut) {\r\n this._hasRenderedMultiScatteringLut = false;\r\n this._diffuseSkyIrradianceLut?.markDirty();\r\n }\r\n\r\n if (!this._transmittanceLut!.isDirty && !this._hasRenderedMultiScatteringLut) {\r\n this._multiScatteringEffectWrapper ??= this._createMultiScatteringEffectWrapper();\r\n if (this._multiScatteringEffectWrapper?.isReady() && this._multiScatteringLutRenderTarget?.isReady()) {\r\n this._drawMultiScatteringLut();\r\n this._hasRenderedMultiScatteringLut = true;\r\n }\r\n }\r\n\r\n if (!this._transmittanceLut!.isDirty && this._hasRenderedMultiScatteringLut) {\r\n this._diffuseSkyIrradianceLut?.render(); // Will only render if needed.\r\n }\r\n }\r\n\r\n /**\r\n * Binds the atmosphere's uniform buffer to an {@link Effect}.\r\n * @param effect - The {@link Effect} to bind the uniform buffer to.\r\n */\r\n public bindUniformBufferToEffect(effect: Effect): void {\r\n const uniformBuffer = this.uniformBuffer;\r\n const name = uniformBuffer.name;\r\n uniformBuffer.bindToEffect(effect, name);\r\n if (uniformBuffer.useUbo) {\r\n uniformBuffer.bindUniformBuffer();\r\n } else {\r\n this.updateUniformBuffer();\r\n }\r\n }\r\n\r\n /**\r\n * Updates the atmosphere's uniform buffer.\r\n */\r\n public updateUniformBuffer(): void {\r\n const physicalProperties = this._physicalProperties;\r\n const cameraAtmosphereVariables = this._cameraAtmosphereVariables;\r\n const ubo = this.uniformBuffer;\r\n\r\n ubo.updateVector3(\"peakRayleighScattering\", physicalProperties.rayleighScattering);\r\n ubo.updateFloat(\"planetRadius\", physicalProperties.planetRadius);\r\n ubo.updateVector3(\"peakMieScattering\", physicalProperties.mieScattering);\r\n ubo.updateFloat(\"atmosphereThickness\", physicalProperties.atmosphereThickness);\r\n ubo.updateVector3(\"peakMieAbsorption\", physicalProperties.mieAbsorption);\r\n ubo.updateFloat(\"planetRadiusSquared\", physicalProperties.planetRadiusSquared);\r\n ubo.updateVector3(\"peakMieExtinction\", physicalProperties.mieExtinction);\r\n ubo.updateFloat(\"atmosphereRadius\", physicalProperties.atmosphereRadius);\r\n ubo.updateVector3(\"peakOzoneAbsorption\", physicalProperties.ozoneAbsorption);\r\n ubo.updateFloat(\"atmosphereRadiusSquared\", physicalProperties.atmosphereRadiusSquared);\r\n ubo.updateFloat(\"horizonDistanceToAtmosphereEdge\", physicalProperties.horizonDistanceToAtmosphereEdge);\r\n ubo.updateFloat(\"horizonDistanceToAtmosphereEdgeSquared\", physicalProperties.horizonDistanceToAtmosphereEdgeSquared);\r\n ubo.updateFloat(\"planetRadiusWithOffset\", physicalProperties.planetRadiusWithOffset);\r\n ubo.updateFloat(\"planetRadiusOffset\", physicalProperties.planetRadiusOffset);\r\n ubo.updateFloat(\"aerialPerspectiveRadianceBias\", this._aerialPerspectiveRadianceBias);\r\n ubo.updateFloat(\"inverseAtmosphereThickness\", 1 / physicalProperties.atmosphereThickness);\r\n ubo.updateFloat(\"aerialPerspectiveTransmittanceScale\", this._aerialPerspectiveTransmittanceScale);\r\n ubo.updateMatrix(\"inverseViewProjectionWithoutTranslation\", cameraAtmosphereVariables.inverseViewProjectionMatrixWithoutTranslation);\r\n ubo.updateVector3(\"directionToLight\", this._directionToLight);\r\n ubo.updateFloat(\"multiScatteringIntensity\", this.multiScatteringIntensity);\r\n ubo.updateVector3(\"directionToLightRelativeToCameraGeocentricNormal\", cameraAtmosphereVariables.directionToLightRelativeToCameraGeocentricNormal);\r\n ubo.updateFloat(\"cameraRadius\", cameraAtmosphereVariables.cameraRadius);\r\n ubo.updateVector3(\"lightRadianceAtCamera\", this._lightRadianceAtCamera);\r\n ubo.updateFloat(\"diffuseSkyIrradianceDesaturationFactor\", this._diffuseSkyIrradianceDesaturationFactor);\r\n ubo.updateColor3(\"groundAlbedo\", this._groundAlbedo);\r\n ubo.updateFloat(\"aerialPerspectiveSaturation\", this._aerialPerspectiveSaturation);\r\n ubo.updateVector3(\"minMultiScattering\", this._minimumMultiScattering);\r\n ubo.updateFloat(\"diffuseSkyIrradianceIntensity\", this._diffuseSkyIrradianceIntensity);\r\n ubo.updateVector3(\"cameraPositionGlobal\", cameraAtmosphereVariables.cameraPositionGlobal);\r\n ubo.updateFloat(\"lightIntensity\", this.lights[0].intensity);\r\n ubo.updateVector3(\"clampedCameraPositionGlobal\", cameraAtmosphereVariables.clampedCameraPositionGlobal);\r\n ubo.updateFloat(\"aerialPerspectiveIntensity\", this._aerialPerspectiveIntensity);\r\n ubo.updateVector3(\"cameraGeocentricNormal\", cameraAtmosphereVariables.cameraGeocentricNormal);\r\n ubo.updateFloat(\"clampedCameraRadius\", cameraAtmosphereVariables.clampedCameraRadius);\r\n ubo.updateVector3(\"cameraForward\", cameraAtmosphereVariables.cameraForward);\r\n ubo.updateFloat(\"clampedCameraHeight\", cameraAtmosphereVariables.clampedCameraHeight);\r\n ubo.updateVector3(\"cameraPosition\", cameraAtmosphereVariables.cameraPosition);\r\n ubo.updateFloat(\"cosCameraHorizonAngleFromZenith\", cameraAtmosphereVariables.cosCameraHorizonAngleFromZenith);\r\n ubo.updateVector4(\"viewport\", cameraAtmosphereVariables.viewport);\r\n ubo.updateColor3(\"additionalDiffuseSkyIrradiance\", this._additionalDiffuseSkyIrradiance);\r\n ubo.updateFloat(\"cameraHeight\", cameraAtmosphereVariables.cameraHeight);\r\n ubo.updateFloat(\"cameraNearPlane\", cameraAtmosphereVariables.cameraNearPlane);\r\n ubo.updateFloat(\"originHeight\", this._originHeight);\r\n ubo.updateFloat(\"sinCameraAtmosphereHorizonAngleFromNadir\", cameraAtmosphereVariables.sinCameraAtmosphereHorizonAngleFromNadir);\r\n ubo.updateFloat(\"atmosphereExposure\", this._exposure);\r\n ubo.update();\r\n }\r\n\r\n /**\r\n * Draws the aerial perspective LUT using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n private _drawAerialPerspectiveLut(): void {\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget;\r\n DrawEffect(\r\n this._engine,\r\n this._effectRenderer!,\r\n this._aerialPerspectiveLutEffectWrapper,\r\n this._aerialPerspectiveLutRenderTarget,\r\n (effectRenderer, renderTarget, effect, engine) => {\r\n this.bindUniformBufferToEffect(effect);\r\n const layers = 32;\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n for (let layer = 0; layer < layers; layer++) {\r\n engine.bindFramebuffer(renderTarget!, undefined, undefined, undefined, true, undefined, layer);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setFloat(\"layerIdx\", layer);\r\n effectRenderer.draw();\r\n }\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Draws the sky view LUT using {@link EffectWrapper} and {@link EffectRenderer}.\r\n */\r\n private _drawSkyViewLut(): void {\r\n const transmittanceLut = this._transmittanceLut!.renderTarget;\r\n const multiScatteringLut = this._multiScatteringLutRenderTarget!;\r\n DrawEffect(this._engine, this._effectRenderer!, this._skyViewLutEffectWrapper, this._skyViewLutRenderTarget, (effectRenderer, renderTarget, effect, engine) => {\r\n this.bindUniformBufferToEffect(effect);\r\n engine.bindFramebuffer(renderTarget!, undefined, undefined, undefined, true);\r\n effectRenderer.bindBuffers(effect);\r\n effect.setTexture(\"transmittanceLut\", transmittanceLut);\r\n effect.setTexture(\"multiScatteringLut\", multiScatteringLut);\r\n effectRenderer.draw();\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Creates an {@link EffectWrapper} with the given parameters.\r\n * @param engine - The engine to use.\r\n * @param name - The name of the effect wrapper.\r\n * @param fragmentShader - The fragment shader source.\r\n * @param uniformNames - The uniform names to use.\r\n * @param samplerNames - The sampler names to use.\r\n * @param uniformBuffers - The uniform buffers to use.\r\n * @param defineNames - Array of define names to prepend with \"#define \".\r\n * @returns The effect wrapper.\r\n */\r\nconst CreateEffectWrapper = (\r\n engine: AbstractEngine,\r\n name: string,\r\n fragmentShader: string,\r\n uniformNames?: string[],\r\n samplerNames?: string[],\r\n uniformBuffers?: string[],\r\n defineNames?: string[]\r\n): EffectWrapper => {\r\n const defines = defineNames?.map((defineName) => `#define ${defineName}`) ?? [];\r\n\r\n return new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader,\r\n attributeNames: [\"position\"],\r\n uniformNames,\r\n uniformBuffers,\r\n samplerNames,\r\n defines,\r\n useShaderStore: true,\r\n });\r\n};\r\n\r\nconst CreateRenderTargetTexture = (\r\n name: string,\r\n size: number | { width: number; height: number; layers?: number },\r\n scene: Scene,\r\n options?: RenderTargetTextureOptions\r\n): RenderTargetTexture => {\r\n const rtOptions: RenderTargetTextureOptions = {\r\n generateMipMaps: false,\r\n generateDepthBuffer: false,\r\n generateStencilBuffer: false,\r\n gammaSpace: false,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n format: Constants.TEXTUREFORMAT_RGBA,\r\n ...options,\r\n };\r\n const renderTarget = new RenderTargetTexture(name, size, scene, rtOptions);\r\n\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n return renderTarget;\r\n};\r\n\r\n/**\r\n * Common setup and teardown for drawing LUTs or composition passes.\r\n * @param engine - The engine to use.\r\n * @param effectRenderer - The effect renderer to use.\r\n * @param effectWrapper - The effect wrapper to use.\r\n * @param renderTarget - The render target.\r\n * @param drawCallback - Callback function that performs the drawing.\r\n * @param depth - The depth value to set in the effect.\r\n * @param alphaMode - The alpha mode to set before drawing.\r\n * @param depthTest - Whether to enable depth testing.\r\n * @param depthWrite - Optional depth write state to set before drawing.\r\n * @param depthFunction - The depth function to set before drawing.\r\n * @param restoreDefaultFramebuffer - Whether to restore the default framebuffer after drawing.\r\n */\r\nconst DrawEffect = (\r\n engine: AbstractEngine,\r\n effectRenderer: EffectRenderer,\r\n effectWrapper: Nullable<EffectWrapper>,\r\n renderTarget: Nullable<RenderTargetTexture>,\r\n drawCallback: (effectRenderer: EffectRenderer, renderTarget: Nullable<RenderTargetWrapper>, effect: Effect, engine: AbstractEngine) => void,\r\n depth = 0,\r\n alphaMode = Constants.ALPHA_DISABLE,\r\n depthTest = true,\r\n depthWrite?: boolean,\r\n depthFunction = Constants.LEQUAL,\r\n restoreDefaultFramebuffer = true\r\n): void => {\r\n if ((renderTarget !== null && !renderTarget.isReady()) || !effectWrapper?.isReady()) {\r\n return;\r\n }\r\n\r\n // Set additional depth/stencil states before calling applyEffectWrapper.\r\n const currentDepthWrite = engine.getDepthWrite();\r\n if (depthWrite !== undefined) {\r\n engine.setDepthWrite(depthWrite);\r\n }\r\n const currentDepthFunction = engine.getDepthFunction();\r\n engine.setDepthFunction(depthFunction);\r\n\r\n // Likewise with the alpha mode, which can affect depth state too.\r\n const currentAlphaMode = engine.getAlphaMode();\r\n if (alphaMode !== Constants.ALPHA_DISABLE) {\r\n engine.setAlphaMode(alphaMode);\r\n }\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n effectRenderer.applyEffectWrapper(effectWrapper, depthTest); // Note, stencil is false by default.\r\n\r\n const effect = effectWrapper.effect;\r\n\r\n effect.setFloat(\"depth\", depth);\r\n\r\n // Call the specific drawing logic.\r\n drawCallback(effectRenderer, renderTarget?.renderTarget!, effect, engine);\r\n\r\n // Restore state (order matters!)\r\n engine.setAlphaMode(currentAlphaMode);\r\n if (currentDepthWrite !== undefined) {\r\n engine.setDepthWrite(currentDepthWrite);\r\n }\r\n if (currentDepthFunction) {\r\n engine.setDepthFunction(currentDepthFunction);\r\n }\r\n effectRenderer.restoreStates();\r\n\r\n // And restore the default framebuffer.\r\n if (restoreDefaultFramebuffer) {\r\n engine.restoreDefaultFramebuffer();\r\n }\r\n};\r\n\r\n/**\r\n * Creates an EffectWrapper for the sky compositor.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer to use.\r\n * @param isSkyViewLutEnabled - Whether the sky view LUT is enabled.\r\n * @param isLinearSpaceComposition - Whether composition is in linear space.\r\n * @param applyApproximateTransmittance - Whether to apply approximate transmittance.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateSkyCompositorEffectWrapper = (\r\n engine: AbstractEngine,\r\n uniformBuffer: UniformBuffer,\r\n isSkyViewLutEnabled: boolean,\r\n isLinearSpaceComposition: boolean,\r\n applyApproximateTransmittance: boolean\r\n): EffectWrapper => {\r\n const useUbo = uniformBuffer.useUbo;\r\n const defines = [\"COMPUTE_WORLD_RAY\"];\r\n if (isSkyViewLutEnabled) {\r\n defines.push(\"USE_SKY_VIEW_LUT\");\r\n }\r\n if (!isLinearSpaceComposition) {\r\n defines.push(\"OUTPUT_TO_SRGB\");\r\n }\r\n if (applyApproximateTransmittance) {\r\n defines.push(\"APPLY_TRANSMITTANCE_BLENDING\");\r\n }\r\n const textures = isSkyViewLutEnabled ? [\"skyViewLut\"] : [\"transmittanceLut\", \"multiScatteringLut\"];\r\n return CreateEffectWrapper(\r\n engine,\r\n \"atmo-skyCompositor\",\r\n \"compositeSky\",\r\n [\"depth\", ...(useUbo ? [] : uniformBuffer.getUniformNames())],\r\n textures,\r\n useUbo ? [uniformBuffer.name] : [],\r\n defines\r\n );\r\n};\r\n\r\n/**\r\n * Creates an EffectWrapper for the aerial perspective LUT.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer to use.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateAerialPerspectiveEffectWrapper = (engine: AbstractEngine, uniformBuffer: UniformBuffer): EffectWrapper =>\r\n CreateEffectWrapper(\r\n engine,\r\n \"atmo-aerialPerspective\",\r\n \"aerialPerspective\",\r\n [\"layerIdx\", \"depth\", ...(uniformBuffer.useUbo ? [] : uniformBuffer.getUniformNames())],\r\n [\"transmittanceLut\", \"multiScatteringLut\"],\r\n uniformBuffer.useUbo ? [uniformBuffer.name] : [],\r\n [\"COMPUTE_WORLD_RAY\"]\r\n );\r\n\r\n/**\r\n * Creates an EffectWrapper for the aerial perspective compositor.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer.\r\n * @param isAerialPerspectiveLutEnabled - Whether the aerial perspective LUT is enabled.\r\n * @param isSkyViewLutEnabled - Whether the sky view LUT is enabled.\r\n * @param isLinearSpaceComposition - Whether composition is in linear space.\r\n * @param applyApproximateTransmittance - Whether to apply approximate transmittance.\r\n * @param aerialPerspectiveIntensity - The aerial perspective intensity.\r\n * @param aerialPerspectiveRadianceBias - The aerial perspective radiance bias.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateAerialPerspectiveCompositorEffectWrapper = (\r\n engine: AbstractEngine,\r\n uniformBuffer: UniformBuffer,\r\n isAerialPerspectiveLutEnabled: boolean,\r\n isSkyViewLutEnabled: boolean,\r\n isLinearSpaceComposition: boolean,\r\n applyApproximateTransmittance: boolean,\r\n aerialPerspectiveIntensity: number,\r\n aerialPerspectiveRadianceBias: number\r\n): EffectWrapper => {\r\n const useUbo = uniformBuffer.useUbo;\r\n const defines = [\"COMPUTE_WORLD_RAY\"];\r\n if (isAerialPerspectiveLutEnabled) {\r\n defines.push(\"USE_AERIAL_PERSPECTIVE_LUT\");\r\n }\r\n if (isSkyViewLutEnabled) {\r\n defines.push(\"USE_SKY_VIEW_LUT\");\r\n }\r\n if (aerialPerspectiveIntensity !== 1) {\r\n defines.push(\"APPLY_AERIAL_PERSPECTIVE_INTENSITY\");\r\n }\r\n if (!isLinearSpaceComposition) {\r\n defines.push(\"OUTPUT_TO_SRGB\");\r\n }\r\n if (applyApproximateTransmittance) {\r\n defines.push(\"APPLY_TRANSMITTANCE_BLENDING\");\r\n }\r\n if (aerialPerspectiveRadianceBias !== 0.0) {\r\n defines.push(\"APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\");\r\n }\r\n\r\n const samplers = [\"transmittanceLut\", \"multiScatteringLut\", \"depthTexture\"];\r\n if (isSkyViewLutEnabled) {\r\n samplers.push(\"skyViewLut\");\r\n }\r\n if (isAerialPerspectiveLutEnabled) {\r\n samplers.push(\"aerialPerspectiveLut\");\r\n }\r\n\r\n return CreateEffectWrapper(\r\n engine,\r\n \"atmo-aerialPerspectiveCompositor\",\r\n \"compositeAerialPerspective\",\r\n [\"depth\", ...(useUbo ? [] : uniformBuffer.getUniformNames())],\r\n samplers,\r\n useUbo ? [uniformBuffer.name] : [],\r\n defines\r\n );\r\n};\r\n\r\n/**\r\n * Creates an EffectWrapper for the globe atmosphere compositor.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer to use.\r\n * @param isSkyViewLutEnabled - Whether the sky view LUT is enabled.\r\n * @param isLinearSpaceComposition - Whether composition is in linear space.\r\n * @param applyApproximateTransmittance - Whether to apply approximate transmittance.\r\n * @param aerialPerspectiveIntensity - The aerial perspective intensity.\r\n * @param aerialPerspectiveRadianceBias - The aerial perspective radiance bias.\r\n * @param hasDepthTexture - Whether a depth texture is available.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateGlobeAtmosphereCompositorEffectWrapper = (\r\n engine: AbstractEngine,\r\n uniformBuffer: UniformBuffer,\r\n isSkyViewLutEnabled: boolean,\r\n isLinearSpaceComposition: boolean,\r\n applyApproximateTransmittance: boolean,\r\n aerialPerspectiveIntensity: number,\r\n aerialPerspectiveRadianceBias: number,\r\n hasDepthTexture: boolean\r\n): EffectWrapper => {\r\n const useUbo = uniformBuffer.useUbo;\r\n const defines = [\"COMPUTE_WORLD_RAY\"];\r\n if (isSkyViewLutEnabled) {\r\n defines.push(\"USE_SKY_VIEW_LUT\");\r\n }\r\n if (aerialPerspectiveIntensity !== 1) {\r\n defines.push(\"APPLY_AERIAL_PERSPECTIVE_INTENSITY\");\r\n }\r\n if (!isLinearSpaceComposition) {\r\n defines.push(\"OUTPUT_TO_SRGB\");\r\n }\r\n if (hasDepthTexture) {\r\n defines.push(\"HAS_DEPTH_TEXTURE\");\r\n }\r\n if (applyApproximateTransmittance) {\r\n defines.push(\"APPLY_TRANSMITTANCE_BLENDING\");\r\n }\r\n if (aerialPerspectiveRadianceBias !== 0.0) {\r\n defines.push(\"APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\");\r\n }\r\n\r\n const samplers = [\"transmittanceLut\", \"multiScatteringLut\"];\r\n if (isSkyViewLutEnabled) {\r\n samplers.push(\"skyViewLut\");\r\n }\r\n if (hasDepthTexture) {\r\n samplers.push(\"depthTexture\");\r\n }\r\n\r\n return CreateEffectWrapper(\r\n engine,\r\n \"atmo-globeAtmosphereCompositor\",\r\n \"compositeGlobeAtmosphere\",\r\n [\"depth\", ...(useUbo ? [] : uniformBuffer.getUniformNames())],\r\n samplers,\r\n useUbo ? [uniformBuffer.name] : [],\r\n defines\r\n );\r\n};\r\n\r\n/**\r\n * Creates an EffectWrapper for the sky view LUT.\r\n * @param engine - The engine to use.\r\n * @param uniformBuffer - The uniform buffer to use.\r\n * @returns The created EffectWrapper.\r\n */\r\nconst CreateSkyViewEffectWrapper = (engine: AbstractEngine, uniformBuffer: UniformBuffer): EffectWrapper =>\r\n CreateEffectWrapper(\r\n engine,\r\n \"atmo-skyView\",\r\n \"skyView\",\r\n [\"depth\", ...(uniformBuffer.useUbo ? [] : uniformBuffer.getUniformNames())],\r\n [\"transmittanceLut\", \"multiScatteringLut\"],\r\n uniformBuffer.useUbo ? [uniformBuffer.name] : []\r\n );\r\n","import type { Scene } from \"core/scene\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math\";\r\n\r\nimport type { HtmlMesh } from \"./htmlMesh\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport type { SubMesh } from \"core/Meshes/subMesh\";\r\nimport { RenderingGroup } from \"core/Rendering/renderingGroup\";\r\n\r\nimport type { Observer } from \"core/Misc/observable\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport type { AbstractEngine } from \"core/Engines\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\n\r\nconst PositionUpdateFailMessage = \"Failed to update html mesh renderer position due to failure to get canvas rect. HtmlMesh instances may not render correctly\";\r\nconst BabylonUnitsToPixels = 100;\r\n\r\n/**\r\n * A function that compares two submeshes and returns a number indicating which\r\n * should be rendered first.\r\n */\r\ntype RenderOrderFunction = (subMeshA: SubMesh, subMeshB: SubMesh) => number;\r\n\r\ntype RenderLayerElements = {\r\n container: HTMLElement;\r\n domElement: HTMLElement;\r\n cameraElement: HTMLElement;\r\n};\r\n\r\n// Returns a function that ensures that HtmlMeshes are rendered before all other meshes.\r\n// Note this will only be applied to group 0.\r\n// If neither mesh is an HtmlMesh, then the default render order is used\r\n// This prevents HtmlMeshes from appearing in front of other meshes when they are behind them\r\nconst RenderOrderFunc = (defaultRenderOrder: RenderOrderFunction): RenderOrderFunction => {\r\n return (subMeshA: SubMesh, subMeshB: SubMesh) => {\r\n const meshA = subMeshA.getMesh();\r\n const meshB = subMeshB.getMesh();\r\n\r\n // Use property check instead of instanceof since it is less expensive and\r\n // this will be called many times per frame\r\n const meshIsHtmlMeshA = (meshA as any)[\"isHtmlMesh\"];\r\n const meshIsHtmlMeshB = (meshB as any)[\"isHtmlMesh\"];\r\n if (meshIsHtmlMeshA) {\r\n return meshIsHtmlMeshB ? (meshA.absolutePosition.z <= meshB.absolutePosition.z ? 1 : -1) : -1;\r\n } else {\r\n return meshIsHtmlMeshB ? 1 : defaultRenderOrder(subMeshA, subMeshB);\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * An instance of this is required to render HtmlMeshes in the scene.\r\n * if using HtmlMeshes, you must not set render order for group 0 using\r\n * scene.setRenderingOrder. You must instead pass the compare functions\r\n * to the HtmlMeshRenderer constructor. If you do not, then your render\r\n * order will be overwritten if the HtmlMeshRenderer is created after and\r\n * the HtmlMeshes will not render correctly (they will appear in front of\r\n * meshes that are actually in front of them) if the HtmlMeshRenderer is\r\n * created before.\r\n */\r\nexport class HtmlMeshRenderer {\r\n /**\r\n * Global scale factor applied to the homogeneous `w` component (m[15]) of the\r\n * transformation matrix when projecting 3D objects into pixel space.\r\n *\r\n * This value is used to balance Babylon units against screen pixels, ensuring\r\n * that HTML-mapped or screen-space objects appear with the correct relative\r\n * size. Adjust with care, as changing it affects the projection scale of all\r\n * transformed objects.\r\n *\r\n * The default value is `0.00001`, which works well when 1 Babylon unit\r\n * corresponds to 1 meter, and the typical screen resolution is around\r\n * 100 pixels per meter (i.e., 1 pixel per centimeter).\r\n */\r\n public static PROJECTION_SCALE_FACTOR = 0.00001;\r\n\r\n private _containerId?: string;\r\n private _inSceneElements?: RenderLayerElements | null;\r\n private _overlayElements?: RenderLayerElements | null;\r\n private _engine: AbstractEngine;\r\n\r\n private _cache = {\r\n cameraData: { fov: 0, position: new Vector3(), style: \"\" },\r\n htmlMeshData: new WeakMap<object, { style: string }>(),\r\n };\r\n private _width = 0;\r\n private _height = 0;\r\n private _heightHalf = 0;\r\n\r\n private _cameraWorldMatrix?: Matrix;\r\n\r\n // Create some refs to avoid creating new objects every frame\r\n private _temp = {\r\n scaleTransform: new Vector3(),\r\n rotationTransform: new Quaternion(),\r\n positionTransform: new Vector3(),\r\n objectMatrix: Matrix.Identity(),\r\n cameraWorldMatrix: Matrix.Identity(),\r\n cameraRotationMatrix: Matrix.Identity(),\r\n cameraWorldMatrixAsArray: new Array(16),\r\n };\r\n\r\n // Keep track of DPR so we can resize if DPR changes\r\n // Otherwise the DOM content will scale, but the mesh won't\r\n private _lastDevicePixelRatio = window.devicePixelRatio;\r\n\r\n // Keep track of camera matrix changes so we only update the\r\n // DOM element styles when necessary\r\n private _cameraMatrixUpdated = true;\r\n\r\n // Keep track of position changes so we only update the DOM element\r\n // styles when necessary\r\n private _previousCanvasDocumentPosition = {\r\n top: 0,\r\n left: 0,\r\n };\r\n\r\n private _renderObserver: Observer<Scene> | null = null;\r\n\r\n /**\r\n * Contruct an instance of HtmlMeshRenderer\r\n * @param scene\r\n * @param options object containing the following optional properties:\r\n * @returns\r\n */\r\n constructor(\r\n scene: Scene,\r\n {\r\n parentContainerId = null,\r\n _containerId = \"css-container\",\r\n enableOverlayRender = true,\r\n defaultOpaqueRenderOrder = RenderingGroup.PainterSortCompare,\r\n defaultAlphaTestRenderOrder = RenderingGroup.PainterSortCompare,\r\n defaultTransparentRenderOrder = RenderingGroup.defaultTransparentSortCompare,\r\n }: {\r\n parentContainerId?: string | null;\r\n _containerId?: string;\r\n defaultOpaqueRenderOrder?: RenderOrderFunction;\r\n defaultAlphaTestRenderOrder?: RenderOrderFunction;\r\n defaultTransparentRenderOrder?: RenderOrderFunction;\r\n enableOverlayRender?: boolean;\r\n } = {}\r\n ) {\r\n // Requires a browser to work. Only init if we are in a browser\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n this._containerId = _containerId;\r\n this._init(scene, parentContainerId, enableOverlayRender, defaultOpaqueRenderOrder, defaultAlphaTestRenderOrder, defaultTransparentRenderOrder);\r\n }\r\n\r\n /**\r\n * Dispose of the HtmlMeshRenderer\r\n */\r\n public dispose() {\r\n if (this._renderObserver) {\r\n this._renderObserver.remove();\r\n this._renderObserver = null;\r\n }\r\n\r\n this._overlayElements?.container.remove();\r\n this._overlayElements = null;\r\n\r\n this._inSceneElements?.container.remove();\r\n this._inSceneElements = null;\r\n }\r\n\r\n protected _init(\r\n scene: Scene,\r\n parentContainerId: string | null,\r\n enableOverlayRender: boolean,\r\n defaultOpaqueRenderOrder: RenderOrderFunction,\r\n defaultAlphaTestRenderOrder: RenderOrderFunction,\r\n defaultTransparentRenderOrder: RenderOrderFunction\r\n ): void {\r\n // Requires a browser to work. Only init if we are in a browser\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n\r\n // Create the DOM containers\r\n let parentContainer = parentContainerId ? document.getElementById(parentContainerId) : document.body;\r\n\r\n if (!parentContainer) {\r\n parentContainer = document.body;\r\n }\r\n\r\n // if the container already exists, then remove it\r\n const inSceneContainerId = `${this._containerId}_in_scene`;\r\n this._inSceneElements = this._createRenderLayerElements(inSceneContainerId);\r\n\r\n parentContainer.insertBefore(this._inSceneElements.container, parentContainer.firstChild);\r\n\r\n if (enableOverlayRender) {\r\n const overlayContainerId = `${this._containerId}_overlay`;\r\n this._overlayElements = this._createRenderLayerElements(overlayContainerId);\r\n const zIndex = +(scene.getEngine().getRenderingCanvas()!.style.zIndex ?? \"0\") + 1;\r\n this._overlayElements.container.style.zIndex = `${zIndex}`;\r\n this._overlayElements.container.style.pointerEvents = \"none\";\r\n parentContainer.insertBefore(this._overlayElements.container, parentContainer.firstChild);\r\n }\r\n this._engine = scene.getEngine();\r\n const clientRect = this._engine.getRenderingCanvasClientRect();\r\n if (!clientRect) {\r\n throw new Error(\"Failed to get client rect for rendering canvas\");\r\n }\r\n\r\n // Set the size and resize behavior\r\n this._setSize(clientRect.width, clientRect.height);\r\n\r\n this._engine.onResizeObservable.add(() => {\r\n const clientRect = this._engine.getRenderingCanvasClientRect();\r\n if (clientRect) {\r\n this._setSize(clientRect.width, clientRect.height);\r\n }\r\n });\r\n\r\n let projectionObs: Observer<Camera>;\r\n let matrixObs: Observer<Camera>;\r\n\r\n const observeCamera = () => {\r\n const camera = scene.activeCamera;\r\n if (camera) {\r\n projectionObs = camera.onProjectionMatrixChangedObservable.add(() => {\r\n this._onCameraMatrixChanged(camera);\r\n });\r\n matrixObs = camera.onViewMatrixChangedObservable.add(() => {\r\n this._onCameraMatrixChanged(camera);\r\n });\r\n }\r\n };\r\n\r\n observeCamera();\r\n\r\n scene.onActiveCameraChanged.add(() => {\r\n if (projectionObs) {\r\n scene.activeCamera?.onProjectionMatrixChangedObservable.remove(projectionObs);\r\n }\r\n if (matrixObs) {\r\n scene.activeCamera?.onViewMatrixChangedObservable.remove(matrixObs);\r\n }\r\n observeCamera();\r\n });\r\n\r\n // We need to make sure that HtmlMeshes are rendered before all other meshes\r\n // so that they don't appear in front of meshes that are actually in front of them\r\n // Updating the render order isn't ideal, but it is the only way to acheive this\r\n // The implication is that an app using the HtmlMeshRendered must set the scene render order\r\n // via the HtmlMeshRendered constructor\r\n const opaqueRenderOrder = RenderOrderFunc(defaultOpaqueRenderOrder);\r\n const alphaTestRenderOrder = RenderOrderFunc(defaultAlphaTestRenderOrder);\r\n const transparentRenderOrder = RenderOrderFunc(defaultTransparentRenderOrder);\r\n scene.setRenderingOrder(0, opaqueRenderOrder, alphaTestRenderOrder, transparentRenderOrder);\r\n\r\n this._renderObserver = scene.onBeforeRenderObservable.add(() => {\r\n this._render(scene, scene.activeCamera as Camera);\r\n });\r\n }\r\n\r\n private _createRenderLayerElements(containerId: string): RenderLayerElements {\r\n const existingContainer = document.getElementById(containerId);\r\n if (existingContainer) {\r\n existingContainer.remove();\r\n }\r\n const container = document.createElement(\"div\");\r\n container.id = containerId;\r\n container.style.position = \"absolute\";\r\n container.style.width = \"100%\";\r\n container.style.height = \"100%\";\r\n container.style.zIndex = \"-1\";\r\n\r\n const domElement = document.createElement(\"div\");\r\n domElement.style.overflow = \"hidden\";\r\n\r\n const cameraElement = document.createElement(\"div\");\r\n\r\n cameraElement.style.webkitTransformStyle = \"preserve-3d\";\r\n cameraElement.style.transformStyle = \"preserve-3d\";\r\n\r\n cameraElement.style.pointerEvents = \"none\";\r\n\r\n domElement.appendChild(cameraElement);\r\n container.appendChild(domElement);\r\n return {\r\n container,\r\n domElement,\r\n cameraElement,\r\n };\r\n }\r\n\r\n protected _getSize(): { width: number; height: number } {\r\n return {\r\n width: this._width,\r\n height: this._height,\r\n };\r\n }\r\n\r\n protected _setSize(width: number, height: number): void {\r\n this._width = width;\r\n this._height = height;\r\n this._heightHalf = this._height / 2;\r\n\r\n if (!this._inSceneElements || !this._overlayElements) {\r\n return;\r\n }\r\n\r\n const domElements = [this._inSceneElements.domElement, this._overlayElements.domElement, this._inSceneElements.cameraElement, this._overlayElements.cameraElement];\r\n for (const dom of domElements) {\r\n if (dom) {\r\n dom.style.width = `${width}px`;\r\n dom.style.height = `${height}px`;\r\n }\r\n }\r\n }\r\n\r\n // prettier-ignore\r\n protected _getCameraCssMatrix(matrix: Matrix): string {\r\n const elements = matrix.m;\r\n return `matrix3d(${\r\n this._epsilon( elements[0] )\r\n },${\r\n this._epsilon( - elements[1] )\r\n },${\r\n this._epsilon( elements[2] )\r\n },${\r\n this._epsilon( elements[3] )\r\n },${\r\n this._epsilon( elements[4] )\r\n },${\r\n this._epsilon( - elements[5] )\r\n },${\r\n this._epsilon( elements[6] )\r\n },${\r\n this._epsilon( elements[7] )\r\n },${\r\n this._epsilon( elements[8] )\r\n },${\r\n this._epsilon( - elements[9] )\r\n },${\r\n this._epsilon( elements[10] )\r\n },${\r\n this._epsilon( elements[11] )\r\n },${\r\n this._epsilon( elements[12] )\r\n },${\r\n this._epsilon( - elements[13] )\r\n },${\r\n this._epsilon( elements[14] )\r\n },${\r\n this._epsilon( elements[15] )\r\n })`;\r\n }\r\n\r\n // Convert a Babylon world matrix to a CSS matrix\r\n // This also handles conversion from BJS left handed coords\r\n // to CSS right handed coords\r\n // prettier-ignore\r\n protected _getHtmlContentCssMatrix(matrix: Matrix, useRightHandedSystem: boolean): string {\r\n const elements = matrix.m;\r\n // In a right handed coordinate system, the elements 11 to 14 have to change their direction\r\n const direction = useRightHandedSystem ? -1 : 1;\r\n const matrix3d = `matrix3d(${\r\n this._epsilon( elements[0] )\r\n },${\r\n this._epsilon( elements[1] )\r\n },${\r\n this._epsilon( elements[2] * -direction )\r\n },${\r\n this._epsilon( elements[3] )\r\n },${\r\n this._epsilon( - elements[4] )\r\n },${\r\n this._epsilon( - elements[5] )\r\n },${\r\n this._epsilon( elements[6] * direction )\r\n },${\r\n this._epsilon( - elements[7] )\r\n },${\r\n this._epsilon( elements[8] * -direction )\r\n },${\r\n this._epsilon( elements[9] * -direction )\r\n },${\r\n this._epsilon( elements[10] )\r\n },${\r\n this._epsilon( elements[11] * direction )\r\n },${\r\n this._epsilon( elements[12] * direction )\r\n },${\r\n this._epsilon( elements[13] * direction )\r\n },${\r\n this._epsilon( elements[14] * direction )\r\n },${\r\n this._epsilon( elements[15] )\r\n })`;\r\n return matrix3d;\r\n }\r\n\r\n protected _getTransformationMatrix(htmlMesh: HtmlMesh, useRightHandedSystem: boolean): Matrix {\r\n // Get the camera world matrix\r\n // Make sure the camera world matrix is up to date\r\n if (!this._cameraWorldMatrix) {\r\n this._cameraWorldMatrix = htmlMesh.getScene().activeCamera?.getWorldMatrix();\r\n }\r\n if (!this._cameraWorldMatrix) {\r\n return Matrix.Identity();\r\n }\r\n\r\n const objectWorldMatrix = htmlMesh.getWorldMatrix();\r\n\r\n // Scale the object matrix by the base scale factor for the mesh\r\n // which is the ratio of the mesh width/height to the renderer\r\n // width/height divided by the babylon units to pixels ratio\r\n let widthScaleFactor = 1;\r\n let heightScaleFactor = 1;\r\n if (htmlMesh.sourceWidth && htmlMesh.sourceHeight) {\r\n widthScaleFactor = htmlMesh.width! / (htmlMesh.sourceWidth / BabylonUnitsToPixels);\r\n heightScaleFactor = htmlMesh.height! / (htmlMesh.sourceHeight / BabylonUnitsToPixels);\r\n }\r\n\r\n // Apply the scale to the object's world matrix. Note we aren't scaling\r\n // the object, just getting a matrix as though it were scaled, so we can\r\n // scale the content\r\n const scaleTransform = this._temp.scaleTransform;\r\n const rotationTransform = this._temp.rotationTransform;\r\n const positionTransform = this._temp.positionTransform;\r\n const scaledAndTranslatedObjectMatrix = this._temp.objectMatrix;\r\n\r\n objectWorldMatrix.decompose(scaleTransform, rotationTransform, positionTransform);\r\n scaleTransform.x *= widthScaleFactor;\r\n scaleTransform.y *= heightScaleFactor;\r\n\r\n Matrix.ComposeToRef(scaleTransform, rotationTransform, positionTransform, scaledAndTranslatedObjectMatrix);\r\n\r\n // Adjust direction of 12 and 13 of the transformation matrix based on the handedness of the system\r\n const direction = useRightHandedSystem ? -1 : 1;\r\n // Adjust translation values to be from camera vs world origin\r\n // Note that we are also adjusting these values to be pixels vs Babylon units\r\n const position = htmlMesh.getAbsolutePosition();\r\n scaledAndTranslatedObjectMatrix.setRowFromFloats(\r\n 3,\r\n (-this._cameraWorldMatrix.m[12] + position.x) * BabylonUnitsToPixels * direction,\r\n (-this._cameraWorldMatrix.m[13] + position.y) * BabylonUnitsToPixels * direction,\r\n (this._cameraWorldMatrix.m[14] - position.z) * BabylonUnitsToPixels,\r\n this._cameraWorldMatrix.m[15] * HtmlMeshRenderer.PROJECTION_SCALE_FACTOR * BabylonUnitsToPixels\r\n );\r\n\r\n // Adjust other values to be pixels vs Babylon units\r\n scaledAndTranslatedObjectMatrix.multiplyAtIndex(3, BabylonUnitsToPixels);\r\n scaledAndTranslatedObjectMatrix.multiplyAtIndex(7, BabylonUnitsToPixels);\r\n scaledAndTranslatedObjectMatrix.multiplyAtIndex(11, BabylonUnitsToPixels);\r\n\r\n return scaledAndTranslatedObjectMatrix;\r\n }\r\n\r\n protected _renderHtmlMesh(htmlMesh: HtmlMesh, useRightHandedSystem: boolean) {\r\n if (!htmlMesh.element || !htmlMesh.element.firstElementChild) {\r\n // nothing to render, so bail\r\n return;\r\n }\r\n\r\n // We need to ensure html mesh data is initialized before\r\n // computing the base scale factor\r\n let htmlMeshData = this._cache.htmlMeshData.get(htmlMesh);\r\n if (!htmlMeshData) {\r\n htmlMeshData = { style: \"\" };\r\n this._cache.htmlMeshData.set(htmlMesh, htmlMeshData);\r\n }\r\n\r\n const cameraElement = htmlMesh._isCanvasOverlay ? this._overlayElements?.cameraElement : this._inSceneElements?.cameraElement;\r\n\r\n if (htmlMesh.element.parentNode !== cameraElement) {\r\n cameraElement!.appendChild(htmlMesh.element);\r\n }\r\n\r\n // If the htmlMesh content has changed, update the base scale factor\r\n if (htmlMesh.requiresUpdate) {\r\n this._updateBaseScaleFactor(htmlMesh);\r\n }\r\n\r\n // Get the transformation matrix for the html mesh\r\n const scaledAndTranslatedObjectMatrix = this._getTransformationMatrix(htmlMesh, useRightHandedSystem);\r\n\r\n let style = `translate(-50%, -50%) ${this._getHtmlContentCssMatrix(scaledAndTranslatedObjectMatrix, useRightHandedSystem)}`;\r\n // In a right handed system, screens are on the wrong side of the mesh, so we have to rotate by Math.PI which results in the matrix3d seen below\r\n // Also in RH + billboard mode, we cancel the handedness so we do not need to scale on x\r\n style += `${useRightHandedSystem ? `matrix3d(${htmlMesh.billboardMode !== TransformNode.BILLBOARDMODE_NONE ? 1 : -1}, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1)` : \"\"}`;\r\n\r\n if (htmlMeshData.style !== style) {\r\n htmlMesh.element.style.webkitTransform = style;\r\n htmlMesh.element.style.transform = style;\r\n }\r\n\r\n htmlMesh._markAsUpdated();\r\n }\r\n\r\n protected _render(scene: Scene, camera: Camera) {\r\n let needsUpdate = false;\r\n\r\n const useRightHandedSystem = scene.useRightHandedSystem;\r\n\r\n // Update the container position and size if necessary\r\n this._updateContainerPositionIfNeeded();\r\n\r\n // Check for a camera change\r\n if (this._cameraMatrixUpdated) {\r\n this._cameraMatrixUpdated = false;\r\n needsUpdate = true;\r\n }\r\n\r\n // If the camera position has changed, then we also need to update\r\n if (\r\n camera.position.x !== this._cache.cameraData.position.x ||\r\n camera.position.y !== this._cache.cameraData.position.y ||\r\n camera.position.z !== this._cache.cameraData.position.z\r\n ) {\r\n this._cache.cameraData.position.copyFrom(camera.position);\r\n needsUpdate = true;\r\n }\r\n\r\n // Check for a dpr change\r\n if (window.devicePixelRatio !== this._lastDevicePixelRatio) {\r\n this._lastDevicePixelRatio = window.devicePixelRatio;\r\n Logger.Log(\"In render - dpr changed: \", this._lastDevicePixelRatio);\r\n needsUpdate = true;\r\n }\r\n\r\n // Check if any meshes need to be updated\r\n const meshesNeedingUpdate = scene.meshes.filter((mesh) => (mesh as any)[\"isHtmlMesh\"] && (needsUpdate || (mesh as HtmlMesh).requiresUpdate));\r\n needsUpdate = needsUpdate || meshesNeedingUpdate.length > 0;\r\n\r\n if (!needsUpdate) {\r\n return;\r\n }\r\n\r\n // Get a projection matrix for the camera\r\n const projectionMatrix = camera.getProjectionMatrix();\r\n const fov = projectionMatrix.m[5] * this._heightHalf;\r\n\r\n if (this._cache.cameraData.fov !== fov) {\r\n const source = [this._overlayElements?.domElement, this._inSceneElements?.domElement];\r\n if (camera.mode == Camera.PERSPECTIVE_CAMERA) {\r\n for (const el of source) {\r\n if (el) {\r\n el.style.webkitPerspective = fov + \"px\";\r\n el.style.perspective = fov + \"px\";\r\n }\r\n }\r\n } else {\r\n for (const el of source) {\r\n if (el) {\r\n el.style.webkitPerspective = \"\";\r\n el.style.perspective = \"\";\r\n }\r\n }\r\n }\r\n this._cache.cameraData.fov = fov;\r\n }\r\n\r\n // Get the CSS matrix for the camera (which will include any camera rotation)\r\n if (camera.parent === null) {\r\n camera.computeWorldMatrix();\r\n }\r\n\r\n const cameraMatrixWorld = this._temp.cameraWorldMatrix;\r\n cameraMatrixWorld.copyFrom(camera.getWorldMatrix());\r\n const cameraRotationMatrix = this._temp.cameraRotationMatrix;\r\n cameraMatrixWorld.getRotationMatrix().transposeToRef(cameraRotationMatrix);\r\n\r\n const cameraMatrixWorldAsArray = this._temp.cameraWorldMatrixAsArray;\r\n cameraMatrixWorld.copyToArray(cameraMatrixWorldAsArray);\r\n\r\n // For a few values, we have to adjust the direction based on the handedness of the system\r\n const direction = useRightHandedSystem ? 1 : -1;\r\n\r\n cameraMatrixWorldAsArray[1] = cameraRotationMatrix.m[1];\r\n cameraMatrixWorldAsArray[2] = cameraRotationMatrix.m[2] * direction;\r\n cameraMatrixWorldAsArray[4] = cameraRotationMatrix.m[4] * direction;\r\n cameraMatrixWorldAsArray[6] = cameraRotationMatrix.m[6] * direction;\r\n cameraMatrixWorldAsArray[8] = cameraRotationMatrix.m[8] * direction;\r\n cameraMatrixWorldAsArray[9] = cameraRotationMatrix.m[9] * direction;\r\n\r\n Matrix.FromArrayToRef(cameraMatrixWorldAsArray, 0, cameraMatrixWorld);\r\n\r\n const cameraCSSMatrix = this._getCameraCssMatrix(cameraMatrixWorld);\r\n const style = cameraCSSMatrix;\r\n\r\n if (this._cache.cameraData.style !== style) {\r\n const source = [this._inSceneElements?.cameraElement, this._overlayElements?.cameraElement];\r\n for (const el of source) {\r\n if (el) {\r\n el.style.webkitTransform = style;\r\n el.style.transform = style;\r\n }\r\n }\r\n this._cache.cameraData.style = style;\r\n }\r\n\r\n // _Render objects if necessary\r\n for (const mesh of meshesNeedingUpdate) {\r\n this._renderHtmlMesh(mesh as HtmlMesh, useRightHandedSystem);\r\n }\r\n }\r\n\r\n protected _updateBaseScaleFactor(htmlMesh: HtmlMesh) {\r\n // Get screen width and height\r\n let screenWidth = this._width;\r\n let screenHeight = this._height;\r\n\r\n // Calculate aspect ratios\r\n const htmlMeshAspectRatio = (htmlMesh.width || 1) / (htmlMesh.height || 1);\r\n const screenAspectRatio = screenWidth / screenHeight;\r\n\r\n // Adjust screen dimensions based on aspect ratios\r\n if (htmlMeshAspectRatio > screenAspectRatio) {\r\n // If the HTML mesh is wider relative to its height than the screen, adjust the screen width\r\n screenWidth = screenHeight * htmlMeshAspectRatio;\r\n } else {\r\n // If the HTML mesh is taller relative to its width than the screen, adjust the screen height\r\n screenHeight = screenWidth / htmlMeshAspectRatio;\r\n }\r\n\r\n // Set content to fill screen so we get max resolution when it is shrunk to fit the mesh\r\n htmlMesh.setContentSizePx(screenWidth, screenHeight);\r\n }\r\n\r\n protected _updateContainerPositionIfNeeded() {\r\n // Determine if the canvas has moved on the screen\r\n const canvasRect = this._engine.getRenderingCanvasClientRect();\r\n\r\n // canvas rect may be null if layout not complete\r\n if (!canvasRect) {\r\n Logger.Warn(PositionUpdateFailMessage);\r\n return;\r\n }\r\n const scrollTop = window.scrollY;\r\n const scrollLeft = window.scrollX;\r\n const canvasDocumentTop = canvasRect.top + scrollTop;\r\n const canvasDocumentLeft = canvasRect.left + scrollLeft;\r\n\r\n if (this._previousCanvasDocumentPosition.top !== canvasDocumentTop || this._previousCanvasDocumentPosition.left !== canvasDocumentLeft) {\r\n this._previousCanvasDocumentPosition.top = canvasDocumentTop;\r\n this._previousCanvasDocumentPosition.left = canvasDocumentLeft;\r\n\r\n const source = [this._inSceneElements?.container, this._overlayElements?.container];\r\n for (const container of source) {\r\n if (!container) {\r\n continue;\r\n }\r\n // set the top and left of the css container to match the canvas\r\n const containerParent = container.offsetParent as HTMLElement;\r\n const parentRect = containerParent.getBoundingClientRect();\r\n const parentDocumentTop = parentRect.top + scrollTop;\r\n const parentDocumentLeft = parentRect.left + scrollLeft;\r\n\r\n const ancestorMarginsAndPadding = this._getAncestorMarginsAndPadding(containerParent);\r\n\r\n // Add the body margin\r\n const bodyStyle = window.getComputedStyle(document.body);\r\n const bodyMarginTop = parseInt(bodyStyle.marginTop, 10);\r\n const bodyMarginLeft = parseInt(bodyStyle.marginLeft, 10);\r\n\r\n container.style.top = `${canvasDocumentTop - parentDocumentTop - ancestorMarginsAndPadding.marginTop + ancestorMarginsAndPadding.paddingTop + bodyMarginTop}px`;\r\n container.style.left = `${\r\n canvasDocumentLeft - parentDocumentLeft - ancestorMarginsAndPadding.marginLeft + ancestorMarginsAndPadding.paddingLeft + bodyMarginLeft\r\n }px`;\r\n }\r\n }\r\n }\r\n\r\n protected _onCameraMatrixChanged = (camera: Camera) => {\r\n this._cameraWorldMatrix = camera.getWorldMatrix();\r\n this._cameraMatrixUpdated = true;\r\n };\r\n\r\n private _epsilon(value: number) {\r\n return Math.abs(value) < 1e-10 ? 0 : value;\r\n }\r\n\r\n // Get total margins and padding for an element, excluding the body and document margins\r\n private _getAncestorMarginsAndPadding(element: HTMLElement) {\r\n let marginTop = 0;\r\n let marginLeft = 0;\r\n let paddingTop = 0;\r\n let paddingLeft = 0;\r\n\r\n while (element && element !== document.body && element !== document.documentElement) {\r\n const style = window.getComputedStyle(element);\r\n marginTop += parseInt(style.marginTop, 10);\r\n marginLeft += parseInt(style.marginLeft, 10);\r\n paddingTop += parseInt(style.paddingTop, 10);\r\n paddingLeft += parseInt(style.paddingLeft, 10);\r\n element = element.offsetParent as HTMLElement;\r\n }\r\n\r\n return { marginTop, marginLeft, paddingTop, paddingLeft };\r\n }\r\n}\r\n","import { Tools } from \"core/Misc/tools\";\r\n\r\n// A capture management system to ensure that the correct object has the pointer\r\n// events by eliminating race conditions that can cause the pointer events to be\r\n// released by a different object after they are captured leaving no object\r\n// as the owner. It does this by queueing requests and only allowing\r\n// capture when the current capture owner releases pointer events.\r\n\r\ntype CaptureReleaseCallback = () => void;\r\n\r\ntype CaptureReleaseCallbacks = {\r\n capture: CaptureReleaseCallback;\r\n release: CaptureReleaseCallback;\r\n};\r\n\r\nlet CaptureRequestQueue: string[] = [];\r\n\r\n// Key is request id, value is object with capture and release callbacks\r\nconst PendingRequestCallbacks: Map<string, CaptureReleaseCallbacks> = new Map();\r\n\r\n// Keep track of release requests with no matching capture request\r\n// in case the release request arrived before the capture to avoid\r\n// the capture request never getting released.\r\nlet UnmatchedReleaseRequests: string[] = [];\r\n\r\nlet CurrentOwner: string | null = null; // Called on first capture or release request\r\n\r\n/**\r\n * Get the id of the object currently capturing pointer events\r\n * @returns The id of the object currently capturing pointer events\r\n * or null if no object is capturing pointer events\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const getCapturingId = () => {\r\n return CurrentOwner;\r\n};\r\n\r\n/**\r\n * Request that the object with the given id capture pointer events. If there is no current\r\n * owner, then the request is granted immediately. If there is a current owner, then the request\r\n * is queued until the current owner releases pointer events.\r\n * @param requestId An id to identify the request. This id will be used to match the capture\r\n * request with the release request.\r\n * @param captureCallback The callback to call when the request is granted and the object is capturing\r\n * @param releaseCallback The callback to call when the object is no longer capturing pointer events\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const requestCapture = (requestId: string, captureCallback: CaptureReleaseCallback, releaseCallback: CaptureReleaseCallback) => {\r\n DebugLog(`In pointerEventsCapture.requestCapture - Pointer events capture requested for ${requestId}`);\r\n\r\n // If there is a release for this request, then ignore the request\r\n if (RemoveUnmatchedRequest(requestId)) {\r\n DebugLog(`In pointerEventsCapture.requestCapture - Capture request matched previous release request ${requestId}. Cancelling capture request`);\r\n return;\r\n } else if (requestId !== CurrentOwner) {\r\n // if the request is not already in the queue, add it to the queue\r\n EnqueueCaptureRequest(requestId, captureCallback, releaseCallback);\r\n }\r\n\r\n if (!CurrentOwner) {\r\n // If there is no current owner, go ahead and grant the request\r\n TransferPointerEventsOwnership();\r\n }\r\n // If the request id is the current owner, do nothing\r\n};\r\n\r\n/**\r\n * Release pointer events from the object with the given id. If the object is the current owner\r\n * then pointer events are released immediately. If the object is not the current owner, then the\r\n * associated capture request is removed from the queue. If there is no matching capture request\r\n * in the queue, then the release request is added to a list of unmatched release requests and will\r\n * negate the next capture request with the same id. This is to guard against the possibility that\r\n * the release request arrived before the capture request.\r\n * @param requestId The id which should match the id of the capture request\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const requestRelease = (requestId: string | null) => {\r\n DebugLog(`In pointerEventsCapture.requestRelease - Pointer events release requested for ${requestId}`);\r\n\r\n // if the requestId is the current capture holder release it\r\n if (!requestId || requestId === CurrentOwner) {\r\n TransferPointerEventsOwnership();\r\n } else if (CancelRequest(requestId)) {\r\n // if the request is in the queue, but not the current capture holder, remove it and it's callbacks\r\n PendingRequestCallbacks.delete(requestId);\r\n } else {\r\n DebugLog(`In pointerEventsCapture.requestRelease - Received release request ${requestId} but no matching capture request was received`);\r\n // request was not current and not in queue, likely because we received a release\r\n // request before the capture. Add it to the unmatched list to guard against this possibility\r\n if (!UnmatchedReleaseRequests.includes(requestId)) {\r\n UnmatchedReleaseRequests.push(requestId);\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Release pointer events from the current owner\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const releaseCurrent = () => {\r\n requestRelease(CurrentOwner);\r\n};\r\n\r\nconst EnqueueCaptureRequest = (requestId: string, capture: CaptureReleaseCallback, release: CaptureReleaseCallback) => {\r\n DebugLog(`In pointerEventsCapture.enqueueCaptureRequest - Enqueueing capture request for ${requestId}`);\r\n if (!CaptureRequestQueue.includes(requestId)) {\r\n CaptureRequestQueue.push(requestId);\r\n PendingRequestCallbacks.set(requestId, { capture, release });\r\n }\r\n};\r\n\r\n// Removes the request from the queue if it exists. Returns true\r\n// if the request was found and removed, otherwise false\r\nconst CancelRequest = (requestId: string | null) => {\r\n let removed = false;\r\n CaptureRequestQueue = CaptureRequestQueue.filter((id) => {\r\n if (id !== requestId) {\r\n return true;\r\n } else {\r\n removed = true;\r\n DebugLog(`In pointerEventsCapture.cancelRequest - Canceling pointer events capture request ${requestId}`);\r\n return false;\r\n }\r\n });\r\n return removed;\r\n};\r\n\r\nconst RemoveUnmatchedRequest = (requestId: string) => {\r\n let removed = false;\r\n UnmatchedReleaseRequests = UnmatchedReleaseRequests.filter((id) => {\r\n if (id !== requestId) {\r\n return true;\r\n } else {\r\n removed = true;\r\n return false;\r\n }\r\n });\r\n return removed;\r\n};\r\n\r\nconst TransferPointerEventsOwnership = () => {\r\n const newOwnerId = NextCaptureRequest();\r\n DebugLog(`In pointerEventsCapture.transferPointerEventsOwnership - Transferrring pointer events from ${CurrentOwner} to ${newOwnerId}`);\r\n // Release the current owner\r\n DoRelease();\r\n if (newOwnerId) {\r\n DoCapture(newOwnerId);\r\n }\r\n};\r\n\r\nconst DoRelease = () => {\r\n DebugLog(`In pointerEventsCapture.doRelease - Releasing pointer events from ${CurrentOwner}`);\r\n if (CurrentOwner) {\r\n // call the release callback\r\n PendingRequestCallbacks.get(CurrentOwner)?.release();\r\n // And remove the callbacks\r\n PendingRequestCallbacks.delete(CurrentOwner);\r\n CurrentOwner = null;\r\n }\r\n};\r\n\r\nconst DoCapture = (newOwnerId: string) => {\r\n if (newOwnerId) {\r\n // call the capture callback\r\n PendingRequestCallbacks.get(newOwnerId)?.capture();\r\n }\r\n CurrentOwner = newOwnerId;\r\n DebugLog(`In pointerEventsCapture.doCapture - Pointer events now captured by ${newOwnerId}`);\r\n};\r\n\r\nconst NextCaptureRequest = () => {\r\n return CaptureRequestQueue.length > 0 ? CaptureRequestQueue.shift() : null;\r\n};\r\n\r\n// #region Debugging support\r\ndeclare global {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n interface Window {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n \"pointer-events-capture-debug\": boolean | null;\r\n }\r\n}\r\n\r\nconst DebugLog = (message: string) => {\r\n // If we are runnning in a test runner (in node, so window is not defined)\r\n // or if the debug flag is set, then log the message\r\n if (typeof window === \"undefined\" || window[\"pointer-events-capture-debug\"]) {\r\n Tools.Log(\r\n `${performance.now()} - game.scene.pointerEvents - ${message}\\ncurrentOwner: ${CurrentOwner}\\nqueue: ${CaptureRequestQueue}\\nunmatched: ${UnmatchedReleaseRequests}`\r\n );\r\n }\r\n};\r\n// #endregion Debugging support\r\n","import type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport type { Behavior } from \"core/Behaviors/behavior\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { requestCapture, requestRelease, releaseCurrent, getCapturingId } from \"./pointerEventsCapture\";\r\n\r\n// Module level variable for holding the current scene\r\nlet LocalScene: Scene | null = null;\r\n\r\n// Module level variable to hold the count of behavior instances that are currently capturing pointer events\r\n// on entry. This is used to determine if we need to start or stop observing pointer movement.\r\nlet CaptureOnEnterCount = 0;\r\n\r\n// Map used to store instance of the PointerEventsCaptureBehavior for a mesh\r\n// We do this because this gets checked on pointer move and we don't want to\r\n// use getBehaviorByName() because that is a linear search\r\nconst MeshToBehaviorMap = new WeakMap<AbstractMesh, PointerEventsCaptureBehavior>();\r\n\r\nconst StartCaptureOnEnter = (scene: Scene) => {\r\n // If we are not in a browser, do nothing\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n if (CaptureOnEnterCount === 0) {\r\n document.addEventListener(\"pointermove\", OnPointerMove);\r\n document.addEventListener(\"touchstart\", OnPointerMove);\r\n LocalScene = LocalScene ?? scene;\r\n Logger.Log(\"PointerEventsCaptureBehavior: Starting observation of pointer move events.\");\r\n LocalScene.onDisposeObservable.add(DoStopCaptureOnEnter);\r\n }\r\n CaptureOnEnterCount++;\r\n};\r\n\r\nconst DoStopCaptureOnEnter = () => {\r\n document.removeEventListener(\"pointermove\", OnPointerMove);\r\n document.removeEventListener(\"touchstart\", OnPointerMove);\r\n LocalScene = null;\r\n Logger.Log(\"PointerEventsCaptureBehavior: Stopping observation of pointer move events.\");\r\n CaptureOnEnterCount = 0;\r\n};\r\n\r\nconst StopCaptureOnEnter = () => {\r\n // If we are not in a browser, do nothing\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n\r\n // If we are not observing pointer movement, do nothing\r\n if (!LocalScene) {\r\n return;\r\n }\r\n\r\n CaptureOnEnterCount--;\r\n if (CaptureOnEnterCount <= 0) {\r\n DoStopCaptureOnEnter();\r\n }\r\n};\r\n\r\n// Module level function used to determine if an entered mesh should capture pointer events\r\nconst OnPointerMove = (evt: PointerEvent | TouchEvent) => {\r\n if (!LocalScene) {\r\n return;\r\n }\r\n\r\n const canvasRect = LocalScene.getEngine().getRenderingCanvasClientRect();\r\n if (!canvasRect) {\r\n return;\r\n }\r\n\r\n // Get the object that contains the client X and Y from either the pointer event or from the\r\n // TouchEvent touch\r\n const { clientX, clientY } = \"touches\" in evt ? evt.touches[0] : evt;\r\n\r\n // get the picked mesh, if any\r\n const pointerScreenX = clientX - canvasRect.left;\r\n const pointerScreenY = clientY - canvasRect.top;\r\n\r\n let pointerCaptureBehavior: PointerEventsCaptureBehavior | undefined;\r\n const pickResult = LocalScene.pick(pointerScreenX, pointerScreenY, (mesh) => {\r\n // If the mesh has an instance of PointerEventsCaptureBehavior attached to it,\r\n // and capture on pointer enter is true, then we want to pick it\r\n const pointerCaptureBehavior = MeshToBehaviorMap.get(mesh);\r\n return mesh.isEnabled() && typeof pointerCaptureBehavior !== \"undefined\" && pointerCaptureBehavior._captureOnPointerEnter;\r\n });\r\n\r\n let pickedMesh: AbstractMesh | null;\r\n if (pickResult.hit) {\r\n pickedMesh = pickResult.pickedMesh;\r\n } else {\r\n pickedMesh = null;\r\n }\r\n\r\n const capturingIdAsInt = parseInt(getCapturingId() || \"\");\r\n\r\n // if the picked mesh is the current capturing mesh, do nothing\r\n if (pickedMesh && pickedMesh.uniqueId === capturingIdAsInt) {\r\n return;\r\n }\r\n\r\n // If there is a capturing mesh and it is not the current picked mesh, or no\r\n // mesh is picked, release the capturing mesh\r\n if (capturingIdAsInt && (!pickedMesh || pickedMesh.uniqueId !== capturingIdAsInt)) {\r\n releaseCurrent();\r\n }\r\n\r\n // If there is a picked mesh and it is not the current capturing mesh, capture\r\n // the pointer events. Note that the current capturing mesh has already been\r\n // released above\r\n if (pickedMesh) {\r\n pointerCaptureBehavior = MeshToBehaviorMap.get(pickedMesh);\r\n pointerCaptureBehavior!.capturePointerEvents();\r\n }\r\n};\r\n\r\n/**\r\n * Behavior for any content that can capture pointer events, i.e. bypass the Babylon pointer event handling\r\n * and receive pointer events directly. It will register the capture triggers and negotiate the capture and\r\n * release of pointer events. Curerntly this applies only to HtmlMesh\r\n */\r\nexport class PointerEventsCaptureBehavior implements Behavior<AbstractMesh> {\r\n /** gets or sets behavior's name */\r\n public name = \"PointerEventsCaptureBehavior\";\r\n\r\n private _attachedMesh: AbstractMesh | null;\r\n /** @internal */\r\n public _captureOnPointerEnter: boolean;\r\n\r\n /**\r\n * Gets or sets the mesh that the behavior is attached to\r\n */\r\n public get attachedMesh() {\r\n return this._attachedMesh;\r\n }\r\n\r\n public set attachedMesh(value: AbstractMesh | null) {\r\n this._attachedMesh = value;\r\n }\r\n\r\n constructor(\r\n private _captureCallback: () => void,\r\n private _releaseCallback: () => void,\r\n { captureOnPointerEnter = true } = {}\r\n ) {\r\n this._attachedMesh = null;\r\n this._captureOnPointerEnter = captureOnPointerEnter;\r\n\r\n // Warn if we are not in a browser\r\n if (typeof document === \"undefined\") {\r\n Logger.Warn(`Creating an instance of PointerEventsCaptureBehavior outside of a browser. The behavior will not work.`);\r\n }\r\n }\r\n\r\n /**\r\n * Set if the behavior should capture pointer events when the pointer enters the mesh\r\n */\r\n public set captureOnPointerEnter(captureOnPointerEnter: boolean) {\r\n if (this._captureOnPointerEnter === captureOnPointerEnter) {\r\n return;\r\n }\r\n this._captureOnPointerEnter = captureOnPointerEnter;\r\n if (this._attachedMesh) {\r\n if (this._captureOnPointerEnter) {\r\n StartCaptureOnEnter(this._attachedMesh.getScene());\r\n } else {\r\n StopCaptureOnEnter();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Function called when the behavior needs to be initialized (before attaching it to a target)\r\n */\r\n public init() {}\r\n\r\n /**\r\n * Called when the behavior is attached to a target\r\n * @param mesh defines the target where the behavior is attached to\r\n */\r\n public attach(mesh: AbstractMesh) {\r\n // Add a reference to this behavior on the mesh. We do this so we can get a\r\n // reference to the behavior in the onPointerMove function without relying on\r\n // getBehaviorByName(), which does a linear search of the behaviors array.\r\n this.attachedMesh = mesh;\r\n MeshToBehaviorMap.set(mesh, this);\r\n if (this._captureOnPointerEnter) {\r\n StartCaptureOnEnter(mesh.getScene());\r\n }\r\n }\r\n\r\n /**\r\n * Called when the behavior is detached from its target\r\n */\r\n public detach() {\r\n if (!this.attachedMesh) {\r\n return;\r\n }\r\n // Remove the reference to this behavior from the mesh\r\n MeshToBehaviorMap.delete(this.attachedMesh);\r\n if (this._captureOnPointerEnter) {\r\n StopCaptureOnEnter();\r\n }\r\n this.attachedMesh = null;\r\n }\r\n\r\n /**\r\n * Dispose the behavior\r\n */\r\n public dispose() {\r\n this.detach();\r\n }\r\n\r\n // Release pointer events\r\n public releasePointerEvents() {\r\n if (!this.attachedMesh) {\r\n return;\r\n }\r\n requestRelease(this.attachedMesh.uniqueId.toString());\r\n }\r\n\r\n // Capture pointer events\r\n public capturePointerEvents() {\r\n if (!this.attachedMesh) {\r\n return;\r\n }\r\n requestCapture(this.attachedMesh.uniqueId.toString(), this._captureCallback, this._releaseCallback);\r\n }\r\n}\r\n","export type FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement;\r\n updateSize(sizingElement: HTMLElement, width: number, height: number): void;\r\n};\r\n\r\nconst FitStrategyContain: FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement {\r\n const sizingElement = document.createElement(\"div\");\r\n sizingElement.style.display = \"flex\";\r\n sizingElement.style.justifyContent = \"center\";\r\n sizingElement.style.alignItems = \"center\";\r\n const scalingElement = document.createElement(\"div\");\r\n scalingElement.style.visibility = \"hidden\";\r\n scalingElement.appendChild(element);\r\n sizingElement.appendChild(scalingElement);\r\n return sizingElement;\r\n },\r\n updateSize(sizingElement: HTMLElement, width: number, height: number) {\r\n const scalingElement = sizingElement.firstElementChild! as HTMLElement;\r\n sizingElement.style.width = `${width}px`;\r\n sizingElement.style.height = `${height}px`;\r\n\r\n const [childWidth, childHeight] = [scalingElement.offsetWidth, scalingElement.offsetHeight];\r\n const scale = Math.min(width / childWidth, height / childHeight);\r\n scalingElement.style.transform = `scale(${scale})`;\r\n scalingElement.style.visibility = \"visible\";\r\n },\r\n};\r\n\r\nconst FitStrategyCover: FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement {\r\n const sizingElement = document.createElement(\"div\");\r\n sizingElement.style.display = \"flex\";\r\n sizingElement.style.justifyContent = \"center\";\r\n sizingElement.style.alignItems = \"center\";\r\n sizingElement.style.overflow = \"hidden\";\r\n const scalingElement = document.createElement(\"div\");\r\n scalingElement.style.visibility = \"hidden\";\r\n scalingElement.appendChild(element);\r\n sizingElement.appendChild(scalingElement);\r\n return sizingElement;\r\n },\r\n updateSize(sizingElement: HTMLElement, width: number, height: number) {\r\n const scalingElement = sizingElement.firstElementChild! as HTMLElement;\r\n sizingElement.style.width = `${width}px`;\r\n sizingElement.style.height = `${height}px`;\r\n\r\n const [childWidth, childHeight] = [scalingElement.offsetWidth, scalingElement.offsetHeight];\r\n const scale = Math.max(width / childWidth, height / childHeight);\r\n scalingElement.style.transform = `scale(${scale})`;\r\n scalingElement.style.visibility = \"visible\";\r\n },\r\n};\r\n\r\nconst FitStrategyStretch: FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement {\r\n const sizingElement = document.createElement(\"div\");\r\n sizingElement.style.display = \"flex\";\r\n sizingElement.style.justifyContent = \"center\";\r\n sizingElement.style.alignItems = \"center\";\r\n const scalingElement = document.createElement(\"div\");\r\n scalingElement.style.visibility = \"hidden\";\r\n scalingElement.appendChild(element);\r\n sizingElement.appendChild(scalingElement);\r\n return sizingElement;\r\n },\r\n updateSize(sizingElement: HTMLElement, width: number, height: number) {\r\n const scalingElement = sizingElement.firstElementChild! as HTMLElement;\r\n sizingElement.style.width = `${width}px`;\r\n sizingElement.style.height = `${height}px`;\r\n\r\n const [childWidth, childHeight] = [scalingElement.offsetWidth, scalingElement.offsetHeight];\r\n scalingElement.style.transform = `scale(${width / childWidth}, ${height / childHeight})`;\r\n scalingElement.style.visibility = \"visible\";\r\n },\r\n};\r\n\r\nconst FitStrategyNone: FitStrategyType = {\r\n wrapElement(element: HTMLElement): HTMLElement {\r\n return element;\r\n },\r\n updateSize(sizingElement: HTMLElement, width: number, height: number) {\r\n if (sizingElement) {\r\n sizingElement.style.width = `${width}px`;\r\n sizingElement.style.height = `${height}px`;\r\n }\r\n },\r\n};\r\n\r\nexport const FitStrategy = {\r\n CONTAIN: FitStrategyContain,\r\n COVER: FitStrategyCover,\r\n STRETCH: FitStrategyStretch,\r\n NONE: FitStrategyNone,\r\n};\r\n","import { Mesh } from \"core/Meshes/mesh\";\r\nimport { CreatePlaneVertexData } from \"core/Meshes/Builders/planeBuilder\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport { Matrix } from \"core/Maths/math\";\r\nimport { PointerEventsCaptureBehavior } from \"./pointerEventsCaptureBehavior\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport type { FitStrategyType } from \"./fitStrategy\";\r\nimport { FitStrategy } from \"./fitStrategy\";\r\n\r\n/**\r\n * This class represents HTML content that we want to render as though it is part of the scene. The HTML content is actually\r\n * rendered below the canvas, but a depth mask is created by this class that writes to the depth buffer but does not\r\n * write to the color buffer, effectively punching a hole in the canvas. CSS transforms are used to scale, translate, and rotate\r\n * the HTML content so that it matches the camera and mesh orientation. The class supports interactions in editable and non-editable mode.\r\n * In non-editable mode (the default), events are passed to the HTML content when the pointer is over the mask (and not occluded by other meshes\r\n * in the scene).\r\n * @see https://playground.babylonjs.com/#HVHYJC#5\r\n * @see https://playground.babylonjs.com/#B17TC7#112\r\n */\r\nexport class HtmlMesh extends Mesh {\r\n /**\r\n * Helps identifying a html mesh from a regular mesh\r\n */\r\n public get isHtmlMesh() {\r\n return true;\r\n }\r\n\r\n // Override the super class's _isEnabled property so we can control when the mesh\r\n // is enabled. I.e., we don't want to render the mesh until there is content to show.\r\n private _enabled = false;\r\n\r\n // The mesh is ready when content has been set and the content size has been set\r\n // The former is done by the user, the latter is done by the renderer.\r\n private _ready = false;\r\n\r\n /**\r\n * @internal\r\n */\r\n public _isCanvasOverlay = false;\r\n\r\n private _requiresUpdate = true;\r\n\r\n private _element?: HTMLElement;\r\n private _width?: number;\r\n private _height?: number;\r\n\r\n private _inverseScaleMatrix: Matrix | null = null;\r\n\r\n private _captureOnPointerEnter: boolean = true;\r\n private _pointerEventCaptureBehavior: PointerEventsCaptureBehavior | null = null;\r\n\r\n private _sourceWidth: number | null = null;\r\n private _sourceHeight: number | null = null;\r\n\r\n /**\r\n * Return the source width of the content in pixels\r\n */\r\n public get sourceWidth() {\r\n return this._sourceWidth;\r\n }\r\n\r\n /**\r\n * Return the source height of the content in pixels\r\n */\r\n public get sourceHeight() {\r\n return this._sourceHeight;\r\n }\r\n\r\n private _worldMatrixUpdateObserver: any;\r\n\r\n private _fitStrategy: FitStrategyType = FitStrategy.NONE;\r\n\r\n /**\r\n * Contruct an instance of HtmlMesh\r\n * @param scene\r\n * @param id The id of the mesh. Will be used as the id of the HTML element as well.\r\n * @param options object with optional parameters\r\n */\r\n constructor(scene: Scene, id: string, { captureOnPointerEnter = true, isCanvasOverlay = false, fitStrategy = FitStrategy.NONE } = {}) {\r\n super(id, scene);\r\n\r\n // Requires a browser to work. Bail if we aren't running in a browser\r\n if (typeof document === \"undefined\") {\r\n Logger.Warn(`Creating an instance of an HtmlMesh with id ${id} outside of a browser. The mesh will not be visible.`);\r\n return;\r\n }\r\n\r\n this._fitStrategy = fitStrategy;\r\n this._isCanvasOverlay = isCanvasOverlay;\r\n this._createMask();\r\n this._element = this._createElement();\r\n\r\n // Set enabled by default, so this will show as soon as it's ready\r\n this.setEnabled(true);\r\n\r\n this._captureOnPointerEnter = captureOnPointerEnter;\r\n\r\n // Create a behavior to capture pointer events\r\n this._pointerEventCaptureBehavior = new PointerEventsCaptureBehavior(this.capturePointerEvents.bind(this), this.releasePointerEvents.bind(this), {\r\n captureOnPointerEnter: this._captureOnPointerEnter,\r\n });\r\n this.addBehavior(this._pointerEventCaptureBehavior);\r\n }\r\n\r\n /**\r\n * The width of the content in pixels\r\n */\r\n public get width() {\r\n return this._width;\r\n }\r\n\r\n /**\r\n * The height of the content in pixels\r\n */\r\n public get height() {\r\n return this._height;\r\n }\r\n\r\n /**\r\n * The HTML element that is being rendered as a mesh\r\n */\r\n public get element() {\r\n return this._element;\r\n }\r\n\r\n /**\r\n * True if the mesh has been moved, rotated, or scaled since the last time this\r\n * property was read. This property is reset to false after reading.\r\n */\r\n public get requiresUpdate() {\r\n return this._requiresUpdate;\r\n }\r\n\r\n /**\r\n * Enable capture for the pointer when entering the mesh area\r\n */\r\n public set captureOnPointerEnter(captureOnPointerEnter: boolean) {\r\n this._captureOnPointerEnter = captureOnPointerEnter;\r\n if (this._pointerEventCaptureBehavior) {\r\n this._pointerEventCaptureBehavior.captureOnPointerEnter = captureOnPointerEnter;\r\n }\r\n }\r\n\r\n /**\r\n * Disposes of the mesh and the HTML element\r\n */\r\n public override dispose() {\r\n super.dispose();\r\n this._element?.remove();\r\n this._element = undefined;\r\n if (this._pointerEventCaptureBehavior) {\r\n this._pointerEventCaptureBehavior.dispose();\r\n this._pointerEventCaptureBehavior = null;\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _markAsUpdated() {\r\n this._requiresUpdate = false;\r\n }\r\n\r\n /**\r\n * Sets the content of the element to the specified content adjusting the mesh scale to match and making it visible.\r\n * If the the specified content is undefined, then it will make the mesh invisible. In either case it will clear the\r\n * element content first.\r\n * @param element The element to render as a mesh\r\n * @param width The width of the mesh in Babylon units\r\n * @param height The height of the mesh in Babylon units\r\n */\r\n setContent(element: HTMLElement, width: number, height: number) {\r\n // If content is changed, we are no longer ready\r\n this._setAsReady(false);\r\n\r\n // Also invalidate the source width and height\r\n this._sourceWidth = null;\r\n this._sourceHeight = null;\r\n\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n this._width = width;\r\n this._height = height;\r\n this._requiresUpdate = true;\r\n\r\n this.scaling.setAll(1);\r\n\r\n if (element) {\r\n this._element.appendChild(this._fitStrategy.wrapElement(element));\r\n\r\n this._updateScaleIfNecessary();\r\n }\r\n\r\n if (this.sourceWidth && this.sourceHeight) {\r\n this._setAsReady(true);\r\n }\r\n }\r\n\r\n // Overides BABYLON.Mesh.setEnabled\r\n public override setEnabled(enabled: boolean) {\r\n // Capture requested enabled state\r\n this._enabled = enabled;\r\n\r\n // If disabling or enabling and we are ready\r\n if (!enabled || this._ready) {\r\n this._doSetEnabled(enabled);\r\n }\r\n }\r\n\r\n /**\r\n * Sets the content size in pixels\r\n * @param width width of the source\r\n * @param height height of the source\r\n */\r\n public setContentSizePx(width: number, height: number) {\r\n this._sourceWidth = width;\r\n this._sourceHeight = height;\r\n\r\n if (!this._element || !this._element.firstElementChild) {\r\n return;\r\n }\r\n\r\n this._fitStrategy.updateSize(this._element.firstElementChild as HTMLElement, width, height);\r\n\r\n this._updateScaleIfNecessary();\r\n\r\n if (this.width && this.height) {\r\n this._setAsReady(true);\r\n }\r\n }\r\n\r\n protected _setAsReady(ready: boolean) {\r\n this._ready = ready;\r\n if (ready) {\r\n this._doSetEnabled(this._enabled);\r\n } else {\r\n this._doSetEnabled(false);\r\n }\r\n }\r\n\r\n protected _doSetEnabled(enabled: boolean) {\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n //if enabled, then start listening for changes to the\r\n // scaling, rotation, and position. otherwise stop listening\r\n if (enabled && !this._worldMatrixUpdateObserver) {\r\n this._worldMatrixUpdateObserver = this.onAfterWorldMatrixUpdateObservable.add(() => {\r\n this._requiresUpdate = true;\r\n });\r\n } else if (!enabled) {\r\n this._worldMatrixUpdateObserver?.remove();\r\n this._worldMatrixUpdateObserver = null;\r\n }\r\n\r\n // If enabled, then revert the content element display\r\n // otherwise hide it\r\n this._element.style.display = enabled ? \"\" : \"none\";\r\n // Capture the content z index\r\n this._setElementzIndex(this.position.z * -10000);\r\n super.setEnabled(enabled);\r\n }\r\n\r\n protected _updateScaleIfNecessary() {\r\n // If we have setContent before, the content scale is baked into the mesh. If we don't reset the vertices to\r\n // the original size, then we will multiply the scale when we bake the scale below. By applying the inverse, we back out\r\n // the scaling that has been done so we are starting from the same point.\r\n // First reset the scale to 1\r\n this.scaling.setAll(1);\r\n // Then back out the original vertices changes to match the content scale\r\n if (this._inverseScaleMatrix) {\r\n this.bakeTransformIntoVertices(this._inverseScaleMatrix);\r\n // Clear out the matrix so it doesn't get applied again unless we scale\r\n this._inverseScaleMatrix = null;\r\n }\r\n\r\n // Set scale to match content. Note we can't just scale the mesh, because that will scale the content as well\r\n // What we need to do is compute a scale matrix and then bake that into the mesh vertices. This will leave the\r\n // mesh scale at 1, so our content will stay it's original width and height until we scale the mesh.\r\n const scaleX = this._width || 1;\r\n const scaleY = this._height || 1;\r\n const scaleMatrix = Matrix.Scaling(scaleX, scaleY, 1);\r\n this.bakeTransformIntoVertices(scaleMatrix);\r\n\r\n // Get an inverse of the scale matrix that we can use to back out the scale changes we have made so\r\n // we don't multiply the scale.\r\n this._inverseScaleMatrix = new Matrix();\r\n scaleMatrix.invertToRef(this._inverseScaleMatrix);\r\n }\r\n\r\n protected _createMask() {\r\n const vertexData = CreatePlaneVertexData({ width: 1, height: 1 });\r\n vertexData.applyToMesh(this);\r\n\r\n const scene = this.getScene();\r\n this.checkCollisions = true;\r\n\r\n const depthMask = new StandardMaterial(`${this.id}-mat`, scene);\r\n if (!this._isCanvasOverlay) {\r\n depthMask.backFaceCulling = false;\r\n depthMask.disableColorWrite = true;\r\n depthMask.disableLighting = true;\r\n }\r\n\r\n this.material = depthMask;\r\n\r\n // Optimization - Freeze material since it never needs to change\r\n this.material.freeze();\r\n }\r\n\r\n protected _setElementzIndex(zIndex: number) {\r\n if (this._element) {\r\n this._element.style.zIndex = `${zIndex}`;\r\n }\r\n }\r\n\r\n /**\r\n * Callback used by the PointerEventsCaptureBehavior to capture pointer events\r\n */\r\n capturePointerEvents() {\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n // Enable dom content to capture pointer events\r\n this._element.style.pointerEvents = \"auto\";\r\n\r\n // Supress events outside of the dom content\r\n document.getElementsByTagName(\"body\")[0].style.pointerEvents = \"none\";\r\n }\r\n\r\n /**\r\n * Callback used by the PointerEventsCaptureBehavior to release pointer events\r\n */\r\n releasePointerEvents() {\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n // Enable pointer events on canvas\r\n document.getElementsByTagName(\"body\")[0].style.pointerEvents = \"auto\";\r\n\r\n // Disable pointer events on dom content\r\n this._element.style.pointerEvents = \"none\";\r\n }\r\n\r\n protected _createElement() {\r\n // Requires a browser to work. Bail if we aren't running in a browser\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n const div = document.createElement(\"div\");\r\n div.id = this.id;\r\n div.style.backgroundColor = this._isCanvasOverlay ? \"transparent\" : \"#000\";\r\n div.style.zIndex = \"1\";\r\n div.style.position = \"absolute\";\r\n div.style.pointerEvents = \"none\";\r\n div.style.backfaceVisibility = \"hidden\";\r\n\r\n return div;\r\n }\r\n}\r\n","import { _LoadScriptModuleAsync } from \"core/Misc/tools.internals\";\nimport type { Nullable } from \"core/types\";\n\nimport type { RecastInjection } from \"../types\";\n\n/**\n * Gets the RecastInjection instance (reference to the recast-navigation-js library).\n * @returns The RecastInjection instance\n * @throws Error if Recast is not initialized\n */\nexport function GetRecast(): RecastInjection {\n if (!_Recast) {\n throw new Error(\"Recast is not initialized. Please call InitRecast first.\");\n }\n return _Recast;\n}\n\n/**\n * Sets the RecastInjection instance (reference to the recast-navigation-js library).\n * @param recast The RecastInjection instance to set\n */\nexport function SetRecast(recast: RecastInjection) {\n _Recast = recast;\n}\n\n/**\n * Reference to the recast-navigation-js library\n */\nlet _Recast: RecastInjection;\n\n/**\n * Promise to wait for the recast-navigation-js library to be ready\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet _InitPromise: Nullable<Promise<{ core: any; generators: any }>> = null;\n\n/**\n * Initialize the Manifold library\n * @param version defines the version of the library to use, default is \"0.43.0\"\n * @param options defines the options to use to initialize the library\n */\nexport async function InitRecast(\n version = \"0.43.0\",\n options?: {\n instance: RecastInjection;\n }\n) {\n const localOptions = {\n url: \"https://unpkg.com/@recast-navigation\",\n version,\n ...options,\n };\n\n if (_Recast) {\n return; // Already initialized\n }\n\n if (_InitPromise) {\n await _InitPromise;\n return;\n }\n\n if (localOptions.instance) {\n _Recast = localOptions.instance;\n } else {\n _InitPromise = ImportRecast(localOptions.url, localOptions.version);\n\n const result = await _InitPromise;\n // eslint-disable-next-line require-atomic-updates\n _Recast = { ...result.core, ...result.generators };\n\n await _Recast.init();\n }\n}\n\nasync function ImportRecast(baseUrl: string, version: string) {\n const importMap = {\n imports: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"@recast-navigation/core\": `${baseUrl}/core@${version}/dist/index.mjs`,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"@recast-navigation/wasm\": `${baseUrl}/wasm@${version}/dist/recast-navigation.wasm-compat.js`,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"@recast-navigation/generators\": `${baseUrl}/generators@${version}/dist/index.mjs`,\n },\n };\n\n const script = document.createElement(\"script\");\n script.type = \"importmap\";\n script.textContent = JSON.stringify(importMap);\n document.body.appendChild(script);\n\n const result = await _LoadScriptModuleAsync(\n `\n import * as CoreModule from '${baseUrl}/core@${version}/dist/index.mjs';\n import * as GeneratorsModule from '${baseUrl}/generators@${version}/dist/index.mjs';\n const returnedValue = {core: CoreModule, generators: GeneratorsModule};\n `\n );\n return result;\n}\n","/* eslint-disable jsdoc/require-jsdoc */\r\n\r\nimport type { IVector2Like } from \"core/Maths/math.like\";\r\nimport type { SdfTextLine } from \"./sdf/line\";\r\nimport type { SdfGlyph } from \"./sdf/glyph\";\r\n\r\nexport interface ISdfTextParagraphMetrics {\r\n /** @internal */\r\n readonly paragraph: string;\r\n /** @internal */\r\n readonly lines: SdfTextLine[];\r\n /** @internal */\r\n readonly width: number;\r\n /** @internal */\r\n readonly height: number;\r\n /** @internal */\r\n readonly glyphs: SdfGlyph[];\r\n}\r\n\r\n/** @internal */\r\nexport type ParagraphOptions = {\r\n maxWidth: number;\r\n lineHeight: number;\r\n letterSpacing: number;\r\n tabSize: number;\r\n whiteSpace: /* 'normal' | 'nowrap' | 'pre' | 'pre-wrap' | */ \"pre-line\" /* | 'break-spaces'*/;\r\n textAlign: \"left\" | \"right\" | \"center\" /* | 'justify'*/;\r\n translate: IVector2Like | undefined;\r\n customLayoutEngine?: (text: string, options: ParagraphOptions) => ISdfTextParagraphMetrics;\r\n};\r\n\r\n/** @internal */\r\nexport const DefaultParagraphOptions: ParagraphOptions = {\r\n maxWidth: Infinity,\r\n lineHeight: 1,\r\n letterSpacing: 1,\r\n tabSize: 4,\r\n whiteSpace: \"pre-line\",\r\n textAlign: \"center\",\r\n translate: { x: -0.5, y: -0.5 },\r\n};\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport type { FontAsset } from \"../fontAsset\";\r\nimport type { ISdfTextParagraphMetrics } from \"../paragraphOptions\";\r\nimport { DefaultParagraphOptions, type ParagraphOptions } from \"../paragraphOptions\";\r\nimport type { BMFontChar } from \"./bmFont\";\r\nimport type { SdfGlyph } from \"./glyph\";\r\nimport type { SdfTextLine } from \"./line\";\r\n\r\n/** @internal */\r\nexport class SdfTextParagraph {\r\n public readonly options: ParagraphOptions;\r\n\r\n get lineHeight() {\r\n return this.fontAsset._font.common.lineHeight * this.options.lineHeight;\r\n }\r\n\r\n readonly paragraph;\r\n readonly lines;\r\n readonly width;\r\n readonly height;\r\n readonly glyphs;\r\n\r\n constructor(\r\n public readonly text: string,\r\n public readonly fontAsset: FontAsset,\r\n options?: Partial<ParagraphOptions>\r\n ) {\r\n this.options = { ...DefaultParagraphOptions, ...options };\r\n\r\n const { paragraph, lines, glyphs, width, height } = this.options.customLayoutEngine ? this.options.customLayoutEngine(text, this.options) : this._computeMetrics(text);\r\n\r\n this.paragraph = paragraph;\r\n this.lines = lines;\r\n this.glyphs = glyphs;\r\n this.width = width;\r\n this.height = height;\r\n }\r\n\r\n private _computeMetrics(text: string): ISdfTextParagraphMetrics {\r\n const collapsed = this._collapse(text);\r\n const breaked = this._breakLines(collapsed);\r\n const trimmed = breaked.map((line) => line.trim());\r\n\r\n const lines: SdfTextLine[] = [];\r\n for (const line of trimmed) {\r\n lines.push(...this._wrap(line, lines.length));\r\n }\r\n\r\n const width = Math.max(...lines.map((line) => line.width));\r\n const height = this.lineHeight * lines.length;\r\n\r\n if (this.options.textAlign !== \"left\" || this.options.translate) {\r\n lines.forEach((line) => {\r\n const anchor = (() => {\r\n switch (this.options.textAlign) {\r\n case \"right\":\r\n return width - line.width;\r\n case \"center\":\r\n return (width - line.width) / 2;\r\n case \"left\":\r\n default:\r\n return 0;\r\n }\r\n })();\r\n\r\n const x = this.options.translate ? this.options.translate.x * width : 0;\r\n const y = this.options.translate ? this.options.translate.y * height : 0;\r\n for (const glyph of line.glyphs) {\r\n glyph.x += anchor;\r\n glyph.x += x;\r\n glyph.y += y;\r\n }\r\n });\r\n }\r\n\r\n const glyphs = lines.flatMap((line) => line.glyphs);\r\n\r\n return {\r\n paragraph: trimmed.join(\"\\n\"),\r\n lines,\r\n glyphs,\r\n width,\r\n height,\r\n };\r\n }\r\n\r\n private _breakLines(text: string) {\r\n return text.split(\"\\n\");\r\n }\r\n\r\n private _collapse(text: string) {\r\n return text.replace(/\\t/g, \" \".repeat(this.options.tabSize)).replace(/ +/g, \" \");\r\n }\r\n\r\n private _wrap(text: string, lineOffset = 0) {\r\n const lines = new Array<SdfTextLine>();\r\n\r\n let currentLine = lineOffset;\r\n let currentGlyphs = new Array<SdfGlyph>();\r\n let currentCursor = 0;\r\n let currentWidth = 0;\r\n let lastChar: BMFontChar | undefined;\r\n let start = 0;\r\n let end = start;\r\n\r\n const pushCurrentLine = () => {\r\n lines.push({\r\n text: text.slice(start, end),\r\n glyphs: currentGlyphs,\r\n start: start,\r\n end: end,\r\n width: currentWidth,\r\n });\r\n };\r\n\r\n while (end < text.length) {\r\n const i = end;\r\n const charCode = text.charCodeAt(i);\r\n const char = this.fontAsset._getChar(charCode);\r\n const charWidth = char.width;\r\n const kerning = lastChar ? this.fontAsset._getKerning(lastChar.id, char.id) : 0;\r\n\r\n currentCursor += kerning;\r\n const newWidth = currentCursor + charWidth;\r\n const cursorProgress = char.xadvance + this.options.letterSpacing;\r\n const nextPosition = currentCursor + cursorProgress;\r\n\r\n const shouldBreak = nextPosition > this.options.maxWidth || newWidth > this.options.maxWidth;\r\n\r\n if (shouldBreak) {\r\n pushCurrentLine();\r\n\r\n currentLine++;\r\n lastChar = undefined;\r\n currentCursor = 0;\r\n currentWidth = 0;\r\n start = end;\r\n end = start + 1;\r\n currentGlyphs = [];\r\n }\r\n\r\n const x = currentCursor;\r\n const y = currentLine * this.lineHeight;\r\n\r\n currentGlyphs.push({\r\n char,\r\n line: currentLine,\r\n position: currentGlyphs.length,\r\n x: x,\r\n y: y,\r\n });\r\n\r\n if (!shouldBreak) {\r\n lastChar = char;\r\n currentCursor = nextPosition;\r\n currentWidth = newWidth;\r\n end++;\r\n } else {\r\n currentCursor = cursorProgress;\r\n }\r\n }\r\n\r\n if (currentGlyphs.length > 0) {\r\n if (lastChar) {\r\n // currentWidth += lastChar.xadvance;\r\n }\r\n pushCurrentLine();\r\n }\r\n\r\n return lines;\r\n }\r\n}\r\n","import type { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Buffer } from \"core/Buffers/buffer\";\r\nimport type { AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { ThinEngine } from \"core/Engines/thinEngine\";\r\nimport { DrawWrapper } from \"core/Materials/drawWrapper\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport type { IDisposable } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { SdfTextParagraph } from \"./sdf/paragraph\";\r\nimport type { FontAsset } from \"./fontAsset\";\r\nimport type { ParagraphOptions } from \"./paragraphOptions\";\r\nimport { ThinMatrix } from \"core/Maths/ThinMaths/thinMath.matrix\";\r\nimport {\r\n CopyMatrixToArray,\r\n CopyMatrixToRef,\r\n IdentityMatrixToRef,\r\n MultiplyMatricesToRef,\r\n ScalingMatrixToRef,\r\n TranslationMatrixToRef,\r\n} from \"core/Maths/ThinMaths/thinMath.matrix.functions\";\r\nimport type { IColor4Like, IMatrixLike } from \"core/Maths/math.like\";\r\n\r\n/**\r\n * Abstract Node class from Babylon.js\r\n */\r\nexport interface INodeLike {\r\n getWorldMatrix(): IMatrixLike;\r\n}\r\n\r\n/**\r\n * Class used to render text using MSDF (Multi-channel Signed Distance Field) technique\r\n * Thanks a lot to the work of Bhushan_Wagh and zb_sj for their amazing work on MSDF for Babylon.js\r\n * #6RLCWP#16\r\n * Star wars scroller: #6RLCWP#29\r\n * With metrics: #6RLCWP#35\r\n * Thickness: #IABMEZ#3\r\n * Solar system: #9YCDYC#9\r\n * Stroke: #6RLCWP#37\r\n */\r\nexport class TextRenderer implements IDisposable {\r\n private readonly _useVAO: boolean = false;\r\n private _engine: AbstractEngine;\r\n private _shaderLanguage: ShaderLanguage;\r\n private _vertexBuffers: { [key: string]: VertexBuffer } = {};\r\n private _spriteBuffer: Nullable<Buffer>;\r\n private _worldBuffer: Nullable<Buffer>;\r\n private _uvBuffer: Nullable<Buffer>;\r\n private _drawWrapperBase: DrawWrapper;\r\n private _vertexArrayObject: WebGLVertexArrayObject;\r\n private _font: FontAsset;\r\n private _charMatrices = new Array<number>();\r\n private _charUvs = new Array<number>();\r\n private _isDirty = true;\r\n private _baseLine = 0;\r\n\r\n // Cache\r\n private _scalingMatrix = new ThinMatrix();\r\n private _fontScaleMatrix = new ThinMatrix();\r\n private _offsetMatrix = new ThinMatrix();\r\n private _translationMatrix = new ThinMatrix();\r\n private _baseMatrix = new ThinMatrix();\r\n private _scaledMatrix = new ThinMatrix();\r\n private _localMatrix = new ThinMatrix();\r\n private _finalMatrix = new ThinMatrix();\r\n private _lineMatrix = new ThinMatrix();\r\n private _parentWorldMatrix = new ThinMatrix();\r\n\r\n /**\r\n * Gets or sets the color of the text\r\n */\r\n public color: IColor4Like = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };\r\n\r\n /**\r\n * Gets or sets the color of the stroke around the text\r\n */\r\n public strokeColor: IColor4Like = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };\r\n\r\n /**\r\n * Gets or sets the width of the stroke around the text (inset)\r\n */\r\n public strokeInsetWidth = 0;\r\n\r\n /**\r\n * Gets or sets the width of the stroke around the text (outset)\r\n */\r\n public strokeOutsetWidth = 0;\r\n\r\n /**\r\n * Gets or sets the thickness of the text (0 means as defined in the font)\r\n * Value must be between -0.5 and 0.5\r\n */\r\n public thicknessControl = 0;\r\n\r\n private _parent: Nullable<INodeLike> = null;\r\n\r\n /**\r\n * Gets or sets the parent of the text renderer\r\n */\r\n public get parent(): Nullable<INodeLike> {\r\n return this._parent;\r\n }\r\n\r\n public set parent(value: Nullable<INodeLike>) {\r\n this._parent = value;\r\n }\r\n\r\n private _transformMatrix: IMatrixLike = new ThinMatrix();\r\n\r\n /**\r\n * Gets or sets the transform matrix of the text renderer\r\n * It will be applied in that order:\r\n * parent x transform x paragraph world\r\n */\r\n public get transformMatrix(): IMatrixLike {\r\n return this._transformMatrix;\r\n }\r\n\r\n public set transformMatrix(value: IMatrixLike) {\r\n this._transformMatrix = value;\r\n }\r\n\r\n /**\r\n * Gets or sets if the text is billboarded\r\n */\r\n public isBillboard = false;\r\n\r\n /**\r\n * Gets or sets if the text is screen projected\r\n * This will work only if the text is billboarded\r\n */\r\n public isBillboardScreenProjected = false;\r\n\r\n /**\r\n * Gets the number of characters in the text renderer\r\n */\r\n public get characterCount(): number {\r\n return this._charMatrices.length / 16;\r\n }\r\n\r\n /**\r\n * Gets or sets if the text renderer should ignore the depth buffer\r\n * Default is false\r\n */\r\n public ignoreDepthBuffer = false;\r\n\r\n private constructor(engine: AbstractEngine, shaderLanguage: ShaderLanguage = ShaderLanguage.GLSL, font: FontAsset) {\r\n this._engine = engine;\r\n this._shaderLanguage = shaderLanguage;\r\n this._font = font;\r\n this._baseLine = font._font.common.lineHeight * font.scale;\r\n\r\n this._useVAO = engine.getCaps().vertexArrayObject && !engine.disableVertexArrayObjects;\r\n\r\n // Main vertex buffer\r\n const spriteData = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);\r\n this._spriteBuffer = new Buffer(engine, spriteData, false, 2);\r\n this._vertexBuffers[\"offsets\"] = this._spriteBuffer.createVertexBuffer(\"offsets\", 0, 2);\r\n\r\n // Instances\r\n this._resizeBuffers(128);\r\n }\r\n\r\n private _resizeBuffers(capacity: number) {\r\n if (this._worldBuffer) {\r\n this._worldBuffer.dispose();\r\n this._worldBuffer = null;\r\n }\r\n\r\n if (this._uvBuffer) {\r\n this._uvBuffer.dispose();\r\n this._uvBuffer = null;\r\n }\r\n\r\n this._worldBuffer = new Buffer(this._engine, new Float32Array(capacity * 16), true, 16);\r\n this._vertexBuffers[\"world0\"] = this._worldBuffer.createVertexBuffer(\"world0\", 0, 4, 16, true);\r\n this._vertexBuffers[\"world1\"] = this._worldBuffer.createVertexBuffer(\"world1\", 4, 4, 16, true);\r\n this._vertexBuffers[\"world2\"] = this._worldBuffer.createVertexBuffer(\"world2\", 8, 4, 16, true);\r\n this._vertexBuffers[\"world3\"] = this._worldBuffer.createVertexBuffer(\"world3\", 12, 4, 16, true);\r\n\r\n this._uvBuffer = new Buffer(this._engine, new Float32Array(capacity * 4), true, 4);\r\n this._vertexBuffers[\"uvs\"] = this._uvBuffer.createVertexBuffer(\"uvs\", 0, 4, 4, true);\r\n }\r\n\r\n private _setShaders(vertex: string, fragment: string) {\r\n this._drawWrapperBase?.dispose();\r\n\r\n this._drawWrapperBase = new DrawWrapper(this._engine);\r\n\r\n if (this._drawWrapperBase.drawContext) {\r\n this._drawWrapperBase.drawContext.useInstancing = true;\r\n }\r\n\r\n const defines = \"\";\r\n\r\n this._drawWrapperBase.effect = this._engine.createEffect(\r\n {\r\n vertexSource: vertex,\r\n fragmentSource: fragment,\r\n },\r\n [\"offsets\", \"world0\", \"world1\", \"world2\", \"world3\", \"uvs\"],\r\n [\"parentWorld\", \"view\", \"projection\", \"uColor\", \"thickness\", \"uStrokeColor\", \"uStrokeInsetWidth\", \"uStrokeOutsetWidth\", \"mode\", \"transform\"],\r\n [\"fontAtlas\"],\r\n defines,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n this._shaderLanguage\r\n );\r\n\r\n this._drawWrapperBase.effect._refCount++;\r\n }\r\n\r\n /**\r\n * Add a paragraph of text to the renderer\r\n * @param text define the text to add\r\n * @param options define the options to use for the paragraph (optional)\r\n * @param worldMatrix define the world matrix to use for the paragraph (optional)\r\n */\r\n public addParagraph(text: string, options?: Partial<ParagraphOptions>, worldMatrix?: IMatrixLike) {\r\n const paragraph = new SdfTextParagraph(text, this._font, options);\r\n\r\n const fontScale = this._font.scale;\r\n\r\n const texWidth = this._font._font.common.scaleW;\r\n const texHeight = this._font._font.common.scaleH;\r\n const glyphs = paragraph.glyphs.filter((g) => g.char.page >= 0);\r\n\r\n let worldMatrixToUse = worldMatrix;\r\n\r\n if (!worldMatrixToUse) {\r\n const lineHeight = paragraph.lineHeight * fontScale;\r\n const lineOffset = (paragraph.lines.length * lineHeight) / 2;\r\n TranslationMatrixToRef(0, this._baseLine - lineOffset, 0, this._lineMatrix);\r\n worldMatrixToUse = this._lineMatrix;\r\n }\r\n\r\n ScalingMatrixToRef(fontScale, fontScale, 1.0, this._fontScaleMatrix);\r\n TranslationMatrixToRef(0.5, -0.5, 0, this._offsetMatrix);\r\n\r\n const charsUvsBase = this._charUvs.length;\r\n const matricesBase = this._charMatrices.length;\r\n glyphs.forEach((g, i) => {\r\n this._charUvs[charsUvsBase + i * 4 + 0] = g.char.x / texWidth;\r\n this._charUvs[charsUvsBase + i * 4 + 1] = g.char.y / texHeight;\r\n this._charUvs[charsUvsBase + i * 4 + 2] = g.char.width / texWidth;\r\n this._charUvs[charsUvsBase + i * 4 + 3] = g.char.height / texHeight;\r\n\r\n const x = g.x + g.char.xoffset;\r\n const y = 1.0 - (g.y + g.char.yoffset);\r\n\r\n ScalingMatrixToRef(g.char.width, g.char.height, 1.0, this._scalingMatrix);\r\n MultiplyMatricesToRef(this._offsetMatrix, this._scalingMatrix, this._baseMatrix);\r\n\r\n TranslationMatrixToRef(x * fontScale, y * fontScale, 0.0, this._translationMatrix);\r\n MultiplyMatricesToRef(this._baseMatrix, this._fontScaleMatrix, this._scaledMatrix);\r\n MultiplyMatricesToRef(this._scaledMatrix, this._translationMatrix, this._localMatrix);\r\n\r\n MultiplyMatricesToRef(this._localMatrix, worldMatrixToUse, this._finalMatrix);\r\n CopyMatrixToArray(this._finalMatrix, this._charMatrices, matricesBase + i * 16);\r\n });\r\n\r\n this._isDirty = true;\r\n\r\n this._baseLine -= paragraph.lineHeight * fontScale * paragraph.lines.length;\r\n }\r\n\r\n /**\r\n * Render the text using the provided view and projection matrices\r\n * @param viewMatrix define the view matrix to use\r\n * @param projectionMatrix define the projection matrix to use\r\n */\r\n public render(viewMatrix: IMatrixLike, projectionMatrix: IMatrixLike): void {\r\n const drawWrapper = this._drawWrapperBase;\r\n\r\n const effect = drawWrapper.effect!;\r\n\r\n // Check\r\n if (!effect.isReady()) {\r\n return;\r\n }\r\n const engine = this._engine;\r\n\r\n engine.setState(false);\r\n engine.enableEffect(drawWrapper);\r\n\r\n if (this.ignoreDepthBuffer) {\r\n engine.setDepthBuffer(false);\r\n }\r\n\r\n if (this._parent) {\r\n CopyMatrixToRef(this._parent.getWorldMatrix(), this._parentWorldMatrix);\r\n } else {\r\n IdentityMatrixToRef(this._parentWorldMatrix);\r\n }\r\n\r\n effect.setInt(\"mode\", this.isBillboard ? (this.isBillboardScreenProjected ? 2 : 1) : 0);\r\n effect.setMatrix(\"parentWorld\", this._parentWorldMatrix);\r\n effect.setMatrix(\"view\", viewMatrix);\r\n effect.setMatrix(\"projection\", projectionMatrix);\r\n effect.setMatrix(\"transform\", this.transformMatrix);\r\n\r\n // Texture\r\n effect.setTexture(\"fontAtlas\", this._font.textures[0]);\r\n effect.setDirectColor4(\"uColor\", this.color);\r\n effect.setDirectColor4(\"uStrokeColor\", this.strokeColor);\r\n effect.setFloat(\"thickness\", this.thicknessControl * 0.9);\r\n effect.setFloat(\"uStrokeInsetWidth\", this.strokeInsetWidth);\r\n effect.setFloat(\"uStrokeOutsetWidth\", this.strokeOutsetWidth);\r\n\r\n const instanceCount = this._charMatrices.length / 16;\r\n\r\n // Need update?\r\n if (this._isDirty) {\r\n this._isDirty = false;\r\n\r\n if (this._worldBuffer!.getBuffer()!.capacity / 4 < instanceCount * 16) {\r\n this._resizeBuffers(instanceCount);\r\n }\r\n\r\n this._worldBuffer!.update(this._charMatrices);\r\n this._uvBuffer!.update(this._charUvs);\r\n }\r\n\r\n if (this._useVAO) {\r\n if (!this._vertexArrayObject) {\r\n this._vertexArrayObject = (engine as ThinEngine).recordVertexArrayObject(this._vertexBuffers, null, effect);\r\n }\r\n (engine as ThinEngine).bindVertexArrayObject(this._vertexArrayObject, null);\r\n } else {\r\n // VBOs\r\n engine.bindBuffers(this._vertexBuffers, null, effect);\r\n }\r\n\r\n engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, instanceCount);\r\n engine.unbindInstanceAttributes();\r\n engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n\r\n if (this.ignoreDepthBuffer) {\r\n engine.setDepthBuffer(true);\r\n }\r\n }\r\n\r\n /**\r\n * Release associated resources\r\n */\r\n public dispose(): void {\r\n if (this._worldBuffer) {\r\n this._worldBuffer.dispose();\r\n this._worldBuffer = null;\r\n }\r\n\r\n if (this._uvBuffer) {\r\n this._uvBuffer.dispose();\r\n this._uvBuffer = null;\r\n }\r\n\r\n if (this._spriteBuffer) {\r\n this._spriteBuffer.dispose();\r\n this._spriteBuffer = null;\r\n }\r\n\r\n if (this._vertexArrayObject) {\r\n (this._engine as ThinEngine).releaseVertexArrayObject(this._vertexArrayObject);\r\n (<any>this._vertexArrayObject) = null;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new TextRenderer instance asynchronously\r\n * @param font define the font asset to use\r\n * @param engine define the engine to use\r\n * @returns a promise that resolves to the created TextRenderer instance\r\n */\r\n public static async CreateTextRendererAsync(font: FontAsset, engine: AbstractEngine) {\r\n if (!engine.getCaps().instancedArrays || !engine._features.supportSpriteInstancing) {\r\n throw new Error(\"Instanced arrays are required for MSDF text rendering.\");\r\n }\r\n\r\n let shaderLanguage = ShaderLanguage.GLSL;\r\n let vertex: string = \"\";\r\n let fragment: string = \"\";\r\n if (engine.isWebGPU) {\r\n shaderLanguage = ShaderLanguage.WGSL;\r\n vertex = (await import(\"./shadersWGSL/msdf.vertex\")).msdfVertexShaderWGSL.shader;\r\n fragment = (await import(\"./shadersWGSL/msdf.fragment\")).msdfPixelShaderWGSL.shader;\r\n } else {\r\n vertex = (await import(\"./shaders/msdf.vertex\")).msdfVertexShader.shader;\r\n fragment = (await import(\"./shaders/msdf.fragment\")).msdfPixelShader.shader;\r\n }\r\n\r\n const textRenderer = new TextRenderer(engine, shaderLanguage, font);\r\n textRenderer._setShaders(vertex, fragment);\r\n\r\n return textRenderer;\r\n }\r\n}\r\n","import type { NavMesh, NavMeshCreateParams, OffMeshConnectionParams, TileCache, UnsignedCharArray, UnsignedShortArray } from \"@recast-navigation/core\";\n\nimport { GetRecast } from \"../factory/common\";\n\n/**\n * Creates a default tile cache mesh process function\n * @param offMeshConnections offMeshConnections\n * @param area the area to be set for each poly\n * @param flags the flags to be set for each poly\n * @returns the tile cache mesh process function\n */\nexport function CreateDefaultTileCacheMeshProcess(offMeshConnections: OffMeshConnectionParams[] = [], area = 0, flags = 1) {\n return new (GetRecast().TileCacheMeshProcess)((navMeshCreateParams: NavMeshCreateParams, polyAreas: UnsignedCharArray, polyFlags: UnsignedShortArray) => {\n for (let i = 0; i < navMeshCreateParams.polyCount(); ++i) {\n polyAreas.set(i, area);\n polyFlags.set(i, flags);\n }\n\n if (offMeshConnections.length > 0) {\n navMeshCreateParams.setOffMeshConnections(offMeshConnections);\n }\n });\n}\n\n/**\n * Waits until the tile cache is fully updated\n * @param navMesh The NavMesh\n * @param tileCache THe TileCache\n */\nexport function WaitForFullTileCacheUpdate(navMesh: NavMesh, tileCache: TileCache) {\n let upToDate = false;\n while (!upToDate) {\n const result = tileCache.update(navMesh);\n upToDate = result.upToDate;\n }\n}\n","import type { SoloNavMeshGeneratorConfig, TileCacheGeneratorConfig, TiledNavMeshGeneratorConfig } from \"@recast-navigation/generators\";\nimport type { CrowdAgentParams } from \"@recast-navigation/core\";\n\nimport { Logger } from \"core/Misc/logger\";\n\nimport type { IAgentParametersV2, INavMeshParametersV2 } from \"../types\";\nimport { CreateDefaultTileCacheMeshProcess } from \"./tile-cache\";\n\nexport const DefaultMaxObstacles = 128;\n\n/**\n * Creates a SoloNavMesh configuration based on the provided parameters.\n * @param parameters The parameters used to configure the SoloNavMesh generation.\n * @returns A configuration object for generating a SoloNavMesh.\n * @see https://docs.recast-navigation-js.isaacmason.com/types/index.RecastConfig.html\n */\nexport function CreateSoloNavMeshConfig(parameters: INavMeshParametersV2): Partial<SoloNavMeshGeneratorConfig> {\n return ToSoloNavMeshGeneratorConfig(parameters);\n}\n\n/**\n * Creates a TiledNavMesh configuration based on the provided parameters.\n * @param parameters The parameters used to configure the TiledNavMesh generation.\n * @returns A configuration object for generating a TiledNavMesh.\n */\nexport function CreateTiledNavMeshConfig(parameters: INavMeshParametersV2): Partial<TiledNavMeshGeneratorConfig> {\n const cfg: Partial<TiledNavMeshGeneratorConfig> = {\n ...CreateSoloNavMeshConfig(parameters),\n tileSize: parameters.tileSize ?? 32,\n };\n return cfg;\n}\n\n/**\n * Creates a TileCacheNavMesh configuration based on the provided parameters.\n * @param parameters The parameters used to configure the TileCacheNavMesh generation.\n * @returns A configuration object for generating a TileCacheNavMesh.\n */\nexport function CreateTileCacheNavMeshConfig(parameters: INavMeshParametersV2): Partial<TileCacheGeneratorConfig> {\n const cfg: Partial<TileCacheGeneratorConfig> = {\n ...CreateTiledNavMeshConfig(parameters),\n expectedLayersPerTile: parameters.expectedLayersPerTile ?? 1,\n maxObstacles: parameters.maxObstacles ?? DefaultMaxObstacles,\n };\n\n if (parameters.tileCacheMeshProcess) {\n cfg.tileCacheMeshProcess = parameters.tileCacheMeshProcess;\n } else if (parameters.offMeshConnections) {\n Logger.Warn(\"offMeshConnections are required but no tileCacheMeshProcess is set. Using fallback DefaultTileCacheMeshProcess.\");\n cfg.tileCacheMeshProcess = CreateDefaultTileCacheMeshProcess(parameters.offMeshConnections);\n }\n\n return cfg;\n}\n\n/**\n * Convert IAgentParameters to Recast CrowdAgentParams\n * @param config Agent parameters\n * @returns Recast crowd agent paramaters\n */\nexport function ToSoloNavMeshGeneratorConfig(config: INavMeshParametersV2): Partial<SoloNavMeshGeneratorConfig> {\n return Object.fromEntries(Object.entries(config).filter(([_, v]) => v !== undefined));\n}\n\n/**\n * Convert IAgentParameters to Recast CrowdAgentParams\n * @param agentParams Agent parameters\n * @returns Recast crowd agent paramaters\n */\nexport function ToCrowdAgentParams(agentParams: IAgentParametersV2): Partial<CrowdAgentParams> {\n return Object.fromEntries(Object.entries(agentParams).filter(([_, v]) => v !== undefined));\n}\n","import type { Crowd } from \"@recast-navigation/core\";\n\nimport type { Nullable } from \"core/types\";\nimport type { IVector3Like } from \"core/Maths/math.like\";\nimport type { TransformNode } from \"core/Meshes/transformNode\";\nimport type { ICrowd } from \"core/Navigation/INavigationEngine\";\nimport { Vector3 } from \"core/Maths/math.vector\";\nimport { Epsilon } from \"core/Maths/math.constants\";\nimport type { Observer } from \"core/Misc/observable\";\nimport { Observable } from \"core/Misc/observable\";\nimport type { Scene } from \"core/scene\";\n\nimport type { RecastNavigationJSPluginV2 } from \"./RecastNavigationJSPlugin\";\nimport type { AbstractEngine } from \"core/Engines/abstractEngine\";\nimport { ToCrowdAgentParams } from \"../common/config\";\nimport type { IAgentParametersV2 } from \"../types\";\nimport { GetRecast } from \"../factory/common\";\n\n/**\n * Recast Detour crowd implementation\n * This class provides methods to manage a crowd of agents, allowing them to navigate a navigation mesh.\n * It supports adding agents, updating their parameters, moving them to destinations, and checking their states.\n * The crowd is updated in the scene's animation loop, and it notifies observers when agents reach their destinations.\n */\nexport class RecastJSCrowd implements ICrowd {\n /**\n * Recast plugin\n */\n public get navigationPlugin(): RecastNavigationJSPluginV2 {\n return this._navigationPlugin;\n }\n\n /**\n * Link to the detour crowd\n */\n public get recastCrowd(): Crowd {\n return this._recastCrowd;\n }\n\n /**\n * One transform per agent\n */\n public get transforms(): TransformNode[] {\n return this._transforms;\n }\n\n /**\n * All agents created\n */\n public get agents(): readonly number[] {\n return Object.freeze(this._agents);\n }\n\n /**\n * Agents reach radius\n */\n public get reachRadii(): readonly number[] {\n return Object.freeze(this._reachRadii);\n }\n\n private _navigationPlugin: RecastNavigationJSPluginV2;\n private _recastCrowd: Crowd;\n private _transforms: TransformNode[] = [];\n private _agents: number[] = [];\n private _reachRadii: number[] = [];\n\n /**\n * true when a destination is active for an agent and notifier hasn't been notified of reach\n */\n private _agentDestinationArmed: boolean[] = new Array<boolean>();\n /**\n * agent current target\n */\n private _agentDestination: Vector3[] = new Array<Vector3>();\n /**\n * Link to the scene is kept to unregister the crowd from the scene\n */\n private _scene: Scene;\n\n private _engine: AbstractEngine;\n\n /**\n * Observer for crowd updates\n */\n private _onBeforeAnimationsObserver: Nullable<Observer<Scene>> = null;\n\n /**\n * Fires each time an agent is in reach radius of its destination\n */\n public onReachTargetObservable = new Observable<{\n /**\n *\n */\n agentIndex: number;\n /**\n *\n */\n destination: Vector3;\n }>();\n\n /**\n * Constructor\n * @param plugin recastJS plugin\n * @param maxAgents the maximum agent count in the crowd\n * @param maxAgentRadius the maximum radius an agent can have\n * @param scene to attach the crowd to\n * @returns the crowd you can add agents to\n */\n public constructor(plugin: RecastNavigationJSPluginV2, maxAgents: number, maxAgentRadius: number, scene: Scene) {\n this._navigationPlugin = plugin;\n\n if (!plugin.navMesh) {\n throw new Error(\"There is no NavMesh generated.\");\n }\n\n this._recastCrowd = new (GetRecast().Crowd)(plugin.navMesh, {\n maxAgents,\n maxAgentRadius,\n });\n\n this._scene = scene;\n this._engine = scene.getEngine();\n\n this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {\n this.update(this._engine.getDeltaTime() * 0.001 * plugin.timeFactor);\n });\n }\n\n /**\n * Add a new agent to the crowd with the specified parameter a corresponding transformNode.\n * You can attach anything to that node. The node position is updated in the scene update tick.\n * @param pos world position that will be constrained by the navigation mesh\n * @param parameters agent parameters\n * @param transform hooked to the agent that will be update by the scene\n * @returns agent index\n */\n public addAgent(pos: IVector3Like, parameters: IAgentParametersV2, transform: TransformNode): number {\n const agentParams = ToCrowdAgentParams(parameters);\n\n const agent = this._recastCrowd.addAgent({ x: pos.x, y: pos.y, z: pos.z }, agentParams);\n\n this._transforms.push(transform);\n this._agents.push(agent.agentIndex);\n this._reachRadii.push(parameters.reachRadius ? parameters.reachRadius : parameters.radius);\n this._agentDestinationArmed.push(false);\n this._agentDestination.push(new Vector3(0, 0, 0));\n\n return agent.agentIndex;\n }\n\n /**\n * Returns the agent position in world space\n * @param index agent index returned by addAgent\n * @returns world space position\n */\n public getAgentPosition(index: number): Vector3 {\n const agentPos = this._recastCrowd.getAgent(index)?.position() ?? Vector3.ZeroReadOnly;\n return new Vector3(agentPos.x, agentPos.y, agentPos.z);\n }\n\n /**\n * Returns the agent position result in world space\n * @param index agent index returned by addAgent\n * @param result output world space position\n */\n public getAgentPositionToRef(index: number, result: Vector3): void {\n const agentPos = this._recastCrowd.getAgent(index)?.position() ?? Vector3.ZeroReadOnly;\n result.set(agentPos.x, agentPos.y, agentPos.z);\n }\n\n /**\n * Returns the agent velocity in world space\n * @param index agent index returned by addAgent\n * @returns world space velocity\n */\n public getAgentVelocity(index: number): Vector3 {\n const agentVel = this._recastCrowd.getAgent(index)?.velocity() ?? Vector3.ZeroReadOnly;\n return new Vector3(agentVel.x, agentVel.y, agentVel.z);\n }\n\n /**\n * Returns the agent velocity result in world space\n * @param index agent index returned by addAgent\n * @param result output world space velocity\n */\n public getAgentVelocityToRef(index: number, result: Vector3): void {\n const agentVel = this._recastCrowd.getAgent(index)?.velocity() ?? Vector3.ZeroReadOnly;\n result.set(agentVel.x, agentVel.y, agentVel.z);\n }\n\n /**\n * Returns the agent next target point on the path\n * @param index agent index returned by addAgent\n * @returns world space position\n */\n public getAgentNextTargetPath(index: number): Vector3 {\n const pathTargetPos = this._recastCrowd.getAgent(index)?.nextTargetInPath() ?? Vector3.ZeroReadOnly;\n return new Vector3(pathTargetPos.x, pathTargetPos.y, pathTargetPos.z);\n }\n\n /**\n * Returns the agent next target point on the path\n * @param index agent index returned by addAgent\n * @param result output world space position\n */\n public getAgentNextTargetPathToRef(index: number, result: Vector3): void {\n const pathTargetPos = this._recastCrowd.getAgent(index)?.nextTargetInPath() ?? Vector3.ZeroReadOnly;\n result.set(pathTargetPos.x, pathTargetPos.y, pathTargetPos.z);\n }\n\n /**\n * Gets the agent state\n * @param index agent index returned by addAgent\n * @returns agent state, 0 = DT_CROWDAGENT_STATE_INVALID, 1 = DT_CROWDAGENT_STATE_WALKING, 2 = DT_CROWDAGENT_STATE_OFFMESH\n */\n public getAgentState(index: number): number {\n return this._recastCrowd.getAgent(index)?.state() ?? 0; // invalid\n }\n\n /**\n * returns true if the agent in over an off mesh link connection\n * @param index agent index returned by addAgent\n * @returns true if over an off mesh link connection\n */\n public overOffmeshConnection(index: number): boolean {\n return this._recastCrowd.getAgent(index)?.overOffMeshConnection() ?? false;\n }\n\n /**\n * Asks a particular agent to go to a destination. That destination is constrained by the navigation mesh\n * @param index agent index returned by addAgent\n * @param destination targeted world position\n */\n public agentGoto(index: number, destination: IVector3Like): void {\n this._recastCrowd.getAgent(index)?.requestMoveTarget(destination);\n\n // arm observer\n const item = this._agents.indexOf(index);\n if (item > -1) {\n this._agentDestinationArmed[item] = true;\n this._agentDestination[item].set(destination.x, destination.y, destination.z);\n }\n }\n\n /**\n * Teleport the agent to a new position\n * @param index agent index returned by addAgent\n * @param destination targeted world position\n */\n public agentTeleport(index: number, destination: IVector3Like): void {\n this._recastCrowd.getAgent(index)?.teleport(destination);\n }\n\n /**\n * Update agent parameters\n * @param index agent index returned by addAgent\n * @param parameters agent parameters\n */\n public updateAgentParameters(index: number, parameters: IAgentParametersV2): void {\n const agent = this._recastCrowd.getAgent(index);\n if (!agent) {\n return;\n }\n\n const agentParams = agent.parameters();\n\n if (!agentParams) {\n return;\n }\n\n if (parameters.radius !== undefined) {\n agentParams.radius = parameters.radius;\n }\n if (parameters.height !== undefined) {\n agentParams.height = parameters.height;\n }\n if (parameters.maxAcceleration !== undefined) {\n agentParams.maxAcceleration = parameters.maxAcceleration;\n }\n if (parameters.maxSpeed !== undefined) {\n agentParams.maxSpeed = parameters.maxSpeed;\n }\n if (parameters.collisionQueryRange !== undefined) {\n agentParams.collisionQueryRange = parameters.collisionQueryRange;\n }\n if (parameters.pathOptimizationRange !== undefined) {\n agentParams.pathOptimizationRange = parameters.pathOptimizationRange;\n }\n if (parameters.separationWeight !== undefined) {\n agentParams.separationWeight = parameters.separationWeight;\n }\n\n agent.updateParameters(agentParams);\n }\n\n /**\n * remove a particular agent previously created\n * @param index agent index returned by addAgent\n */\n public removeAgent(index: number): void {\n this._recastCrowd.removeAgent(index);\n\n const item = this._agents.indexOf(index);\n if (item > -1) {\n this._agents.splice(item, 1);\n this._transforms.splice(item, 1);\n this._reachRadii.splice(item, 1);\n this._agentDestinationArmed.splice(item, 1);\n this._agentDestination.splice(item, 1);\n }\n }\n\n /**\n * get the list of all agents attached to this crowd\n * @returns list of agent indices\n */\n public getAgents(): number[] {\n return this._agents;\n }\n\n /**\n * Tick update done by the Scene. Agent position/velocity/acceleration is updated by this function\n * @param deltaTime in seconds\n */\n public update(deltaTime: number): void {\n this._recastCrowd.update(deltaTime);\n\n if (deltaTime <= Epsilon) {\n return;\n }\n\n // update crowd\n const timeStep = this._navigationPlugin.getTimeStep();\n const maxStepCount = this._navigationPlugin.getMaximumSubStepCount();\n if (timeStep <= Epsilon) {\n this._recastCrowd.update(deltaTime);\n } else {\n let iterationCount = Math.floor(deltaTime / timeStep);\n if (maxStepCount && iterationCount > maxStepCount) {\n iterationCount = maxStepCount;\n }\n if (iterationCount < 1) {\n iterationCount = 1;\n }\n\n const step = deltaTime / iterationCount;\n for (let i = 0; i < iterationCount; i++) {\n this._recastCrowd.update(step);\n }\n }\n\n // update transforms\n for (let index = 0; index < this._agents.length; index++) {\n // update transform position\n const agentIndex = this._agents[index];\n const agentPosition = this.getAgentPosition(agentIndex);\n this._transforms[index].position = agentPosition;\n // check agent reach destination\n if (this._agentDestinationArmed[index]) {\n const dx = agentPosition.x - this._agentDestination[index].x;\n const dz = agentPosition.z - this._agentDestination[index].z;\n const radius = this._reachRadii[index];\n const groundY = this._agentDestination[index].y - this._reachRadii[index];\n const ceilingY = this._agentDestination[index].y + this._reachRadii[index];\n const distanceXZSquared = dx * dx + dz * dz;\n if (agentPosition.y > groundY && agentPosition.y < ceilingY && distanceXZSquared < radius * radius) {\n this._agentDestinationArmed[index] = false;\n this.onReachTargetObservable.notifyObservers({\n agentIndex: agentIndex,\n destination: this._agentDestination[index],\n });\n }\n }\n }\n }\n\n /**\n * Set the Bounding box extent for doing spatial queries (getClosestPoint, getRandomPointAround, ...)\n * The queries will try to find a solution within those bounds\n * default is (1,1,1)\n * @param extent x,y,z value that define the extent around the queries point of reference\n */\n setDefaultQueryExtent(extent: IVector3Like): void {\n this._navigationPlugin.setDefaultQueryExtent(extent);\n }\n\n /**\n * Get the Bounding box extent specified by setDefaultQueryExtent\n * @returns the box extent values\n */\n getDefaultQueryExtent(): Vector3 {\n const p = this._navigationPlugin.getDefaultQueryExtent();\n return new Vector3(p.x, p.y, p.z);\n }\n\n /**\n * Get the Bounding box extent result specified by setDefaultQueryExtent\n * @param result output the box extent values\n */\n getDefaultQueryExtentToRef(result: Vector3): void {\n const p = this._navigationPlugin.getDefaultQueryExtent();\n result.set(p.x, p.y, p.z);\n }\n\n /**\n * Get the next corner points composing the path (max 4 points)\n * @param index agent index returned by addAgent\n * @returns array containing world position composing the path\n */\n public getCorners(index: number): Vector3[] {\n const corners = this._recastCrowd.getAgent(index)?.corners();\n if (!corners) {\n return [];\n }\n\n const positions = [];\n for (let i = 0; i < corners.length; i++) {\n positions.push(new Vector3(corners[i].x, corners[i].y, corners[i].z));\n }\n return positions;\n }\n\n /**\n * Release all resources\n */\n public dispose(): void {\n this._recastCrowd.destroy();\n\n if (this._onBeforeAnimationsObserver) {\n this._scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);\n this._onBeforeAnimationsObserver = null;\n }\n\n this.onReachTargetObservable.clear();\n }\n}\n","import { Vector3 } from \"core/Maths/math.vector\";\nimport { Logger } from \"core/Misc/logger\";\n\nimport type { ComputePathResult } from \"../types\";\n\n/**\n * Converts navigation path points to a Vector3 array.\n * @param navPath The navigation path containing points and success status.\n * @returns An array of Vector3 points representing the navigation path.\n */\nexport function ConvertNavPathPoints(navPath: ComputePathResult): Vector3[] {\n const positions = [];\n\n if (navPath.success) {\n const pointCount = navPath.path.length;\n for (let pt = 0; pt < pointCount; pt++) {\n const p = navPath.path[pt];\n positions.push(new Vector3(p.x, p.y, p.z));\n }\n } else {\n Logger.Warn(\"Unable to convert navigation path point, because navPath generation has failed.\");\n }\n\n return positions;\n}\n","import type { NavMesh, NavMeshQuery, TileCache, TileCacheMeshProcess } from \"@recast-navigation/core\";\nimport type { SoloNavMeshGeneratorIntermediates, TileCacheGeneratorIntermediates, TiledNavMeshGeneratorIntermediates } from \"@recast-navigation/generators\";\n\nimport type { IVector3Like } from \"core/Maths/math.like\";\nimport type { Vector3 } from \"core/Maths/math.vector\";\nimport type { IAgentParameters, INavMeshParameters } from \"core/Navigation/INavigationEngine\";\nimport type { Nullable } from \"core/types\";\n\n/**\n * Recast injection type\n */\nexport type RecastInjection = any; // typeof import(\"@recast-navigation/core\") & typeof import(\"@recast-navigation/generators\");\n\n/**\n * Off-mesh connection data\n */\nexport interface IOffMeshConnection {\n /**\n * The start position of the off-mesh connection.\n */\n startPosition: IVector3Like;\n /**\n * The end position of the off-mesh connection.\n */\n endPosition: IVector3Like;\n /**\n * The radius of the off-mesh connection.\n */\n radius: number;\n /**\n * The type of the off-mesh connection.\n */\n bidirectional: boolean;\n /**\n * The area type of the off-mesh connection.\n */\n area: number;\n /**\n * The flags of the off-mesh connection.\n */\n flags: number;\n /**\n * The user ID of the off-mesh connection.\n * @remarks This can be used to associate the off-mesh connection with a specific user\n */\n userId?: number;\n}\n\n/**\n * Result of a navigation mesh creation.\n */\nexport type CreateNavMeshResult = Nullable<{\n /**\n * Navigation mesh\n */\n navMesh: NavMesh;\n /**\n * Navigation mesh query\n */\n navMeshQuery: NavMeshQuery;\n /**\n * Intermediates generated during the NavMesh creation process.\n * @remarks This is only available if the `keepIntermediates` parameter is set to true in the `INavMeshParametersV2`.\n * It can be used for debugging or visualization purposes.\n */\n intermediates?: GeneratorIntermediates;\n /**\n * Tile cache generated during the NavMesh creation process.\n * @remarks This is only available if the `maxObstacles` parameter is set to a value greater than 0 in the `INavMeshParametersV2`. Defaults `maxObstacles` to 128.\n * It can be used for obstacle avoidance and dynamic navigation mesh updates.\n * @see {@link INavMeshParametersV2}\n */\n tileCache?: TileCache;\n}>;\n\n/**\n * Agent parameters\n * For actual limits and default values check the recast-navigation-js docs.\n * @see https://docs.recast-navigation-js.isaacmason.com/types/index.CrowdAgentParams.html\n */\nexport interface IAgentParametersV2 extends IAgentParameters {\n /**\n * Flags that impact steering behavior.\n */\n updateFlags: number;\n /**\n * The index of the avoidance configuration to use for the agent. [Limits: 0 to #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS inclusive]\n */\n obstacleAvoidanceType: number;\n /**\n * The index of the query filter used by this agent.\n */\n queryFilterType: number;\n /**\n * User defined data attached to the agent.\n */\n userData: unknown;\n}\n\n/**\n * NavMesh parameters\n * For actual limits and default values check the recast-navigation-js docs.\n * @see https://docs.recast-navigation-js.isaacmason.com/types/index.RecastConfig.html\n */\nexport interface INavMeshParametersV2 extends INavMeshParameters {\n /**\n * OffMeshConnections - Teleports\n */\n offMeshConnections?: IOffMeshConnection[];\n /**\n * Whether to keep intermediate navigation mesh data for debug visualization. Default is false.\n */\n keepIntermediates?: boolean;\n /**\n * The maximum number of obstacles that can be added to the navigation mesh. Default is 32.\n * If this value is greater then 0, the navigation mesh will be generated with a tile cache.\n */\n maxObstacles?: number;\n /**\n * The size of each tile in the tiled navigation mesh. Default is 32.\n */\n expectedLayersPerTile?: number;\n /**\n * Function which is sets the polyAreas and polyFlags for the tile cache mesh. Defaults to a function that sets all areas to 0 and flags to 1.\n */\n tileCacheMeshProcess?: TileCacheMeshProcess;\n}\n\n/**\n * Result of a steer target computation.\n */\nexport type SteerTargetResult =\n | {\n /**\n * Indicates whether the steering target computation was successful.\n */\n success: false;\n }\n | {\n /**\n * Indicates whether the steering target computation was successful.\n */\n success: true;\n /**\n * The position to steer towards.\n */\n steerPos: Vector3;\n /**\n * The flag indicating the type of steering position.\n */\n steerPosFlag: number;\n /**\n * The reference to the polygon that the steering position is associated with.\n */\n steerPosRef: number;\n /**\n * The points that make up the path to the steering position.\n */\n points: Vector3[];\n };\n\n/**\n * Error types for path computation.\n */\nexport const ComputePathError = {\n START_NEAREST_POLY_FAILED: \"START_NEAREST_POLY_FAILED\",\n END_NEAREST_POLY_FAILED: \"END_NEAREST_POLY_FAILED\",\n FIND_PATH_FAILED: \"FIND_PATH_FAILED\",\n NO_POLYGON_PATH_FOUND: \"NO_POLYGON_PATH_FOUND\",\n NO_CLOSEST_POINT_ON_LAST_POLYGON_FOUND: \"NO_CLOSEST_POINT_ON_LAST_POLYGON_FOUND\",\n};\n\nexport type ComputePathErrorType = (typeof ComputePathError)[keyof typeof ComputePathError];\n\n/**\n * Result of a path computation.\n */\nexport type ComputePathResult = {\n /**\n * Indicates whether the path computation was successful.\n */\n success: boolean;\n /**\n * The error message if the path computation failed.\n */\n error?: {\n /**\n * A descriptive error message.\n */\n name?: string;\n /**\n * The type of error that occurred during path computation.\n * @remarks This will be one of the values from `ComputePathError`\n */\n type?: ComputePathErrorType;\n /**\n * Statusring describing the error.\n */\n status?: number;\n };\n /**\n * The computed path as an array of Vector3 points.\n */\n path: IVector3Like[];\n};\n\n/**\n * Intermediates generated during the NavMesh creation process.\n * @remarks This is only available if the `keepIntermediates` parameter is set to true in the `INavMeshParametersV2`.\n * It can be used for debugging or visualization purposes.\n */\nexport type GeneratorIntermediates = SoloNavMeshGeneratorIntermediates | TiledNavMeshGeneratorIntermediates | TileCacheGeneratorIntermediates | null;\n","import type { NavMeshQuery, NavMesh, QueryFilter } from \"@recast-navigation/core\";\n\nimport type { IVector3Like } from \"core/Maths/math.like\";\nimport { Vector3 } from \"core/Maths/math.vector\";\n\nimport { ConvertNavPathPoints } from \"./convert\";\nimport type { RecastInjection, SteerTargetResult } from \"../types\";\nimport { ComputePathError, type ComputePathResult } from \"../types\";\nimport { GetRecast } from \"../factory/common\";\n\nconst _DELTA = new Vector3();\nconst _MOVE_TARGET = new Vector3();\n\n/**\n * Compute a smooth navigation path from start to end. Returns an empty array if no path can be computed\n * @param navMesh the navigation mesh to use\n * @param navmeshQuery the navigation mesh query to use\n * @param start world position\n * @param end world position\n * @param options options object\n * @returns array containing world position composing the path\n */\nexport function ComputeSmoothPath(\n navMesh: NavMesh,\n navmeshQuery: NavMeshQuery,\n start: IVector3Like,\n end: IVector3Like,\n options?: {\n filter?: QueryFilter;\n halfExtents?: IVector3Like;\n\n /**\n * @default 256\n */\n maxPathPolys?: number;\n\n /**\n * @default 2048\n */\n maxSmoothPathPoints?: number;\n\n /**\n * @default 0.5\n */\n stepSize?: number;\n\n /**\n * @default 0.01\n */\n slop?: number;\n }\n): Vector3[] {\n return ConvertNavPathPoints(ComputeSmoothPathImpl(navMesh, navmeshQuery, start, end, options));\n}\n\nfunction ComputeSmoothPathImpl(\n navMesh: NavMesh,\n navMeshQuery: NavMeshQuery,\n start: IVector3Like,\n end: IVector3Like,\n options?: {\n filter?: QueryFilter;\n halfExtents?: IVector3Like;\n maxPathPolys?: number;\n maxSmoothPathPoints?: number;\n stepSize?: number;\n slop?: number;\n }\n): ComputePathResult {\n const recast = GetRecast();\n const filter = options?.filter ?? navMeshQuery.defaultFilter;\n const halfExtents = options?.halfExtents ?? navMeshQuery.defaultQueryHalfExtents;\n const maxSmoothPathPoints = options?.maxSmoothPathPoints ?? 2048;\n const maxPathPolys = options?.maxPathPolys ?? 256;\n const stepSize = options?.stepSize ?? 0.5;\n const slop = options?.slop ?? 0.01;\n\n // find nearest polygons for start and end positions\n const startNearestPolyResult = navMeshQuery.findNearestPoly(start, {\n filter,\n halfExtents,\n });\n\n if (!startNearestPolyResult.success) {\n return {\n success: false,\n error: {\n type: ComputePathError.START_NEAREST_POLY_FAILED,\n status: startNearestPolyResult.status,\n },\n path: [],\n };\n }\n\n const endNearestPolyResult = navMeshQuery.findNearestPoly(end, {\n filter,\n halfExtents,\n });\n\n if (!endNearestPolyResult.success) {\n return {\n success: false,\n error: {\n type: ComputePathError.END_NEAREST_POLY_FAILED,\n status: endNearestPolyResult.status,\n },\n path: [],\n };\n }\n\n const startRef = startNearestPolyResult.nearestRef;\n const endRef = endNearestPolyResult.nearestRef;\n\n // find polygon path\n const findPathResult = navMeshQuery.findPath(startRef, endRef, start, end, {\n filter,\n maxPathPolys,\n });\n\n if (!findPathResult.success) {\n return {\n success: false,\n error: {\n type: ComputePathError.FIND_PATH_FAILED,\n status: findPathResult.status,\n },\n path: [],\n };\n }\n\n if (findPathResult.polys.size <= 0) {\n return {\n success: false,\n error: {\n type: ComputePathError.NO_POLYGON_PATH_FOUND,\n },\n path: [],\n };\n }\n\n const lastPoly = findPathResult.polys.get(findPathResult.polys.size - 1);\n\n let closestEnd = end;\n\n if (lastPoly !== endRef) {\n const lastPolyClosestPointResult = navMeshQuery.closestPointOnPoly(lastPoly, end);\n\n if (!lastPolyClosestPointResult.success) {\n return {\n success: false,\n error: {\n type: ComputePathError.NO_CLOSEST_POINT_ON_LAST_POLYGON_FOUND,\n status: lastPolyClosestPointResult.status,\n },\n path: [],\n };\n }\n\n closestEnd = lastPolyClosestPointResult.closestPoint;\n }\n\n // Iterate over the path to find a smooth path on the detail mesh\n const iterPos = new Vector3(start.x, start.y, start.z);\n const targetPos = new Vector3(closestEnd.x, closestEnd.y, closestEnd.z);\n\n const polys = Array.from(findPathResult.polys.getHeapView());\n const smoothPath: Vector3[] = [];\n\n smoothPath.push(iterPos.clone());\n\n while (polys.length > 0 && smoothPath.length < maxSmoothPathPoints) {\n // Find location to steer towards\n const steerTarget = getSteerTarget(navMeshQuery, iterPos, targetPos, slop, polys, recast);\n\n if (!steerTarget.success) {\n break;\n }\n\n const isEndOfPath = steerTarget.steerPosFlag & recast.Detour.DT_STRAIGHTPATH_END;\n const isOffMeshConnection = steerTarget.steerPosFlag & recast.Detour.DT_STRAIGHTPATH_OFFMESH_CONNECTION;\n\n // Find movement delta.\n const steerPos = steerTarget.steerPos;\n const delta = _DELTA.copyFrom(steerPos).subtract(iterPos);\n let len = Math.sqrt(delta.dot(delta));\n\n // If the steer target is the end of the path or an off-mesh connection, do not move past the location.\n if ((isEndOfPath || isOffMeshConnection) && len < stepSize) {\n len = 1;\n } else {\n len = stepSize / len;\n }\n\n const moveTarget = _MOVE_TARGET.copyFrom(iterPos).addInPlace(delta.scale(len));\n\n // Move\n const moveAlongSurface = navMeshQuery.moveAlongSurface(polys[0], iterPos, moveTarget, { filter, maxVisitedSize: 16 });\n\n if (!moveAlongSurface.success) {\n break;\n }\n\n const result = moveAlongSurface.resultPosition;\n\n fixupCorridor(polys, maxPathPolys, moveAlongSurface.visited);\n fixupShortcuts(polys, navMesh, recast);\n\n const polyHeightResult = navMeshQuery.getPolyHeight(polys[0], result);\n\n if (polyHeightResult.success) {\n result.y = polyHeightResult.height;\n }\n\n iterPos.copyFromFloats(result.x, result.y, result.z);\n\n // Handle end of path and off-mesh links when close enough\n if (isEndOfPath && inRange(iterPos, steerTarget.steerPos, slop, 1.0)) {\n // Reached end of path\n iterPos.copyFrom(targetPos);\n\n if (smoothPath.length < maxSmoothPathPoints) {\n smoothPath.push(new Vector3(iterPos.x, iterPos.y, iterPos.z));\n }\n\n break;\n } else if (isOffMeshConnection && inRange(iterPos, steerTarget.steerPos, slop, 1.0)) {\n // Reached off-mesh connection.\n\n // Advance the path up to and over the off-mesh connection.\n const offMeshConRef = steerTarget.steerPosRef;\n\n // Advance the path up to and over the off-mesh connection.\n let prevPolyRef = 0;\n let polyRef = polys[0];\n let npos = 0;\n while (npos < polys.length && polyRef !== offMeshConRef) {\n prevPolyRef = polyRef;\n polyRef = polys[npos];\n npos++;\n }\n\n for (let i = npos; i < polys.length; i++) {\n polys[i - npos] = polys[i];\n }\n polys.splice(npos, polys.length - npos);\n\n // Handle the connection\n const offMeshConnectionPolyEndPoints = navMesh.getOffMeshConnectionPolyEndPoints(prevPolyRef, polyRef);\n\n if (offMeshConnectionPolyEndPoints.success) {\n if (smoothPath.length < maxSmoothPathPoints) {\n smoothPath.push(new Vector3(iterPos.x, iterPos.y, iterPos.z));\n\n // Hack to make the dotted path not visible during off-mesh connection.\n if (smoothPath.length & 1) {\n smoothPath.push(new Vector3(iterPos.x, iterPos.y, iterPos.z));\n }\n\n // Move position at the other side of the off-mesh link.\n iterPos.copyFromFloats(offMeshConnectionPolyEndPoints.end.x, offMeshConnectionPolyEndPoints.end.y, offMeshConnectionPolyEndPoints.end.z);\n\n const endPositionPolyHeight = navMeshQuery.getPolyHeight(polys[0], iterPos);\n\n if (endPositionPolyHeight.success) {\n iterPos.y = endPositionPolyHeight.height;\n }\n }\n }\n }\n\n // Store results.\n if (smoothPath.length < maxSmoothPathPoints) {\n smoothPath.push(new Vector3(iterPos.x, iterPos.y, iterPos.z));\n }\n }\n\n return {\n success: true,\n path: smoothPath,\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction getSteerTarget(navMeshQuery: NavMeshQuery, start: Vector3, end: Vector3, minTargetDist: number, pathPolys: number[], recast: RecastInjection): SteerTargetResult {\n const maxSteerPoints = 3;\n const straightPath = navMeshQuery.findStraightPath(start, end, pathPolys, {\n maxStraightPathPoints: maxSteerPoints,\n });\n\n if (!straightPath.success) {\n return {\n success: false,\n };\n }\n\n const outPoints: Vector3[] = [];\n for (let i = 0; i < straightPath.straightPathCount; i++) {\n const point = new Vector3(straightPath.straightPath.get(i * 3), straightPath.straightPath.get(i * 3 + 1), straightPath.straightPath.get(i * 3 + 2));\n\n outPoints.push(point);\n }\n\n // Find vertex far enough to steer to\n let ns = 0;\n while (ns < outPoints.length) {\n // Stop at Off-Mesh link or when point is further than slop away\n if (straightPath.straightPathFlags.get(ns) & recast.Detour.DT_STRAIGHTPATH_OFFMESH_CONNECTION) {\n break;\n }\n\n const posA = outPoints[ns];\n const posB = start;\n\n if (!inRange(posA, posB, minTargetDist, 1000.0)) {\n break;\n }\n\n ns++;\n }\n\n // Failed to find good point to steer to\n if (ns >= straightPath.straightPathCount) {\n return {\n success: false,\n };\n }\n\n const steerPos = outPoints[ns];\n const steerPosFlag = straightPath.straightPathFlags.get(ns);\n const steerPosRef = straightPath.straightPathRefs.get(ns);\n\n return {\n success: true,\n steerPos,\n steerPosFlag,\n steerPosRef,\n points: outPoints,\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction inRange(a: Vector3, b: Vector3, r: number, h: number) {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const dz = b.z - a.z;\n return dx * dx + dz * dz < r && Math.abs(dy) < h;\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction fixupCorridor(pathPolys: number[], maxPath: number, visitedPolyRefs: number[]) {\n let furthestPath = -1;\n let furthestVisited = -1;\n\n // Find furthest common polygon.\n for (let i = pathPolys.length - 1; i >= 0; i--) {\n let found = false;\n for (let j = visitedPolyRefs.length - 1; j >= 0; j--) {\n if (pathPolys[i] === visitedPolyRefs[j]) {\n furthestPath = i;\n furthestVisited = j;\n found = true;\n }\n }\n if (found) {\n break;\n }\n }\n\n // If no intersection found just return current path.\n if (furthestPath === -1 || furthestVisited === -1) {\n return pathPolys;\n }\n\n // Concatenate paths.\n\n // Adjust beginning of the buffer to include the visited.\n const req = visitedPolyRefs.length - furthestVisited;\n const orig = Math.min(furthestPath + 1, pathPolys.length);\n\n let size = Math.max(0, pathPolys.length - orig);\n\n if (req + size > maxPath) {\n size = maxPath - req;\n }\n if (size) {\n pathPolys.splice(req, size, ...pathPolys.slice(orig, orig + size));\n }\n\n // Store visited\n for (let i = 0; i < req; i++) {\n pathPolys[i] = visitedPolyRefs[visitedPolyRefs.length - (1 + i)];\n }\n\n return pathPolys;\n}\n\n/**\n * This function checks if the path has a small U-turn, that is,\n * a polygon further in the path is adjacent to the first polygon\n * in the path. If that happens, a shortcut is taken.\n * This can happen if the target (T) location is at tile boundary,\n * and we're (S) approaching it parallel to the tile edge.\n * The choice at the vertex can be arbitrary,\n * +---+---+\n * |:::|:::|\n * +-S-+-T-+\n * |:::| | -- the step can end up in here, resulting U-turn path.\n * +---+---+\n * @param pathPolys The path polygons to check for U-turns.\n * @param navMesh The navigation mesh used to check adjacency.\n * @param recast The recast injection to use.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction fixupShortcuts(pathPolys: number[], navMesh: NavMesh, recast: RecastInjection) {\n if (pathPolys.length < 3) {\n return;\n }\n\n // Get connected polygons\n const maxNeis = 16;\n let nneis = 0;\n const neis: number[] = [];\n\n const tileAndPoly = navMesh.getTileAndPolyByRef(pathPolys[0]);\n\n if (!tileAndPoly.success) {\n return;\n }\n\n const poly = tileAndPoly.poly;\n const tile = tileAndPoly.tile;\n for (let k = poly.firstLink(); k !== recast.Detour.DT_NULL_LINK; k = tile.links(k).next()) {\n const link = tile.links(k);\n\n if (link.ref() !== 0) {\n if (nneis < maxNeis) {\n neis.push(link.ref());\n nneis++;\n }\n }\n }\n\n // If any of the neighbour polygons is within the next few polygons\n // in the path, short cut to that polygon directly.\n const maxLookAhead = 6;\n let cut = 0;\n for (let i = Math.min(maxLookAhead, pathPolys.length) - 1; i > 1 && cut === 0; i--) {\n for (let j = 0; j < nneis; j++) {\n if (pathPolys[i] === neis[j]) {\n cut = i;\n break;\n }\n }\n }\n\n if (cut > 1) {\n pathPolys.splice(1, cut - 1);\n }\n}\n","import { VertexBuffer } from \"core/Buffers/buffer\";\nimport { Matrix, Vector3 } from \"core/Maths/math.vector\";\nimport { Mesh } from \"core/Meshes/mesh\";\n\n/**\n * Extracts positions and indices from an array of meshes.\n * @param meshes The array of meshes from which to extract positions and indices.\n * @returns A tuple containing a Float32Array of positions and a Uint32Array of\n */\nexport function GetPositionsAndIndices(meshes: Mesh[]): [positions: Float32Array, indices: Uint32Array] {\n let offset = 0;\n let index: number;\n let tri: number;\n let pt: number;\n const positions: number[] = [];\n const indices: number[] = [];\n\n for (index = 0; index < meshes.length; index++) {\n if (meshes[index]) {\n const mesh = meshes[index];\n\n const meshIndices = GetReversedIndices(mesh);\n if (!meshIndices) {\n continue;\n }\n\n const meshPositions = mesh.getVerticesData(VertexBuffer.PositionKind, false, false);\n if (!meshPositions) {\n continue;\n }\n\n const worldMatrices: Matrix[] = [];\n const worldMatrix = mesh.computeWorldMatrix(true);\n\n if (mesh.hasThinInstances) {\n const thinMatrices = (mesh as Mesh).thinInstanceGetWorldMatrices();\n for (let instanceIndex = 0; instanceIndex < thinMatrices.length; instanceIndex++) {\n const tmpMatrix = new Matrix();\n const thinMatrix = thinMatrices[instanceIndex];\n thinMatrix.multiplyToRef(worldMatrix, tmpMatrix);\n worldMatrices.push(tmpMatrix);\n }\n } else {\n worldMatrices.push(worldMatrix);\n }\n\n const transformed = Vector3.Zero();\n const position = Vector3.Zero();\n\n for (let matrixIndex = 0; matrixIndex < worldMatrices.length; matrixIndex++) {\n const wm = worldMatrices[matrixIndex];\n for (tri = 0; tri < meshIndices.length; tri++) {\n indices.push(meshIndices[tri] + offset);\n }\n\n for (pt = 0; pt < meshPositions.length; pt += 3) {\n Vector3.FromArrayToRef(meshPositions, pt, position);\n Vector3.TransformCoordinatesToRef(position, wm, transformed);\n positions.push(transformed.x, transformed.y, transformed.z);\n }\n\n offset += meshPositions.length / 3;\n }\n }\n }\n return [Float32Array.from(positions), Uint32Array.from(indices)];\n}\n\n/**\n * Reverses the order of vertices in each triangle (3 indices per face) to ensure\n * that the winding order is consistent with the Recast Navigation requirements.\n * This is necessary because Recast Navigation expects the indices to be in a specific winding order.\n * @param meshOrIndices The mesh from which to extract indices or the indices themselves.\n * @returns Array of indices with reversed winding order.\n */\nexport function GetReversedIndices(\n meshOrIndices: Mesh | Uint32Array | number[]\n): Uint32Array<ArrayBufferLike> | number[] | Int32Array<ArrayBufferLike> | Uint16Array<ArrayBufferLike> | null {\n const indices = meshOrIndices instanceof Mesh ? meshOrIndices.getIndices() : meshOrIndices;\n\n if (indices) {\n for (let i = 0; i < indices.length; i += 3) {\n // Swap the second and third index to reverse the winding order\n [indices[i + 1], indices[i + 2]] = [indices[i + 2], indices[i + 1]];\n }\n }\n\n return indices;\n}\n","import type { NavMesh } from \"@recast-navigation/core\";\n\nimport type { Scene } from \"core/scene\";\nimport type { Node } from \"core/node\";\nimport { Mesh } from \"core/Meshes/mesh\";\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\n\nimport { GetReversedIndices } from \"../common/getters\";\nimport { GetRecast } from \"../factory/common\";\n\n/**\n * Creates a debug mesh for visualizing a NavMesh in the scene.\n * @param navMesh The NavMesh to visualize.\n * @param scene The scene in which to create the debug mesh.\n * @param parent Optional parent node for the debug mesh.\n * @param flags Poly flags to filter by, defaults to undefined to include all polys\n * @returns The created debug mesh.\n */\nexport function CreateDebugNavMesh(navMesh: NavMesh, scene: Scene, parent?: Node, flags?: number) {\n const [positions, indices] = GetRecast().getNavMeshPositionsAndIndices(navMesh, flags);\n\n const mesh = new Mesh(\"NavMeshDebug\", scene);\n const vertexData = new VertexData();\n\n vertexData.indices = GetReversedIndices(indices);\n vertexData.positions = positions;\n vertexData.applyToMesh(mesh, false);\n\n parent && (mesh.parent = parent);\n\n return mesh;\n}\n","import type { SoloNavMeshGeneratorConfig, TileCacheGeneratorConfig, TiledNavMeshGeneratorConfig } from \"@recast-navigation/generators\";\n\nimport { Logger } from \"core/Misc/logger\";\nimport type { Mesh } from \"core/Meshes/mesh\";\n\nimport type { INavMeshParametersV2 } from \"../types\";\nimport { GetPositionsAndIndices } from \"../common/getters\";\nimport { CreateSoloNavMeshConfig, CreateTileCacheNavMeshConfig, CreateTiledNavMeshConfig } from \"../common/config\";\nimport { GetRecast } from \"../factory/common\";\n\n/**\n * Builds a NavMesh and NavMeshQuery from meshes using provided parameters.\n * @param meshes The array of meshes used to create the NavMesh.\n * @param parameters The parameters used to configure the NavMesh generation.\n * @returns An object containing the NavMesh and NavMeshQuery.\n * @remarks This function generates a NavMesh based on the provided meshes and parameters.\n * It supports different configurations such as solo, tiled, and tile cache nav meshes.\n * If you need obstacles, ensure that `maxObstacles` is set to a value greater than 0.\n * Recommended values for `tileSize` are between 32 and 64 when using obstacles/tile cache.\n * If you need a tiled nav mesh, ensure that `tileSize` is set to a value greater than 0.\n * @throws Error if the NavMesh data is invalid or cannot be deserialized.\n */\nexport function GenerateNavMesh(meshes: Array<Mesh>, parameters: INavMeshParametersV2) {\n const recast = GetRecast();\n\n if (meshes.length === 0) {\n throw new Error(\"At least one mesh is needed to create the nav mesh.\");\n }\n\n const [positions, indices] = GetPositionsAndIndices(meshes);\n if (!positions || !indices) {\n throw new Error(\"Unable to get nav mesh. No vertices or indices.\");\n }\n\n // Decide on the type of nav mesh to generate based on parameters\n // If tileSize is set, we will generate a tiled nav mesh\n // If maxObstacles is set, we will generate a tile cache nav mesh\n // Otherwise, we will generate a solo nav mesh\n // Note: tileSize is only used for tiled nav meshes, not tile cache nav meshes\n // If both tileSize and maxObstacles are set, we will generate a tile cache\n const tileSize = parameters.tileSize ?? 0;\n const needsTileCache = (parameters.maxObstacles ?? 0) > 0;\n const needsTiledNavMesh = tileSize > 0;\n if (needsTileCache) {\n if (tileSize < 32 || tileSize > 64) {\n Logger.Warn(\"NavigationPlugin: Tile cache is enabled. Recommended tileSize is 32 to 64. Other values may lead to unexpected behavior.\");\n }\n }\n\n // Create the appropriate configuration based on the parameters\n const config = needsTileCache ? CreateTileCacheNavMeshConfig(parameters) : needsTiledNavMesh ? CreateTiledNavMeshConfig(parameters) : CreateSoloNavMeshConfig(parameters);\n const result = needsTileCache\n ? recast.generateTileCache(positions, indices, config as TileCacheGeneratorConfig, parameters.keepIntermediates)\n : needsTiledNavMesh\n ? recast.generateTiledNavMesh(positions, indices, config as TiledNavMeshGeneratorConfig, parameters.keepIntermediates)\n : recast.generateSoloNavMesh(positions, indices, config as SoloNavMeshGeneratorConfig, parameters.keepIntermediates);\n\n if (!result.success) {\n throw new Error(`Unable to generateSoloNavMesh: ${result.error}`);\n }\n\n return {\n navMesh: result.navMesh,\n intermediates: result.intermediates,\n navMeshQuery: new recast.NavMeshQuery(result.navMesh),\n tileCache: \"tileCache\" in result ? result.tileCache : undefined,\n };\n}\n","import type { Mesh } from \"core/Meshes/mesh\";\n\nimport type { RecastNavigationJSPluginV2 } from \"../plugin/RecastNavigationJSPlugin\";\nimport type { INavMeshParametersV2 } from \"../types\";\nimport { GenerateNavMesh } from \"./generator.single-thread\";\n\n/**\n * Injects the navigation mesh generation methods into the navigation plugin.\n * @param navigationPlugin The navigation plugin to inject the methods into.\n */\nexport function InjectGenerators(navigationPlugin: RecastNavigationJSPluginV2) {\n navigationPlugin.createNavMeshImpl = (meshes: Mesh[], parameters: INavMeshParametersV2) => {\n return GenerateNavMesh(meshes, parameters);\n };\n\n navigationPlugin.createNavMeshAsyncImpl = async (meshes: Mesh[], parameters: INavMeshParametersV2) => {\n return await new Promise((resolve) => {\n resolve(GenerateNavMesh(meshes, parameters));\n });\n };\n}\n","import type { TileCacheMeshProcess, NavMesh, QueryFilter, TileCache, NavMeshQuery } from \"@recast-navigation/core\";\n\nimport type { ICrowd, INavigationEnginePlugin, IObstacle } from \"core/Navigation/INavigationEngine\";\nimport { Logger } from \"core/Misc/logger\";\nimport type { Mesh } from \"core/Meshes/mesh\";\nimport type { Scene } from \"core/scene\";\nimport { TmpVectors, Vector3 } from \"core/Maths/math\";\nimport type { IVector3Like } from \"core/Maths/math.like\";\nimport type { Nullable } from \"core/types\";\n\nimport type { CreateNavMeshResult, GeneratorIntermediates, INavMeshParametersV2, RecastInjection } from \"../types\";\nimport { RecastJSCrowd } from \"./RecastJSCrowd\";\nimport { ConvertNavPathPoints } from \"../common/convert\";\nimport { ComputeSmoothPath } from \"../common/smooth-path\";\nimport { CreateDebugNavMesh } from \"../debug/simple-debug\";\nimport { GetRecast } from \"../factory/common\";\nimport { InjectGenerators } from \"../generator/injection\";\nimport { DefaultMaxObstacles } from \"../common/config\";\nimport { CreateDefaultTileCacheMeshProcess, WaitForFullTileCacheUpdate } from \"../common/tile-cache\";\n\n/**\n * Navigation plugin for Babylon.js. It is a simple wrapper around the recast-navigation-js library. Not all features are implemented.\n * @remarks This plugin provides navigation mesh generation and pathfinding capabilities using the recast-navigation-js library\n * @remarks It supports both single-threaded and multi-threaded generation of navigation meshes.\n * @remarks The plugin can be used to create navigation meshes from meshes in a scene, compute paths, and manage crowd agents, etc.\n * @remarks It also provides methods for creating obstacles and querying the navigation mesh.\n * @see https://github.com/isaac-mason/recast-navigation-js\n */\nexport class RecastNavigationJSPluginV2 implements INavigationEnginePlugin {\n /**\n * Creates a navigation mesh - will be injected by the factory\n * @param meshes array of all the geometry used to compute the navigation mesh\n * @param parameters bunch of parameters used to filter geometry\n * @returns the created navmesh and navmesh query\n */\n createNavMeshImpl: (meshes: Array<Mesh>, parameters: INavMeshParametersV2) => CreateNavMeshResult;\n\n /**\n * Creates a navigation mesh - will be injected by the factory\n * @param meshes array of all the geometry used to compute the navigation mesh\n * @param parameters bunch of parameters used to filter geometry\n * @returns the created navmesh and navmesh query\n */\n createNavMeshAsyncImpl: (meshes: Array<Mesh>, parameters: INavMeshParametersV2) => Promise<CreateNavMeshResult>;\n\n /**\n * recast-navigation-js injection\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public bjsRECAST: RecastInjection;\n\n /**\n * plugin name\n */\n public name: string = \"RecastNavigationJSPlugin\";\n\n /**\n * the navmesh created\n */\n public navMesh?: NavMesh;\n\n /**\n * The navmesh query created from the navmesh\n * @remarks This is used to query the navmesh for pathfinding and other navigation tasks\n */\n public get navMeshQuery(): NavMeshQuery {\n return this._navMeshQuery;\n }\n\n private _navMeshQuery!: NavMeshQuery;\n\n /**\n * Intermediates generated during the navmesh creation\n * @remarks This is used for debugging and visualization purposes.\n * @remarks You have access to vertices, indices and vertex colors to visusalize the navmesh creation process.\n * @remarks This is only available if the `keepIntermediates` parameter is set\n * @remarks to true during navmesh generation.\n */\n private _intermediates?: GeneratorIntermediates;\n\n /**\n * Gets the intermediates generated during the navmesh creation\n * @returns The generator intermediates, or undefined if not available\n */\n public get intermediates(): GeneratorIntermediates | undefined {\n return this._intermediates;\n }\n\n /**\n * Tile cache used for tiled navigation meshes\n * @remarks This is used to store and manage tiles of the navigation mesh for efficient path and when obstacles are used.\n */\n private _tileCache?: TileCache;\n\n /**\n * Gets the tile cache used for tiled navigation meshes\n * @returns The tile cache instance, or undefined if not available\n */\n public get tileCache(): TileCache | undefined {\n return this._tileCache;\n }\n\n // Crowd specific properties\n private _maximumSubStepCount: number = 10;\n private _timeStep: number = 1 / 60;\n private _timeFactor: number = 1;\n\n private _crowd?: ICrowd;\n\n /**\n * Creates a RecastNavigationJSPluginV2 instance\n * @param recastInjection The recast-navigation-js injection containing core and generators\n */\n public constructor(recastInjection?: RecastInjection) {\n if (!recastInjection) {\n recastInjection = GetRecast();\n InjectGenerators(this);\n }\n\n this.bjsRECAST = recastInjection;\n\n if (!this.isSupported()) {\n Logger.Error(\"RecastJS is not available. Please make sure you included the js file.\");\n return;\n }\n this.setTimeStep();\n }\n\n /**\n * Set the time step of the navigation tick update.\n * Default is 1/60.\n * A value of 0 will disable fixed time update\n * @param newTimeStep the new timestep to apply to this world.\n */\n public setTimeStep(newTimeStep: number = 1 / 60): void {\n this._timeStep = newTimeStep;\n }\n\n /**\n * Get the time step of the navigation tick update.\n * @returns the current time step\n */\n public getTimeStep(): number {\n return this._timeStep;\n }\n\n /**\n * If delta time in navigation tick update is greater than the time step\n * a number of sub iterations are done. If more iterations are need to reach deltatime\n * they will be discarded.\n * A value of 0 will set to no maximum and update will use as many substeps as needed\n * @param newStepCount the maximum number of iterations\n */\n public setMaximumSubStepCount(newStepCount: number = 10): void {\n this._maximumSubStepCount = newStepCount;\n }\n\n /**\n * Get the maximum number of iterations per navigation tick update\n * @returns the maximum number of iterations\n */\n public getMaximumSubStepCount(): number {\n return this._maximumSubStepCount;\n }\n\n /**\n * Time factor applied when updating crowd agents (default 1). A value of 0 will pause crowd updates.\n * @param value the time factor applied at update\n */\n public set timeFactor(value: number) {\n this._timeFactor = Math.max(value, 0);\n }\n\n /**\n * Get the time factor used for crowd agent update\n * @returns the time factor\n */\n public get timeFactor(): number {\n return this._timeFactor;\n }\n\n /**\n * Creates a navigation mesh - will be injected by the factory\n * @param meshes array of all the geometry used to compute the navigation mesh\n * @param parameters bunch of parameters used to filter geometry\n * @returns the created navmesh and navmesh query\n * @throws Error if the function is not injected yet or if the navmesh is not created\n */\n public createNavMesh(meshes: Array<Mesh>, parameters: INavMeshParametersV2): CreateNavMeshResult {\n if (!this.createNavMeshImpl) {\n throw new Error(\"Function not injected yet. Use the factory to create the plugin.\");\n }\n\n this._preprocessParameters(parameters);\n\n const result = this.createNavMeshImpl(meshes, parameters);\n return this._processNavMeshResult(result);\n }\n\n /**\n * Creates a navigation mesh asynchronously - will be injected by the factory\n * @param meshes array of all the geometry used to compute the navigation mesh\n * @param parameters bunch of parameters used to filter geometry\n * @returns the created navmesh and navmesh query\n * @throws Error if the function is not injected yet or if the navmesh is not created\n */\n public async createNavMeshAsync(meshes: Array<Mesh>, parameters: INavMeshParametersV2): Promise<CreateNavMeshResult> {\n if (!this.createNavMeshAsyncImpl) {\n throw new Error(\"Function not injected yet. Use the factory to create the plugin.\");\n }\n\n this._preprocessParameters(parameters);\n\n const result = await this.createNavMeshAsyncImpl(meshes, parameters);\n return this._processNavMeshResult(result);\n }\n\n /**\n * Create a navigation mesh debug mesh\n * @param scene is where the mesh will be added\n * @returns debug display mesh\n */\n public createDebugNavMesh(scene: Scene): Mesh {\n if (!this.navMesh) {\n throw new Error(\"There is no navMesh generated.\");\n }\n\n if (this.navMesh && this._tileCache) {\n WaitForFullTileCacheUpdate(this.navMesh, this._tileCache);\n }\n\n return CreateDebugNavMesh(this.navMesh, scene);\n }\n\n /**\n * Get a navigation mesh constrained position, closest to the parameter position\n * @param position world position\n * @returns the closest point to position constrained by the navigation mesh\n */\n public getClosestPoint(\n position: IVector3Like,\n options?: {\n /**\n * The polygon filter to apply to the query.\n */\n filter?: QueryFilter;\n /**\n * Half extents for the search box\n */\n halfExtents?: IVector3Like;\n }\n ): Vector3 {\n const ret = this._navMeshQuery.findClosestPoint(position, options);\n const pr = new Vector3(ret.point.x, ret.point.y, ret.point.z);\n return pr;\n }\n\n /**\n * Get a navigation mesh constrained position, closest to the parameter position\n * @param position world position\n * @param result output the closest point to position constrained by the navigation mesh\n */\n public getClosestPointToRef(\n position: IVector3Like,\n result: Vector3,\n options?: {\n /**\n * The polygon filter to apply to the query.\n */\n filter?: QueryFilter;\n /**\n * Half extents for the search box\n */\n halfExtents?: IVector3Like;\n }\n ): void {\n const ret = this._navMeshQuery.findClosestPoint(position, options);\n result.set(ret.point.x, ret.point.y, ret.point.z);\n }\n\n /**\n * Get a navigation mesh constrained position, within a particular radius\n * @param position world position\n * @param maxRadius the maximum distance to the constrained world position\n * @returns the closest point to position constrained by the navigation mesh\n */\n public getRandomPointAround(\n position: IVector3Like,\n maxRadius: number,\n options?: {\n startRef?: number;\n /**\n * The polygon filter to apply to the query.\n */\n filter?: QueryFilter;\n /**\n * Half extents for the search box\n */\n halfExtents?: IVector3Like;\n }\n ): Vector3 {\n const ret = this._navMeshQuery.findRandomPointAroundCircle(position, maxRadius, options);\n const pr = new Vector3(ret.randomPoint.x, ret.randomPoint.y, ret.randomPoint.z);\n return pr;\n }\n\n /**\n * Get a navigation mesh constrained position, within a particular radius\n * @param position world position\n * @param maxRadius the maximum distance to the constrained world position\n * @param result output the closest point to position constrained by the navigation mesh\n */\n public getRandomPointAroundToRef(\n position: IVector3Like,\n maxRadius: number,\n result: Vector3,\n options?: {\n startRef?: number;\n /**\n * The polygon filter to apply to the query.\n */\n filter?: QueryFilter;\n /**\n * Half extents for the search box\n */\n halfExtents?: IVector3Like;\n }\n ): void {\n const ret = this._navMeshQuery.findRandomPointAroundCircle(position, maxRadius, options);\n result.set(ret.randomPoint.x, ret.randomPoint.y, ret.randomPoint.z);\n }\n\n /**\n * Compute the final position from a segment made of destination-position\n * @param position position to start from\n * @param destination position to go to\n * @param startRef the reference id of the start polygon\n * @param options options for the function\n * @returns the resulting point along the navmesh\n */\n public moveAlong(\n position: IVector3Like,\n destination: IVector3Like,\n startRef = 0,\n options?: {\n /**\n * The polygon filter to apply to the query.\n */\n filter?: QueryFilter;\n /**\n * The maximum number of polygons the output visited array can hold.\n */\n maxVisitedSize?: number;\n }\n ): Vector3 {\n const ret = this._navMeshQuery.moveAlongSurface(startRef, position, destination, options);\n const pr = new Vector3(ret.resultPosition.x, ret.resultPosition.y, ret.resultPosition.z);\n return pr;\n }\n\n /**\n * Compute the final position from a segment made of destination-position\n * @param position world position\n * @param destination world position\n * @param result output the resulting point along the navmesh\n * @param startRef the reference id of the start polygon.\n * @param options options for the function\n */\n public moveAlongToRef(\n position: IVector3Like,\n destination: IVector3Like,\n result: Vector3,\n startRef = 0,\n options?: {\n /**\n * The polygon filter to apply to the query.\n */\n filter?: QueryFilter;\n maxVisitedSize?: number;\n }\n ): void {\n const ret = this._navMeshQuery.moveAlongSurface(startRef, position, destination, options);\n result.set(ret.resultPosition.x, ret.resultPosition.y, ret.resultPosition.z);\n }\n\n /**\n * Compute a navigation path from start to end. Returns an empty array if no path can be computed\n * Path is straight.\n * @param start world position\n * @param end world position\n * @param options options for the function\n * @returns array containing world position composing the path\n */\n public computePath(\n start: IVector3Like,\n end: IVector3Like,\n options?: {\n /**\n * The polygon filter to apply to the query.\n */\n filter?: QueryFilter;\n /**\n * Half extents for the search box\n */\n halfExtents?: IVector3Like;\n maxPathPolys?: number;\n maxStraightPathPoints?: number;\n }\n ): Vector3[] {\n return ConvertNavPathPoints(this._navMeshQuery.computePath(start, end, options));\n }\n\n /**\n * Creates a navigation mesh - will be injected by the factory\n * @param start the start position of the navmesh\n * @param end the end position of the navmesh\n * @param options options to configure the path computation\n * @returns array containing world position composing the path\n */\n public computePathSmooth(\n start: Vector3,\n end: Vector3,\n options?: {\n /**\n * The polygon filter to apply to the query.\n */\n filter?: QueryFilter;\n /**\n * Half extents for the search box\n */\n halfExtents?: IVector3Like;\n maxPathPolys?: number;\n maxSmoothPathPoints?: number;\n stepSize?: number;\n slop?: number;\n }\n ): Vector3[] {\n if (!this.navMesh) {\n Logger.Error(\"No navmesh available. Cannot compute smooth path.\");\n return [];\n }\n return ComputeSmoothPath(this.navMesh, this._navMeshQuery, start, end, options);\n }\n\n /**\n * Create a new Crowd so you can add agents\n * @param maxAgents the maximum agent count in the crowd\n * @param maxAgentRadius the maximum radius an agent can have\n * @param scene to attach the crowd to\n * @returns the crowd you can add agents to\n */\n public createCrowd(maxAgents: number, maxAgentRadius: number, scene: Scene): ICrowd {\n const crowd = new RecastJSCrowd(this, maxAgents, maxAgentRadius, scene);\n this._crowd = crowd;\n return crowd;\n }\n\n /**\n * Set the Bounding box extent for doing spatial queries (getClosestPoint, getRandomPointAround, ...)\n * The queries will try to find a solution within those bounds\n * default is (1,1,1)\n * @param extent x,y,z value that define the extent around the queries point of reference\n */\n public setDefaultQueryExtent(extent: IVector3Like): void {\n this._navMeshQuery.defaultQueryHalfExtents = extent;\n }\n\n /**\n * Get the Bounding box extent specified by setDefaultQueryExtent\n * @returns the box extent values\n */\n public getDefaultQueryExtent(): Vector3 {\n return new Vector3(this._navMeshQuery.defaultQueryHalfExtents.x, this._navMeshQuery.defaultQueryHalfExtents.y, this._navMeshQuery.defaultQueryHalfExtents.z);\n }\n\n /**\n * Get the Bounding box extent result specified by setDefaultQueryExtent\n * @param result output the box extent values\n */\n public getDefaultQueryExtentToRef(result: Vector3): void {\n result.set(this._navMeshQuery.defaultQueryHalfExtents.x, this._navMeshQuery.defaultQueryHalfExtents.y, this._navMeshQuery.defaultQueryHalfExtents.z);\n }\n\n /**\n * build the navmesh from a previously saved state using getNavmeshData\n * @param data the Uint8Array returned by getNavmeshData\n */\n public buildFromNavmeshData(data: Uint8Array): void {\n const result = this.bjsRECAST.importNavMesh(data);\n this.navMesh = result.navMesh;\n this._navMeshQuery = new this.bjsRECAST.NavMeshQuery(this.navMesh);\n }\n\n /**\n * returns the navmesh data that can be used later. The navmesh must be built before retrieving the data\n * @returns data the Uint8Array that can be saved and reused\n */\n public getNavmeshData(): Uint8Array {\n if (!this.navMesh) {\n throw new Error(\"There is no NavMesh generated.\");\n }\n return this.bjsRECAST.exportNavMesh(this.navMesh);\n }\n\n /**\n * build the tile cache from a previously saved state using getTileCacheData\n * @param tileCacheData the data returned by getTileCacheData\n * @param tileCacheMeshProcess optional process to apply to each tile created\n */\n public buildFromTileCacheData(tileCacheData: Uint8Array, tileCacheMeshProcess?: TileCacheMeshProcess): void {\n const result = this.bjsRECAST.importTileCache(tileCacheData, tileCacheMeshProcess ?? CreateDefaultTileCacheMeshProcess([]));\n this.navMesh = result.navMesh;\n this._tileCache = result.tileCache;\n this._navMeshQuery = new this.bjsRECAST.NavMeshQuery(this.navMesh);\n }\n\n /**\n * returns the tile cache data that can be used later. The tile cache must be built before retrieving the data\n * @returns the tile cache data that can be used later. The tile cache must be built before retrieving the data\n * @throws Error if there is no TileCache generated\n * @remarks The returned data can be used to rebuild the tile cache later using buildFromTileCacheData\n */\n public getTileCacheData(): Uint8Array {\n if (!this.navMesh || !this._tileCache) {\n throw new Error(\"There is no TileCache generated.\");\n }\n return this.bjsRECAST.exportTileCache(this.navMesh, this._tileCache);\n }\n\n /**\n * Disposes\n */\n public dispose() {\n this._crowd?.dispose();\n this.navMesh?.destroy();\n this._navMeshQuery?.destroy();\n this._tileCache?.destroy();\n }\n\n /**\n * Creates a cylinder obstacle and add it to the navigation\n * @param position world position\n * @param radius cylinder radius\n * @param height cylinder height\n * @param doNotWaitForCacheUpdate if true the function will not wait for the tile cache to be fully updated before returning\n * @returns the obstacle freshly created\n */\n public addCylinderObstacle(position: IVector3Like, radius: number, height: number, doNotWaitForCacheUpdate = false): Nullable<IObstacle> {\n const obstacleResult = this._tileCache?.addCylinderObstacle(position, radius, height);\n if (!obstacleResult?.success) {\n return null;\n }\n\n if (!doNotWaitForCacheUpdate && this.navMesh && this._tileCache) {\n WaitForFullTileCacheUpdate(this.navMesh, this._tileCache);\n }\n\n return (obstacleResult.obstacle as IObstacle) ?? null;\n }\n\n /**\n * Creates an oriented box obstacle and add it to the navigation\n * @param position world position\n * @param extent box size\n * @param angle angle in radians of the box orientation on Y axis\n * @param doNotWaitForCacheUpdate if true the function will not wait for the tile cache to be fully updated before returning\n * @returns the obstacle freshly created\n */\n public addBoxObstacle(position: IVector3Like, extent: IVector3Like, angle: number, doNotWaitForCacheUpdate = false): Nullable<IObstacle> {\n const obstacleResult = this._tileCache?.addBoxObstacle(position, extent, angle);\n if (!obstacleResult?.success) {\n return null;\n }\n\n if (!doNotWaitForCacheUpdate && this.navMesh && this._tileCache) {\n WaitForFullTileCacheUpdate(this.navMesh, this._tileCache);\n }\n\n return (obstacleResult.obstacle as IObstacle) ?? null;\n }\n\n /**\n * Removes an obstacle created by addCylinderObstacle or addBoxObstacle\n * @param obstacle obstacle to remove from the navigation\n * @param doNotWaitForCacheUpdate if true the function will not wait for the tile cache to be fully updated before returning\n *\n */\n public removeObstacle(obstacle: IObstacle, doNotWaitForCacheUpdate = false): void {\n this._tileCache?.removeObstacle(obstacle);\n\n if (!doNotWaitForCacheUpdate && this.navMesh && this._tileCache) {\n WaitForFullTileCacheUpdate(this.navMesh, this._tileCache);\n }\n }\n\n /**\n * If this plugin is supported\n * @returns true if plugin is supported\n */\n public isSupported(): boolean {\n return !!this.bjsRECAST;\n }\n\n /**\n * Returns the seed used for randomized functions like `getRandomPointAround`\n * @returns seed number\n */\n public getRandomSeed(): number {\n return this.bjsRECAST.getRandomSeed();\n }\n\n /**\n * Set the seed used for randomized functions like `getRandomPointAround`\n * @param seed number used as seed for random functions\n */\n public setRandomSeed(seed: number): void {\n this.bjsRECAST.setRandomSeed(seed);\n }\n\n // New funccntions beyond the INavigationEnginePlugin interface\n\n /**\n * Perform a raycast on the navmesh\n * @param start start position\n * @param end end position\n * @returns if a direct path exists between start and end, and the hit point if any\n */\n public raycast(start: IVector3Like, end: IVector3Like) {\n const nearestStartPoly = this._navMeshQuery.findNearestPoly(start);\n const raycastResult = this._navMeshQuery.raycast(nearestStartPoly.nearestRef, start, end);\n\n const hit = 0 < raycastResult.t && raycastResult.t < 1.0;\n if (!hit) {\n return {\n hit: false,\n };\n } else {\n TmpVectors.Vector3[0].set(start.x, start.y, start.z);\n TmpVectors.Vector3[1].set(end.x, end.y, end.z);\n\n const distanceToHitBorder = Vector3.Distance(TmpVectors.Vector3[0], TmpVectors.Vector3[1]) * (raycastResult?.t ?? 0);\n const direction = TmpVectors.Vector3[1].subtract(TmpVectors.Vector3[0]).normalize();\n const hitPoint = TmpVectors.Vector3[0].add(direction.multiplyByFloats(distanceToHitBorder, distanceToHitBorder, distanceToHitBorder));\n\n return {\n hit: true,\n hitPoint,\n };\n }\n }\n\n /**\n * Compute the final position from a segment made of destination-position, and return the height of the polygon\n * This is a more sophisiticated version of moveAlong that will use the height of the polygon at the end position\n * @param position world position to start from\n * @param velocity wvelocity of the movement\n * @param options options for the function\n * @returns the resulting point along the navmesh, the polygon reference id and the height of the polygon\n */\n public moveAlongWithVelocity(\n position: IVector3Like,\n velocity: IVector3Like,\n options?: {\n /**\n * The polygon filter to apply to the query.\n */\n filter?: QueryFilter;\n /**\n * Half extents for the search box\n */\n halfExtents?: IVector3Like;\n /**\n * The maximum number of polygons the output visited array can hold.\n */\n maxVisitedSize?: number;\n }\n ) {\n const { point, polyRef } = this._navMeshQuery.findClosestPoint(\n {\n x: position.x,\n y: position.y,\n z: position.z,\n },\n options\n );\n\n const { resultPosition } = this._navMeshQuery.moveAlongSurface(\n polyRef,\n point,\n {\n x: point.x + velocity.x,\n y: point.y + velocity.y,\n z: point.z + velocity.z,\n },\n options\n );\n const polyHeightResult = this._navMeshQuery.getPolyHeight(polyRef, resultPosition);\n\n return {\n position: { x: resultPosition.x, y: polyHeightResult.success ? polyHeightResult.height : resultPosition.y, z: resultPosition.z },\n polyRef: polyRef,\n height: polyHeightResult.height,\n };\n }\n\n /**\n * Handles common post-processing and validation of navmesh creation results\n * @param result The partial result from navmesh creation\n * @returns The validated and complete CreateNavMeshresult\n */\n private _processNavMeshResult(result: Nullable<Partial<CreateNavMeshResult>>): CreateNavMeshResult {\n if (!result?.navMesh || !result?.navMeshQuery) {\n throw new Error(\"Unable to create navmesh. No navMesh or navMeshQuery returned.\");\n }\n\n this.navMesh = result.navMesh;\n this._navMeshQuery = result.navMeshQuery;\n this._intermediates = result.intermediates;\n this._tileCache = result.tileCache;\n\n return {\n navMesh: result.navMesh,\n navMeshQuery: result.navMeshQuery,\n intermediates: result.intermediates,\n tileCache: result.tileCache, // tileCache is optional\n };\n }\n\n private _preprocessParameters(parameters: INavMeshParametersV2) {\n if ((parameters.tileSize ?? 0 > 0) && !!parameters.maxObstacles) {\n parameters.maxObstacles = DefaultMaxObstacles;\n }\n\n parameters.walkableSlopeAngle = Math.max(0.1, parameters.walkableSlopeAngle ?? 60);\n }\n}\n","import { InjectGenerators } from \"../generator/injection\";\nimport { RecastNavigationJSPluginV2 } from \"../plugin/RecastNavigationJSPlugin\";\nimport { GetRecast, InitRecast } from \"./common\";\n\n/**\n * Creates a navigation plugin for the given scene.\n * @returns A promise that resolves to the created navigation plugin.\n * @remarks This function initializes the Recast module and sets up the navigation plugin.\n */\nexport async function CreateNavigationPluginAsync() {\n await InitRecast();\n\n const navigationPlugin = new RecastNavigationJSPluginV2(GetRecast());\n InjectGenerators(navigationPlugin);\n\n return navigationPlugin;\n}\n","import type { IVector3Like } from \"core/Maths/math.like\";\nimport { Vector3 } from \"core/Maths/math.vector\";\n\n/**\n * Utility function based on Chaikin's alogrithm for navigation path smoothing and segment generation.\n * @param points Array of points to be smoothed, where each point is an object with x, y, and z properties.\n * @param iterations Number of smoothing iterations to apply. Default 1.\n * @returns A new array of smoothed points after applying the Chaikin's algorithm.\n */\nexport function GetChaikinSmoothPath(points: IVector3Like[], iterations = 1) {\n for (let i = 0; i < iterations; i++) {\n const smoothed = [];\n for (let j = 0; j < points.length - 1; j++) {\n const p0 = points[j];\n const p1 = points[j + 1];\n\n smoothed.push({\n x: 0.75 * p0.x + 0.25 * p1.x,\n y: 0.75 * p0.y + 0.25 * p1.y,\n z: 0.75 * p0.z + 0.25 * p1.z,\n });\n\n smoothed.push({\n x: 0.25 * p0.x + 0.75 * p1.x,\n y: 0.25 * p0.y + 0.75 * p1.y,\n z: 0.25 * p0.z + 0.75 * p1.z,\n });\n }\n\n if (points[0].x === points[points.length - 1].x && points[0].y === points[points.length - 1].y && points[0].z === points[points.length - 1].z) {\n smoothed.push(smoothed[0]);\n }\n\n points = smoothed;\n }\n return points;\n}\n\n/**\n * Generates a series of points that create an L-shaped path between each pair of points in the input navigation segment.\n * The path consists of a horizontal segment followed by a vertical segment, or vice versa,\n * depending on the relative distances between the x and z coordinates of the points.\n * @param navSegment An array of Vector3 points representing the navigation segment.\n * @returns An array of Vector3 points representing the L-shaped path.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function GetLShapedPath(navSegment: Vector3[]) {\n const points = [];\n for (let j = 0; j < navSegment.length - 1; j++) {\n const p0 = navSegment[j];\n const p1 = navSegment[j + 1];\n const p01 = getLShapedPoint(p0, p1);\n points.push(p0, new Vector3(p01.x, p1.y, p01.z), p1);\n }\n return points;\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction getLShapedPoint(pointA: IVector3Like, pointB: IVector3Like) {\n const { x: x1, z: y1 } = pointA;\n const { x: x2, z: y2 } = pointB;\n\n let pointC;\n\n // Determine turn direction automatically based on the offset\n if (Math.abs(x2 - x1) >= Math.abs(y2 - y1)) {\n // Horizontal-then-vertical turn\n pointC = { x: x2, z: y1 };\n } else {\n // Vertical-then-horizontal turn\n pointC = { x: x1, z: y2 };\n }\n\n return pointC;\n}\n","import type { TileCacheMeshProcess } from \"@recast-navigation/core\";\n\nimport { GetRecast } from \"../factory/common\";\n\n/**\n * Builds a NavMesh and NavMeshQuery from serialized data.\n * @param data The serialized NavMesh data.\n * @returns An object containing the NavMesh and NavMeshQuery.\n * @remarks This function deserializes the NavMesh data and creates a NavMeshQuery\n * instance for querying the NavMesh.\n * @throws Error if the NavMesh data is invalid or cannot be deserialized.\n */\nexport function BuildFromNavmeshData(data: Uint8Array) {\n const recast = GetRecast();\n const result = recast.importNavMesh(data);\n\n if (!result.navMesh) {\n throw new Error(`Unable to deserialize NavMesh.`);\n }\n\n return {\n navMesh: result.navMesh,\n navMeshQuery: new recast.NavMeshQuery(result.navMesh),\n tileCache: undefined,\n };\n}\n\n/**\n * Builds a TileCache and NavMeshQuery from serialized data.\n * @param data The serialized TileCache data.\n * @param tileCacheMeshProcess Optional function to process the TileCache mesh.\n * @returns An object containing the TileCache, NavMesh, and NavMeshQuery.\n */\nexport function BuildFromTileCacheData(data: Uint8Array, tileCacheMeshProcess: TileCacheMeshProcess) {\n const recast = GetRecast();\n const result = recast.importTileCache(data, tileCacheMeshProcess);\n\n if (!result.tileCache) {\n throw new Error(`Unable to deserialize TileCache.`);\n }\n\n return {\n navMesh: result.navMesh,\n navMeshQuery: new recast.NavMeshQuery(result.navMesh),\n tileCache: result.tileCache,\n };\n}\n","import type {\n DebugDrawerPrimitive,\n DebugDrawerPrimitiveType,\n NavMesh,\n NavMeshQuery,\n RecastCompactHeightfield,\n RecastContourSet,\n RecastHeightfield,\n RecastHeightfieldLayer,\n RecastHeightfieldLayerSet,\n RecastPolyMesh,\n RecastPolyMeshDetail,\n DebugDrawerUtils,\n} from \"@recast-navigation/core\";\n\nimport type { GreasedLineMaterialOptions } from \"core/Materials/GreasedLine/greasedLineMaterialInterfaces\";\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\nimport { Color3 } from \"core/Maths/math.color\";\nimport { Matrix } from \"core/Maths/math.vector\";\nimport { CreateGreasedLine } from \"core/Meshes/Builders/greasedLineBuilder\";\nimport type { GreasedLineBaseMesh, GreasedLineMeshOptions } from \"core/Meshes/GreasedLine/greasedLineBaseMesh\";\nimport { Mesh } from \"core/Meshes/mesh\";\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\nimport { TransformNode } from \"core/Meshes/transformNode\";\nimport type { Scene } from \"core/scene\";\nimport type { Nullable } from \"core/types\";\nimport { CreateBox } from \"core/Meshes/Builders/boxBuilder\";\nimport { Logger } from \"core/Misc/logger\";\n\nimport type { GeneratorIntermediates } from \"../types\";\nimport { GetRecast } from \"../factory/common\";\n\n// TODO: Enum?\nexport const DebugLayerOption = {\n HEIGHTFIELD_SOLID: \"heightfield solid\",\n HEIGHTFIELD_WALKABLE: \"heightfield walkable\",\n COMPACT_HEIGHTFIELD_SOLID: \"compact heightfield solid\",\n COMPACT_HEIGHTFIELD_REGIONS: \"compact heightfield regions\",\n COMPACT_HEIGHTFIELD_DISTANCE: \"compact heightfield distance\",\n RAW_CONTOURS: \"raw contours\",\n CONTOURS: \"contours\",\n POLY_MESH: \"poly mesh\",\n POLY_MESH_DETAIL: \"poly mesh detail\",\n NAVMESH: \"navmesh\",\n NAVMESH_BV_TREE: \"navmesh bv tree\",\n};\n\nexport type DebugLayerOptions = (typeof DebugLayerOption)[keyof typeof DebugLayerOption];\n\n/**\n * NavigationDebugger is a utility class for visualizing navigation meshes and related data in a Babylon.js scene.\n * It provides methods to draw various navigation-related primitives such as points, lines, triangles, and quads.\n * It also supports drawing heightfields, compact heightfields, contours, poly meshes, and nav meshes.\n */\nexport class NavigationDebugger {\n /**\n * The name of the debug mesh used for navigation debugging.\n * This is used to group all navigation debug meshes under a single name for easier management\n */\n public static NAV_MESH_DEBUG_NAME = \"nav-mesh-debug\";\n\n /**\n * The name of the debug mesh used for visualization of the navigation mesh using points.\n */\n public static NAV_MESH_DEBUG_NAME_POINTS = \"nav-mesh-debug-points\";\n\n /**\n * The name of the debug mesh used for visualization of the navigation mesh using triangles.\n */\n public static NAV_MESH_DEBUG_NAME_TRIS = \"nav-mesh-debug-tris\";\n\n /**\n * The name of the debug mesh used for visualization of the navigation mesh using quads.\n */\n public static NAV_MESH_DEBUG_NAME_QUADS = \"nav-mesh-debug-quads\";\n\n /**\n * The name of the debug mesh used for visualization of the navigation mesh using lines.\n */\n public static NAV_MESH_DEBUG_NAME_LINES = \"nav-mesh-debug-lines\";\n\n /**\n * The material used for rendering triangles in the navigation debug visualization.\n */\n public triMaterial: StandardMaterial;\n /**\n * The material used for rendering points in the navigation debug visualization.\n */\n public pointMaterial: StandardMaterial;\n\n /**\n * The list of line materials used in the navigation debug visualization.\n */\n public lineMaterials: StandardMaterial[] = [];\n\n /**\n * The parent node for the debug drawer.\n */\n public debugDrawerParentNode: TransformNode;\n\n /**\n * * Gets or sets the primitive types to be drawn by the debug drawer.\n * * This allows you to control which types of primitives (points, lines, tris, quads) are rendered in the navigation debug visualization.\n * * The default value is `[\"points\", \"lines\", \"tris\", \"quads\"]`.\n * * You can modify this property to include or exclude specific primitive types based on your debugging needs.\n * @returns An array of primitive types that the debug drawer will render.\n */\n public get primitiveTypes(): DebugDrawerPrimitiveType[] {\n return this._primitiveTypes;\n }\n\n public set primitiveTypes(value: DebugDrawerPrimitiveType[]) {\n this._primitiveTypes = value;\n }\n\n private _lineMaterialOptions: {\n greasedLineMaterialOptions: Partial<GreasedLineMaterialOptions>;\n greasedLineMeshOptions: Partial<GreasedLineMeshOptions>;\n };\n private _pointMesh: Mesh;\n private _debugDrawerUtils: DebugDrawerUtils;\n private _primitiveTypes: DebugDrawerPrimitiveType[];\n\n constructor(\n private _scene: Scene,\n options?: {\n parent?: {\n node?: TransformNode | string;\n };\n primitiveTypes?: DebugDrawerPrimitiveType[];\n materials?: {\n triMaterial?: StandardMaterial;\n pointMaterial?: StandardMaterial;\n lineMaterialOptions: {\n greasedLineMaterialOptions: Partial<GreasedLineMaterialOptions>;\n greasedLineMeshOptions: Partial<GreasedLineMeshOptions>;\n };\n };\n }\n ) {\n this._debugDrawerUtils = new (GetRecast().DebugDrawerUtils)();\n\n this._primitiveTypes = options?.primitiveTypes ?? [\"points\", \"lines\", \"tris\", \"quads\"];\n\n this.debugDrawerParentNode =\n options?.parent?.node instanceof TransformNode ? options.parent.node : new TransformNode((options?.parent?.node as string) ?? \"nav-mesh-debug-parent\", this._scene);\n\n const materials = options?.materials;\n if (materials?.triMaterial) {\n this.triMaterial = materials.triMaterial;\n } else {\n this.triMaterial = new StandardMaterial(\"nav-debug-tris-material\");\n this.triMaterial.backFaceCulling = false;\n this.triMaterial.specularColor = Color3.Black();\n this.triMaterial.alpha = 0.5;\n }\n\n if (materials?.pointMaterial) {\n this.pointMaterial = materials.pointMaterial;\n } else {\n this.pointMaterial = new StandardMaterial(\"nav-debug-points-material\");\n this.pointMaterial.backFaceCulling = false;\n this.pointMaterial.specularColor = Color3.Black();\n }\n\n if (materials?.lineMaterialOptions) {\n this._lineMaterialOptions = materials.lineMaterialOptions;\n } else {\n this._lineMaterialOptions = {\n greasedLineMaterialOptions: {\n width: 2,\n sizeAttenuation: true,\n },\n greasedLineMeshOptions: {},\n };\n }\n\n this._pointMesh = CreateBox(NavigationDebugger.NAV_MESH_DEBUG_NAME_POINTS, { size: 0.02 });\n }\n\n /**\n * Resets the debug drawer by disposing of all child meshes in the debug drawer parent node.\n * This is useful for clearing the debug visualization before drawing new primitives.\n */\n public clear() {\n for (const child of this.debugDrawerParentNode.getChildMeshes()) {\n child.dispose();\n }\n }\n\n /**\n * Disposes of the debug drawer, including all meshes and materials used for rendering.\n * This method should be called when the debug drawer is no longer needed to free up resources.\n */\n public dispose() {\n this.clear();\n this._debugDrawerUtils.dispose();\n this._pointMesh.dispose();\n this.triMaterial.dispose();\n this.pointMaterial.dispose();\n }\n\n /**\n * This method iterates through the provided primitives and draws them based on their type.\n * It supports drawing points, lines, triangles, and quads, depending on the primitive type.\n * @param primitives An array of debug drawer primitives to be drawn.\n * @param options Optional parameters to control the drawing behavior, such as whether to join meshes.\n */\n public drawPrimitives(primitives: DebugDrawerPrimitive[], options?: { joinMeshes?: boolean }) {\n let linesInstance = null;\n\n for (const primitive of primitives) {\n // draw only the primitives that are in the primitiveTypes array\n if (!this._primitiveTypes.includes(primitive.type)) {\n continue;\n }\n\n switch (primitive.type) {\n case \"points\":\n this._drawPoints(primitive);\n break;\n case \"lines\": {\n const line = this._drawLines(primitive, linesInstance);\n if (!linesInstance) {\n linesInstance = line;\n }\n break;\n }\n case \"tris\":\n this._drawTris(primitive);\n break;\n case \"quads\":\n this._drawQuads(primitive);\n break;\n }\n }\n\n linesInstance?.updateLazy();\n\n if (options?.joinMeshes ?? true) {\n // Join the debug meshes into a single mesh for better performance\n this._joinDebugMeshes();\n }\n }\n\n /**\n * Draws a heightfield as solid using the debug drawer utilities.\n * @param hf The heightfield to draw as solid.\n */\n public drawHeightfieldSolid(hf: RecastHeightfield): void {\n const primitives = this._debugDrawerUtils.drawHeightfieldSolid(hf);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws a heightfield as walkable using the debug drawer utilities.\n * @param hf The heightfield to draw as walkable.\n */\n public drawHeightfieldWalkable(hf: RecastHeightfield): void {\n const primitives = this._debugDrawerUtils.drawHeightfieldWalkable(hf);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws a compact heightfield as solid using the debug drawer utilities.\n * @param chf The compact heightfield to draw as solid.\n */\n public drawCompactHeightfieldSolid(chf: RecastCompactHeightfield): void {\n const primitives = this._debugDrawerUtils.drawCompactHeightfieldSolid(chf);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws the regions of a compact heightfield using the debug drawer utilities.\n * @param chf The compact heightfield to draw regions for.\n */\n public drawCompactHeightfieldRegions(chf: RecastCompactHeightfield): void {\n const primitives = this._debugDrawerUtils.drawCompactHeightfieldRegions(chf);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws the distance field of a compact heightfield using the debug drawer utilities.\n * @param chf The compact heightfield to draw the distance for.\n */\n public drawCompactHeightfieldDistance(chf: RecastCompactHeightfield): void {\n const primitives = this._debugDrawerUtils.drawCompactHeightfieldDistance(chf);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws a heightfield layer using the debug drawer utilities.\n * @param layer The heightfield layer to draw.\n * @param idx The index of the layer to draw.\n */\n public drawHeightfieldLayer(layer: RecastHeightfieldLayer, idx: number): void {\n const primitives = this._debugDrawerUtils.drawHeightfieldLayer(layer, idx);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws the layers of a heightfield using the debug drawer utilities.\n * @param lset The heightfield layer set containing the layers to draw.\n */\n public drawHeightfieldLayers(lset: RecastHeightfieldLayerSet): void {\n const primitives = this._debugDrawerUtils.drawHeightfieldLayers(lset);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws the region connections of a RecastContourSet using the debug drawer utilities.\n * @param cset RecastContourSet to draw\n * @param alpha The alpha value for the drawn contours, default is 1.\n */\n public drawRegionConnections(cset: RecastContourSet, alpha: number = 1): void {\n const primitives = this._debugDrawerUtils.drawRegionConnections(cset, alpha);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws raw contours from a RecastContourSet using the debug drawer utilities.\n * @param cset RecastContourSet to draw\n * @param alpha The alpha value for the drawn contours, default is 1.\n */\n public drawRawContours(cset: RecastContourSet, alpha: number = 1): void {\n const primitives = this._debugDrawerUtils.drawRawContours(cset, alpha);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws contours from a RecastContourSet using the debug drawer utilities.\n * @param cset RecastContourSet to draw\n * @param alpha The alpha value for the drawn contours, default is 1.\n */\n public drawContours(cset: RecastContourSet, alpha: number = 1): void {\n const primitives = this._debugDrawerUtils.drawContours(cset, alpha);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws a poly mesh using the debug drawer utilities.\n * @param mesh RecastPolyMesh to draw\n */\n public drawPolyMesh(mesh: RecastPolyMesh): void {\n const primitives = this._debugDrawerUtils.drawPolyMesh(mesh);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws a poly mesh detail using the debug drawer utilities.\n * @param dmesh RecastPolyMeshDetail to draw\n */\n public drawPolyMeshDetail(dmesh: RecastPolyMeshDetail): void {\n const primitives = this._debugDrawerUtils.drawPolyMeshDetail(dmesh);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws a NavMesh using the debug drawer utilities.\n * @param mesh NavMesh to draw\n * @param flags Flags to control the drawing behavior, default is 0.\n */\n public drawNavMesh(mesh: NavMesh, flags: number = 0): void {\n const primitives = this._debugDrawerUtils.drawNavMesh(mesh, flags);\n this.drawPrimitives(primitives);\n }\n\n // todo:\n // - drawTileCacheLayerAreas\n // - drawTileCacheLayerRegions\n // - drawTileCacheContours\n // - drawTileCachePolyMesh\n\n /**\n * Draws a NavMesh with closed list using the debug drawer utilities.\n * @param mesh NavMesh to draw\n * @param query NavMeshQuery to use for drawing the closed list.\n * @param flags Flags to control the drawing behavior, default is 0.\n */\n public drawNavMeshWithClosedList(mesh: NavMesh, query: NavMeshQuery, flags: number = 0): void {\n const primitives = this._debugDrawerUtils.drawNavMeshWithClosedList(mesh, query, flags);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws the nodes of a NavMesh using the debug drawer utilities.\n * @param query NavMeshQuery to use for drawing the nodes.\n */\n public drawNavMeshNodes(query: NavMeshQuery): void {\n const primitives = this._debugDrawerUtils.drawNavMeshNodes(query);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws the bounding volume tree of a NavMesh using the debug drawer utilities.\n * @param mesh NavMesh to draw the bounding volume tree for.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public drawNavMeshBVTree(mesh: NavMesh): void {\n const primitives = this._debugDrawerUtils.drawNavMeshBVTree(mesh);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws the portals of a NavMesh using the debug drawer utilities.\n * @param mesh NavMesh to draw the portals for.\n */\n public drawNavMeshPortals(mesh: NavMesh): void {\n const primitives = this._debugDrawerUtils.drawNavMeshPortals(mesh);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws polygons of a NavMesh with specific flags using the debug drawer utilities.\n * @param mesh NavMesh to draw the polygons with specific flags.\n * @param flags The flags to filter the polygons to be drawn.\n * @param col The color to use for the drawn polygons, represented as a number.\n */\n public drawNavMeshPolysWithFlags(mesh: NavMesh, flags: number, col: number): void {\n const primitives = this._debugDrawerUtils.drawNavMeshPolysWithFlags(mesh, flags, col);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Draws polygons of a NavMesh with specific reference and color using the debug drawer utilities.\n * @param mesh NavMesh to draw the polygons with specific reference and color.\n * @param ref The reference number of the polygons to be drawn.\n * @param col The color to use for the drawn polygons, represented as a number.\n */\n public drawNavMeshPoly(mesh: NavMesh, ref: number, col: number): void {\n const primitives = this._debugDrawerUtils.drawNavMeshPoly(mesh, ref, col);\n this.drawPrimitives(primitives);\n }\n\n /**\n * Get the intermediates from the generator\n * @param intermediates - The generator intermediates\n * @returns An object containing lists of heightfields, compact heightfields, contour sets\n */\n public getIntermediates = (intermediates: GeneratorIntermediates) => {\n const heightfieldList: RecastHeightfield[] = [];\n const compactHeightfieldList: RecastCompactHeightfield[] = [];\n const contourSetList: RecastContourSet[] = [];\n const polyMeshList: RecastPolyMesh[] = [];\n const polyMeshDetailList: RecastPolyMeshDetail[] = [];\n\n if (intermediates) {\n if (intermediates.type === \"solo\") {\n if (intermediates.heightfield) {\n heightfieldList.push(intermediates.heightfield);\n }\n\n if (intermediates.compactHeightfield) {\n compactHeightfieldList.push(intermediates.compactHeightfield);\n }\n\n if (intermediates.contourSet) {\n contourSetList.push(intermediates.contourSet);\n }\n\n if (intermediates.polyMesh) {\n polyMeshList.push(intermediates.polyMesh);\n }\n\n if (intermediates.polyMeshDetail) {\n polyMeshDetailList.push(intermediates.polyMeshDetail);\n }\n } else if (intermediates.type === \"tiled\") {\n for (const tile of intermediates.tileIntermediates) {\n if (tile.heightfield) {\n heightfieldList.push(tile.heightfield);\n }\n\n if (tile.compactHeightfield) {\n compactHeightfieldList.push(tile.compactHeightfield);\n }\n\n if (tile.contourSet) {\n contourSetList.push(tile.contourSet);\n }\n\n if (tile.polyMesh) {\n polyMeshList.push(tile.polyMesh);\n }\n\n if (tile.polyMeshDetail) {\n polyMeshDetailList.push(tile.polyMeshDetail);\n }\n }\n } else if (intermediates.type === \"tilecache\") {\n for (const tile of intermediates.tileIntermediates) {\n if (tile.heightfield) {\n heightfieldList.push(tile.heightfield);\n }\n\n if (tile.compactHeightfield) {\n compactHeightfieldList.push(tile.compactHeightfield);\n }\n }\n }\n }\n\n return {\n heightfieldList,\n compactHeightfieldList,\n contourSetList,\n polyMeshList,\n polyMeshDetailList,\n };\n };\n\n /**\n * Draw debug information based on the selected option\n * @param navMesh - The navigation mesh to draw\n * @param intermediates - The generator intermediates containing the data to draw\n * @param scene - The scene to draw in\n * @param option - The debug drawer option to use\n * @remarks This method will reset the debug drawer before drawing.\n */\n public draw(navMesh: NavMesh, intermediates: GeneratorIntermediates, scene: Scene, option: DebugLayerOptions) {\n this.clear();\n\n const { heightfieldList, compactHeightfieldList, contourSetList, polyMeshList, polyMeshDetailList } = this.getIntermediates(intermediates);\n\n if (option === DebugLayerOption.HEIGHTFIELD_SOLID) {\n for (const heightfield of heightfieldList) {\n this.drawHeightfieldSolid(heightfield);\n }\n } else if (option === DebugLayerOption.HEIGHTFIELD_WALKABLE) {\n for (const heightfield of heightfieldList) {\n this.drawHeightfieldWalkable(heightfield);\n }\n } else if (option === DebugLayerOption.COMPACT_HEIGHTFIELD_SOLID) {\n for (const compactHeightfield of compactHeightfieldList) {\n this.drawCompactHeightfieldSolid(compactHeightfield);\n }\n } else if (option === DebugLayerOption.COMPACT_HEIGHTFIELD_REGIONS) {\n for (const compactHeightfield of compactHeightfieldList) {\n this.drawCompactHeightfieldRegions(compactHeightfield);\n }\n } else if (option === DebugLayerOption.COMPACT_HEIGHTFIELD_DISTANCE) {\n for (const compactHeightfield of compactHeightfieldList) {\n this.drawCompactHeightfieldDistance(compactHeightfield);\n }\n } else if (option === DebugLayerOption.RAW_CONTOURS) {\n for (const contourSet of contourSetList) {\n this.drawRawContours(contourSet);\n }\n } else if (option === DebugLayerOption.CONTOURS) {\n for (const contourSet of contourSetList) {\n this.drawContours(contourSet);\n }\n } else if (option === DebugLayerOption.POLY_MESH) {\n for (const polyMesh of polyMeshList) {\n this.drawPolyMesh(polyMesh);\n }\n } else if (option === DebugLayerOption.POLY_MESH_DETAIL) {\n for (const polyMeshDetail of polyMeshDetailList) {\n this.drawPolyMeshDetail(polyMeshDetail);\n }\n } else if (option === DebugLayerOption.NAVMESH) {\n this.drawNavMesh(navMesh);\n } else if (option === DebugLayerOption.NAVMESH_BV_TREE) {\n this.drawNavMeshBVTree(navMesh);\n }\n }\n\n private _drawPoints(primitive: DebugDrawerPrimitive): void {\n if (primitive.vertices.length === 0) {\n return;\n }\n\n const matricesData = new Float32Array(16 * primitive.vertices.length);\n const colorData = new Float32Array(4 * primitive.vertices.length);\n\n for (let i = 0; i < primitive.vertices.length; i++) {\n const [x, y, z, r, g, b, a] = primitive.vertices[i];\n\n colorData[i * 4] = r;\n colorData[i * 4 + 1] = g;\n colorData[i * 4 + 2] = b;\n colorData[i * 4 + 3] = a;\n\n const matrix = Matrix.Translation(x, y, z);\n matrix.copyToArray(matricesData, i * 16);\n }\n\n this._pointMesh.thinInstanceSetBuffer(\"matrix\", matricesData, 16);\n this._pointMesh.thinInstanceSetBuffer(\"color\", colorData, 4);\n\n this._pointMesh.parent = this.debugDrawerParentNode;\n }\n\n private _drawLines(primitive: DebugDrawerPrimitive, instance: Nullable<GreasedLineBaseMesh>): Nullable<GreasedLineBaseMesh> {\n if (primitive.vertices.length === 0) {\n return null;\n }\n\n const points: number[][] = [];\n const colors: Color3[] = [];\n\n for (let i = 0; i < primitive.vertices.length; i += 2) {\n const [x1, y1, z1, r1, g1, b1] = primitive.vertices[i];\n const [x2, y2, z2, r2, g2, b2] = primitive.vertices[i + 1];\n\n points.push([x1, y1, z1, x2, y2, z2]);\n\n colors.push(new Color3(r1, g1, b1));\n colors.push(new Color3(r2, g2, b2));\n }\n\n const options = { ...this._lineMaterialOptions.greasedLineMeshOptions, points, instance: instance ?? undefined };\n const materialOptions = { ...this._lineMaterialOptions.greasedLineMaterialOptions, colors };\n\n const lines = CreateGreasedLine(NavigationDebugger.NAV_MESH_DEBUG_NAME_LINES, options, materialOptions);\n\n lines.parent = this.debugDrawerParentNode;\n this.lineMaterials.push(lines.material as StandardMaterial);\n\n return lines;\n }\n\n private _drawTris(primitive: DebugDrawerPrimitive): void {\n if (primitive.vertices.length === 0) {\n return;\n }\n\n const positions = new Float32Array(primitive.vertices.length * 3);\n const colors = new Float32Array(primitive.vertices.length * 4);\n\n for (let i = 0; i < primitive.vertices.length; i++) {\n const [x, y, z, r, g, b] = primitive.vertices[i];\n positions[i * 3 + 0] = x;\n positions[i * 3 + 1] = y;\n positions[i * 3 + 2] = z;\n\n colors[i * 4 + 0] = r;\n colors[i * 4 + 1] = g;\n colors[i * 4 + 2] = b;\n colors[i * 4 + 3] = 1;\n }\n\n const vertexData = new VertexData();\n\n vertexData.positions = positions;\n vertexData.colors = colors;\n\n const customMesh = new Mesh(NavigationDebugger.NAV_MESH_DEBUG_NAME_TRIS);\n customMesh.isUnIndexed = true;\n vertexData.applyToMesh(customMesh);\n\n customMesh.material = this.triMaterial;\n customMesh.parent = this.debugDrawerParentNode;\n }\n\n private _drawQuads(primitive: DebugDrawerPrimitive): void {\n if (primitive.vertices.length === 0) {\n return;\n }\n\n const positions: number[] = [];\n const colors: number[] = [];\n for (let i = 0; i < primitive.vertices.length; i += 4) {\n const vertices = [\n primitive.vertices[i],\n primitive.vertices[i + 1],\n primitive.vertices[i + 2],\n primitive.vertices[i],\n primitive.vertices[i + 2],\n primitive.vertices[i + 3],\n ];\n for (const [x, y, z, r, g, b] of vertices) {\n positions.push(x, y, z);\n colors.push(r, g, b, 1);\n }\n }\n\n const vertexData = new VertexData();\n\n vertexData.positions = positions;\n vertexData.colors = colors;\n\n const customMesh = new Mesh(NavigationDebugger.NAV_MESH_DEBUG_NAME_QUADS);\n customMesh.isUnIndexed = true;\n vertexData.applyToMesh(customMesh);\n\n customMesh.material = this.triMaterial;\n customMesh.parent = this.debugDrawerParentNode;\n }\n\n /**\n * Merge the debug meshes for better performance\n */\n private _joinDebugMeshes() {\n const debugMeshes = this._scene.meshes.filter((m) => m.name === NavigationDebugger.NAV_MESH_DEBUG_NAME) as Mesh[];\n\n // only indexed meshes can be merged\n debugMeshes.forEach((m) => {\n this._convertUnindexedToIndexed(m);\n });\n\n const merged = Mesh.MergeMeshes(debugMeshes, true);\n if (merged) {\n merged.name = NavigationDebugger.NAV_MESH_DEBUG_NAME;\n merged.parent = this.debugDrawerParentNode;\n }\n }\n\n private _convertUnindexedToIndexed(mesh: Mesh): void {\n const vertexData = VertexData.ExtractFromMesh(mesh);\n const positions = vertexData.positions;\n\n if (!positions || positions.length % 9 !== 0) {\n Logger.Warn(\"Mesh must be fully unindexed with triangles.\");\n return;\n }\n\n const vertexCount = positions.length / 3;\n const indices = Array.from({ length: vertexCount }, (_, i) => i);\n\n const newVertexData = new VertexData();\n newVertexData.positions = positions;\n newVertexData.indices = indices;\n\n newVertexData.applyToMesh(mesh, true);\n }\n}\n","import * as addons from \"addons/index\";\r\n\r\nexport { addons };\r\nexport default addons;\r\n"],"names":["root","factory","exports","module","require","define","amd","self","global","this","__WEBPACK_EXTERNAL_MODULE__597__","name","shader","ShaderStore","ShadersStore","msdfVertexShader","ShadersStoreWGSL","msdfPixelShaderWGSL","msdfPixelShader","msdfVertexShaderWGSL","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","n","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","extendStatics","b","setPrototypeOf","__proto__","Array","p","__extends","TypeError","String","__","constructor","create","__assign","assign","t","s","i","arguments","length","apply","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","e","rejected","result","done","then","__generator","body","f","y","_","label","sent","trys","ops","g","Iterator","verb","iterator","v","op","pop","push","__spreadArray","to","from","pack","ar","l","slice","concat","SuppressedError","UboArray","useAerialPerspectiveLut","APPLY_AERIAL_PERSPECTIVE_INTENSITY","APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS","USE_AERIAL_PERSPECTIVE_LUT","MaterialDefines","size","type","material","_atmosphere","_isAerialPerspectiveEnabled","USE_CUSTOM_REFLECTION","diffuseSkyIrradianceLut","CUSTOM_FRAGMENT_BEFORE_FOG","isAerialPerspectiveLutEnabled","aerialPerspectiveIntensity","aerialPerspectiveRadianceBias","doNotSerialize","_pluginManager","_addPlugin","getUniformBuffersNames","_ubos","uniformBuffer","useUbo","getUniforms","atmosphere","ubo","fragment","externalUniforms","getUniformNames","isReadyForSubMesh","isReady","aerialPerspectiveLutRenderTarget","transmittanceLutRenderTarget","transmittanceLut","renderTarget","getActiveTextures","_activeTextures","bindForSubMesh","engine","scene","getEngine","effect","currentEffect","bindUniformBufferToEffect","width","getRenderWidth","height","getRenderHeight","updateFloat2","setTexture","prepareDefines","defines","lastUseAerialPerspectiveLut","lastApplyAerialPerspectiveIntensity","lastApplyAerialPerspectiveRadianceBias","markAllAsDirty","getSamplers","samplers","getCustomCode","shaderType","directionToLightSnippet","supportsUniformBuffers","atmosphereImportSnippet","CUSTOM_FRAGMENT_DEFINITIONS","CUSTOM_LIGHT0_COLOR","CUSTOM_REFLECTION","MaterialPluginBase","TempRay","Ray","Vector3","Zero","_inverseViewProjectionMatrixWithoutTranslation","Matrix","Identity","_directionToLightRelativeToCameraGeocentricNormal","Up","_cosAngleLightToZenith","_cameraRadius","_clampedCameraRadius","_cameraHeight","_clampedCameraHeight","_cameraPositionGlobal","_clampedCameraPositionGlobal","_cosCameraHorizonAngleFromZenith","_sinCameraAtmosphereHorizonAngleFromNadir","_cameraGeocentricNormal","_cameraForward","Down","_cameraNearPlane","_cameraPosition","_viewport","Vector4","_lastViewMatrix","_lastProjectionMatrix","_inverseViewMatrixWithoutTranslation","_inverseProjectionMatrix","update","camera","planetRadius","planetRadiusWithOffset","atmosphereRadius","directionToLight","originHeight","minZ","copyFrom","getForwardRayToRef","direction","getScene","copyFromFloats","viewMatrix","getViewMatrix","projectionMatrix","getProjectionMatrix","equals","setTranslation","ZeroReadOnly","invertToRef","multiplyToRef","globalPosition","scaleToRef","normalizeToRef","ComputeCosHorizonAngleFromZenith","Math","min","Vector3Dot","lightZenithSinAngle","sqrt","max","normalize","radius","sinHorizonAngleFromNadir","DefaultPeakRayleighScattering","DefaultPeakMieScattering","DefaultPeakMieAbsorption","DefaultPeakOzoneAbsorption","options","onChangedObservable","Observable","_peakRayleighScattering","_peakMieScattering","_peakMieAbsorption","_peakOzoneAbsorption","_planetRadiusWithOffset","_planetRadiusSquared","_atmosphereRadius","_atmosphereRadiusSquared","_horizonDistanceToAtmosphereEdge","_horizonDistanceToAtmosphereEdgeSquared","_rayleighScattering","_mieScattering","_mieAbsorption","_mieExtinction","_ozoneAbsorption","_planetRadius","_planetRadiusOffset","planetRadiusOffset","_atmosphereThickness","atmosphereThickness","_rayleighScatteringScale","rayleighScatteringScale","peakRayleighScattering","_mieScatteringScale","mieScatteringScale","peakMieScattering","_mieAbsorptionScale","mieAbsorptionScale","peakMieAbsorption","_ozoneAbsorptionScale","ozoneAbsorptionScale","peakOzoneAbsorption","_recomputeDimensionalParameters","_recomputeRayleighScattering","_recomputeMieScattering","_recomputeMieAbsorption","_recomputeOzoneAbsorption","notifyObservers","_recomputeMieExtinction","addToRef","MakeTempColor4Like","Number","NaN","TmpColor1","TmpColor2","TmpColor3","TmpColor4","Sample2DRgbaToRef","u","widthPx","heightPx","data","normalizeFunc","Error","expectedLength","Clamp","fractionalTexelX","fractionalTexelY","xLeft","floor","xRight","yBottom","yTop","lowerLeftColor","TexelFetch2DRgbaToRef","upperLeftColor","lowerRightColor","upperRightColor","tX","tY","oneMinusTX","oneMinusTY","w0","w1","w2","w3","x","clampedTexelX","index","IncludesShadersStore","UvTemp","Color4Temp","_renderTarget","_effectWrapper","_effectRenderer","_isDirty","_isDisposed","_lutData","Uint16Array","RenderTargetTexture","generateMipMaps","Constants","TEXTURETYPE_HALF_FLOAT","samplingMode","TEXTURE_BILINEAR_SAMPLINGMODE","generateDepthBuffer","gammaSpace","wrapU","TEXTURE_CLAMP_ADDRESSMODE","wrapV","anisotropicFilteringLevel","skipInitialClear","EffectWrapper","vertexShader","fragmentShader","attributeNames","uniformNames","uniformBuffers","useShaderStore","EffectRenderer","indices","positions","environmentTexture","irradianceTexture","environmentIntensity","isRenderTarget","getDiffuseSkyIrradianceToRef","cameraGeocentricNormal","lightIrradiance","additionalDiffuseSkyIrradiance","properties","physicalProperties","cosAngleLightToZenith","unitX","unitY","ComputeLutUVToRef","z","FromHalfFloat","intensity","diffuseSkyIrradianceIntensity","render","effectWrapper","bindFramebuffer","effectRenderer","applyEffectWrapper","saveStates","setViewport","bindBuffers","multiScatteringLutRenderTarget","setFloat","draw","restoreStates","restoreDefaultFramebuffer","readPixels","markDirty","dispose","TransmittanceHorizonRange","Uv","LightColorTemp","DirectionToLightTemp","onUpdatedObservable","Uint8Array","TEXTURETYPE_UNSIGNED_BYTE","getTransmittedColorToRef","pointRadius","pointGeocentricNormal","lutData","positionDistanceToOrigin","uv","radiusSquared","distanceToHorizon","planetRadiusSquared","discriminant","atmosphereRadiusSquared","distanceToAtmosphereEdge","minDistanceToAtmosphereEdge","maxDistanceToAtmosphereEdge","horizonDistanceToAtmosphereEdge","cosAngleLightToZenithCoordinate","distanceToHorizonCoordinate","weight","SmoothStep","SampleLutToRef","updateLightParameters","light","lightDirection","diffuse","specular","CharCode","MaterialPlugin","lights","_directionToLight","_tempSceneAmbient","Color3","_additionalDiffuseSkyIrradiance","_atmosphereUbo","_minimumMultiScattering","_cameraAtmosphereVariables","AtmospherePerCameraVariables","_lightRadianceAtCamera","_linearLightColor","_atmosphereUniformBufferAsArray","_isEnabled","_hasRenderedMultiScatteringLut","_multiScatteringEffectWrapper","_multiScatteringLutRenderTarget","_aerialPerspectiveLutEffectWrapper","_aerialPerspectiveLutEffectRenderer","_aerialPerspectiveLutRenderTarget","_skyViewLutEffectWrapper","_skyViewLutEffectRenderer","_skyViewLutRenderTarget","_aerialPerspectiveCompositorEffectWrapper","_skyCompositorEffectWrapper","_globeAtmosphereCompositorEffectWrapper","_onBeforeCameraRenderObserver","_onBeforeDrawPhaseObserver","_onAfterRenderingGroupObserver","onAfterUpdateVariablesForCameraObservable","onBeforeLightVariablesUpdateObservable","onBeforeRenderLutsForCameraObservable","onAfterRenderLutsForCameraObservable","depthTexture","_transmittanceLut","_diffuseSkyIrradianceLut","_engine","uniqueId","getUniqueId","isWebGPU","version","_physicalProperties","AtmospherePhysicalProperties","add","_lights","_exposure","exposure","_isLinearSpaceLight","isLinearSpaceLight","_isLinearSpaceComposition","isLinearSpaceComposition","_applyApproximateTransmittance","applyApproximateTransmittance","_aerialPerspectiveRadianceBias","_aerialPerspectiveTransmittanceScale","aerialPerspectiveTransmittanceScale","_aerialPerspectiveSaturation","aerialPerspectiveSaturation","_aerialPerspectiveIntensity","_diffuseSkyIrradianceDesaturationFactor","diffuseSkyIrradianceDesaturationFactor","_diffuseSkyIrradianceIntensity","_additionalDiffuseSkyIrradianceIntensity","additionalDiffuseSkyIrradianceIntensity","_multiScatteringIntensity","multiScatteringIntensity","_minimumMultiScatteringIntensity","minimumMultiScatteringIntensity","_isSkyViewLutEnabled","isSkyViewLutEnabled","_isAerialPerspectiveLutEnabled","_originHeight","_additionalDiffuseSkyIrradianceColor","additionalDiffuseSkyIrradianceColor","_groundAlbedo","groundAlbedo","set","minimumMultiScatteringColor","_minimumMultiScatteringColor","_skyRenderingGroup","skyRenderingGroup","_aerialPerspectiveRenderingGroup","aerialPerspectiveRenderingGroup","_globeAtmosphereRenderingGroup","globeAtmosphereRenderingGroup","TransmittanceLut","CreateRenderTargetTexture","isDiffuseSkyIrradianceLutEnabled","DiffuseSkyIrradianceLut","skyViewLutRenderTarget","onBeforeCameraRenderObservable","_updatePerCameraVariables","_renderLutsForCamera","renderingManager","getRenderingGroup","onBeforeDrawPhaseObservable","_empty","onAfterRenderingGroupObservable","group","groupId","renderingGroupId","drawSkyCompositor","drawAerialPerspectiveCompositor","drawGlobeAtmosphereCompositor","onDisposeObservable","addOnce","removeExternalData","addExternalData","UnregisterMaterialPlugin","RegisterMaterialPlugin","getClassName","AtmospherePBRMaterialPlugin","IsSupported","_badOS","minimumScatteringColor","newValue","_disposeSkyCompositor","_disposeGlobeAtmosphereCompositor","coordinatesMode","TEXTURE_EQUIRECTANGULAR_MODE","CreateSkyViewEffectWrapper","_disposeAerialPerspectiveCompositor","layers","CreateAerialPerspectiveEffectWrapper","hasDefineChanged","atmosphereUbo","UniformBuffer","addUniform","remove","isEnabled","setEnabled","enabled","_createMultiScatteringEffectWrapper","BlackReadOnly","samplerNames","_drawMultiScatteringLut","DrawEffect","clampedCameraRadius","CreateAerialPerspectiveCompositorEffectWrapper","skyViewLut","multiScatteringLut","aerialPerspectiveLut","ALPHA_PREMULTIPLIED_PORTERDUFF","ALPHA_ONEONE","ALWAYS","CreateSkyCompositorEffectWrapper","EQUAL","CreateGlobeAtmosphereCompositorEffectWrapper","scaleInPlace","cameraAtmosphereVariables","toGammaSpaceToRef","ambientColor","updateUniformBuffer","renderGlobalLuts","isDirty","_drawSkyViewLut","_drawAerialPerspectiveLut","bindToEffect","bindUniformBuffer","updateVector3","rayleighScattering","updateFloat","mieScattering","mieAbsorption","mieExtinction","ozoneAbsorption","horizonDistanceToAtmosphereEdgeSquared","updateMatrix","inverseViewProjectionMatrixWithoutTranslation","directionToLightRelativeToCameraGeocentricNormal","cameraRadius","updateColor3","cameraPositionGlobal","clampedCameraPositionGlobal","cameraForward","clampedCameraHeight","cameraPosition","cosCameraHorizonAngleFromZenith","updateVector4","viewport","cameraHeight","cameraNearPlane","sinCameraAtmosphereHorizonAngleFromNadir","layer","CreateEffectWrapper","defineNames","map","defineName","rtOptions","generateStencilBuffer","format","TEXTUREFORMAT_RGBA","drawCallback","depth","alphaMode","depthTest","depthWrite","depthFunction","ALPHA_DISABLE","LEQUAL","currentDepthWrite","getDepthWrite","setDepthWrite","currentDepthFunction","getDepthFunction","setDepthFunction","currentAlphaMode","getAlphaMode","setAlphaMode","textures","hasDepthTexture","BabylonUnitsToPixels","RenderOrderFunc","defaultRenderOrder","subMeshA","subMeshB","meshA","getMesh","meshB","meshIsHtmlMeshA","meshIsHtmlMeshB","absolutePosition","parentContainerId","_containerId","enableOverlayRender","defaultOpaqueRenderOrder","RenderingGroup","PainterSortCompare","defaultAlphaTestRenderOrder","defaultTransparentRenderOrder","defaultTransparentSortCompare","_cache","cameraData","fov","position","style","htmlMeshData","WeakMap","_width","_height","_heightHalf","_temp","scaleTransform","rotationTransform","Quaternion","positionTransform","objectMatrix","cameraWorldMatrix","cameraRotationMatrix","cameraWorldMatrixAsArray","_lastDevicePixelRatio","window","devicePixelRatio","_cameraMatrixUpdated","_previousCanvasDocumentPosition","top","left","_renderObserver","_onCameraMatrixChanged","_cameraWorldMatrix","getWorldMatrix","document","_init","_overlayElements","container","_inSceneElements","parentContainer","getElementById","inSceneContainerId","_createRenderLayerElements","insertBefore","firstChild","overlayContainerId","zIndex","getRenderingCanvas","pointerEvents","projectionObs","matrixObs","clientRect","getRenderingCanvasClientRect","_setSize","onResizeObservable","observeCamera","activeCamera","onProjectionMatrixChangedObservable","onViewMatrixChangedObservable","onActiveCameraChanged","opaqueRenderOrder","alphaTestRenderOrder","transparentRenderOrder","setRenderingOrder","onBeforeRenderObservable","_render","containerId","existingContainer","createElement","id","domElement","overflow","cameraElement","webkitTransformStyle","transformStyle","appendChild","_getSize","dom","_getCameraCssMatrix","matrix","elements","m","_epsilon","_getHtmlContentCssMatrix","useRightHandedSystem","_getTransformationMatrix","htmlMesh","objectWorldMatrix","widthScaleFactor","heightScaleFactor","sourceWidth","sourceHeight","scaledAndTranslatedObjectMatrix","decompose","ComposeToRef","getAbsolutePosition","setRowFromFloats","HtmlMeshRenderer","PROJECTION_SCALE_FACTOR","multiplyAtIndex","_renderHtmlMesh","element","firstElementChild","_isCanvasOverlay","parentNode","requiresUpdate","_updateBaseScaleFactor","billboardMode","TransformNode","BILLBOARDMODE_NONE","webkitTransform","transform","_markAsUpdated","needsUpdate","_updateContainerPositionIfNeeded","Logger","Log","meshesNeedingUpdate","meshes","filter","mesh","source","mode","Camera","PERSPECTIVE_CAMERA","el","webkitPerspective","perspective","parent","computeWorldMatrix","cameraMatrixWorld","getRotationMatrix","transposeToRef","cameraMatrixWorldAsArray","copyToArray","FromArrayToRef","screenWidth","screenHeight","htmlMeshAspectRatio","setContentSizePx","canvasRect","scrollTop","scrollY","scrollLeft","scrollX","canvasDocumentTop","canvasDocumentLeft","containerParent","offsetParent","parentRect","getBoundingClientRect","parentDocumentTop","parentDocumentLeft","ancestorMarginsAndPadding","_getAncestorMarginsAndPadding","bodyStyle","getComputedStyle","bodyMarginTop","parseInt","marginTop","bodyMarginLeft","marginLeft","paddingTop","paddingLeft","Warn","abs","documentElement","CaptureRequestQueue","PendingRequestCallbacks","Map","UnmatchedReleaseRequests","CurrentOwner","requestRelease","requestId","DebugLog","CancelRequest","delete","includes","TransferPointerEventsOwnership","removed","newOwnerId","NextCaptureRequest","DoRelease","DoCapture","release","capture","shift","message","Tools","performance","now","LocalScene","CaptureOnEnterCount","MeshToBehaviorMap","StartCaptureOnEnter","addEventListener","OnPointerMove","DoStopCaptureOnEnter","removeEventListener","StopCaptureOnEnter","evt","pickedMesh","touches","clientX","clientY","pointerScreenX","pointerScreenY","pickResult","pick","pointerCaptureBehavior","_captureOnPointerEnter","hit","capturingIdAsInt","capturePointerEvents","_captureCallback","_releaseCallback","captureOnPointerEnter","_attachedMesh","init","attach","attachedMesh","detach","releasePointerEvents","toString","captureCallback","releaseCallback","RemoveUnmatchedRequest","EnqueueCaptureRequest","FitStrategy","CONTAIN","wrapElement","sizingElement","display","justifyContent","alignItems","scalingElement","visibility","updateSize","offsetWidth","offsetHeight","childWidth","childHeight","scale","COVER","STRETCH","NONE","isCanvasOverlay","fitStrategy","_enabled","_ready","_requiresUpdate","_inverseScaleMatrix","_pointerEventCaptureBehavior","_sourceWidth","_sourceHeight","_fitStrategy","_createMask","_element","_createElement","PointerEventsCaptureBehavior","bind","addBehavior","setContent","_setAsReady","scaling","setAll","_updateScaleIfNecessary","_doSetEnabled","ready","_worldMatrixUpdateObserver","onAfterWorldMatrixUpdateObservable","_setElementzIndex","bakeTransformIntoVertices","scaleX","scaleY","scaleMatrix","Scaling","CreatePlaneVertexData","applyToMesh","checkCollisions","depthMask","StandardMaterial","backFaceCulling","disableColorWrite","disableLighting","freeze","getElementsByTagName","div","backgroundColor","backfaceVisibility","Mesh","_Recast","definitionData","textureUrl","_chars","_kernings","_font","JSON","parse","pages","chars","forEach","char","kernings","kerning","submap","first","second","amount","_charsRegex","RegExp","c","replace","join","_updateFallbacks","info","page","texture","Texture","noMipmap","invertY","has","SPACE","xoffset","yoffset","xadvance","chnl","TOFU","_getChar","charCode","_getKerning","_unsupportedChars","text","DefaultParagraphOptions","maxWidth","Infinity","lineHeight","letterSpacing","tabSize","whiteSpace","textAlign","translate","fontAsset","customLayoutEngine","_computeMetrics","paragraph","lines","glyphs","common","collapsed","_collapse","trimmed","_breakLines","line","trim","_wrap","anchor","glyph","flatMap","split","repeat","lineOffset","lastChar","currentLine","currentGlyphs","currentCursor","currentWidth","start","end","pushCurrentLine","charCodeAt","charWidth","newWidth","cursorProgress","nextPosition","shouldBreak","shaderLanguage","font","_useVAO","_vertexBuffers","_charMatrices","_charUvs","_baseLine","_scalingMatrix","ThinMatrix","_fontScaleMatrix","_offsetMatrix","_translationMatrix","_baseMatrix","_scaledMatrix","_localMatrix","_finalMatrix","_lineMatrix","_parentWorldMatrix","color","strokeColor","strokeInsetWidth","strokeOutsetWidth","thicknessControl","_parent","_transformMatrix","isBillboard","isBillboardScreenProjected","ignoreDepthBuffer","_shaderLanguage","getCaps","vertexArrayObject","disableVertexArrayObjects","spriteData","Float32Array","_spriteBuffer","Buffer","createVertexBuffer","_resizeBuffers","capacity","_worldBuffer","_uvBuffer","_setShaders","vertex","_drawWrapperBase","DrawWrapper","drawContext","useInstancing","createEffect","vertexSource","fragmentSource","_refCount","addParagraph","worldMatrix","SdfTextParagraph","fontScale","texWidth","scaleW","texHeight","scaleH","worldMatrixToUse","TranslationMatrixToRef","ScalingMatrixToRef","charsUvsBase","matricesBase","MultiplyMatricesToRef","CopyMatrixToArray","drawWrapper","setState","enableEffect","setDepthBuffer","CopyMatrixToRef","IdentityMatrixToRef","setInt","setMatrix","transformMatrix","setDirectColor4","instanceCount","getBuffer","_vertexArrayObject","recordVertexArrayObject","bindVertexArrayObject","ALPHA_COMBINE","drawArraysType","MATERIAL_TriangleStripDrawMode","unbindInstanceAttributes","releaseVertexArrayObject","CreateTextRendererAsync","instancedArrays","_features","supportSpriteInstancing","textRenderer","TextRenderer","GetRecast","_InitPromise","InitRecast","localOptions","url","instance","baseUrl","importMap","imports","script","textContent","stringify","_LoadScriptModuleAsync","ImportRecast","core","generators","CreateDefaultTileCacheMeshProcess","offMeshConnections","area","flags","navMeshCreateParams","polyAreas","polyFlags","polyCount","setOffMeshConnections","WaitForFullTileCacheUpdate","navMesh","tileCache","upToDate","DefaultMaxObstacles","CreateSoloNavMeshConfig","parameters","ToSoloNavMeshGeneratorConfig","CreateTiledNavMeshConfig","tileSize","CreateTileCacheNavMeshConfig","cfg","expectedLayersPerTile","maxObstacles","tileCacheMeshProcess","config","fromEntries","entries","ToCrowdAgentParams","agentParams","plugin","maxAgents","maxAgentRadius","_transforms","_agents","_reachRadii","_agentDestinationArmed","_agentDestination","_onBeforeAnimationsObserver","onReachTargetObservable","_navigationPlugin","_recastCrowd","_scene","onBeforeAnimationsObservable","getDeltaTime","timeFactor","addAgent","pos","agent","agentIndex","reachRadius","getAgentPosition","agentPos","getAgent","getAgentPositionToRef","getAgentVelocity","agentVel","velocity","getAgentVelocityToRef","getAgentNextTargetPath","pathTargetPos","nextTargetInPath","getAgentNextTargetPathToRef","getAgentState","state","overOffmeshConnection","overOffMeshConnection","agentGoto","destination","requestMoveTarget","item","indexOf","agentTeleport","teleport","updateAgentParameters","maxAcceleration","maxSpeed","collisionQueryRange","pathOptimizationRange","separationWeight","updateParameters","removeAgent","splice","getAgents","deltaTime","Epsilon","timeStep","getTimeStep","maxStepCount","getMaximumSubStepCount","iterationCount","agentPosition","dx","dz","groundY","ceilingY","distanceXZSquared","setDefaultQueryExtent","extent","getDefaultQueryExtent","getDefaultQueryExtentToRef","getCorners","corners","destroy","clear","ConvertNavPathPoints","navPath","success","pointCount","path","pt","ComputePathError","START_NEAREST_POLY_FAILED","END_NEAREST_POLY_FAILED","FIND_PATH_FAILED","NO_POLYGON_PATH_FOUND","NO_CLOSEST_POINT_ON_LAST_POLYGON_FOUND","_DELTA","_MOVE_TARGET","ComputeSmoothPath","navmeshQuery","navMeshQuery","recast","defaultFilter","halfExtents","defaultQueryHalfExtents","maxSmoothPathPoints","maxPathPolys","stepSize","slop","startNearestPolyResult","findNearestPoly","error","status","endNearestPolyResult","startRef","nearestRef","endRef","findPathResult","findPath","polys","lastPoly","closestEnd","lastPolyClosestPointResult","closestPointOnPoly","closestPoint","iterPos","targetPos","getHeapView","smoothPath","clone","steerTarget","getSteerTarget","isEndOfPath","steerPosFlag","Detour","DT_STRAIGHTPATH_END","isOffMeshConnection","DT_STRAIGHTPATH_OFFMESH_CONNECTION","steerPos","delta","subtract","len","dot","moveTarget","addInPlace","moveAlongSurface","maxVisitedSize","resultPosition","fixupCorridor","visited","fixupShortcuts","polyHeightResult","getPolyHeight","inRange","offMeshConRef","steerPosRef","prevPolyRef","polyRef","npos","offMeshConnectionPolyEndPoints","getOffMeshConnectionPolyEndPoints","endPositionPolyHeight","ComputeSmoothPathImpl","minTargetDist","pathPolys","straightPath","findStraightPath","maxStraightPathPoints","outPoints","straightPathCount","point","ns","straightPathFlags","straightPathRefs","points","h","dy","maxPath","visitedPolyRefs","furthestPath","furthestVisited","found","j","req","orig","nneis","neis","tileAndPoly","getTileAndPolyByRef","poly","tile","k","firstLink","DT_NULL_LINK","links","link","ref","cut","GetPositionsAndIndices","tri","offset","meshIndices","GetReversedIndices","meshPositions","getVerticesData","VertexBuffer","PositionKind","worldMatrices","hasThinInstances","thinMatrices","thinInstanceGetWorldMatrices","instanceIndex","tmpMatrix","transformed","matrixIndex","wm","TransformCoordinatesToRef","Uint32Array","meshOrIndices","getIndices","CreateDebugNavMesh","getNavMeshPositionsAndIndices","vertexData","VertexData","GenerateNavMesh","needsTileCache","needsTiledNavMesh","generateTileCache","keepIntermediates","generateTiledNavMesh","generateSoloNavMesh","intermediates","NavMeshQuery","InjectGenerators","navigationPlugin","createNavMeshImpl","createNavMeshAsyncImpl","recastInjection","_maximumSubStepCount","_timeStep","_timeFactor","bjsRECAST","isSupported","setTimeStep","_navMeshQuery","_intermediates","_tileCache","newTimeStep","setMaximumSubStepCount","newStepCount","createNavMesh","_preprocessParameters","_processNavMeshResult","createNavMeshAsync","createDebugNavMesh","getClosestPoint","ret","findClosestPoint","getClosestPointToRef","getRandomPointAround","maxRadius","findRandomPointAroundCircle","randomPoint","getRandomPointAroundToRef","moveAlong","moveAlongToRef","computePath","computePathSmooth","createCrowd","crowd","RecastJSCrowd","_crowd","buildFromNavmeshData","importNavMesh","getNavmeshData","exportNavMesh","buildFromTileCacheData","tileCacheData","importTileCache","getTileCacheData","exportTileCache","addCylinderObstacle","doNotWaitForCacheUpdate","obstacleResult","obstacle","addBoxObstacle","angle","removeObstacle","getRandomSeed","setRandomSeed","seed","raycast","nearestStartPoly","raycastResult","TmpVectors","distanceToHitBorder","Distance","hitPoint","multiplyByFloats","moveAlongWithVelocity","walkableSlopeAngle","CreateNavigationPluginAsync","RecastNavigationJSPluginV2","GetChaikinSmoothPath","iterations","smoothed","p0","p1","GetLShapedPath","navSegment","p01","pointB","x1","y1","x2","y2","pointA","BuildFromNavmeshData","BuildFromTileCacheData","DebugLayerOption","HEIGHTFIELD_SOLID","HEIGHTFIELD_WALKABLE","COMPACT_HEIGHTFIELD_SOLID","COMPACT_HEIGHTFIELD_REGIONS","COMPACT_HEIGHTFIELD_DISTANCE","RAW_CONTOURS","CONTOURS","POLY_MESH","POLY_MESH_DETAIL","NAVMESH","NAVMESH_BV_TREE","lineMaterials","getIntermediates","heightfieldList","compactHeightfieldList","contourSetList","polyMeshList","polyMeshDetailList","heightfield","compactHeightfield","contourSet","polyMesh","polyMeshDetail","tileIntermediates","_debugDrawerUtils","_primitiveTypes","primitiveTypes","debugDrawerParentNode","node","materials","triMaterial","specularColor","Black","alpha","pointMaterial","lineMaterialOptions","_lineMaterialOptions","greasedLineMaterialOptions","sizeAttenuation","greasedLineMeshOptions","_pointMesh","CreateBox","NavigationDebugger","NAV_MESH_DEBUG_NAME_POINTS","getChildMeshes","drawPrimitives","primitives","linesInstance","primitive","_drawPoints","_drawLines","_drawTris","_drawQuads","updateLazy","joinMeshes","_joinDebugMeshes","drawHeightfieldSolid","hf","drawHeightfieldWalkable","drawCompactHeightfieldSolid","chf","drawCompactHeightfieldRegions","drawCompactHeightfieldDistance","drawHeightfieldLayer","idx","drawHeightfieldLayers","lset","drawRegionConnections","cset","drawRawContours","drawContours","drawPolyMesh","drawPolyMeshDetail","dmesh","drawNavMesh","drawNavMeshWithClosedList","query","drawNavMeshNodes","drawNavMeshBVTree","drawNavMeshPortals","drawNavMeshPolysWithFlags","col","drawNavMeshPoly","option","vertices","matricesData","colorData","Translation","thinInstanceSetBuffer","colors","z1","r1","g1","b1","z2","r2","g2","b2","materialOptions","CreateGreasedLine","NAV_MESH_DEBUG_NAME_LINES","customMesh","NAV_MESH_DEBUG_NAME_TRIS","isUnIndexed","NAV_MESH_DEBUG_NAME_QUADS","debugMeshes","NAV_MESH_DEBUG_NAME","_convertUnindexedToIndexed","merged","MergeMeshes","ExtractFromMesh","vertexCount","newVertexData"],"sourceRoot":""}