@onerjs/core 8.54.2 → 8.54.3

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.
Files changed (165) hide show
  1. package/Animations/animatable.core.js.map +1 -1
  2. package/AudioV2/abstractAudio/abstractSoundSource.d.ts +26 -0
  3. package/AudioV2/abstractAudio/abstractSoundSource.js.map +1 -1
  4. package/AudioV2/webAudio/webAudioEngine.js +2 -0
  5. package/AudioV2/webAudio/webAudioEngine.js.map +1 -1
  6. package/AudioV2/webAudio/webAudioSoundSource.d.ts +16 -0
  7. package/AudioV2/webAudio/webAudioSoundSource.js +43 -1
  8. package/AudioV2/webAudio/webAudioSoundSource.js.map +1 -1
  9. package/Bones/skeleton.functions.js +1 -1
  10. package/Bones/skeleton.functions.js.map +1 -1
  11. package/Cameras/inputMapper.js.map +1 -1
  12. package/Debug/physicsViewer.pure.js +1 -1
  13. package/Debug/physicsViewer.pure.js.map +1 -1
  14. package/Engines/Extensions/engine.alphaToCoverage.d.ts +6 -0
  15. package/Engines/Extensions/engine.alphaToCoverage.js +9 -0
  16. package/Engines/Extensions/engine.alphaToCoverage.js.map +1 -0
  17. package/Engines/Extensions/engine.alphaToCoverage.pure.d.ts +6 -0
  18. package/Engines/Extensions/engine.alphaToCoverage.pure.js +54 -0
  19. package/Engines/Extensions/engine.alphaToCoverage.pure.js.map +1 -0
  20. package/Engines/Extensions/engine.alphaToCoverage.types.d.ts +21 -0
  21. package/Engines/Extensions/engine.alphaToCoverage.types.js +2 -0
  22. package/Engines/Extensions/engine.alphaToCoverage.types.js.map +1 -0
  23. package/Engines/Extensions/index.d.ts +1 -0
  24. package/Engines/Extensions/index.js +1 -0
  25. package/Engines/Extensions/index.js.map +1 -1
  26. package/Engines/Extensions/pure.d.ts +1 -0
  27. package/Engines/Extensions/pure.js +1 -0
  28. package/Engines/Extensions/pure.js.map +1 -1
  29. package/Engines/Native/nativeHelpers.js +6 -4
  30. package/Engines/Native/nativeHelpers.js.map +1 -1
  31. package/Engines/Native/nativeInterfaces.d.ts +1 -0
  32. package/Engines/Native/nativeInterfaces.js.map +1 -1
  33. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.d.ts +6 -0
  34. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.js +9 -0
  35. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.js.map +1 -0
  36. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.pure.d.ts +6 -0
  37. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.pure.js +34 -0
  38. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.pure.js.map +1 -0
  39. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.types.d.ts +16 -0
  40. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.types.js +2 -0
  41. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.types.js.map +1 -0
  42. package/Engines/WebGPU/Extensions/index.d.ts +1 -0
  43. package/Engines/WebGPU/Extensions/index.js +1 -0
  44. package/Engines/WebGPU/Extensions/index.js.map +1 -1
  45. package/Engines/WebGPU/Extensions/pure.d.ts +1 -0
  46. package/Engines/WebGPU/Extensions/pure.js +1 -0
  47. package/Engines/WebGPU/Extensions/pure.js.map +1 -1
  48. package/Engines/WebGPU/webgpuCacheRenderPipeline.js +0 -1
  49. package/Engines/WebGPU/webgpuCacheRenderPipeline.js.map +1 -1
  50. package/Engines/abstractEngine.pure.d.ts +0 -15
  51. package/Engines/abstractEngine.pure.js +2 -23
  52. package/Engines/abstractEngine.pure.js.map +1 -1
  53. package/Engines/constants.d.ts +4 -0
  54. package/Engines/constants.js +4 -0
  55. package/Engines/constants.js.map +1 -1
  56. package/Engines/engine.d.ts +2 -2
  57. package/Engines/engine.js +1 -0
  58. package/Engines/engine.js.map +1 -1
  59. package/Engines/engine.pure.js +1 -1
  60. package/Engines/engine.pure.js.map +1 -1
  61. package/Engines/thinEngine.pure.d.ts +0 -11
  62. package/Engines/thinEngine.pure.js +0 -19
  63. package/Engines/thinEngine.pure.js.map +1 -1
  64. package/Engines/webgpuEngine.d.ts +2 -0
  65. package/Engines/webgpuEngine.js +2 -0
  66. package/Engines/webgpuEngine.js.map +1 -1
  67. package/Engines/webgpuEngine.pure.d.ts +0 -5
  68. package/Engines/webgpuEngine.pure.js +1 -10
  69. package/Engines/webgpuEngine.pure.js.map +1 -1
  70. package/FrameGraph/Node/Types/nodeRenderGraphTypes.js.map +1 -1
  71. package/Loading/loadingScreen.pure.js +2 -0
  72. package/Loading/loadingScreen.pure.js.map +1 -1
  73. package/Materials/Node/Blocks/Fragment/ambientOcclusionBlock.pure.js.map +1 -1
  74. package/Materials/Textures/ktx2decoderTypes.d.ts +14 -3
  75. package/Materials/Textures/ktx2decoderTypes.js +2 -0
  76. package/Materials/Textures/ktx2decoderTypes.js.map +1 -1
  77. package/Materials/Textures/rawTexture2DArray.functions.d.ts +29 -0
  78. package/Materials/Textures/rawTexture2DArray.functions.js +71 -0
  79. package/Materials/Textures/rawTexture2DArray.functions.js.map +1 -1
  80. package/Materials/material.pure.d.ts +1 -0
  81. package/Materials/material.pure.js +1 -0
  82. package/Materials/material.pure.js.map +1 -1
  83. package/Meshes/Builders/pure.d.ts +2 -2
  84. package/Meshes/Builders/pure.js +2 -2
  85. package/Meshes/Builders/pure.js.map +1 -1
  86. package/Meshes/Builders/textBuilder.js.map +1 -1
  87. package/Meshes/Builders/tiledBoxBuilder.d.ts +1 -83
  88. package/Meshes/Builders/tiledBoxBuilder.js +3 -215
  89. package/Meshes/Builders/tiledBoxBuilder.js.map +1 -1
  90. package/Meshes/Builders/tiledBoxBuilder.pure.d.ts +89 -0
  91. package/Meshes/Builders/tiledBoxBuilder.pure.js +229 -0
  92. package/Meshes/Builders/tiledBoxBuilder.pure.js.map +1 -0
  93. package/Meshes/Builders/tiledPlaneBuilder.d.ts +1 -79
  94. package/Meshes/Builders/tiledPlaneBuilder.js +3 -429
  95. package/Meshes/Builders/tiledPlaneBuilder.js.map +1 -1
  96. package/Meshes/Builders/tiledPlaneBuilder.pure.d.ts +85 -0
  97. package/Meshes/Builders/tiledPlaneBuilder.pure.js +442 -0
  98. package/Meshes/Builders/tiledPlaneBuilder.pure.js.map +1 -0
  99. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +29 -9
  100. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
  101. package/Meshes/Node/Blocks/bevelBlock.pure.js.map +1 -1
  102. package/Meshes/meshBuilder.d.ts +21 -57
  103. package/Meshes/meshBuilder.js +21 -58
  104. package/Meshes/meshBuilder.js.map +1 -1
  105. package/Meshes/meshBuilder.pure.d.ts +58 -0
  106. package/Meshes/meshBuilder.pure.js +60 -0
  107. package/Meshes/meshBuilder.pure.js.map +1 -0
  108. package/Meshes/pure.d.ts +1 -1
  109. package/Meshes/pure.js +1 -1
  110. package/Meshes/pure.js.map +1 -1
  111. package/Misc/greasedLineTools.js.map +1 -1
  112. package/Misc/khronosTextureContainer2.d.ts +10 -0
  113. package/Misc/khronosTextureContainer2.js +23 -12
  114. package/Misc/khronosTextureContainer2.js.map +1 -1
  115. package/Misc/perfCounter.d.ts +2 -0
  116. package/Misc/perfCounter.js +17 -2
  117. package/Misc/perfCounter.js.map +1 -1
  118. package/Misc/rgbdTextureTools.js +1 -1
  119. package/Misc/rgbdTextureTools.js.map +1 -1
  120. package/Misc/tools.pure.js +1 -1
  121. package/Misc/tools.pure.js.map +1 -1
  122. package/Navigation/Plugins/recastJSPlugin.js +1 -1
  123. package/Navigation/Plugins/recastJSPlugin.js.map +1 -1
  124. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.pure.js.map +1 -1
  125. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.pure.js.map +1 -1
  126. package/PostProcesses/thinSSAO2PostProcess.js.map +1 -1
  127. package/PostProcesses/volumetricLightScatteringPostProcess.d.ts +3 -0
  128. package/PostProcesses/volumetricLightScatteringPostProcess.js +3 -0
  129. package/PostProcesses/volumetricLightScatteringPostProcess.js.map +1 -1
  130. package/PostProcesses/volumetricLightScatteringPostProcess.pure.d.ts +1 -0
  131. package/PostProcesses/volumetricLightScatteringPostProcess.pure.js +25 -6
  132. package/PostProcesses/volumetricLightScatteringPostProcess.pure.js.map +1 -1
  133. package/Shaders/ShadersInclude/openpbrDielectricReflectance.js +6 -6
  134. package/Shaders/ShadersInclude/openpbrDielectricReflectance.js.map +1 -1
  135. package/ShadersWGSL/ShadersInclude/depthPrePass.js +2 -0
  136. package/ShadersWGSL/ShadersInclude/depthPrePass.js.map +1 -1
  137. package/ShadersWGSL/ShadersInclude/openpbrDielectricReflectance.js +7 -8
  138. package/ShadersWGSL/ShadersInclude/openpbrDielectricReflectance.js.map +1 -1
  139. package/ShadersWGSL/default.fragment.js +3 -0
  140. package/ShadersWGSL/default.fragment.js.map +1 -1
  141. package/ShadersWGSL/openpbr.fragment.js +3 -0
  142. package/ShadersWGSL/openpbr.fragment.js.map +1 -1
  143. package/ShadersWGSL/pbr.fragment.js +3 -0
  144. package/ShadersWGSL/pbr.fragment.js.map +1 -1
  145. package/ShadersWGSL/volumetricLightScattering.fragment.d.ts +5 -0
  146. package/ShadersWGSL/volumetricLightScattering.fragment.js +20 -0
  147. package/ShadersWGSL/volumetricLightScattering.fragment.js.map +1 -0
  148. package/ShadersWGSL/volumetricLightScatteringPass.fragment.d.ts +5 -0
  149. package/ShadersWGSL/volumetricLightScatteringPass.fragment.js +24 -0
  150. package/ShadersWGSL/volumetricLightScatteringPass.fragment.js.map +1 -0
  151. package/ShadersWGSL/volumetricLightScatteringPass.vertex.d.ts +5 -0
  152. package/ShadersWGSL/volumetricLightScatteringPass.vertex.js +67 -0
  153. package/ShadersWGSL/volumetricLightScatteringPass.vertex.js.map +1 -0
  154. package/SmartAssets/smartAssetManager.pure.js +9 -1
  155. package/SmartAssets/smartAssetManager.pure.js.map +1 -1
  156. package/States/alphaCullingState.d.ts +0 -9
  157. package/States/alphaCullingState.js +4 -31
  158. package/States/alphaCullingState.js.map +1 -1
  159. package/XR/features/WebXRLayers.pure.js +4 -4
  160. package/XR/features/WebXRLayers.pure.js.map +1 -1
  161. package/node.d.ts +18 -1
  162. package/node.js +52 -1
  163. package/node.js.map +1 -1
  164. package/package.json +1 -1
  165. package/types.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"nodeRenderGraphTypes.js","sourceRoot":"","sources":["../../../../../../dev/core/src/FrameGraph/Node/Types/nodeRenderGraphTypes.ts"],"names":[],"mappings":"AAyDA;;GAEG;AACH,MAAM,CAAN,IAAY,wCAgEX;AAhED,WAAY,wCAAwC;IAChD,8BAA8B;IAC9B,6GAAoB,CAAA;IACpB,gCAAgC;IAChC,iIAA8B,CAAA;IAC9B,2CAA2C;IAC3C,6KAAoD,CAAA;IACpD,+BAA+B;IAC/B,yJAA0C,CAAA;IAC1C,6CAA6C;IAC7C,gIAA6B,CAAA;IAC7B,8CAA8C;IAC9C,kIAA8B,CAAA;IAC9B,8BAA8B;IAC9B,0HAA0B,CAAA;IAC1B,oCAAoC;IACpC,uIAAgC,CAAA;IAChC,iDAAiD;IACjD,yIAAiC,CAAA;IACjC,gCAAgC;IAChC,+HAA4B,CAAA;IAC5B,kCAAkC;IAClC,oIAA8B,CAAA;IAC9B,qCAAqC;IACrC,oIAA8B,CAAA;IAC9B,+CAA+C;IAC/C,sIAA+B,CAAA;IAC/B,+CAA+C;IAC/C,sIAA+B,CAAA;IAC/B,iDAAiD;IACjD,2IAAiC,CAAA;IACjC,uCAAuC;IACvC,6IAAkC,CAAA;IAClC,uDAAuD;IACvD,uJAAuC,CAAA;IAEvC,+DAA+D;IAC/D,2KAAgD,CAAA;IAChD,yEAAyE;IACzE,mJAAoC,CAAA;IACpC,iCAAiC;IACjC,yHAAuB,CAAA;IAEvB,yBAAyB;IACzB,uIAA8B,CAAA;IAC9B,uBAAuB;IACvB,mIAA4B,CAAA;IAC5B,YAAY;IACZ,2HAAwB,CAAA;IACxB,aAAa;IACb,kHAAmB,CAAA;IACnB,0DAA0D;IAC1D,0HAAuB,CAAA;IAEvB,sCAAsC;IACtC,2HAAuB,CAAA;IACvB,qDAAqD;IACrD,+HAAyB,CAAA;IACzB,gBAAgB;IAChB,0HAAsB,CAAA;IACtB,oBAAoB;IACpB,oHAAmB,CAAA;IACnB,2BAA2B;IAC3B,8GAAgB,CAAA;AACpB,CAAC,EAhEW,wCAAwC,KAAxC,wCAAwC,QAgEnD;AAED;;GAEG;AACH,MAAM,CAAN,IAAkB,iDAOjB;AAPD,WAAkB,iDAAiD;IAC/D,6BAA6B;IAC7B,qIAAU,CAAA;IACV,qDAAqD;IACrD,iJAAgB,CAAA;IAChB,sEAAsE;IACtE,6IAAc,CAAA;AAClB,CAAC,EAPiB,iDAAiD,KAAjD,iDAAiD,QAOlE;AAED;;GAEG;AACH,MAAM,CAAN,IAAkB,uCAKjB;AALD,WAAkB,uCAAuC;IACrD,YAAY;IACZ,uGAAK,CAAA;IACL,aAAa;IACb,yGAAM,CAAA;AACV,CAAC,EALiB,uCAAuC,KAAvC,uCAAuC,QAKxD","sourcesContent":["import {\r\n type Color4,\r\n type Scene,\r\n type FrameGraphTextureHandle,\r\n type Camera,\r\n type FrameGraphObjectList,\r\n type IShadowLight,\r\n type FrameGraphShadowGeneratorTask,\r\n type FrameGraphObjectRendererTask,\r\n type FrameGraph,\r\n type NodeRenderGraphBlock,\r\n} from \"core/index\";\r\n\r\n/**\r\n * Description of a custom block to be used in the node render graph editor\r\n */\r\nexport interface INodeRenderGraphCustomBlockDescription {\r\n /** Block name. It will be used as the block name in the left menu of the editor. Spaces must be replaced by underscores in the name. */\r\n name: string;\r\n /** Description (tooltip) of the block. */\r\n description: string;\r\n /** Category of the block. Spaces must be replaced by underscores in the category name. */\r\n menu: string;\r\n /** Factory function to create the block. */\r\n factory: (frameGraph: FrameGraph, scene: Scene) => NodeRenderGraphBlock;\r\n}\r\n\r\n/**\r\n * Interface used to configure the node render graph editor\r\n */\r\nexport interface INodeRenderGraphEditorOptions {\r\n /** Define the URL to load node editor script from */\r\n editorURL?: string;\r\n /** Additional configuration for the FGE */\r\n nodeRenderGraphEditorConfig?: {\r\n backgroundColor?: Color4;\r\n hostScene?: Scene;\r\n customBlockDescriptions?: INodeRenderGraphCustomBlockDescription[];\r\n };\r\n}\r\n\r\n/**\r\n * Options that can be passed to the node render graph build method\r\n */\r\nexport interface INodeRenderGraphCreateOptions {\r\n /** If true, textures created by the node render graph will be visible in the inspector, for easier debugging (default: false) */\r\n debugTextures?: boolean;\r\n /** Rebuild the node render graph when the screen is resized (default: true) */\r\n rebuildGraphOnEngineResize?: boolean;\r\n /** Defines if the build should log activity (default: false) */\r\n verbose?: boolean;\r\n /** Defines if the autoConfigure method should be called when initializing blocks (default: false) */\r\n autoConfigure?: boolean;\r\n /** If true, external inputs like object lists and cameras will be filled with default values, taken from the scene. Note that external textures are not concerned (default: true). */\r\n autoFillExternalInputs?: boolean;\r\n}\r\n\r\n/**\r\n * Defines the kind of connection point for node render graph nodes\r\n */\r\nexport enum NodeRenderGraphBlockConnectionPointTypes {\r\n /** General purpose texture */\r\n Texture = 0x00000001,\r\n /** Back buffer color texture */\r\n TextureBackBuffer = 0x00000002,\r\n /** Back buffer depth/stencil attachment */\r\n TextureBackBufferDepthStencilAttachment = 0x00000004,\r\n /** Depth/stencil attachment */\r\n TextureDepthStencilAttachment = 0x00000008,\r\n /** Depth (in view space) geometry texture */\r\n TextureViewDepth = 0x00000010,\r\n /** Normal (in view space) geometry texture */\r\n TextureViewNormal = 0x00000020,\r\n /** Albedo geometry texture */\r\n TextureAlbedo = 0x00000040,\r\n /** Reflectivity geometry texture */\r\n TextureReflectivity = 0x00000080,\r\n /** Position (in world space) geometry texture */\r\n TextureWorldPosition = 0x00000100,\r\n /** Velocity geometry texture */\r\n TextureVelocity = 0x00000200,\r\n /** Irradiance geometry texture */\r\n TextureIrradiance = 0x00000400,\r\n /** Albedo (sqrt) geometry texture */\r\n TextureAlbedoSqrt = 0x00000800,\r\n /** Depth (in screen space) geometry texture */\r\n TextureScreenDepth = 0x00001000,\r\n /** Normal (in world space) geometry texture */\r\n TextureWorldNormal = 0x00002000,\r\n /** Position (in local space) geometry texture */\r\n TextureLocalPosition = 0x00004000,\r\n /** Linear velocity geometry texture */\r\n TextureLinearVelocity = 0x00008000,\r\n /** Normalied depth (in view space) geometry texture */\r\n TextureNormalizedViewDepth = 0x00010000,\r\n\r\n /** Bit field for all textures but back buffer depth/stencil */\r\n TextureAllButBackBufferDepthStencil = 0x000ffffb,\r\n /** Bit field for all textures but back buffer color and depth/stencil */\r\n TextureAllButBackBuffer = 0x000ffff9,\r\n /** Bit field for all textures */\r\n TextureAll = 0x000fffff,\r\n\r\n /** Resource container */\r\n ResourceContainer = 0x00100000,\r\n /** Shadow generator */\r\n ShadowGenerator = 0x00200000,\r\n /** Light */\r\n ShadowLight = 0x00400000,\r\n /** Camera */\r\n Camera = 0x01000000,\r\n /** List of objects (meshes, particle systems, sprites) */\r\n ObjectList = 0x02000000,\r\n\r\n /** Detect type based on connection */\r\n AutoDetect = 0x10000000,\r\n /** Output type that will be defined by input type */\r\n BasedOnInput = 0x20000000,\r\n /** Undefined */\r\n Undefined = 0x40000000,\r\n /** Custom object */\r\n Object = 0x80000000,\r\n /** Bitmask of all types */\r\n All = 0xffffffff,\r\n}\r\n\r\n/**\r\n * Enum used to define the compatibility state between two connection points\r\n */\r\nexport const enum NodeRenderGraphConnectionPointCompatibilityStates {\r\n /** Points are compatibles */\r\n Compatible,\r\n /** Points are incompatible because of their types */\r\n TypeIncompatible,\r\n /** Points are incompatible because they are in the same hierarchy **/\r\n HierarchyIssue,\r\n}\r\n\r\n/**\r\n * Defines the direction of a connection point\r\n */\r\nexport const enum NodeRenderGraphConnectionPointDirection {\r\n /** Input */\r\n Input,\r\n /** Output */\r\n Output,\r\n}\r\n\r\n/**\r\n * Defines the type of a connection point value\r\n */\r\nexport type NodeRenderGraphBlockConnectionPointValueType =\r\n | FrameGraphTextureHandle\r\n | Camera\r\n | FrameGraphObjectList\r\n | IShadowLight\r\n | FrameGraphShadowGeneratorTask\r\n | FrameGraphObjectRendererTask;\r\n"]}
1
+ {"version":3,"file":"nodeRenderGraphTypes.js","sourceRoot":"","sources":["../../../../../../dev/core/src/FrameGraph/Node/Types/nodeRenderGraphTypes.ts"],"names":[],"mappings":"AAyDA;;GAEG;AACH,MAAM,CAAN,IAAY,wCAgEX;AAhED,WAAY,wCAAwC;IAChD,8BAA8B;IAC9B,6GAAoB,CAAA;IACpB,gCAAgC;IAChC,iIAA8B,CAAA;IAC9B,2CAA2C;IAC3C,6KAAoD,CAAA;IACpD,+BAA+B;IAC/B,yJAA0C,CAAA;IAC1C,6CAA6C;IAC7C,gIAA6B,CAAA;IAC7B,8CAA8C;IAC9C,kIAA8B,CAAA;IAC9B,8BAA8B;IAC9B,0HAA0B,CAAA;IAC1B,oCAAoC;IACpC,uIAAgC,CAAA;IAChC,iDAAiD;IACjD,yIAAiC,CAAA;IACjC,gCAAgC;IAChC,+HAA4B,CAAA;IAC5B,kCAAkC;IAClC,oIAA8B,CAAA;IAC9B,qCAAqC;IACrC,oIAA8B,CAAA;IAC9B,+CAA+C;IAC/C,sIAA+B,CAAA;IAC/B,+CAA+C;IAC/C,sIAA+B,CAAA;IAC/B,iDAAiD;IACjD,2IAAiC,CAAA;IACjC,uCAAuC;IACvC,6IAAkC,CAAA;IAClC,uDAAuD;IACvD,uJAAuC,CAAA;IAEvC,+DAA+D;IAC/D,2KAAgD,CAAA;IAChD,yEAAyE;IACzE,mJAAoC,CAAA;IACpC,iCAAiC;IACjC,yHAAuB,CAAA;IAEvB,yBAAyB;IACzB,uIAA8B,CAAA;IAC9B,uBAAuB;IACvB,mIAA4B,CAAA;IAC5B,YAAY;IACZ,2HAAwB,CAAA;IACxB,aAAa;IACb,kHAAmB,CAAA;IACnB,0DAA0D;IAC1D,0HAAuB,CAAA;IAEvB,sCAAsC;IACtC,2HAAuB,CAAA;IACvB,qDAAqD;IACrD,+HAAyB,CAAA;IACzB,gBAAgB;IAChB,0HAAsB,CAAA;IACtB,oBAAoB;IACpB,oHAAmB,CAAA;IACnB,2BAA2B;IAC3B,8GAAgB,CAAA;AACpB,CAAC,EAhEW,wCAAwC,KAAxC,wCAAwC,QAgEnD;AAED;;GAEG;AACH,MAAM,CAAN,IAAkB,iDAOjB;AAPD,WAAkB,iDAAiD;IAC/D,6BAA6B;IAC7B,qIAAU,CAAA;IACV,qDAAqD;IACrD,iJAAgB,CAAA;IAChB,sEAAsE;IACtE,6IAAc,CAAA;AAClB,CAAC,EAPiB,iDAAiD,KAAjD,iDAAiD,QAOlE;AAED;;GAEG;AACH,MAAM,CAAN,IAAkB,uCAKjB;AALD,WAAkB,uCAAuC;IACrD,YAAY;IACZ,uGAAK,CAAA;IACL,aAAa;IACb,yGAAM,CAAA;AACV,CAAC,EALiB,uCAAuC,KAAvC,uCAAuC,QAKxD","sourcesContent":["import {\r\n type Color4,\r\n type Scene,\r\n type FrameGraphTextureHandle,\r\n type Camera,\r\n type FrameGraphObjectList,\r\n type IShadowLight,\r\n type FrameGraphShadowGeneratorTask,\r\n type FrameGraphObjectRendererTask,\r\n type FrameGraph,\r\n type NodeRenderGraphBlock,\r\n} from \"core/index\";\r\n\r\n/**\r\n * Description of a custom block to be used in the node render graph editor\r\n */\r\nexport interface INodeRenderGraphCustomBlockDescription {\r\n /** Block name. It will be used as the block name in the left menu of the editor. Spaces must be replaced by underscores in the name. */\r\n name: string;\r\n /** Description (tooltip) of the block. */\r\n description: string;\r\n /** Category of the block. Spaces must be replaced by underscores in the category name. */\r\n menu: string;\r\n /** Factory function to create the block. */\r\n factory: (frameGraph: FrameGraph, scene: Scene) => NodeRenderGraphBlock;\r\n}\r\n\r\n/**\r\n * Interface used to configure the node render graph editor\r\n */\r\nexport interface INodeRenderGraphEditorOptions {\r\n /** Define the URL to load node editor script from */\r\n editorURL?: string;\r\n /** Additional configuration for the FGE */\r\n nodeRenderGraphEditorConfig?: {\r\n backgroundColor?: Color4;\r\n hostScene?: Scene;\r\n customBlockDescriptions?: INodeRenderGraphCustomBlockDescription[];\r\n };\r\n}\r\n\r\n/**\r\n * Options that can be passed to the node render graph build method\r\n */\r\nexport interface INodeRenderGraphCreateOptions {\r\n /** If true, textures created by the node render graph will be visible in the inspector, for easier debugging (default: false) */\r\n debugTextures?: boolean;\r\n /** Rebuild the node render graph when the screen is resized (default: true) */\r\n rebuildGraphOnEngineResize?: boolean;\r\n /** Defines if the build should log activity (default: false) */\r\n verbose?: boolean;\r\n /** Defines if the autoConfigure method should be called when initializing blocks (default: false) */\r\n autoConfigure?: boolean;\r\n /** If true, external inputs like object lists and cameras will be filled with default values, taken from the scene. Note that external textures are not concerned (default: true). */\r\n autoFillExternalInputs?: boolean;\r\n}\r\n\r\n/**\r\n * Defines the kind of connection point for node render graph nodes\r\n */\r\nexport enum NodeRenderGraphBlockConnectionPointTypes {\r\n /** General purpose texture */\r\n Texture = 0x00000001,\r\n /** Back buffer color texture */\r\n TextureBackBuffer = 0x00000002,\r\n /** Back buffer depth/stencil attachment */\r\n TextureBackBufferDepthStencilAttachment = 0x00000004,\r\n /** Depth/stencil attachment */\r\n TextureDepthStencilAttachment = 0x00000008,\r\n /** Depth (in view space) geometry texture */\r\n TextureViewDepth = 0x00000010,\r\n /** Normal (in view space) geometry texture */\r\n TextureViewNormal = 0x00000020,\r\n /** Albedo geometry texture */\r\n TextureAlbedo = 0x00000040,\r\n /** Reflectivity geometry texture */\r\n TextureReflectivity = 0x00000080,\r\n /** Position (in world space) geometry texture */\r\n TextureWorldPosition = 0x00000100,\r\n /** Velocity geometry texture */\r\n TextureVelocity = 0x00000200,\r\n /** Irradiance geometry texture */\r\n TextureIrradiance = 0x00000400,\r\n /** Albedo (sqrt) geometry texture */\r\n TextureAlbedoSqrt = 0x00000800,\r\n /** Depth (in screen space) geometry texture */\r\n TextureScreenDepth = 0x00001000,\r\n /** Normal (in world space) geometry texture */\r\n TextureWorldNormal = 0x00002000,\r\n /** Position (in local space) geometry texture */\r\n TextureLocalPosition = 0x00004000,\r\n /** Linear velocity geometry texture */\r\n TextureLinearVelocity = 0x00008000,\r\n /** Normalied depth (in view space) geometry texture */\r\n TextureNormalizedViewDepth = 0x00010000,\r\n\r\n /** Bit field for all textures but back buffer depth/stencil */\r\n TextureAllButBackBufferDepthStencil = 0x000ffffb,\r\n /** Bit field for all textures but back buffer color and depth/stencil */\r\n TextureAllButBackBuffer = 0x000ffff9,\r\n /** Bit field for all textures */\r\n TextureAll = 0x000fffff,\r\n\r\n /** Resource container */\r\n ResourceContainer = 0x00100000,\r\n /** Shadow generator */\r\n ShadowGenerator = 0x00200000,\r\n /** Light */\r\n ShadowLight = 0x00400000,\r\n /** Camera */\r\n Camera = 0x01000000,\r\n /** List of objects (meshes, particle systems, sprites) */\r\n ObjectList = 0x02000000,\r\n\r\n /** Detect type based on connection */\r\n AutoDetect = 0x10000000,\r\n /** Output type that will be defined by input type */\r\n BasedOnInput = 0x20000000,\r\n /** Undefined */\r\n Undefined = 0x40000000,\r\n /** Custom object */\r\n Object = 0x80000000,\r\n /** Bitmask of all types */\r\n All = 0xffffffff,\r\n}\r\n\r\n/**\r\n * Enum used to define the compatibility state between two connection points\r\n */\r\nexport const enum NodeRenderGraphConnectionPointCompatibilityStates {\r\n /** Points are compatibles */\r\n Compatible,\r\n /** Points are incompatible because of their types */\r\n TypeIncompatible,\r\n /** Points are incompatible because they are in the same hierarchy **/\r\n HierarchyIssue,\r\n}\r\n\r\n/**\r\n * Defines the direction of a connection point\r\n */\r\nexport const enum NodeRenderGraphConnectionPointDirection {\r\n /** Input */\r\n Input,\r\n /** Output */\r\n Output,\r\n}\r\n\r\n/**\r\n * Defines the type of a connection point value\r\n */\r\nexport type NodeRenderGraphBlockConnectionPointValueType =\r\n FrameGraphTextureHandle | Camera | FrameGraphObjectList | IShadowLight | FrameGraphShadowGeneratorTask | FrameGraphObjectRendererTask;\r\n"]}
@@ -1,5 +1,6 @@
1
1
  /** This file must only contain pure code and pure imports */
2
2
  import { AbstractEngine } from "../Engines/abstractEngine.pure.js";
3
+ import { RegisterAbstractEngineLoadingScreen } from "../Engines/AbstractEngine/abstractEngine.loadingScreen.pure.js";
3
4
  import { EngineStore } from "../Engines/engineStore.js";
4
5
  /**
5
6
  * Class used for the default loading screen
@@ -278,6 +279,7 @@ export function RegisterLoadingScreen() {
278
279
  return;
279
280
  }
280
281
  _Registered = true;
282
+ RegisterAbstractEngineLoadingScreen();
281
283
  AbstractEngine.DefaultLoadingScreenFactory = (canvas) => {
282
284
  return new DefaultLoadingScreen(canvas);
283
285
  };
@@ -1 +1 @@
1
- {"version":3,"file":"loadingScreen.pure.js","sourceRoot":"","sources":["../../../../dev/core/src/Loading/loadingScreen.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type Observer } from \"../Misc/observable.pure\";\r\n\r\n/**\r\n * Interface used to present a loading screen while loading a scene\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\nexport interface ILoadingScreen {\r\n /**\r\n * Function called to display the loading screen\r\n */\r\n displayLoadingUI: () => void;\r\n /**\r\n * Function called to hide the loading screen\r\n */\r\n hideLoadingUI: () => void;\r\n /**\r\n * Gets or sets the color to use for the background\r\n */\r\n loadingUIBackgroundColor: string;\r\n /**\r\n * Gets or sets the text to display while loading\r\n */\r\n loadingUIText: string;\r\n}\r\n\r\n/**\r\n * Class used for the default loading screen\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\nexport class DefaultLoadingScreen implements ILoadingScreen {\r\n private _engine: Nullable<AbstractEngine>;\r\n private _resizeObserver: Nullable<Observer<AbstractEngine>>;\r\n private _isLoading: boolean;\r\n /**\r\n * Maps a loading `HTMLDivElement` to a tuple containing the associated `HTMLCanvasElement`\r\n * and its `DOMRect` (or `null` if not yet available).\r\n */\r\n private _loadingDivToRenderingCanvasMap: Map<HTMLDivElement, [HTMLCanvasElement, DOMRect | null]> = new Map();\r\n private _loadingTextDiv: Nullable<HTMLDivElement>;\r\n private _style: Nullable<HTMLStyleElement>;\r\n\r\n /** Gets or sets the logo url to use for the default loading screen */\r\n public static DefaultLogoUrl = \"\";\r\n\r\n /** Gets or sets the spinner url to use for the default loading screen */\r\n public static DefaultSpinnerUrl = \"\";\r\n\r\n /**\r\n * Creates a new default loading screen\r\n * @param _renderingCanvas defines the canvas used to render the scene\r\n * @param _loadingText defines the default text to display\r\n * @param _loadingDivBackgroundColor defines the default background color\r\n */\r\n constructor(\r\n private _renderingCanvas: HTMLCanvasElement,\r\n private _loadingText = \"\",\r\n private _loadingDivBackgroundColor = \"black\"\r\n ) {}\r\n\r\n /**\r\n * Function called to display the loading screen\r\n */\r\n public displayLoadingUI(): void {\r\n if (this._isLoading) {\r\n // Do not add a loading screen if it is already loading\r\n return;\r\n }\r\n\r\n this._isLoading = true;\r\n // get current engine by rendering canvas\r\n this._engine = EngineStore.Instances.find((engine) => engine.getRenderingCanvas() === this._renderingCanvas) as AbstractEngine;\r\n\r\n const loadingDiv = document.createElement(\"div\");\r\n\r\n loadingDiv.id = \"babylonjsLoadingDiv\";\r\n loadingDiv.style.opacity = \"0\";\r\n loadingDiv.style.transition = \"opacity 1.5s ease\";\r\n loadingDiv.style.pointerEvents = \"none\";\r\n loadingDiv.style.display = \"grid\";\r\n loadingDiv.style.gridTemplateRows = \"100%\";\r\n loadingDiv.style.gridTemplateColumns = \"100%\";\r\n loadingDiv.style.justifyItems = \"center\";\r\n loadingDiv.style.alignItems = \"center\";\r\n\r\n // Loading text\r\n this._loadingTextDiv = document.createElement(\"div\");\r\n this._loadingTextDiv.style.position = \"absolute\";\r\n this._loadingTextDiv.style.left = \"0\";\r\n this._loadingTextDiv.style.top = \"50%\";\r\n this._loadingTextDiv.style.marginTop = \"80px\";\r\n this._loadingTextDiv.style.width = \"100%\";\r\n this._loadingTextDiv.style.height = \"20px\";\r\n this._loadingTextDiv.style.fontFamily = \"Arial\";\r\n this._loadingTextDiv.style.fontSize = \"14px\";\r\n this._loadingTextDiv.style.color = \"white\";\r\n this._loadingTextDiv.style.textAlign = \"center\";\r\n this._loadingTextDiv.style.zIndex = \"1\";\r\n this._loadingTextDiv.innerHTML = \"Loading\";\r\n\r\n loadingDiv.appendChild(this._loadingTextDiv);\r\n\r\n //set the predefined text\r\n this._loadingTextDiv.innerHTML = this._loadingText;\r\n\r\n // Generating keyframes\r\n this._style = document.createElement(\"style\");\r\n const keyFrames = `@-webkit-keyframes spin1 {\\\r\n 0% { -webkit-transform: rotate(0deg);}\r\n 100% { -webkit-transform: rotate(360deg);}\r\n }\\\r\n @keyframes spin1 {\\\r\n 0% { transform: rotate(0deg);}\r\n 100% { transform: rotate(360deg);}\r\n }`;\r\n this._style.innerHTML = keyFrames;\r\n document.getElementsByTagName(\"head\")[0].appendChild(this._style);\r\n\r\n const svgSupport = !!window.SVGSVGElement;\r\n // Loading img\r\n const imgBack = new Image();\r\n if (!DefaultLoadingScreen.DefaultLogoUrl) {\r\n imgBack.src = !svgSupport\r\n ? \"https://cdn.babylonjs.com/Assets/babylonLogo.png\"\r\n : `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxODAuMTcgMjA4LjA0Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2ZmZjt9LmNscy0ye2ZpbGw6I2UwNjg0Yjt9LmNscy0ze2ZpbGw6I2JiNDY0Yjt9LmNscy00e2ZpbGw6I2UwZGVkODt9LmNscy01e2ZpbGw6I2Q1ZDJjYTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPkJhYnlsb25Mb2dvPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iUGFnZV9FbGVtZW50cyIgZGF0YS1uYW1lPSJQYWdlIEVsZW1lbnRzIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik05MC4wOSwwLDAsNTJWMTU2bDkwLjA5LDUyLDkwLjA4LTUyVjUyWiIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMiIgcG9pbnRzPSIxODAuMTcgNTIuMDEgMTUxLjk3IDM1LjczIDEyNC44NSA1MS4zOSAxNTMuMDUgNjcuNjcgMTgwLjE3IDUyLjAxIi8+PHBvbHlnb24gY2xhc3M9ImNscy0yIiBwb2ludHM9IjI3LjEyIDY3LjY3IDExNy4yMSAxNS42NiA5MC4wOCAwIDAgNTIuMDEgMjcuMTIgNjcuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iNjEuODkgMTIwLjMgOTAuMDggMTM2LjU4IDExOC4yOCAxMjAuMyA5MC4wOCAxMDQuMDIgNjEuODkgMTIwLjMiLz48cG9seWdvbiBjbGFzcz0iY2xzLTMiIHBvaW50cz0iMTUzLjA1IDY3LjY3IDE1My4wNSAxNDAuMzcgOTAuMDggMTc2LjcyIDI3LjEyIDE0MC4zNyAyNy4xMiA2Ny42NyAwIDUyLjAxIDAgMTU2LjAzIDkwLjA4IDIwOC4wNCAxODAuMTcgMTU2LjAzIDE4MC4xNyA1Mi4wMSAxNTMuMDUgNjcuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTMiIHBvaW50cz0iOTAuMDggNzEuNDYgNjEuODkgODcuNzQgNjEuODkgMTIwLjMgOTAuMDggMTA0LjAyIDExOC4yOCAxMjAuMyAxMTguMjggODcuNzQgOTAuMDggNzEuNDYiLz48cG9seWdvbiBjbGFzcz0iY2xzLTQiIHBvaW50cz0iMTUzLjA1IDY3LjY3IDExOC4yOCA4Ny43NCAxMTguMjggMTIwLjMgOTAuMDggMTM2LjU4IDkwLjA4IDE3Ni43MiAxNTMuMDUgMTQwLjM3IDE1My4wNSA2Ny42NyIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtNSIgcG9pbnRzPSIyNy4xMiA2Ny42NyA2MS44OSA4Ny43NCA2MS44OSAxMjAuMyA5MC4wOCAxMzYuNTggOTAuMDggMTc2LjcyIDI3LjEyIDE0MC4zNyAyNy4xMiA2Ny42NyIvPjwvZz48L2c+PC9zdmc+`;\r\n } else {\r\n imgBack.src = DefaultLoadingScreen.DefaultLogoUrl;\r\n }\r\n\r\n imgBack.style.width = \"150px\";\r\n imgBack.style.gridColumn = \"1\";\r\n imgBack.style.gridRow = \"1\";\r\n imgBack.style.top = \"50%\";\r\n imgBack.style.left = \"50%\";\r\n imgBack.style.transform = \"translate(-50%, -50%)\";\r\n imgBack.style.position = \"absolute\";\r\n\r\n const imageSpinnerContainer = document.createElement(\"div\");\r\n imageSpinnerContainer.style.width = \"300px\";\r\n imageSpinnerContainer.style.gridColumn = \"1\";\r\n imageSpinnerContainer.style.gridRow = \"1\";\r\n imageSpinnerContainer.style.top = \"50%\";\r\n imageSpinnerContainer.style.left = \"50%\";\r\n imageSpinnerContainer.style.transform = \"translate(-50%, -50%)\";\r\n imageSpinnerContainer.style.position = \"absolute\";\r\n\r\n // Loading spinner\r\n const imgSpinner = new Image();\r\n\r\n if (!DefaultLoadingScreen.DefaultSpinnerUrl) {\r\n imgSpinner.src = !svgSupport\r\n ? \"https://cdn.babylonjs.com/Assets/loadingIcon.png\"\r\n : `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzOTIgMzkyIj48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2UwNjg0Yjt9LmNscy0ye2ZpbGw6bm9uZTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPlNwaW5uZXJJY29uPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iU3Bpbm5lciI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNDAuMjEsMTI2LjQzYzMuNy03LjMxLDcuNjctMTQuNDQsMTItMjEuMzJsMy4zNi01LjEsMy41Mi01YzEuMjMtMS42MywyLjQxLTMuMjksMy42NS00LjkxczIuNTMtMy4yMSwzLjgyLTQuNzlBMTg1LjIsMTg1LjIsMCwwLDEsODMuNCw2Ny40M2EyMDgsMjA4LDAsMCwxLDE5LTE1LjY2YzMuMzUtMi40MSw2Ljc0LTQuNzgsMTAuMjUtN3M3LjExLTQuMjgsMTAuNzUtNi4zMmM3LjI5LTQsMTQuNzMtOCwyMi41My0xMS40OSwzLjktMS43Miw3Ljg4LTMuMywxMi00LjY0YTEwNC4yMiwxMDQuMjIsMCwwLDEsMTIuNDQtMy4yMyw2Mi40NCw2Mi40NCwwLDAsMSwxMi43OC0xLjM5QTI1LjkyLDI1LjkyLDAsMCwxLDE5NiwyMS40NGE2LjU1LDYuNTUsMCwwLDEsMi4wNSw5LDYuNjYsNi42NiwwLDAsMS0xLjY0LDEuNzhsLS40MS4yOWEyMi4wNywyMi4wNywwLDAsMS01Ljc4LDMsMzAuNDIsMzAuNDIsMCwwLDEtNS42NywxLjYyLDM3LjgyLDM3LjgyLDAsMCwxLTUuNjkuNzFjLTEsMC0xLjkuMTgtMi44NS4yNmwtMi44NS4yNHEtNS43Mi41MS0xMS40OCwxLjFjLTMuODQuNC03LjcxLjgyLTExLjU4LDEuNGExMTIuMzQsMTEyLjM0LDAsMCwwLTIyLjk0LDUuNjFjLTMuNzIsMS4zNS03LjM0LDMtMTAuOTQsNC42NHMtNy4xNCwzLjUxLTEwLjYsNS41MUExNTEuNiwxNTEuNiwwLDAsMCw2OC41Niw4N0M2Ny4yMyw4OC40OCw2Niw5MCw2NC42NCw5MS41NnMtMi41MSwzLjE1LTMuNzUsNC43M2wtMy41NCw0LjljLTEuMTMsMS42Ni0yLjIzLDMuMzUtMy4zMyw1YTEyNywxMjcsMCwwLDAtMTAuOTMsMjEuNDksMS41OCwxLjU4LDAsMSwxLTMtMS4xNVM0MC4xOSwxMjYuNDcsNDAuMjEsMTI2LjQzWiIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzOTIiLz48L2c+PC9nPjwvc3ZnPg==`;\r\n } else {\r\n imgSpinner.src = DefaultLoadingScreen.DefaultSpinnerUrl;\r\n }\r\n\r\n imgSpinner.style.animation = \"spin1 0.75s infinite linear\";\r\n imgSpinner.style.transformOrigin = \"50% 50%\";\r\n\r\n if (!svgSupport) {\r\n const logoSize = { w: 16, h: 18.5 };\r\n const loadingSize = { w: 30, h: 30 };\r\n // set styling correctly\r\n imgBack.style.width = `${logoSize.w}vh`;\r\n imgBack.style.height = `${logoSize.h}vh`;\r\n imgBack.style.left = `calc(50% - ${logoSize.w / 2}vh)`;\r\n imgBack.style.top = `calc(50% - ${logoSize.h / 2}vh)`;\r\n\r\n imgSpinner.style.width = `${loadingSize.w}vh`;\r\n imgSpinner.style.height = `${loadingSize.h}vh`;\r\n imgSpinner.style.left = `calc(50% - ${loadingSize.w / 2}vh)`;\r\n imgSpinner.style.top = `calc(50% - ${loadingSize.h / 2}vh)`;\r\n }\r\n\r\n imageSpinnerContainer.appendChild(imgSpinner);\r\n\r\n loadingDiv.appendChild(imgBack);\r\n loadingDiv.appendChild(imageSpinnerContainer);\r\n loadingDiv.style.backgroundColor = this._loadingDivBackgroundColor;\r\n loadingDiv.style.opacity = \"1\";\r\n\r\n const canvases: Array<HTMLCanvasElement> = [];\r\n const views = this._engine.views;\r\n if (views?.length) {\r\n for (const view of views) {\r\n if (view.enabled) {\r\n canvases.push(view.target);\r\n }\r\n }\r\n } else {\r\n canvases.push(this._renderingCanvas);\r\n }\r\n for (let i = 0; i < canvases.length; i++) {\r\n const canvas = canvases[i];\r\n const clonedLoadingDiv = loadingDiv.cloneNode(true) as HTMLDivElement;\r\n clonedLoadingDiv.id += `-${i}`;\r\n this._loadingDivToRenderingCanvasMap.set(clonedLoadingDiv, [canvas, null]);\r\n }\r\n\r\n this._resizeLoadingUI();\r\n\r\n this._resizeObserver = this._engine.onResizeObservable.add(() => {\r\n this._resizeLoadingUI();\r\n });\r\n\r\n this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n document.body.appendChild(loadingDiv);\r\n });\r\n }\r\n\r\n /**\r\n * Function called to hide the loading screen\r\n */\r\n public hideLoadingUI(): void {\r\n if (!this._isLoading) {\r\n return;\r\n }\r\n\r\n let completedTransitions = 0;\r\n\r\n const onTransitionEnd = (event: TransitionEvent) => {\r\n const loadingDiv = event.target as HTMLDivElement;\r\n // ensure that ending transition event is generated by one of the current loadingDivs\r\n const isTransitionEndOnLoadingDiv = this._loadingDivToRenderingCanvasMap.has(loadingDiv);\r\n\r\n if (isTransitionEndOnLoadingDiv) {\r\n completedTransitions++;\r\n loadingDiv.remove();\r\n\r\n const allTransitionsCompleted = completedTransitions === this._loadingDivToRenderingCanvasMap.size;\r\n if (allTransitionsCompleted) {\r\n if (this._loadingTextDiv) {\r\n this._loadingTextDiv.remove();\r\n this._loadingTextDiv = null;\r\n }\r\n if (this._style) {\r\n this._style.remove();\r\n this._style = null;\r\n }\r\n\r\n window.removeEventListener(\"transitionend\", onTransitionEnd);\r\n this._engine!.onResizeObservable.remove(this._resizeObserver);\r\n this._loadingDivToRenderingCanvasMap.clear();\r\n this._engine = null;\r\n this._isLoading = false;\r\n }\r\n }\r\n };\r\n\r\n this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n loadingDiv.style.opacity = \"0\";\r\n });\r\n\r\n window.addEventListener(\"transitionend\", onTransitionEnd);\r\n }\r\n\r\n /**\r\n * Gets or sets the text to display while loading\r\n */\r\n public set loadingUIText(text: string) {\r\n this._loadingText = text;\r\n\r\n if (this._loadingTextDiv) {\r\n this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n // set loadingTextDiv of current loadingDiv\r\n loadingDiv.children[0].innerHTML = this._loadingText;\r\n });\r\n }\r\n }\r\n\r\n public get loadingUIText(): string {\r\n return this._loadingText;\r\n }\r\n\r\n /**\r\n * Gets or sets the color to use for the background\r\n */\r\n public get loadingUIBackgroundColor(): string {\r\n return this._loadingDivBackgroundColor;\r\n }\r\n\r\n public set loadingUIBackgroundColor(color: string) {\r\n this._loadingDivBackgroundColor = color;\r\n\r\n if (!this._isLoading) {\r\n return;\r\n }\r\n\r\n this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n loadingDiv.style.backgroundColor = this._loadingDivBackgroundColor;\r\n });\r\n }\r\n\r\n /**\r\n * Checks if the layout of the canvas has changed by comparing the current layout\r\n * rectangle with the previous one.\r\n *\r\n * This function compares of the two `DOMRect` objects to determine if any of the layout dimensions have changed.\r\n * If the layout has changed or if there is no previous layout (i.e., `previousCanvasRect` is `null`),\r\n * it returns `true`. Otherwise, it returns `false`.\r\n *\r\n * @param previousCanvasRect defines the previously recorded `DOMRect` of the canvas, or `null` if no previous state exists.\r\n * @param currentCanvasRect defines the current `DOMRect` of the canvas to compare against the previous layout.\r\n * @returns `true` if the layout has changed, otherwise `false`.\r\n */\r\n private _isCanvasLayoutChanged(previousCanvasRect: DOMRect | null, currentCanvasRect: DOMRect) {\r\n return (\r\n !previousCanvasRect ||\r\n previousCanvasRect.left !== currentCanvasRect.left ||\r\n previousCanvasRect.top !== currentCanvasRect.top ||\r\n previousCanvasRect.right !== currentCanvasRect.right ||\r\n previousCanvasRect.bottom !== currentCanvasRect.bottom ||\r\n previousCanvasRect.width !== currentCanvasRect.width ||\r\n previousCanvasRect.height !== currentCanvasRect.height ||\r\n previousCanvasRect.x !== currentCanvasRect.x ||\r\n previousCanvasRect.y !== currentCanvasRect.y\r\n );\r\n }\r\n\r\n // Resize\r\n private _resizeLoadingUI = () => {\r\n if (!this._isLoading) {\r\n return;\r\n }\r\n\r\n this._loadingDivToRenderingCanvasMap.forEach(([canvas, previousCanvasRect], loadingDiv) => {\r\n const currentCanvasRect = canvas.getBoundingClientRect();\r\n if (this._isCanvasLayoutChanged(previousCanvasRect, currentCanvasRect)) {\r\n const canvasPositioning = window.getComputedStyle(canvas).position;\r\n\r\n loadingDiv.style.position = canvasPositioning === \"fixed\" ? \"fixed\" : \"absolute\";\r\n loadingDiv.style.left = currentCanvasRect.left + window.scrollX + \"px\";\r\n loadingDiv.style.top = currentCanvasRect.top + window.scrollY + \"px\";\r\n loadingDiv.style.width = currentCanvasRect.width + \"px\";\r\n loadingDiv.style.height = currentCanvasRect.height + \"px\";\r\n\r\n this._loadingDivToRenderingCanvasMap.set(loadingDiv, [canvas, currentCanvasRect]);\r\n }\r\n });\r\n };\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for loadingScreen.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLoadingScreen(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n AbstractEngine.DefaultLoadingScreenFactory = (canvas: HTMLCanvasElement) => {\r\n return new DefaultLoadingScreen(canvas);\r\n };\r\n}\r\n"]}
1
+ {"version":3,"file":"loadingScreen.pure.js","sourceRoot":"","sources":["../../../../dev/core/src/Loading/loadingScreen.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { RegisterAbstractEngineLoadingScreen } from \"../Engines/AbstractEngine/abstractEngine.loadingScreen.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type Observer } from \"../Misc/observable.pure\";\r\n\r\n/**\r\n * Interface used to present a loading screen while loading a scene\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\nexport interface ILoadingScreen {\r\n /**\r\n * Function called to display the loading screen\r\n */\r\n displayLoadingUI: () => void;\r\n /**\r\n * Function called to hide the loading screen\r\n */\r\n hideLoadingUI: () => void;\r\n /**\r\n * Gets or sets the color to use for the background\r\n */\r\n loadingUIBackgroundColor: string;\r\n /**\r\n * Gets or sets the text to display while loading\r\n */\r\n loadingUIText: string;\r\n}\r\n\r\n/**\r\n * Class used for the default loading screen\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\nexport class DefaultLoadingScreen implements ILoadingScreen {\r\n private _engine: Nullable<AbstractEngine>;\r\n private _resizeObserver: Nullable<Observer<AbstractEngine>>;\r\n private _isLoading: boolean;\r\n /**\r\n * Maps a loading `HTMLDivElement` to a tuple containing the associated `HTMLCanvasElement`\r\n * and its `DOMRect` (or `null` if not yet available).\r\n */\r\n private _loadingDivToRenderingCanvasMap: Map<HTMLDivElement, [HTMLCanvasElement, DOMRect | null]> = new Map();\r\n private _loadingTextDiv: Nullable<HTMLDivElement>;\r\n private _style: Nullable<HTMLStyleElement>;\r\n\r\n /** Gets or sets the logo url to use for the default loading screen */\r\n public static DefaultLogoUrl = \"\";\r\n\r\n /** Gets or sets the spinner url to use for the default loading screen */\r\n public static DefaultSpinnerUrl = \"\";\r\n\r\n /**\r\n * Creates a new default loading screen\r\n * @param _renderingCanvas defines the canvas used to render the scene\r\n * @param _loadingText defines the default text to display\r\n * @param _loadingDivBackgroundColor defines the default background color\r\n */\r\n constructor(\r\n private _renderingCanvas: HTMLCanvasElement,\r\n private _loadingText = \"\",\r\n private _loadingDivBackgroundColor = \"black\"\r\n ) {}\r\n\r\n /**\r\n * Function called to display the loading screen\r\n */\r\n public displayLoadingUI(): void {\r\n if (this._isLoading) {\r\n // Do not add a loading screen if it is already loading\r\n return;\r\n }\r\n\r\n this._isLoading = true;\r\n // get current engine by rendering canvas\r\n this._engine = EngineStore.Instances.find((engine) => engine.getRenderingCanvas() === this._renderingCanvas) as AbstractEngine;\r\n\r\n const loadingDiv = document.createElement(\"div\");\r\n\r\n loadingDiv.id = \"babylonjsLoadingDiv\";\r\n loadingDiv.style.opacity = \"0\";\r\n loadingDiv.style.transition = \"opacity 1.5s ease\";\r\n loadingDiv.style.pointerEvents = \"none\";\r\n loadingDiv.style.display = \"grid\";\r\n loadingDiv.style.gridTemplateRows = \"100%\";\r\n loadingDiv.style.gridTemplateColumns = \"100%\";\r\n loadingDiv.style.justifyItems = \"center\";\r\n loadingDiv.style.alignItems = \"center\";\r\n\r\n // Loading text\r\n this._loadingTextDiv = document.createElement(\"div\");\r\n this._loadingTextDiv.style.position = \"absolute\";\r\n this._loadingTextDiv.style.left = \"0\";\r\n this._loadingTextDiv.style.top = \"50%\";\r\n this._loadingTextDiv.style.marginTop = \"80px\";\r\n this._loadingTextDiv.style.width = \"100%\";\r\n this._loadingTextDiv.style.height = \"20px\";\r\n this._loadingTextDiv.style.fontFamily = \"Arial\";\r\n this._loadingTextDiv.style.fontSize = \"14px\";\r\n this._loadingTextDiv.style.color = \"white\";\r\n this._loadingTextDiv.style.textAlign = \"center\";\r\n this._loadingTextDiv.style.zIndex = \"1\";\r\n this._loadingTextDiv.innerHTML = \"Loading\";\r\n\r\n loadingDiv.appendChild(this._loadingTextDiv);\r\n\r\n //set the predefined text\r\n this._loadingTextDiv.innerHTML = this._loadingText;\r\n\r\n // Generating keyframes\r\n this._style = document.createElement(\"style\");\r\n const keyFrames = `@-webkit-keyframes spin1 {\\\r\n 0% { -webkit-transform: rotate(0deg);}\r\n 100% { -webkit-transform: rotate(360deg);}\r\n }\\\r\n @keyframes spin1 {\\\r\n 0% { transform: rotate(0deg);}\r\n 100% { transform: rotate(360deg);}\r\n }`;\r\n this._style.innerHTML = keyFrames;\r\n document.getElementsByTagName(\"head\")[0].appendChild(this._style);\r\n\r\n const svgSupport = !!window.SVGSVGElement;\r\n // Loading img\r\n const imgBack = new Image();\r\n if (!DefaultLoadingScreen.DefaultLogoUrl) {\r\n imgBack.src = !svgSupport\r\n ? \"https://cdn.babylonjs.com/Assets/babylonLogo.png\"\r\n : `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxODAuMTcgMjA4LjA0Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2ZmZjt9LmNscy0ye2ZpbGw6I2UwNjg0Yjt9LmNscy0ze2ZpbGw6I2JiNDY0Yjt9LmNscy00e2ZpbGw6I2UwZGVkODt9LmNscy01e2ZpbGw6I2Q1ZDJjYTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPkJhYnlsb25Mb2dvPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iUGFnZV9FbGVtZW50cyIgZGF0YS1uYW1lPSJQYWdlIEVsZW1lbnRzIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik05MC4wOSwwLDAsNTJWMTU2bDkwLjA5LDUyLDkwLjA4LTUyVjUyWiIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMiIgcG9pbnRzPSIxODAuMTcgNTIuMDEgMTUxLjk3IDM1LjczIDEyNC44NSA1MS4zOSAxNTMuMDUgNjcuNjcgMTgwLjE3IDUyLjAxIi8+PHBvbHlnb24gY2xhc3M9ImNscy0yIiBwb2ludHM9IjI3LjEyIDY3LjY3IDExNy4yMSAxNS42NiA5MC4wOCAwIDAgNTIuMDEgMjcuMTIgNjcuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iNjEuODkgMTIwLjMgOTAuMDggMTM2LjU4IDExOC4yOCAxMjAuMyA5MC4wOCAxMDQuMDIgNjEuODkgMTIwLjMiLz48cG9seWdvbiBjbGFzcz0iY2xzLTMiIHBvaW50cz0iMTUzLjA1IDY3LjY3IDE1My4wNSAxNDAuMzcgOTAuMDggMTc2LjcyIDI3LjEyIDE0MC4zNyAyNy4xMiA2Ny42NyAwIDUyLjAxIDAgMTU2LjAzIDkwLjA4IDIwOC4wNCAxODAuMTcgMTU2LjAzIDE4MC4xNyA1Mi4wMSAxNTMuMDUgNjcuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTMiIHBvaW50cz0iOTAuMDggNzEuNDYgNjEuODkgODcuNzQgNjEuODkgMTIwLjMgOTAuMDggMTA0LjAyIDExOC4yOCAxMjAuMyAxMTguMjggODcuNzQgOTAuMDggNzEuNDYiLz48cG9seWdvbiBjbGFzcz0iY2xzLTQiIHBvaW50cz0iMTUzLjA1IDY3LjY3IDExOC4yOCA4Ny43NCAxMTguMjggMTIwLjMgOTAuMDggMTM2LjU4IDkwLjA4IDE3Ni43MiAxNTMuMDUgMTQwLjM3IDE1My4wNSA2Ny42NyIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtNSIgcG9pbnRzPSIyNy4xMiA2Ny42NyA2MS44OSA4Ny43NCA2MS44OSAxMjAuMyA5MC4wOCAxMzYuNTggOTAuMDggMTc2LjcyIDI3LjEyIDE0MC4zNyAyNy4xMiA2Ny42NyIvPjwvZz48L2c+PC9zdmc+`;\r\n } else {\r\n imgBack.src = DefaultLoadingScreen.DefaultLogoUrl;\r\n }\r\n\r\n imgBack.style.width = \"150px\";\r\n imgBack.style.gridColumn = \"1\";\r\n imgBack.style.gridRow = \"1\";\r\n imgBack.style.top = \"50%\";\r\n imgBack.style.left = \"50%\";\r\n imgBack.style.transform = \"translate(-50%, -50%)\";\r\n imgBack.style.position = \"absolute\";\r\n\r\n const imageSpinnerContainer = document.createElement(\"div\");\r\n imageSpinnerContainer.style.width = \"300px\";\r\n imageSpinnerContainer.style.gridColumn = \"1\";\r\n imageSpinnerContainer.style.gridRow = \"1\";\r\n imageSpinnerContainer.style.top = \"50%\";\r\n imageSpinnerContainer.style.left = \"50%\";\r\n imageSpinnerContainer.style.transform = \"translate(-50%, -50%)\";\r\n imageSpinnerContainer.style.position = \"absolute\";\r\n\r\n // Loading spinner\r\n const imgSpinner = new Image();\r\n\r\n if (!DefaultLoadingScreen.DefaultSpinnerUrl) {\r\n imgSpinner.src = !svgSupport\r\n ? \"https://cdn.babylonjs.com/Assets/loadingIcon.png\"\r\n : `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzOTIgMzkyIj48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2UwNjg0Yjt9LmNscy0ye2ZpbGw6bm9uZTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPlNwaW5uZXJJY29uPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iU3Bpbm5lciI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNDAuMjEsMTI2LjQzYzMuNy03LjMxLDcuNjctMTQuNDQsMTItMjEuMzJsMy4zNi01LjEsMy41Mi01YzEuMjMtMS42MywyLjQxLTMuMjksMy42NS00LjkxczIuNTMtMy4yMSwzLjgyLTQuNzlBMTg1LjIsMTg1LjIsMCwwLDEsODMuNCw2Ny40M2EyMDgsMjA4LDAsMCwxLDE5LTE1LjY2YzMuMzUtMi40MSw2Ljc0LTQuNzgsMTAuMjUtN3M3LjExLTQuMjgsMTAuNzUtNi4zMmM3LjI5LTQsMTQuNzMtOCwyMi41My0xMS40OSwzLjktMS43Miw3Ljg4LTMuMywxMi00LjY0YTEwNC4yMiwxMDQuMjIsMCwwLDEsMTIuNDQtMy4yMyw2Mi40NCw2Mi40NCwwLDAsMSwxMi43OC0xLjM5QTI1LjkyLDI1LjkyLDAsMCwxLDE5NiwyMS40NGE2LjU1LDYuNTUsMCwwLDEsMi4wNSw5LDYuNjYsNi42NiwwLDAsMS0xLjY0LDEuNzhsLS40MS4yOWEyMi4wNywyMi4wNywwLDAsMS01Ljc4LDMsMzAuNDIsMzAuNDIsMCwwLDEtNS42NywxLjYyLDM3LjgyLDM3LjgyLDAsMCwxLTUuNjkuNzFjLTEsMC0xLjkuMTgtMi44NS4yNmwtMi44NS4yNHEtNS43Mi41MS0xMS40OCwxLjFjLTMuODQuNC03LjcxLjgyLTExLjU4LDEuNGExMTIuMzQsMTEyLjM0LDAsMCwwLTIyLjk0LDUuNjFjLTMuNzIsMS4zNS03LjM0LDMtMTAuOTQsNC42NHMtNy4xNCwzLjUxLTEwLjYsNS41MUExNTEuNiwxNTEuNiwwLDAsMCw2OC41Niw4N0M2Ny4yMyw4OC40OCw2Niw5MCw2NC42NCw5MS41NnMtMi41MSwzLjE1LTMuNzUsNC43M2wtMy41NCw0LjljLTEuMTMsMS42Ni0yLjIzLDMuMzUtMy4zMyw1YTEyNywxMjcsMCwwLDAtMTAuOTMsMjEuNDksMS41OCwxLjU4LDAsMSwxLTMtMS4xNVM0MC4xOSwxMjYuNDcsNDAuMjEsMTI2LjQzWiIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzOTIiLz48L2c+PC9nPjwvc3ZnPg==`;\r\n } else {\r\n imgSpinner.src = DefaultLoadingScreen.DefaultSpinnerUrl;\r\n }\r\n\r\n imgSpinner.style.animation = \"spin1 0.75s infinite linear\";\r\n imgSpinner.style.transformOrigin = \"50% 50%\";\r\n\r\n if (!svgSupport) {\r\n const logoSize = { w: 16, h: 18.5 };\r\n const loadingSize = { w: 30, h: 30 };\r\n // set styling correctly\r\n imgBack.style.width = `${logoSize.w}vh`;\r\n imgBack.style.height = `${logoSize.h}vh`;\r\n imgBack.style.left = `calc(50% - ${logoSize.w / 2}vh)`;\r\n imgBack.style.top = `calc(50% - ${logoSize.h / 2}vh)`;\r\n\r\n imgSpinner.style.width = `${loadingSize.w}vh`;\r\n imgSpinner.style.height = `${loadingSize.h}vh`;\r\n imgSpinner.style.left = `calc(50% - ${loadingSize.w / 2}vh)`;\r\n imgSpinner.style.top = `calc(50% - ${loadingSize.h / 2}vh)`;\r\n }\r\n\r\n imageSpinnerContainer.appendChild(imgSpinner);\r\n\r\n loadingDiv.appendChild(imgBack);\r\n loadingDiv.appendChild(imageSpinnerContainer);\r\n loadingDiv.style.backgroundColor = this._loadingDivBackgroundColor;\r\n loadingDiv.style.opacity = \"1\";\r\n\r\n const canvases: Array<HTMLCanvasElement> = [];\r\n const views = this._engine.views;\r\n if (views?.length) {\r\n for (const view of views) {\r\n if (view.enabled) {\r\n canvases.push(view.target);\r\n }\r\n }\r\n } else {\r\n canvases.push(this._renderingCanvas);\r\n }\r\n for (let i = 0; i < canvases.length; i++) {\r\n const canvas = canvases[i];\r\n const clonedLoadingDiv = loadingDiv.cloneNode(true) as HTMLDivElement;\r\n clonedLoadingDiv.id += `-${i}`;\r\n this._loadingDivToRenderingCanvasMap.set(clonedLoadingDiv, [canvas, null]);\r\n }\r\n\r\n this._resizeLoadingUI();\r\n\r\n this._resizeObserver = this._engine.onResizeObservable.add(() => {\r\n this._resizeLoadingUI();\r\n });\r\n\r\n this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n document.body.appendChild(loadingDiv);\r\n });\r\n }\r\n\r\n /**\r\n * Function called to hide the loading screen\r\n */\r\n public hideLoadingUI(): void {\r\n if (!this._isLoading) {\r\n return;\r\n }\r\n\r\n let completedTransitions = 0;\r\n\r\n const onTransitionEnd = (event: TransitionEvent) => {\r\n const loadingDiv = event.target as HTMLDivElement;\r\n // ensure that ending transition event is generated by one of the current loadingDivs\r\n const isTransitionEndOnLoadingDiv = this._loadingDivToRenderingCanvasMap.has(loadingDiv);\r\n\r\n if (isTransitionEndOnLoadingDiv) {\r\n completedTransitions++;\r\n loadingDiv.remove();\r\n\r\n const allTransitionsCompleted = completedTransitions === this._loadingDivToRenderingCanvasMap.size;\r\n if (allTransitionsCompleted) {\r\n if (this._loadingTextDiv) {\r\n this._loadingTextDiv.remove();\r\n this._loadingTextDiv = null;\r\n }\r\n if (this._style) {\r\n this._style.remove();\r\n this._style = null;\r\n }\r\n\r\n window.removeEventListener(\"transitionend\", onTransitionEnd);\r\n this._engine!.onResizeObservable.remove(this._resizeObserver);\r\n this._loadingDivToRenderingCanvasMap.clear();\r\n this._engine = null;\r\n this._isLoading = false;\r\n }\r\n }\r\n };\r\n\r\n this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n loadingDiv.style.opacity = \"0\";\r\n });\r\n\r\n window.addEventListener(\"transitionend\", onTransitionEnd);\r\n }\r\n\r\n /**\r\n * Gets or sets the text to display while loading\r\n */\r\n public set loadingUIText(text: string) {\r\n this._loadingText = text;\r\n\r\n if (this._loadingTextDiv) {\r\n this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n // set loadingTextDiv of current loadingDiv\r\n loadingDiv.children[0].innerHTML = this._loadingText;\r\n });\r\n }\r\n }\r\n\r\n public get loadingUIText(): string {\r\n return this._loadingText;\r\n }\r\n\r\n /**\r\n * Gets or sets the color to use for the background\r\n */\r\n public get loadingUIBackgroundColor(): string {\r\n return this._loadingDivBackgroundColor;\r\n }\r\n\r\n public set loadingUIBackgroundColor(color: string) {\r\n this._loadingDivBackgroundColor = color;\r\n\r\n if (!this._isLoading) {\r\n return;\r\n }\r\n\r\n this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n loadingDiv.style.backgroundColor = this._loadingDivBackgroundColor;\r\n });\r\n }\r\n\r\n /**\r\n * Checks if the layout of the canvas has changed by comparing the current layout\r\n * rectangle with the previous one.\r\n *\r\n * This function compares of the two `DOMRect` objects to determine if any of the layout dimensions have changed.\r\n * If the layout has changed or if there is no previous layout (i.e., `previousCanvasRect` is `null`),\r\n * it returns `true`. Otherwise, it returns `false`.\r\n *\r\n * @param previousCanvasRect defines the previously recorded `DOMRect` of the canvas, or `null` if no previous state exists.\r\n * @param currentCanvasRect defines the current `DOMRect` of the canvas to compare against the previous layout.\r\n * @returns `true` if the layout has changed, otherwise `false`.\r\n */\r\n private _isCanvasLayoutChanged(previousCanvasRect: DOMRect | null, currentCanvasRect: DOMRect) {\r\n return (\r\n !previousCanvasRect ||\r\n previousCanvasRect.left !== currentCanvasRect.left ||\r\n previousCanvasRect.top !== currentCanvasRect.top ||\r\n previousCanvasRect.right !== currentCanvasRect.right ||\r\n previousCanvasRect.bottom !== currentCanvasRect.bottom ||\r\n previousCanvasRect.width !== currentCanvasRect.width ||\r\n previousCanvasRect.height !== currentCanvasRect.height ||\r\n previousCanvasRect.x !== currentCanvasRect.x ||\r\n previousCanvasRect.y !== currentCanvasRect.y\r\n );\r\n }\r\n\r\n // Resize\r\n private _resizeLoadingUI = () => {\r\n if (!this._isLoading) {\r\n return;\r\n }\r\n\r\n this._loadingDivToRenderingCanvasMap.forEach(([canvas, previousCanvasRect], loadingDiv) => {\r\n const currentCanvasRect = canvas.getBoundingClientRect();\r\n if (this._isCanvasLayoutChanged(previousCanvasRect, currentCanvasRect)) {\r\n const canvasPositioning = window.getComputedStyle(canvas).position;\r\n\r\n loadingDiv.style.position = canvasPositioning === \"fixed\" ? \"fixed\" : \"absolute\";\r\n loadingDiv.style.left = currentCanvasRect.left + window.scrollX + \"px\";\r\n loadingDiv.style.top = currentCanvasRect.top + window.scrollY + \"px\";\r\n loadingDiv.style.width = currentCanvasRect.width + \"px\";\r\n loadingDiv.style.height = currentCanvasRect.height + \"px\";\r\n\r\n this._loadingDivToRenderingCanvasMap.set(loadingDiv, [canvas, currentCanvasRect]);\r\n }\r\n });\r\n };\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for loadingScreen.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLoadingScreen(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n RegisterAbstractEngineLoadingScreen();\r\n AbstractEngine.DefaultLoadingScreenFactory = (canvas: HTMLCanvasElement) => {\r\n return new DefaultLoadingScreen(canvas);\r\n };\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ambientOcclusionBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/Materials/Node/Blocks/Fragment/ambientOcclusionBlock.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialConnectionPointDirection, type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { RandomRange } from \"../../../../Maths/math.scalar.functions\";\r\nimport { RawTexture } from \"../../../Textures/rawTexture\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type AbstractEngine } from \"../../../../Engines/abstractEngine.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { ImageSourceBlock } from \"../Dual/imageSourceBlock.pure\";\r\nimport { type DepthSourceBlock } from \"../Dual/depthSourceBlock.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to evaluate screen spaceambient occlusion in a shader\r\n */\r\nexport class AmbientOcclusionBlock extends NodeMaterialBlock {\r\n private _randomTexture: Texture;\r\n private _randomSamplerName: string;\r\n\r\n /**\r\n * Defines the radius around the analyzed pixel used by the SSAO post-process\r\n */\r\n @editableInPropertyPage(\"radius\", PropertyTypeForEdition.Float, \"ADVANCED\", {\r\n min: 0.0001,\r\n })\r\n public radius = 0.0001;\r\n\r\n /**\r\n * Related to fallOff, used to interpolate SSAO samples (first interpolate function input) based on the occlusion difference of each pixel\r\n * Must not be equal to fallOff and superior to fallOff.\r\n */\r\n @editableInPropertyPage(\"area\", PropertyTypeForEdition.Float, \"ADVANCED\", {\r\n min: 0,\r\n })\r\n public area = 0.0075;\r\n\r\n /**\r\n * Related to area, used to interpolate SSAO samples (second interpolate function input) based on the occlusion difference of each pixel\r\n * Must not be equal to area and inferior to area.\r\n */\r\n @editableInPropertyPage(\"fallOff\", PropertyTypeForEdition.Float, \"ADVANCED\", {\r\n min: 0,\r\n })\r\n public fallOff = 0.000001;\r\n\r\n /**\r\n * Create a new AmbientOcclusionBlock\r\n * @param name defines the block name\r\n */\r\n public constructor(name: string) {\r\n super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n this.registerInput(\r\n \"source\",\r\n NodeMaterialBlockConnectionPointTypes.Object,\r\n true,\r\n NodeMaterialBlockTargets.VertexAndFragment,\r\n new NodeMaterialConnectionPointCustomObject(\"source\", this, NodeMaterialConnectionPointDirection.Input, ImageSourceBlock, \"ImageSourceBlock\")\r\n );\r\n this.registerInput(\"screenSize\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n this.registerOutput(\"occlusion\", NodeMaterialBlockConnectionPointTypes.Float);\r\n }\r\n\r\n /**\r\n * Gets the current class name\r\n * @returns the class name\r\n */\r\n public override getClassName() {\r\n return \"AmbientOcclusionBlock\";\r\n }\r\n\r\n /**\r\n * Gets the source component\r\n */\r\n public get source(): NodeMaterialConnectionPoint {\r\n return this._inputs[0];\r\n }\r\n\r\n /**\r\n * Gets the screenSize component\r\n */\r\n public get screenSize(): NodeMaterialConnectionPoint {\r\n return this._inputs[1];\r\n }\r\n\r\n /**\r\n * Gets the occlusion output\r\n */\r\n public get occlusion(): NodeMaterialConnectionPoint {\r\n return this._outputs[0];\r\n }\r\n\r\n /**\r\n * Bind data to effect\r\n * @param effect - the effect to bind to\r\n */\r\n public override bind(effect: Effect) {\r\n if (!this._randomTexture) {\r\n this._createRandomTexture(effect.getEngine());\r\n }\r\n\r\n effect.setTexture(this._randomSamplerName, this._randomTexture);\r\n }\r\n\r\n private _createRandomTexture(engine: AbstractEngine): void {\r\n const size = 512;\r\n\r\n const data = new Uint8Array(size * size * 4);\r\n for (let index = 0; index < data.length; ) {\r\n data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n data[index++] = 255;\r\n }\r\n\r\n const texture = RawTexture.CreateRGBATexture(data, size, size, engine, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n texture.name = \"SSAORandomTexture\";\r\n texture.wrapU = Texture.WRAP_ADDRESSMODE;\r\n texture.wrapV = Texture.WRAP_ADDRESSMODE;\r\n this._randomTexture = texture;\r\n }\r\n\r\n protected override _buildBlock(state: NodeMaterialBuildState) {\r\n super._buildBlock(state);\r\n\r\n if (!this.source.connectedPoint) {\r\n return this;\r\n }\r\n\r\n state.sharedData.bindableBlocks.push(this);\r\n const depthSource = this.source.connectedPoint!.ownerBlock as DepthSourceBlock;\r\n\r\n const occlusion = this._outputs[0];\r\n const screenSize = this.screenSize;\r\n\r\n let functionString: string;\r\n\r\n // Get view position from depth\r\n if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n functionString = `fn normalFromDepth(depth: f32, coords: vec2f, radius: f32) -> vec3f {\r\n let offset1: vec2f = vec2f(0.0, radius);\r\n let offset2: vec2f = vec2f(radius, 0.0);\r\n\r\n let depth1: f32 = textureSampleLevel(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, coords + offset1, 0.0).r;\r\n let depth2: f32 = textureSampleLevel(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, coords + offset2, 0.0).r;\r\n\r\n let p1: vec3f = vec3f(offset1, depth1 - depth);\r\n let p2: vec3f = vec3f(offset2, depth2 - depth);\r\n\r\n var normal: vec3f = cross(p1, p2);\r\n normal.z = -normal.z;\r\n\r\n return normalize(normal);\r\n }\r\n `;\r\n } else {\r\n functionString = `vec3 normalFromDepth(float depth, vec2 coords, float radius) {\r\n vec2 offset1 = vec2(0.0, radius);\r\n vec2 offset2 = vec2(radius, 0.0);\r\n\r\n float depth1 = textureLod(${depthSource.samplerName}, coords + offset1, 0.0).r;\r\n float depth2 = textureLod(${depthSource.samplerName}, coords + offset2, 0.0).r;\r\n\r\n vec3 p1 = vec3(offset1, depth1 - depth);\r\n vec3 p2 = vec3(offset2, depth2 - depth);\r\n\r\n vec3 normal = cross(p1, p2);\r\n normal.z = -normal.z;\r\n\r\n return normalize(normal);\r\n }\r\n `;\r\n }\r\n\r\n state._emitFunction(\"normalFromDepth\", functionString, \"// normalFromDepth function\");\r\n\r\n // Calculate ambient occlusion\r\n this._randomSamplerName = state._getFreeVariableName(\"randomSampler\");\r\n\r\n state._emit2DSampler(this._randomSamplerName);\r\n if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n functionString = `\r\n const sampleSphere: array<vec3f, 16> = array<vec3f, 16>(\r\n vec3f( 0.5381, 0.1856, -0.4319),\r\n vec3f( 0.1379, 0.2486, 0.4430),\r\n vec3f( 0.3371, 0.5679, -0.0057),\r\n vec3f(-0.6999, -0.0451, -0.0019),\r\n vec3f( 0.0689, -0.1598, -0.8547),\r\n vec3f( 0.0560, 0.0069, -0.1843),\r\n vec3f(-0.0146, 0.1402, 0.0762),\r\n vec3f( 0.0100, -0.1924, -0.0344),\r\n vec3f(-0.3577, -0.5301, -0.4358),\r\n vec3f(-0.3169, 0.1063, 0.0158),\r\n vec3f( 0.0103, -0.5869, 0.0046),\r\n vec3f(-0.0897, -0.4940, 0.3287),\r\n vec3f( 0.7119, -0.0154, -0.0918),\r\n vec3f(-0.0533, 0.0596, -0.5411),\r\n vec3f( 0.0352, -0.0631, 0.5460),\r\n vec3f(-0.4776, 0.2847, -0.0271)\r\n );\r\n\r\n fn computeOcclusion(screenSize: vec2f) -> f32 {\r\n let uv: vec2f = fragmentInputs.position.xy / screenSize;\r\n let random: vec3f = normalize(textureSampleLevel(${this._randomSamplerName}, ${this._randomSamplerName}Sampler, uv * 4.0, 0.0).rgb);\r\n let depth: f32 = textureSampleLevel(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, uv, 0.0).r;\r\n let position: vec3f = vec3f(uv, depth);\r\n let normal: vec3f = normalFromDepth(depth, uv, ${this.radius}f);\r\n\r\n let radiusDepth: f32 = ${this.radius}f / depth;\r\n var occlusion: f32 = 0.0;\r\n\r\n var ray: vec3f;\r\n var hemiRay: vec3f;\r\n var occlusionDepth: f32;\r\n var difference: f32;\r\n\r\n for (var i: i32 = 0; i < 16; i++)\r\n {\r\n ray = radiusDepth * reflect(sampleSphere[i], random);\r\n hemiRay = position + sign(dot(ray, normal)) * ray;\r\n\r\n occlusionDepth = textureSample(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, clamp(hemiRay.xy, vec2f(0.001, 0.001), vec2f(0.999, 0.999))).r;\r\n difference = depth - occlusionDepth;\r\n\r\n occlusion += step(${this.fallOff}f, difference) * (1.0 - smoothstep(${this.fallOff}f, ${this.area}f, difference));\r\n }\r\n\r\n return clamp(1.0 - occlusion / 16.0, 0.0, 1.0);\r\n }\r\n `;\r\n } else {\r\n functionString = `\r\n const vec3 sampleSphere[16] = vec3[](\r\n vec3( 0.5381, 0.1856, -0.4319),\r\n vec3( 0.1379, 0.2486, 0.4430),\r\n vec3( 0.3371, 0.5679, -0.0057),\r\n vec3(-0.6999, -0.0451, -0.0019),\r\n vec3( 0.0689, -0.1598, -0.8547),\r\n vec3( 0.0560, 0.0069, -0.1843),\r\n vec3(-0.0146, 0.1402, 0.0762),\r\n vec3( 0.0100, -0.1924, -0.0344),\r\n vec3(-0.3577, -0.5301, -0.4358),\r\n vec3(-0.3169, 0.1063, 0.0158),\r\n vec3( 0.0103, -0.5869, 0.0046),\r\n vec3(-0.0897, -0.4940, 0.3287),\r\n vec3( 0.7119, -0.0154, -0.0918),\r\n vec3(-0.0533, 0.0596, -0.5411),\r\n vec3( 0.0352, -0.0631, 0.5460),\r\n vec3(-0.4776, 0.2847, -0.0271)\r\n );\r\n\r\n float computeOcclusion(vec2 screenSize) {\r\n vec2 uv = gl_FragCoord.xy / screenSize;\r\n vec3 random = normalize(textureLod(${this._randomSamplerName}, uv * 4., 0.0).rgb);\r\n float depth = textureLod(${depthSource.samplerName}, uv, 0.0).r; \r\n vec3 position = vec3(uv, depth);\r\n vec3 normal = normalFromDepth(depth, uv, ${this.radius} );\r\n\r\n float radiusDepth = ${this.radius} / depth;\r\n float occlusion = 0.0;\r\n\r\n vec3 ray;\r\n vec3 hemiRay;\r\n float occlusionDepth;\r\n float difference;\r\n\r\n for (int i = 0; i < 16; i++)\r\n {\r\n ray = radiusDepth * reflect(sampleSphere[i], random);\r\n hemiRay = position + sign(dot(ray, normal)) * ray;\r\n\r\n occlusionDepth = texture2D(${depthSource.samplerName}, clamp(hemiRay.xy, vec2(0.001, 0.001), vec2(0.999, 0.999))).r;\r\n difference = depth - occlusionDepth;\r\n\r\n occlusion += step(${this.fallOff}, difference) * (1.0 - smoothstep(${this.fallOff}, ${this.area}, difference));\r\n }\r\n\r\n return clamp(1.0 - occlusion / 16.0, 0.0, 1.0);\r\n }\r\n `;\r\n }\r\n\r\n state._emitFunction(\"computeOcclusion\", functionString, \"// computeOcclusion function\");\r\n\r\n state.compilationString += state._declareOutput(occlusion) + ` = computeOcclusion(${screenSize.associatedVariableName});`;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Releases the resources held by the block\r\n */\r\n public override dispose(): void {\r\n if (this._randomTexture) {\r\n this._randomTexture.dispose();\r\n this._randomTexture = null!;\r\n }\r\n super.dispose();\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for ambientOcclusionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAmbientOcclusionBlock(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n RegisterClass(\"BABYLON.AmbientOcclusionBlock\", AmbientOcclusionBlock);\r\n}\r\n"]}
1
+ {"version":3,"file":"ambientOcclusionBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/Materials/Node/Blocks/Fragment/ambientOcclusionBlock.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialConnectionPointDirection, type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { RandomRange } from \"../../../../Maths/math.scalar.functions\";\r\nimport { RawTexture } from \"../../../Textures/rawTexture\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type AbstractEngine } from \"../../../../Engines/abstractEngine.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { ImageSourceBlock } from \"../Dual/imageSourceBlock.pure\";\r\nimport { type DepthSourceBlock } from \"../Dual/depthSourceBlock.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to evaluate screen spaceambient occlusion in a shader\r\n */\r\nexport class AmbientOcclusionBlock extends NodeMaterialBlock {\r\n private _randomTexture: Texture;\r\n private _randomSamplerName: string;\r\n\r\n /**\r\n * Defines the radius around the analyzed pixel used by the SSAO post-process\r\n */\r\n @editableInPropertyPage(\"radius\", PropertyTypeForEdition.Float, \"ADVANCED\", {\r\n min: 0.0001,\r\n })\r\n public radius = 0.0001;\r\n\r\n /**\r\n * Related to fallOff, used to interpolate SSAO samples (first interpolate function input) based on the occlusion difference of each pixel\r\n * Must not be equal to fallOff and superior to fallOff.\r\n */\r\n @editableInPropertyPage(\"area\", PropertyTypeForEdition.Float, \"ADVANCED\", {\r\n min: 0,\r\n })\r\n public area = 0.0075;\r\n\r\n /**\r\n * Related to area, used to interpolate SSAO samples (second interpolate function input) based on the occlusion difference of each pixel\r\n * Must not be equal to area and inferior to area.\r\n */\r\n @editableInPropertyPage(\"fallOff\", PropertyTypeForEdition.Float, \"ADVANCED\", {\r\n min: 0,\r\n })\r\n public fallOff = 0.000001;\r\n\r\n /**\r\n * Create a new AmbientOcclusionBlock\r\n * @param name defines the block name\r\n */\r\n public constructor(name: string) {\r\n super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n this.registerInput(\r\n \"source\",\r\n NodeMaterialBlockConnectionPointTypes.Object,\r\n true,\r\n NodeMaterialBlockTargets.VertexAndFragment,\r\n new NodeMaterialConnectionPointCustomObject(\"source\", this, NodeMaterialConnectionPointDirection.Input, ImageSourceBlock, \"ImageSourceBlock\")\r\n );\r\n this.registerInput(\"screenSize\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n this.registerOutput(\"occlusion\", NodeMaterialBlockConnectionPointTypes.Float);\r\n }\r\n\r\n /**\r\n * Gets the current class name\r\n * @returns the class name\r\n */\r\n public override getClassName() {\r\n return \"AmbientOcclusionBlock\";\r\n }\r\n\r\n /**\r\n * Gets the source component\r\n */\r\n public get source(): NodeMaterialConnectionPoint {\r\n return this._inputs[0];\r\n }\r\n\r\n /**\r\n * Gets the screenSize component\r\n */\r\n public get screenSize(): NodeMaterialConnectionPoint {\r\n return this._inputs[1];\r\n }\r\n\r\n /**\r\n * Gets the occlusion output\r\n */\r\n public get occlusion(): NodeMaterialConnectionPoint {\r\n return this._outputs[0];\r\n }\r\n\r\n /**\r\n * Bind data to effect\r\n * @param effect - the effect to bind to\r\n */\r\n public override bind(effect: Effect) {\r\n if (!this._randomTexture) {\r\n this._createRandomTexture(effect.getEngine());\r\n }\r\n\r\n effect.setTexture(this._randomSamplerName, this._randomTexture);\r\n }\r\n\r\n private _createRandomTexture(engine: AbstractEngine): void {\r\n const size = 512;\r\n\r\n const data = new Uint8Array(size * size * 4);\r\n for (let index = 0; index < data.length;) {\r\n data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n data[index++] = 255;\r\n }\r\n\r\n const texture = RawTexture.CreateRGBATexture(data, size, size, engine, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n texture.name = \"SSAORandomTexture\";\r\n texture.wrapU = Texture.WRAP_ADDRESSMODE;\r\n texture.wrapV = Texture.WRAP_ADDRESSMODE;\r\n this._randomTexture = texture;\r\n }\r\n\r\n protected override _buildBlock(state: NodeMaterialBuildState) {\r\n super._buildBlock(state);\r\n\r\n if (!this.source.connectedPoint) {\r\n return this;\r\n }\r\n\r\n state.sharedData.bindableBlocks.push(this);\r\n const depthSource = this.source.connectedPoint!.ownerBlock as DepthSourceBlock;\r\n\r\n const occlusion = this._outputs[0];\r\n const screenSize = this.screenSize;\r\n\r\n let functionString: string;\r\n\r\n // Get view position from depth\r\n if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n functionString = `fn normalFromDepth(depth: f32, coords: vec2f, radius: f32) -> vec3f {\r\n let offset1: vec2f = vec2f(0.0, radius);\r\n let offset2: vec2f = vec2f(radius, 0.0);\r\n\r\n let depth1: f32 = textureSampleLevel(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, coords + offset1, 0.0).r;\r\n let depth2: f32 = textureSampleLevel(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, coords + offset2, 0.0).r;\r\n\r\n let p1: vec3f = vec3f(offset1, depth1 - depth);\r\n let p2: vec3f = vec3f(offset2, depth2 - depth);\r\n\r\n var normal: vec3f = cross(p1, p2);\r\n normal.z = -normal.z;\r\n\r\n return normalize(normal);\r\n }\r\n `;\r\n } else {\r\n functionString = `vec3 normalFromDepth(float depth, vec2 coords, float radius) {\r\n vec2 offset1 = vec2(0.0, radius);\r\n vec2 offset2 = vec2(radius, 0.0);\r\n\r\n float depth1 = textureLod(${depthSource.samplerName}, coords + offset1, 0.0).r;\r\n float depth2 = textureLod(${depthSource.samplerName}, coords + offset2, 0.0).r;\r\n\r\n vec3 p1 = vec3(offset1, depth1 - depth);\r\n vec3 p2 = vec3(offset2, depth2 - depth);\r\n\r\n vec3 normal = cross(p1, p2);\r\n normal.z = -normal.z;\r\n\r\n return normalize(normal);\r\n }\r\n `;\r\n }\r\n\r\n state._emitFunction(\"normalFromDepth\", functionString, \"// normalFromDepth function\");\r\n\r\n // Calculate ambient occlusion\r\n this._randomSamplerName = state._getFreeVariableName(\"randomSampler\");\r\n\r\n state._emit2DSampler(this._randomSamplerName);\r\n if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n functionString = `\r\n const sampleSphere: array<vec3f, 16> = array<vec3f, 16>(\r\n vec3f( 0.5381, 0.1856, -0.4319),\r\n vec3f( 0.1379, 0.2486, 0.4430),\r\n vec3f( 0.3371, 0.5679, -0.0057),\r\n vec3f(-0.6999, -0.0451, -0.0019),\r\n vec3f( 0.0689, -0.1598, -0.8547),\r\n vec3f( 0.0560, 0.0069, -0.1843),\r\n vec3f(-0.0146, 0.1402, 0.0762),\r\n vec3f( 0.0100, -0.1924, -0.0344),\r\n vec3f(-0.3577, -0.5301, -0.4358),\r\n vec3f(-0.3169, 0.1063, 0.0158),\r\n vec3f( 0.0103, -0.5869, 0.0046),\r\n vec3f(-0.0897, -0.4940, 0.3287),\r\n vec3f( 0.7119, -0.0154, -0.0918),\r\n vec3f(-0.0533, 0.0596, -0.5411),\r\n vec3f( 0.0352, -0.0631, 0.5460),\r\n vec3f(-0.4776, 0.2847, -0.0271)\r\n );\r\n\r\n fn computeOcclusion(screenSize: vec2f) -> f32 {\r\n let uv: vec2f = fragmentInputs.position.xy / screenSize;\r\n let random: vec3f = normalize(textureSampleLevel(${this._randomSamplerName}, ${this._randomSamplerName}Sampler, uv * 4.0, 0.0).rgb);\r\n let depth: f32 = textureSampleLevel(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, uv, 0.0).r;\r\n let position: vec3f = vec3f(uv, depth);\r\n let normal: vec3f = normalFromDepth(depth, uv, ${this.radius}f);\r\n\r\n let radiusDepth: f32 = ${this.radius}f / depth;\r\n var occlusion: f32 = 0.0;\r\n\r\n var ray: vec3f;\r\n var hemiRay: vec3f;\r\n var occlusionDepth: f32;\r\n var difference: f32;\r\n\r\n for (var i: i32 = 0; i < 16; i++)\r\n {\r\n ray = radiusDepth * reflect(sampleSphere[i], random);\r\n hemiRay = position + sign(dot(ray, normal)) * ray;\r\n\r\n occlusionDepth = textureSample(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, clamp(hemiRay.xy, vec2f(0.001, 0.001), vec2f(0.999, 0.999))).r;\r\n difference = depth - occlusionDepth;\r\n\r\n occlusion += step(${this.fallOff}f, difference) * (1.0 - smoothstep(${this.fallOff}f, ${this.area}f, difference));\r\n }\r\n\r\n return clamp(1.0 - occlusion / 16.0, 0.0, 1.0);\r\n }\r\n `;\r\n } else {\r\n functionString = `\r\n const vec3 sampleSphere[16] = vec3[](\r\n vec3( 0.5381, 0.1856, -0.4319),\r\n vec3( 0.1379, 0.2486, 0.4430),\r\n vec3( 0.3371, 0.5679, -0.0057),\r\n vec3(-0.6999, -0.0451, -0.0019),\r\n vec3( 0.0689, -0.1598, -0.8547),\r\n vec3( 0.0560, 0.0069, -0.1843),\r\n vec3(-0.0146, 0.1402, 0.0762),\r\n vec3( 0.0100, -0.1924, -0.0344),\r\n vec3(-0.3577, -0.5301, -0.4358),\r\n vec3(-0.3169, 0.1063, 0.0158),\r\n vec3( 0.0103, -0.5869, 0.0046),\r\n vec3(-0.0897, -0.4940, 0.3287),\r\n vec3( 0.7119, -0.0154, -0.0918),\r\n vec3(-0.0533, 0.0596, -0.5411),\r\n vec3( 0.0352, -0.0631, 0.5460),\r\n vec3(-0.4776, 0.2847, -0.0271)\r\n );\r\n\r\n float computeOcclusion(vec2 screenSize) {\r\n vec2 uv = gl_FragCoord.xy / screenSize;\r\n vec3 random = normalize(textureLod(${this._randomSamplerName}, uv * 4., 0.0).rgb);\r\n float depth = textureLod(${depthSource.samplerName}, uv, 0.0).r; \r\n vec3 position = vec3(uv, depth);\r\n vec3 normal = normalFromDepth(depth, uv, ${this.radius} );\r\n\r\n float radiusDepth = ${this.radius} / depth;\r\n float occlusion = 0.0;\r\n\r\n vec3 ray;\r\n vec3 hemiRay;\r\n float occlusionDepth;\r\n float difference;\r\n\r\n for (int i = 0; i < 16; i++)\r\n {\r\n ray = radiusDepth * reflect(sampleSphere[i], random);\r\n hemiRay = position + sign(dot(ray, normal)) * ray;\r\n\r\n occlusionDepth = texture2D(${depthSource.samplerName}, clamp(hemiRay.xy, vec2(0.001, 0.001), vec2(0.999, 0.999))).r;\r\n difference = depth - occlusionDepth;\r\n\r\n occlusion += step(${this.fallOff}, difference) * (1.0 - smoothstep(${this.fallOff}, ${this.area}, difference));\r\n }\r\n\r\n return clamp(1.0 - occlusion / 16.0, 0.0, 1.0);\r\n }\r\n `;\r\n }\r\n\r\n state._emitFunction(\"computeOcclusion\", functionString, \"// computeOcclusion function\");\r\n\r\n state.compilationString += state._declareOutput(occlusion) + ` = computeOcclusion(${screenSize.associatedVariableName});`;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Releases the resources held by the block\r\n */\r\n public override dispose(): void {\r\n if (this._randomTexture) {\r\n this._randomTexture.dispose();\r\n this._randomTexture = null!;\r\n }\r\n super.dispose();\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for ambientOcclusionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAmbientOcclusionBlock(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n RegisterClass(\"BABYLON.AmbientOcclusionBlock\", AmbientOcclusionBlock);\r\n}\r\n"]}
@@ -1,6 +1,8 @@
1
1
  export declare enum SourceTextureFormat {
2
2
  ETC1S = 0,
3
- UASTC4x4 = 1
3
+ UASTC4x4 = 1,
4
+ /** Uncompressed 8 bits per channel RGBA data, stored as-is in the container (no transcoding required) */
5
+ RGBA32 = 2
4
6
  }
5
7
  export declare enum TranscodeTarget {
6
8
  ASTC_4X4_RGBA = 0,
@@ -95,9 +97,9 @@ export interface INode {
95
97
  */
96
98
  export interface IDecisionTree {
97
99
  /**
98
- * textureFormat can be either UASTC or ETC1S
100
+ * textureFormat can be either UASTC, ETC1S or RGBA32
99
101
  */
100
- [textureFormat: string]: INode;
102
+ [textureFormat: string]: INode | ILeaf;
101
103
  }
102
104
  /**
103
105
  * Result of the KTX2 decode function
@@ -119,8 +121,13 @@ export interface IDecodedData {
119
121
  /**
120
122
  * List of mipmap levels.
121
123
  * The first element is the base level, the last element is the smallest mipmap level (if more than one mipmap level is present)
124
+ * For array textures (layerCount greater than 1), each level contributes layerCount consecutive entries, ordered by layer.
122
125
  */
123
126
  mipmaps: Array<IMipmap>;
127
+ /**
128
+ * Number of array layers of the texture. 1 for a regular (non array) texture
129
+ */
130
+ layerCount: number;
124
131
  /**
125
132
  * Whether the texture data is in gamma space or not
126
133
  */
@@ -154,6 +161,10 @@ export interface IMipmap {
154
161
  * The height of the mipmap level
155
162
  */
156
163
  height: number;
164
+ /**
165
+ * The array layer this mipmap level belongs to. 0 for a regular (non array) texture
166
+ */
167
+ layerIndex: number;
157
168
  }
158
169
  /**
159
170
  * The compressed texture formats supported by the browser
@@ -3,6 +3,8 @@ export var SourceTextureFormat;
3
3
  SourceTextureFormat[SourceTextureFormat["ETC1S"] = 0] = "ETC1S";
4
4
  // eslint-disable-next-line @typescript-eslint/naming-convention
5
5
  SourceTextureFormat[SourceTextureFormat["UASTC4x4"] = 1] = "UASTC4x4";
6
+ /** Uncompressed 8 bits per channel RGBA data, stored as-is in the container (no transcoding required) */
7
+ SourceTextureFormat[SourceTextureFormat["RGBA32"] = 2] = "RGBA32";
6
8
  })(SourceTextureFormat || (SourceTextureFormat = {}));
7
9
  export var TranscodeTarget;
8
10
  (function (TranscodeTarget) {
@@ -1 +1 @@
1
- {"version":3,"file":"ktx2decoderTypes.js","sourceRoot":"","sources":["../../../../../dev/core/src/Materials/Textures/ktx2decoderTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC3B,+DAAK,CAAA;IACL,gEAAgE;IAChE,qEAAQ,CAAA;AACZ,CAAC,EAJW,mBAAmB,KAAnB,mBAAmB,QAI9B;AAED,MAAM,CAAN,IAAY,eAcX;AAdD,WAAY,eAAe;IACvB,uEAAa,CAAA;IACb,gEAAgE;IAChE,uEAA6B,CAAA;IAC7B,6DAAQ,CAAA;IACR,6DAAQ,CAAA;IACR,2DAAO,CAAA;IACP,uEAAa,CAAA;IACb,qEAAY,CAAA;IACZ,+DAAS,CAAA;IACT,6DAAQ,CAAA;IACR,yDAAM,CAAA;IACN,iDAAE,CAAA;IACF,oDAAG,CAAA;AACP,CAAC,EAdW,eAAe,KAAf,eAAe,QAc1B;AAED,MAAM,CAAN,IAAkB,YAcjB;AAdD,WAAkB,YAAY;IAC1B,uGAAuC,CAAA;IACvC,mGAAqC,CAAA;IACrC,mGAAqC,CAAA;IACrC,qGAAsC,CAAA;IACtC,2GAAyC,CAAA;IACzC,yGAAwC,CAAA;IACxC,6FAAkC,CAAA;IAClC,mFAA6B,CAAA;IAC7B,6FAAkC,CAAA;IAClC,iEAAoB,CAAA;IACpB,2DAAiB,CAAA;IACjB,gEAAgE;IAChE,6DAAkB,CAAA;AACtB,CAAC,EAdiB,YAAY,KAAZ,YAAY,QAc7B","sourcesContent":["export enum SourceTextureFormat {\r\n ETC1S,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n UASTC4x4,\r\n}\r\n\r\nexport enum TranscodeTarget {\r\n ASTC_4X4_RGBA,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n ASTC_4x4_RGBA = ASTC_4X4_RGBA,\r\n BC7_RGBA,\r\n BC3_RGBA,\r\n BC1_RGB,\r\n PVRTC1_4_RGBA,\r\n PVRTC1_4_RGB,\r\n ETC2_RGBA,\r\n ETC1_RGB,\r\n RGBA32,\r\n R8,\r\n RG8,\r\n}\r\n\r\nexport const enum EngineFormat {\r\n COMPRESSED_RGBA_BPTC_UNORM_EXT = 0x8e8c,\r\n COMPRESSED_RGBA_ASTC_4X4_KHR = 0x93b0,\r\n COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83f0,\r\n COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83f3,\r\n COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8c02,\r\n COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8c00,\r\n COMPRESSED_RGBA8_ETC2_EAC = 0x9278,\r\n COMPRESSED_RGB8_ETC2 = 0x9274,\r\n COMPRESSED_RGB_ETC1_WEBGL = 0x8d64,\r\n RGBA8Format = 0x8058,\r\n R8Format = 0x8229,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n RG8Format = 0x822b,\r\n}\r\n\r\n/**\r\n * Leaf node of a decision tree\r\n * It defines the transcoding format to use to transcode the texture as well as the corresponding format to use at the engine level when creating the texture\r\n */\r\nexport interface ILeaf {\r\n /**\r\n * The format to transcode to\r\n */\r\n transcodeFormat: TranscodeTarget;\r\n\r\n /**\r\n * The format to use when creating the texture at the engine level after it has been transcoded to transcodeFormat\r\n */\r\n engineFormat: EngineFormat;\r\n\r\n /**\r\n * Whether the texture must be rounded to a multiple of 4 (should normally be the case for all compressed formats). Default: true\r\n */\r\n roundToMultiple4?: boolean;\r\n}\r\n\r\n/**\r\n * Regular node of a decision tree\r\n *\r\n * Each property (except for \"yes\" and \"no\"), if not empty, will be checked in order to determine the next node to select.\r\n * If all checks are successful, the \"yes\" node will be selected, else the \"no\" node will be selected.\r\n */\r\nexport interface INode {\r\n /**\r\n * The name of the capability to check. Can be one of the following:\r\n * astc\r\n * bptc\r\n * s3tc\r\n * pvrtc\r\n * etc2\r\n * etc1\r\n */\r\n cap?: string;\r\n\r\n /**\r\n * The name of the option to check from the options object passed to the KTX2 decode function. {@link IKTX2DecoderOptions}\r\n */\r\n option?: string;\r\n\r\n /**\r\n * Checks if alpha is present in the texture\r\n */\r\n alpha?: boolean;\r\n\r\n /**\r\n * Checks the currently selected transcoding format.\r\n */\r\n transcodeFormat?: TranscodeTarget | TranscodeTarget[];\r\n\r\n /**\r\n * Checks that the texture is a power of two\r\n */\r\n needsPowerOfTwo?: boolean;\r\n\r\n /**\r\n * The node to select if all checks are successful\r\n */\r\n yes?: INode | ILeaf;\r\n\r\n /**\r\n * The node to select if at least one check is not successful\r\n */\r\n no?: INode | ILeaf;\r\n}\r\n\r\n/**\r\n * Decision tree used to determine the transcoding format to use for a given source texture format\r\n */\r\nexport interface IDecisionTree {\r\n /**\r\n * textureFormat can be either UASTC or ETC1S\r\n */\r\n [textureFormat: string]: INode;\r\n}\r\n\r\n/**\r\n * Result of the KTX2 decode function\r\n */\r\nexport interface IDecodedData {\r\n /**\r\n * Width of the texture\r\n */\r\n width: number;\r\n\r\n /**\r\n * Height of the texture\r\n */\r\n height: number;\r\n\r\n /**\r\n * The format to use when creating the texture at the engine level\r\n * This corresponds to the engineFormat property of the leaf node of the decision tree\r\n */\r\n transcodedFormat: number;\r\n\r\n /**\r\n * List of mipmap levels.\r\n * The first element is the base level, the last element is the smallest mipmap level (if more than one mipmap level is present)\r\n */\r\n mipmaps: Array<IMipmap>;\r\n\r\n /**\r\n * Whether the texture data is in gamma space or not\r\n */\r\n isInGammaSpace: boolean;\r\n\r\n /**\r\n * Whether the texture has an alpha channel or not\r\n */\r\n hasAlpha: boolean;\r\n\r\n /**\r\n * The name of the transcoder used to transcode the texture\r\n */\r\n transcoderName: string;\r\n\r\n /**\r\n * The errors (if any) encountered during the decoding process\r\n */\r\n errors?: string;\r\n}\r\n\r\n/**\r\n * Defines a mipmap level\r\n */\r\nexport interface IMipmap {\r\n /**\r\n * The data of the mipmap level\r\n */\r\n data: Uint8Array | null;\r\n\r\n /**\r\n * The width of the mipmap level\r\n */\r\n width: number;\r\n\r\n /**\r\n * The height of the mipmap level\r\n */\r\n height: number;\r\n}\r\n\r\n/**\r\n * The compressed texture formats supported by the browser\r\n */\r\nexport interface ICompressedFormatCapabilities {\r\n /**\r\n * Whether the browser supports ASTC\r\n */\r\n astc?: boolean;\r\n\r\n /**\r\n * Whether the browser supports BPTC\r\n */\r\n bptc?: boolean;\r\n\r\n /**\r\n * Whether the browser supports S3TC\r\n */\r\n s3tc?: boolean;\r\n\r\n /**\r\n * Whether the browser supports PVRTC\r\n */\r\n pvrtc?: boolean;\r\n\r\n /**\r\n * Whether the browser supports ETC2\r\n */\r\n etc2?: boolean;\r\n\r\n /**\r\n * Whether the browser supports ETC1\r\n */\r\n etc1?: boolean;\r\n}\r\n\r\n/**\r\n * Options passed to the KTX2 decode function\r\n */\r\nexport interface IKTX2DecoderOptions {\r\n /** use RGBA format if ASTC and BC7 are not available as transcoded format */\r\n useRGBAIfASTCBC7NotAvailableWhenUASTC?: boolean;\r\n\r\n /** force to always use (uncompressed) RGBA for transcoded format */\r\n forceRGBA?: boolean;\r\n\r\n /** force to always use (uncompressed) R8 for transcoded format */\r\n forceR8?: boolean;\r\n\r\n /** force to always use (uncompressed) RG8 for transcoded format */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n forceRG8?: boolean;\r\n\r\n /**\r\n * list of transcoders to bypass when looking for a suitable transcoder. The available transcoders are:\r\n * UniversalTranscoder_UASTC_ASTC\r\n * UniversalTranscoder_UASTC_BC7\r\n * UniversalTranscoder_UASTC_RGBA_UNORM\r\n * UniversalTranscoder_UASTC_RGBA_SRGB\r\n * UniversalTranscoder_UASTC_R8_UNORM\r\n * UniversalTranscoder_UASTC_RG8_UNORM\r\n * MSCTranscoder\r\n */\r\n bypassTranscoders?: string[];\r\n\r\n /**\r\n * Custom decision tree to apply after the default decision tree has selected a transcoding format.\r\n * Allows the user to override the default decision tree selection.\r\n * The decision tree can use the INode.transcodeFormat property to base its decision on the transcoding format selected by the default decision tree.\r\n */\r\n transcodeFormatDecisionTree?: IDecisionTree;\r\n}\r\n"]}
1
+ {"version":3,"file":"ktx2decoderTypes.js","sourceRoot":"","sources":["../../../../../dev/core/src/Materials/Textures/ktx2decoderTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC3B,+DAAK,CAAA;IACL,gEAAgE;IAChE,qEAAQ,CAAA;IACR,yGAAyG;IACzG,iEAAM,CAAA;AACV,CAAC,EANW,mBAAmB,KAAnB,mBAAmB,QAM9B;AAED,MAAM,CAAN,IAAY,eAcX;AAdD,WAAY,eAAe;IACvB,uEAAa,CAAA;IACb,gEAAgE;IAChE,uEAA6B,CAAA;IAC7B,6DAAQ,CAAA;IACR,6DAAQ,CAAA;IACR,2DAAO,CAAA;IACP,uEAAa,CAAA;IACb,qEAAY,CAAA;IACZ,+DAAS,CAAA;IACT,6DAAQ,CAAA;IACR,yDAAM,CAAA;IACN,iDAAE,CAAA;IACF,oDAAG,CAAA;AACP,CAAC,EAdW,eAAe,KAAf,eAAe,QAc1B;AAED,MAAM,CAAN,IAAkB,YAcjB;AAdD,WAAkB,YAAY;IAC1B,uGAAuC,CAAA;IACvC,mGAAqC,CAAA;IACrC,mGAAqC,CAAA;IACrC,qGAAsC,CAAA;IACtC,2GAAyC,CAAA;IACzC,yGAAwC,CAAA;IACxC,6FAAkC,CAAA;IAClC,mFAA6B,CAAA;IAC7B,6FAAkC,CAAA;IAClC,iEAAoB,CAAA;IACpB,2DAAiB,CAAA;IACjB,gEAAgE;IAChE,6DAAkB,CAAA;AACtB,CAAC,EAdiB,YAAY,KAAZ,YAAY,QAc7B","sourcesContent":["export enum SourceTextureFormat {\r\n ETC1S,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n UASTC4x4,\r\n /** Uncompressed 8 bits per channel RGBA data, stored as-is in the container (no transcoding required) */\r\n RGBA32,\r\n}\r\n\r\nexport enum TranscodeTarget {\r\n ASTC_4X4_RGBA,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n ASTC_4x4_RGBA = ASTC_4X4_RGBA,\r\n BC7_RGBA,\r\n BC3_RGBA,\r\n BC1_RGB,\r\n PVRTC1_4_RGBA,\r\n PVRTC1_4_RGB,\r\n ETC2_RGBA,\r\n ETC1_RGB,\r\n RGBA32,\r\n R8,\r\n RG8,\r\n}\r\n\r\nexport const enum EngineFormat {\r\n COMPRESSED_RGBA_BPTC_UNORM_EXT = 0x8e8c,\r\n COMPRESSED_RGBA_ASTC_4X4_KHR = 0x93b0,\r\n COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83f0,\r\n COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83f3,\r\n COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8c02,\r\n COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8c00,\r\n COMPRESSED_RGBA8_ETC2_EAC = 0x9278,\r\n COMPRESSED_RGB8_ETC2 = 0x9274,\r\n COMPRESSED_RGB_ETC1_WEBGL = 0x8d64,\r\n RGBA8Format = 0x8058,\r\n R8Format = 0x8229,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n RG8Format = 0x822b,\r\n}\r\n\r\n/**\r\n * Leaf node of a decision tree\r\n * It defines the transcoding format to use to transcode the texture as well as the corresponding format to use at the engine level when creating the texture\r\n */\r\nexport interface ILeaf {\r\n /**\r\n * The format to transcode to\r\n */\r\n transcodeFormat: TranscodeTarget;\r\n\r\n /**\r\n * The format to use when creating the texture at the engine level after it has been transcoded to transcodeFormat\r\n */\r\n engineFormat: EngineFormat;\r\n\r\n /**\r\n * Whether the texture must be rounded to a multiple of 4 (should normally be the case for all compressed formats). Default: true\r\n */\r\n roundToMultiple4?: boolean;\r\n}\r\n\r\n/**\r\n * Regular node of a decision tree\r\n *\r\n * Each property (except for \"yes\" and \"no\"), if not empty, will be checked in order to determine the next node to select.\r\n * If all checks are successful, the \"yes\" node will be selected, else the \"no\" node will be selected.\r\n */\r\nexport interface INode {\r\n /**\r\n * The name of the capability to check. Can be one of the following:\r\n * astc\r\n * bptc\r\n * s3tc\r\n * pvrtc\r\n * etc2\r\n * etc1\r\n */\r\n cap?: string;\r\n\r\n /**\r\n * The name of the option to check from the options object passed to the KTX2 decode function. {@link IKTX2DecoderOptions}\r\n */\r\n option?: string;\r\n\r\n /**\r\n * Checks if alpha is present in the texture\r\n */\r\n alpha?: boolean;\r\n\r\n /**\r\n * Checks the currently selected transcoding format.\r\n */\r\n transcodeFormat?: TranscodeTarget | TranscodeTarget[];\r\n\r\n /**\r\n * Checks that the texture is a power of two\r\n */\r\n needsPowerOfTwo?: boolean;\r\n\r\n /**\r\n * The node to select if all checks are successful\r\n */\r\n yes?: INode | ILeaf;\r\n\r\n /**\r\n * The node to select if at least one check is not successful\r\n */\r\n no?: INode | ILeaf;\r\n}\r\n\r\n/**\r\n * Decision tree used to determine the transcoding format to use for a given source texture format\r\n */\r\nexport interface IDecisionTree {\r\n /**\r\n * textureFormat can be either UASTC, ETC1S or RGBA32\r\n */\r\n [textureFormat: string]: INode | ILeaf;\r\n}\r\n\r\n/**\r\n * Result of the KTX2 decode function\r\n */\r\nexport interface IDecodedData {\r\n /**\r\n * Width of the texture\r\n */\r\n width: number;\r\n\r\n /**\r\n * Height of the texture\r\n */\r\n height: number;\r\n\r\n /**\r\n * The format to use when creating the texture at the engine level\r\n * This corresponds to the engineFormat property of the leaf node of the decision tree\r\n */\r\n transcodedFormat: number;\r\n\r\n /**\r\n * List of mipmap levels.\r\n * The first element is the base level, the last element is the smallest mipmap level (if more than one mipmap level is present)\r\n * For array textures (layerCount greater than 1), each level contributes layerCount consecutive entries, ordered by layer.\r\n */\r\n mipmaps: Array<IMipmap>;\r\n\r\n /**\r\n * Number of array layers of the texture. 1 for a regular (non array) texture\r\n */\r\n layerCount: number;\r\n\r\n /**\r\n * Whether the texture data is in gamma space or not\r\n */\r\n isInGammaSpace: boolean;\r\n\r\n /**\r\n * Whether the texture has an alpha channel or not\r\n */\r\n hasAlpha: boolean;\r\n\r\n /**\r\n * The name of the transcoder used to transcode the texture\r\n */\r\n transcoderName: string;\r\n\r\n /**\r\n * The errors (if any) encountered during the decoding process\r\n */\r\n errors?: string;\r\n}\r\n\r\n/**\r\n * Defines a mipmap level\r\n */\r\nexport interface IMipmap {\r\n /**\r\n * The data of the mipmap level\r\n */\r\n data: Uint8Array | null;\r\n\r\n /**\r\n * The width of the mipmap level\r\n */\r\n width: number;\r\n\r\n /**\r\n * The height of the mipmap level\r\n */\r\n height: number;\r\n\r\n /**\r\n * The array layer this mipmap level belongs to. 0 for a regular (non array) texture\r\n */\r\n layerIndex: number;\r\n}\r\n\r\n/**\r\n * The compressed texture formats supported by the browser\r\n */\r\nexport interface ICompressedFormatCapabilities {\r\n /**\r\n * Whether the browser supports ASTC\r\n */\r\n astc?: boolean;\r\n\r\n /**\r\n * Whether the browser supports BPTC\r\n */\r\n bptc?: boolean;\r\n\r\n /**\r\n * Whether the browser supports S3TC\r\n */\r\n s3tc?: boolean;\r\n\r\n /**\r\n * Whether the browser supports PVRTC\r\n */\r\n pvrtc?: boolean;\r\n\r\n /**\r\n * Whether the browser supports ETC2\r\n */\r\n etc2?: boolean;\r\n\r\n /**\r\n * Whether the browser supports ETC1\r\n */\r\n etc1?: boolean;\r\n}\r\n\r\n/**\r\n * Options passed to the KTX2 decode function\r\n */\r\nexport interface IKTX2DecoderOptions {\r\n /** use RGBA format if ASTC and BC7 are not available as transcoded format */\r\n useRGBAIfASTCBC7NotAvailableWhenUASTC?: boolean;\r\n\r\n /** force to always use (uncompressed) RGBA for transcoded format */\r\n forceRGBA?: boolean;\r\n\r\n /** force to always use (uncompressed) R8 for transcoded format */\r\n forceR8?: boolean;\r\n\r\n /** force to always use (uncompressed) RG8 for transcoded format */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n forceRG8?: boolean;\r\n\r\n /**\r\n * list of transcoders to bypass when looking for a suitable transcoder. The available transcoders are:\r\n * UniversalTranscoder_UASTC_ASTC\r\n * UniversalTranscoder_UASTC_BC7\r\n * UniversalTranscoder_UASTC_RGBA_UNORM\r\n * UniversalTranscoder_UASTC_RGBA_SRGB\r\n * UniversalTranscoder_UASTC_R8_UNORM\r\n * UniversalTranscoder_UASTC_RG8_UNORM\r\n * MSCTranscoder\r\n */\r\n bypassTranscoders?: string[];\r\n\r\n /**\r\n * Custom decision tree to apply after the default decision tree has selected a transcoding format.\r\n * Allows the user to override the default decision tree selection.\r\n * The decision tree can use the INode.transcodeFormat property to base its decision on the transcoding format selected by the default decision tree.\r\n */\r\n transcodeFormatDecisionTree?: IDecisionTree;\r\n}\r\n"]}
@@ -55,6 +55,35 @@ export declare function UploadImageToTexture2DArrayLayer(texture: RawTexture2DAr
55
55
  * @returns a promise resolved once the layer has been uploaded
56
56
  */
57
57
  export declare function LoadImageToTexture2DArrayLayerAsync(texture: RawTexture2DArray, url: string, layer: number, options?: IUploadImageToTexture2DArrayLayerOptions): Promise<void>;
58
+ /**
59
+ * Options controlling the creation of a 2D array texture from a KTX2 file.
60
+ */
61
+ export interface ICreateTexture2DArrayFromKTX2Options {
62
+ /** Defines if mip levels should be generated (true by default) */
63
+ generateMipMaps?: boolean;
64
+ /** Defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default) */
65
+ samplingMode?: number;
66
+ /** Defines if the texture must be stored with the Y axis inverted (false by default) */
67
+ invertY?: boolean;
68
+ }
69
+ /**
70
+ * Creates a 2D array texture from a single KTX2 file holding several array layers (layerCount greater than 1).
71
+ * This is the single-file counterpart to CreateTexture2DArrayFromImageUrlsAsync: rather than fetching one image
72
+ * per layer, the whole array travels in one container.
73
+ *
74
+ * The data is transcoded to uncompressed RGBA. Keeping the texture in its transcoded compressed form would
75
+ * require compressedTexImage3D support in the engine raw texture path, which does not exist yet, so the
76
+ * GPU cost here matches a plain RGBA array texture.
77
+ *
78
+ * Only the base mip level stored in the file is uploaded; when generateMipMaps is on, the remaining levels are
79
+ * regenerated by the engine. Uploading the file's own mip chain needs per-mip array uploads, which WebGL's
80
+ * updateRawTexture2DArray does not support today.
81
+ * @param scene defines the hosting scene
82
+ * @param data defines the url of the KTX2 file, or its already fetched content
83
+ * @param options defines optional creation settings
84
+ * @returns a promise resolved with the created RawTexture2DArray
85
+ */
86
+ export declare function CreateTexture2DArrayFromKTX2Async(scene: Scene, data: string | ArrayBufferView, options?: ICreateTexture2DArrayFromKTX2Options): Promise<RawTexture2DArray>;
58
87
  /**
59
88
  * Creates a 2D array texture and fills each layer from a list of image urls.
60
89
  * All images must share the same dimensions.
@@ -52,6 +52,77 @@ export async function LoadImageToTexture2DArrayLayerAsync(texture, url, layer, o
52
52
  bitmap.close();
53
53
  }
54
54
  }
55
+ /**
56
+ * Creates a 2D array texture from a single KTX2 file holding several array layers (layerCount greater than 1).
57
+ * This is the single-file counterpart to CreateTexture2DArrayFromImageUrlsAsync: rather than fetching one image
58
+ * per layer, the whole array travels in one container.
59
+ *
60
+ * The data is transcoded to uncompressed RGBA. Keeping the texture in its transcoded compressed form would
61
+ * require compressedTexImage3D support in the engine raw texture path, which does not exist yet, so the
62
+ * GPU cost here matches a plain RGBA array texture.
63
+ *
64
+ * Only the base mip level stored in the file is uploaded; when generateMipMaps is on, the remaining levels are
65
+ * regenerated by the engine. Uploading the file's own mip chain needs per-mip array uploads, which WebGL's
66
+ * updateRawTexture2DArray does not support today.
67
+ * @param scene defines the hosting scene
68
+ * @param data defines the url of the KTX2 file, or its already fetched content
69
+ * @param options defines optional creation settings
70
+ * @returns a promise resolved with the created RawTexture2DArray
71
+ */
72
+ export async function CreateTexture2DArrayFromKTX2Async(scene, data, options) {
73
+ let buffer;
74
+ if (typeof data === "string") {
75
+ const response = await fetch(data);
76
+ if (!response.ok) {
77
+ throw new Error(`Failed to fetch KTX2 file "${data}": ${response.status} ${response.statusText}`);
78
+ }
79
+ buffer = new Uint8Array(await response.arrayBuffer());
80
+ }
81
+ else {
82
+ buffer = data;
83
+ }
84
+ const { KhronosTextureContainer2 } = await import("../../Misc/khronosTextureContainer2.js");
85
+ if (!KhronosTextureContainer2.IsValid(buffer)) {
86
+ throw new Error("The provided data is not a valid KTX2 file.");
87
+ }
88
+ const container = new KhronosTextureContainer2(scene.getEngine());
89
+ // forceRGBA: the transcoded compressed formats cannot be uploaded to an array texture yet (see above).
90
+ const decodedData = await container._decodeAsync(buffer, { forceRGBA: true });
91
+ if (decodedData.errors) {
92
+ throw new Error("Failed to decode the KTX2 file. " + decodedData.errors);
93
+ }
94
+ const layerCount = Math.max(decodedData.layerCount ?? 1, 1);
95
+ // mipmaps are ordered level by level, and within a level layer by layer, so the base level occupies
96
+ // the first layerCount entries and its layers are already in ascending order.
97
+ const baseLevel = decodedData.mipmaps.slice(0, layerCount);
98
+ if (baseLevel.length !== layerCount) {
99
+ throw new Error(`Failed to decode the KTX2 file: expected ${layerCount} layers for the base mip level but got ${baseLevel.length}.`);
100
+ }
101
+ // Every layer of a level shares the level's dimensions, and forceRGBA above means each one must be exactly
102
+ // width * height * 4 bytes. RawTexture2DArray takes all the layers as one flat buffer and cannot detect a
103
+ // short or mismatched layer, so validate here rather than uploading malformed data.
104
+ const { width, height } = baseLevel[0];
105
+ const expectedLayerByteLength = width * height * 4;
106
+ for (const mipmap of baseLevel) {
107
+ if (!mipmap.data) {
108
+ throw new Error(`Failed to decode the KTX2 file: layer ${mipmap.layerIndex} of the base mip level is empty.`);
109
+ }
110
+ if (mipmap.width !== width || mipmap.height !== height) {
111
+ throw new Error(`Failed to decode the KTX2 file: layer ${mipmap.layerIndex} of the base mip level is ${mipmap.width}x${mipmap.height} but layer 0 is ${width}x${height}.`);
112
+ }
113
+ if (mipmap.data.byteLength !== expectedLayerByteLength) {
114
+ throw new Error(`Failed to decode the KTX2 file: layer ${mipmap.layerIndex} of the base mip level holds ${mipmap.data.byteLength} bytes but ${expectedLayerByteLength} were expected.`);
115
+ }
116
+ }
117
+ // A 2D array texture is uploaded as a single buffer holding every layer back to back.
118
+ const textureData = new Uint8Array(expectedLayerByteLength * layerCount);
119
+ let byteOffset = 0;
120
+ for (const mipmap of baseLevel) {
121
+ textureData.set(mipmap.data, byteOffset);
122
+ byteOffset += mipmap.data.byteLength;
123
+ }
124
+ return new RawTexture2DArray(textureData, width, height, layerCount, 5, scene, options?.generateMipMaps ?? true, options?.invertY ?? false, options?.samplingMode, 0);
125
+ }
55
126
  /**
56
127
  * Creates a 2D array texture and fills each layer from a list of image urls.
57
128
  * All images must share the same dimensions.
@@ -1 +1 @@
1
- {"version":3,"file":"rawTexture2DArray.functions.js","sourceRoot":"","sources":["../../../../../dev/core/src/Materials/Textures/rawTexture2DArray.functions.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ImageSource } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { _IsSideEffectImplemented, _WarnImport } from \"../../Misc/devTools\";\r\nimport { RawTexture2DArray } from \"./rawTexture2DArray\";\r\n\r\n/**\r\n * These helpers populate 2D array texture layers from decoded image sources.\r\n * They rely on the AbstractEngine.updateTextureArrayLayerFromImageSource engine extension, which is\r\n * an opt-in side effect. Register it before use by importing the matching module for your backend:\r\n * - WebGL2: import \"core/Engines/Extensions/engine.texture2DArrayImageSource\";\r\n * - WebGPU: import \"core/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource\";\r\n * (the full Engine build does not register it by default to keep it out of every engine bundle).\r\n *\r\n * Consuming the result: the built-in way to sample a chosen layer is Node Material's Texture block,\r\n * which exposes a `layer` input (feed it a Float) and samples the array at that layer for you — no\r\n * custom shader code required. If you instead write your own shader, declare a `sampler2DArray`\r\n * (GLSL) / `texture_2d_array<f32>` (WGSL) uniform and sample it with an explicit integer layer index;\r\n * the classic StandardMaterial / PBRMaterial texture slots are plain 2D and cannot read an array layer.\r\n */\r\n\r\n/**\r\n * Options controlling how an image source is uploaded into a 2D array texture layer.\r\n */\r\nexport interface IUploadImageToTexture2DArrayLayerOptions {\r\n /** Defines if the source must be stored with the Y axis inverted (false by default) */\r\n invertY?: boolean;\r\n /** Defines if the source alpha must be premultiplied (false by default) */\r\n premultiplyAlpha?: boolean;\r\n}\r\n\r\n/**\r\n * Options controlling the creation of a 2D array texture from a list of image urls.\r\n */\r\nexport interface ICreateTexture2DArrayFromImageUrlsOptions extends IUploadImageToTexture2DArrayLayerOptions {\r\n /** Defines if mip levels should be generated (true by default) */\r\n generateMipMaps?: boolean;\r\n /** Defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default) */\r\n samplingMode?: number;\r\n /** Defines the texture type (Constants.TEXTURETYPE_UNSIGNED_BYTE by default) */\r\n textureType?: number;\r\n /** Options forwarded to createImageBitmap when decoding each url */\r\n imageBitmapOptions?: ImageBitmapOptions;\r\n}\r\n\r\n/**\r\n * Uploads a decoded image source (ImageBitmap, canvas, video, image element...) into a single layer of a 2D array texture.\r\n * This is the image-source counterpart to RawTexture2DArray.update, which only accepts raw bytes.\r\n * @param texture defines the 2D array texture to upload into\r\n * @param source defines the image source to upload\r\n * @param layer defines the array layer to upload into\r\n * @param options defines optional upload settings (invertY, premultiplyAlpha)\r\n */\r\nexport function UploadImageToTexture2DArrayLayer(texture: RawTexture2DArray, source: ImageSource, layer: number, options?: IUploadImageToTexture2DArrayLayerOptions): void {\r\n const internalTexture = texture.getInternalTexture();\r\n if (!internalTexture) {\r\n throw new Error(\"Cannot upload to a 2D array texture that has no internal texture.\");\r\n }\r\n\r\n if (!Number.isInteger(layer) || layer < 0 || layer >= texture.depth) {\r\n throw new Error(`Layer ${layer} is out of range for a 2D array texture with ${texture.depth} layers.`);\r\n }\r\n\r\n const scene = texture.getScene();\r\n if (!scene) {\r\n throw new Error(\"Cannot upload to a 2D array texture that is not attached to a scene.\");\r\n }\r\n\r\n const engine = scene.getEngine();\r\n // updateTextureArrayLayerFromImageSource is an opt-in engine extension. When the consumer never\r\n // imported it, the augmented method is missing, so fail early with the standard side-effect import\r\n // message (matching the engine.rawTexture family) instead of a generic \"is not a function\" error.\r\n if (!_IsSideEffectImplemented(engine.updateTextureArrayLayerFromImageSource)) {\r\n throw _WarnImport(\"engine.texture2DArrayImageSource\");\r\n }\r\n\r\n engine.updateTextureArrayLayerFromImageSource(internalTexture, source, layer, options?.invertY ?? false, options?.premultiplyAlpha ?? false);\r\n}\r\n\r\n/**\r\n * Fetches an image from a url, decodes it and uploads it into a single layer of a 2D array texture.\r\n * @param texture defines the 2D array texture to upload into\r\n * @param url defines the url of the image to load\r\n * @param layer defines the array layer to upload into\r\n * @param options defines optional upload settings (invertY, premultiplyAlpha)\r\n * @returns a promise resolved once the layer has been uploaded\r\n */\r\nexport async function LoadImageToTexture2DArrayLayerAsync(\r\n texture: RawTexture2DArray,\r\n url: string,\r\n layer: number,\r\n options?: IUploadImageToTexture2DArrayLayerOptions\r\n): Promise<void> {\r\n const response = await fetch(url);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch image \"${url}\": ${response.status} ${response.statusText}`);\r\n }\r\n const blob = await response.blob();\r\n const bitmap = await createImageBitmap(blob);\r\n try {\r\n UploadImageToTexture2DArrayLayer(texture, bitmap, layer, options);\r\n } finally {\r\n bitmap.close();\r\n }\r\n}\r\n\r\n/**\r\n * Creates a 2D array texture and fills each layer from a list of image urls.\r\n * All images must share the same dimensions.\r\n * @param scene defines the hosting scene\r\n * @param urls defines the url of the image for each layer (at least one)\r\n * @param options defines optional creation and upload settings\r\n * @returns a promise resolved with the created RawTexture2DArray\r\n */\r\nexport async function CreateTexture2DArrayFromImageUrlsAsync(\r\n scene: Scene,\r\n urls: readonly [string, ...string[]],\r\n options?: ICreateTexture2DArrayFromImageUrlsOptions\r\n): Promise<RawTexture2DArray> {\r\n // allSettled (not all): a rejected fetch/decode must not leak the layers that\r\n // already decoded. Promise.all rejects on the first failure and never enters the\r\n // try/finally below, orphaning every ImageBitmap that resolved. Close the\r\n // fulfilled ones here, then rethrow the original failure.\r\n const results = await Promise.allSettled(\r\n urls.map(async (url) => {\r\n const response = await fetch(url);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch image \"${url}\": ${response.status} ${response.statusText}`);\r\n }\r\n return await createImageBitmap(await response.blob(), options?.imageBitmapOptions);\r\n })\r\n );\r\n\r\n const firstRejection = results.find((result): result is PromiseRejectedResult => result.status === \"rejected\");\r\n if (firstRejection) {\r\n for (const result of results) {\r\n if (result.status === \"fulfilled\") {\r\n result.value.close();\r\n }\r\n }\r\n throw firstRejection.reason;\r\n }\r\n\r\n const bitmaps = results.filter((result): result is PromiseFulfilledResult<ImageBitmap> => result.status === \"fulfilled\").map((result) => result.value) as [\r\n ImageBitmap,\r\n ...ImageBitmap[],\r\n ];\r\n\r\n try {\r\n const width = bitmaps[0].width;\r\n const height = bitmaps[0].height;\r\n\r\n for (let index = 1; index < bitmaps.length; index++) {\r\n const bitmap = bitmaps[index];\r\n if (bitmap.width !== width || bitmap.height !== height) {\r\n throw new Error(`All images must share the same dimensions. Image at index ${index} is ${bitmap.width}x${bitmap.height}, expected ${width}x${height}.`);\r\n }\r\n }\r\n\r\n const texture = new RawTexture2DArray(\r\n null,\r\n width,\r\n height,\r\n bitmaps.length,\r\n Constants.TEXTUREFORMAT_RGBA,\r\n scene,\r\n options?.generateMipMaps ?? true,\r\n options?.invertY ?? false,\r\n options?.samplingMode,\r\n options?.textureType\r\n );\r\n\r\n try {\r\n const uploadOptions: IUploadImageToTexture2DArrayLayerOptions = {\r\n invertY: options?.invertY ?? false,\r\n premultiplyAlpha: options?.premultiplyAlpha ?? false,\r\n };\r\n\r\n // updateTextureArrayLayerFromImageSource rebuilds the whole mip chain on each upload when mips\r\n // are enabled. Uploading N layers that way is O(N) redundant mip generation, so suppress it\r\n // per-layer and let only the final upload regenerate the mips once — a single generateMipmap\r\n // covers every layer of the array.\r\n const internalTexture = texture.getInternalTexture();\r\n const generateMipMaps = internalTexture?.generateMipMaps ?? false;\r\n if (internalTexture && generateMipMaps) {\r\n internalTexture.generateMipMaps = false;\r\n }\r\n\r\n for (let layer = 0; layer < bitmaps.length; layer++) {\r\n if (internalTexture && generateMipMaps && layer === bitmaps.length - 1) {\r\n internalTexture.generateMipMaps = true;\r\n }\r\n UploadImageToTexture2DArrayLayer(texture, bitmaps[layer], layer, uploadOptions);\r\n }\r\n\r\n return texture;\r\n } catch (error) {\r\n // A layer upload can throw (out-of-range layer, missing engine extension, backend upload\r\n // failure). Dispose the freshly allocated GPU texture so it does not leak, then rethrow.\r\n texture.dispose();\r\n throw error;\r\n }\r\n } finally {\r\n for (let index = 0; index < bitmaps.length; index++) {\r\n bitmaps[index].close();\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"rawTexture2DArray.functions.js","sourceRoot":"","sources":["../../../../../dev/core/src/Materials/Textures/rawTexture2DArray.functions.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ImageSource } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { _IsSideEffectImplemented, _WarnImport } from \"../../Misc/devTools\";\r\nimport { RawTexture2DArray } from \"./rawTexture2DArray\";\r\n\r\n/**\r\n * These helpers populate 2D array texture layers from decoded image sources.\r\n * They rely on the AbstractEngine.updateTextureArrayLayerFromImageSource engine extension, which is\r\n * an opt-in side effect. Register it before use by importing the matching module for your backend:\r\n * - WebGL2: import \"core/Engines/Extensions/engine.texture2DArrayImageSource\";\r\n * - WebGPU: import \"core/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource\";\r\n * (the full Engine build does not register it by default to keep it out of every engine bundle).\r\n *\r\n * Consuming the result: the built-in way to sample a chosen layer is Node Material's Texture block,\r\n * which exposes a `layer` input (feed it a Float) and samples the array at that layer for you — no\r\n * custom shader code required. If you instead write your own shader, declare a `sampler2DArray`\r\n * (GLSL) / `texture_2d_array<f32>` (WGSL) uniform and sample it with an explicit integer layer index;\r\n * the classic StandardMaterial / PBRMaterial texture slots are plain 2D and cannot read an array layer.\r\n */\r\n\r\n/**\r\n * Options controlling how an image source is uploaded into a 2D array texture layer.\r\n */\r\nexport interface IUploadImageToTexture2DArrayLayerOptions {\r\n /** Defines if the source must be stored with the Y axis inverted (false by default) */\r\n invertY?: boolean;\r\n /** Defines if the source alpha must be premultiplied (false by default) */\r\n premultiplyAlpha?: boolean;\r\n}\r\n\r\n/**\r\n * Options controlling the creation of a 2D array texture from a list of image urls.\r\n */\r\nexport interface ICreateTexture2DArrayFromImageUrlsOptions extends IUploadImageToTexture2DArrayLayerOptions {\r\n /** Defines if mip levels should be generated (true by default) */\r\n generateMipMaps?: boolean;\r\n /** Defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default) */\r\n samplingMode?: number;\r\n /** Defines the texture type (Constants.TEXTURETYPE_UNSIGNED_BYTE by default) */\r\n textureType?: number;\r\n /** Options forwarded to createImageBitmap when decoding each url */\r\n imageBitmapOptions?: ImageBitmapOptions;\r\n}\r\n\r\n/**\r\n * Uploads a decoded image source (ImageBitmap, canvas, video, image element...) into a single layer of a 2D array texture.\r\n * This is the image-source counterpart to RawTexture2DArray.update, which only accepts raw bytes.\r\n * @param texture defines the 2D array texture to upload into\r\n * @param source defines the image source to upload\r\n * @param layer defines the array layer to upload into\r\n * @param options defines optional upload settings (invertY, premultiplyAlpha)\r\n */\r\nexport function UploadImageToTexture2DArrayLayer(texture: RawTexture2DArray, source: ImageSource, layer: number, options?: IUploadImageToTexture2DArrayLayerOptions): void {\r\n const internalTexture = texture.getInternalTexture();\r\n if (!internalTexture) {\r\n throw new Error(\"Cannot upload to a 2D array texture that has no internal texture.\");\r\n }\r\n\r\n if (!Number.isInteger(layer) || layer < 0 || layer >= texture.depth) {\r\n throw new Error(`Layer ${layer} is out of range for a 2D array texture with ${texture.depth} layers.`);\r\n }\r\n\r\n const scene = texture.getScene();\r\n if (!scene) {\r\n throw new Error(\"Cannot upload to a 2D array texture that is not attached to a scene.\");\r\n }\r\n\r\n const engine = scene.getEngine();\r\n // updateTextureArrayLayerFromImageSource is an opt-in engine extension. When the consumer never\r\n // imported it, the augmented method is missing, so fail early with the standard side-effect import\r\n // message (matching the engine.rawTexture family) instead of a generic \"is not a function\" error.\r\n if (!_IsSideEffectImplemented(engine.updateTextureArrayLayerFromImageSource)) {\r\n throw _WarnImport(\"engine.texture2DArrayImageSource\");\r\n }\r\n\r\n engine.updateTextureArrayLayerFromImageSource(internalTexture, source, layer, options?.invertY ?? false, options?.premultiplyAlpha ?? false);\r\n}\r\n\r\n/**\r\n * Fetches an image from a url, decodes it and uploads it into a single layer of a 2D array texture.\r\n * @param texture defines the 2D array texture to upload into\r\n * @param url defines the url of the image to load\r\n * @param layer defines the array layer to upload into\r\n * @param options defines optional upload settings (invertY, premultiplyAlpha)\r\n * @returns a promise resolved once the layer has been uploaded\r\n */\r\nexport async function LoadImageToTexture2DArrayLayerAsync(\r\n texture: RawTexture2DArray,\r\n url: string,\r\n layer: number,\r\n options?: IUploadImageToTexture2DArrayLayerOptions\r\n): Promise<void> {\r\n const response = await fetch(url);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch image \"${url}\": ${response.status} ${response.statusText}`);\r\n }\r\n const blob = await response.blob();\r\n const bitmap = await createImageBitmap(blob);\r\n try {\r\n UploadImageToTexture2DArrayLayer(texture, bitmap, layer, options);\r\n } finally {\r\n bitmap.close();\r\n }\r\n}\r\n\r\n/**\r\n * Options controlling the creation of a 2D array texture from a KTX2 file.\r\n */\r\nexport interface ICreateTexture2DArrayFromKTX2Options {\r\n /** Defines if mip levels should be generated (true by default) */\r\n generateMipMaps?: boolean;\r\n /** Defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default) */\r\n samplingMode?: number;\r\n /** Defines if the texture must be stored with the Y axis inverted (false by default) */\r\n invertY?: boolean;\r\n}\r\n\r\n/**\r\n * Creates a 2D array texture from a single KTX2 file holding several array layers (layerCount greater than 1).\r\n * This is the single-file counterpart to CreateTexture2DArrayFromImageUrlsAsync: rather than fetching one image\r\n * per layer, the whole array travels in one container.\r\n *\r\n * The data is transcoded to uncompressed RGBA. Keeping the texture in its transcoded compressed form would\r\n * require compressedTexImage3D support in the engine raw texture path, which does not exist yet, so the\r\n * GPU cost here matches a plain RGBA array texture.\r\n *\r\n * Only the base mip level stored in the file is uploaded; when generateMipMaps is on, the remaining levels are\r\n * regenerated by the engine. Uploading the file's own mip chain needs per-mip array uploads, which WebGL's\r\n * updateRawTexture2DArray does not support today.\r\n * @param scene defines the hosting scene\r\n * @param data defines the url of the KTX2 file, or its already fetched content\r\n * @param options defines optional creation settings\r\n * @returns a promise resolved with the created RawTexture2DArray\r\n */\r\nexport async function CreateTexture2DArrayFromKTX2Async(scene: Scene, data: string | ArrayBufferView, options?: ICreateTexture2DArrayFromKTX2Options): Promise<RawTexture2DArray> {\r\n let buffer: ArrayBufferView;\r\n if (typeof data === \"string\") {\r\n const response = await fetch(data);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch KTX2 file \"${data}\": ${response.status} ${response.statusText}`);\r\n }\r\n buffer = new Uint8Array(await response.arrayBuffer());\r\n } else {\r\n buffer = data;\r\n }\r\n\r\n const { KhronosTextureContainer2 } = await import(\"../../Misc/khronosTextureContainer2\");\r\n\r\n if (!KhronosTextureContainer2.IsValid(buffer)) {\r\n throw new Error(\"The provided data is not a valid KTX2 file.\");\r\n }\r\n\r\n const container = new KhronosTextureContainer2(scene.getEngine());\r\n\r\n // forceRGBA: the transcoded compressed formats cannot be uploaded to an array texture yet (see above).\r\n const decodedData = await container._decodeAsync(buffer, { forceRGBA: true });\r\n\r\n if (decodedData.errors) {\r\n throw new Error(\"Failed to decode the KTX2 file. \" + decodedData.errors);\r\n }\r\n\r\n const layerCount = Math.max(decodedData.layerCount ?? 1, 1);\r\n // mipmaps are ordered level by level, and within a level layer by layer, so the base level occupies\r\n // the first layerCount entries and its layers are already in ascending order.\r\n const baseLevel = decodedData.mipmaps.slice(0, layerCount);\r\n\r\n if (baseLevel.length !== layerCount) {\r\n throw new Error(`Failed to decode the KTX2 file: expected ${layerCount} layers for the base mip level but got ${baseLevel.length}.`);\r\n }\r\n\r\n // Every layer of a level shares the level's dimensions, and forceRGBA above means each one must be exactly\r\n // width * height * 4 bytes. RawTexture2DArray takes all the layers as one flat buffer and cannot detect a\r\n // short or mismatched layer, so validate here rather than uploading malformed data.\r\n const { width, height } = baseLevel[0];\r\n const expectedLayerByteLength = width * height * 4;\r\n\r\n for (const mipmap of baseLevel) {\r\n if (!mipmap.data) {\r\n throw new Error(`Failed to decode the KTX2 file: layer ${mipmap.layerIndex} of the base mip level is empty.`);\r\n }\r\n if (mipmap.width !== width || mipmap.height !== height) {\r\n throw new Error(\r\n `Failed to decode the KTX2 file: layer ${mipmap.layerIndex} of the base mip level is ${mipmap.width}x${mipmap.height} but layer 0 is ${width}x${height}.`\r\n );\r\n }\r\n if (mipmap.data.byteLength !== expectedLayerByteLength) {\r\n throw new Error(\r\n `Failed to decode the KTX2 file: layer ${mipmap.layerIndex} of the base mip level holds ${mipmap.data.byteLength} bytes but ${expectedLayerByteLength} were expected.`\r\n );\r\n }\r\n }\r\n\r\n // A 2D array texture is uploaded as a single buffer holding every layer back to back.\r\n const textureData = new Uint8Array(expectedLayerByteLength * layerCount);\r\n let byteOffset = 0;\r\n for (const mipmap of baseLevel) {\r\n textureData.set(mipmap.data!, byteOffset);\r\n byteOffset += mipmap.data!.byteLength;\r\n }\r\n\r\n return new RawTexture2DArray(\r\n textureData,\r\n width,\r\n height,\r\n layerCount,\r\n Constants.TEXTUREFORMAT_RGBA,\r\n scene,\r\n options?.generateMipMaps ?? true,\r\n options?.invertY ?? false,\r\n options?.samplingMode,\r\n Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n );\r\n}\r\n\r\n/**\r\n * Creates a 2D array texture and fills each layer from a list of image urls.\r\n * All images must share the same dimensions.\r\n * @param scene defines the hosting scene\r\n * @param urls defines the url of the image for each layer (at least one)\r\n * @param options defines optional creation and upload settings\r\n * @returns a promise resolved with the created RawTexture2DArray\r\n */\r\nexport async function CreateTexture2DArrayFromImageUrlsAsync(\r\n scene: Scene,\r\n urls: readonly [string, ...string[]],\r\n options?: ICreateTexture2DArrayFromImageUrlsOptions\r\n): Promise<RawTexture2DArray> {\r\n // allSettled (not all): a rejected fetch/decode must not leak the layers that\r\n // already decoded. Promise.all rejects on the first failure and never enters the\r\n // try/finally below, orphaning every ImageBitmap that resolved. Close the\r\n // fulfilled ones here, then rethrow the original failure.\r\n const results = await Promise.allSettled(\r\n urls.map(async (url) => {\r\n const response = await fetch(url);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch image \"${url}\": ${response.status} ${response.statusText}`);\r\n }\r\n return await createImageBitmap(await response.blob(), options?.imageBitmapOptions);\r\n })\r\n );\r\n\r\n const firstRejection = results.find((result): result is PromiseRejectedResult => result.status === \"rejected\");\r\n if (firstRejection) {\r\n for (const result of results) {\r\n if (result.status === \"fulfilled\") {\r\n result.value.close();\r\n }\r\n }\r\n throw firstRejection.reason;\r\n }\r\n\r\n const bitmaps = results.filter((result): result is PromiseFulfilledResult<ImageBitmap> => result.status === \"fulfilled\").map((result) => result.value) as [\r\n ImageBitmap,\r\n ...ImageBitmap[],\r\n ];\r\n\r\n try {\r\n const width = bitmaps[0].width;\r\n const height = bitmaps[0].height;\r\n\r\n for (let index = 1; index < bitmaps.length; index++) {\r\n const bitmap = bitmaps[index];\r\n if (bitmap.width !== width || bitmap.height !== height) {\r\n throw new Error(`All images must share the same dimensions. Image at index ${index} is ${bitmap.width}x${bitmap.height}, expected ${width}x${height}.`);\r\n }\r\n }\r\n\r\n const texture = new RawTexture2DArray(\r\n null,\r\n width,\r\n height,\r\n bitmaps.length,\r\n Constants.TEXTUREFORMAT_RGBA,\r\n scene,\r\n options?.generateMipMaps ?? true,\r\n options?.invertY ?? false,\r\n options?.samplingMode,\r\n options?.textureType\r\n );\r\n\r\n try {\r\n const uploadOptions: IUploadImageToTexture2DArrayLayerOptions = {\r\n invertY: options?.invertY ?? false,\r\n premultiplyAlpha: options?.premultiplyAlpha ?? false,\r\n };\r\n\r\n // updateTextureArrayLayerFromImageSource rebuilds the whole mip chain on each upload when mips\r\n // are enabled. Uploading N layers that way is O(N) redundant mip generation, so suppress it\r\n // per-layer and let only the final upload regenerate the mips once — a single generateMipmap\r\n // covers every layer of the array.\r\n const internalTexture = texture.getInternalTexture();\r\n const generateMipMaps = internalTexture?.generateMipMaps ?? false;\r\n if (internalTexture && generateMipMaps) {\r\n internalTexture.generateMipMaps = false;\r\n }\r\n\r\n for (let layer = 0; layer < bitmaps.length; layer++) {\r\n if (internalTexture && generateMipMaps && layer === bitmaps.length - 1) {\r\n internalTexture.generateMipMaps = true;\r\n }\r\n UploadImageToTexture2DArrayLayer(texture, bitmaps[layer], layer, uploadOptions);\r\n }\r\n\r\n return texture;\r\n } catch (error) {\r\n // A layer upload can throw (out-of-range layer, missing engine extension, backend upload\r\n // failure). Dispose the freshly allocated GPU texture so it does not leak, then rethrow.\r\n texture.dispose();\r\n throw error;\r\n }\r\n } finally {\r\n for (let index = 0; index < bitmaps.length; index++) {\r\n bitmaps[index].close();\r\n }\r\n }\r\n}\r\n"]}
@@ -436,6 +436,7 @@ export declare class Material implements IAnimatable, IClipPlanesHolder {
436
436
  * | 18 | ALPHA_MIN | Defines that alpha blending is COLOR=MIN(SRC, DEST), ALPHA=MIN(SRC_ALPHA, DEST_ALPHA) |
437
437
  * | 19 | ALPHA_MAX | Defines that alpha blending is COLOR=MAX(SRC, DEST), ALPHA=MAX(SRC_ALPHA, DEST_ALPHA) |
438
438
  * | 20 | ALPHA_DUAL_SRC0_ADD_SRC1xDST | Defines that alpha blending uses dual source blending and is COLOR=SRC + SRC1 * DEST, ALPHA=DST_ALPHA |
439
+ * | 21 | ALPHA_REPLACE_COLOR | Defines that alpha blending is COLOR=SRC, ALPHA=SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA |
439
440
  *
440
441
  */
441
442
  set alphaMode(value: number);