@onerjs/core 8.53.5 → 8.53.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Animations/animationGroup.d.ts +0 -1
- package/Animations/animationGroup.js +0 -1
- package/Animations/animationGroup.js.map +1 -1
- package/Animations/animationGroup.pure.js +2 -0
- package/Animations/animationGroup.pure.js.map +1 -1
- package/Animations/runtimeAnimation.js +11 -0
- package/Animations/runtimeAnimation.js.map +1 -1
- package/Audio/audioSceneComponent.pure.js +1 -1
- package/AudioV2/abstractAudio/abstractSound.d.ts +2 -1
- package/AudioV2/abstractAudio/abstractSound.js +7 -2
- package/AudioV2/abstractAudio/abstractSound.js.map +1 -1
- package/AudioV2/abstractAudio/abstractSoundInstance.d.ts +3 -1
- package/AudioV2/abstractAudio/abstractSoundInstance.js.map +1 -1
- package/AudioV2/abstractAudio/staticSound.d.ts +6 -0
- package/AudioV2/abstractAudio/staticSound.js +17 -1
- package/AudioV2/abstractAudio/staticSound.js.map +1 -1
- package/AudioV2/abstractAudio/staticSoundInstance.d.ts +4 -2
- package/AudioV2/abstractAudio/staticSoundInstance.js.map +1 -1
- package/AudioV2/abstractAudio/streamingSound.d.ts +6 -0
- package/AudioV2/abstractAudio/streamingSound.js +9 -1
- package/AudioV2/abstractAudio/streamingSound.js.map +1 -1
- package/AudioV2/webAudio/webAudioStaticSound.d.ts +7 -1
- package/AudioV2/webAudio/webAudioStaticSound.js +56 -8
- package/AudioV2/webAudio/webAudioStaticSound.js.map +1 -1
- package/AudioV2/webAudio/webAudioStreamingSound.d.ts +3 -1
- package/AudioV2/webAudio/webAudioStreamingSound.js +16 -4
- package/AudioV2/webAudio/webAudioStreamingSound.js.map +1 -1
- package/BakedVertexAnimation/bakedVertexAnimationManager.d.ts +2 -2
- package/BakedVertexAnimation/bakedVertexAnimationManager.js +151 -121
- package/BakedVertexAnimation/bakedVertexAnimationManager.js.map +1 -1
- package/Behaviors/Cameras/interpolatingBehavior.d.ts +17 -2
- package/Behaviors/Cameras/interpolatingBehavior.js +53 -23
- package/Behaviors/Cameras/interpolatingBehavior.js.map +1 -1
- package/Bones/bone.pure.js +3 -3
- package/Buffers/buffer.pure.js +0 -12
- package/Buffers/buffer.pure.js.map +1 -1
- package/Cameras/Inputs/BaseCameraMouseWheelInput.js +141 -126
- package/Cameras/Inputs/BaseCameraMouseWheelInput.js.map +1 -1
- package/Cameras/Inputs/BaseCameraPointersInput.d.ts +2 -1
- package/Cameras/Inputs/BaseCameraPointersInput.js +290 -277
- package/Cameras/Inputs/BaseCameraPointersInput.js.map +1 -1
- package/Cameras/Inputs/arcRotateCameraGamepadInput.js +115 -102
- package/Cameras/Inputs/arcRotateCameraGamepadInput.js.map +1 -1
- package/Cameras/Inputs/arcRotateCameraKeyboardMoveInput.d.ts +3 -0
- package/Cameras/Inputs/arcRotateCameraKeyboardMoveInput.js +334 -273
- package/Cameras/Inputs/arcRotateCameraKeyboardMoveInput.js.map +1 -1
- package/Cameras/Inputs/arcRotateCameraMouseWheelInput.js +273 -258
- package/Cameras/Inputs/arcRotateCameraMouseWheelInput.js.map +1 -1
- package/Cameras/Inputs/arcRotateCameraPointersInput.js +237 -213
- package/Cameras/Inputs/arcRotateCameraPointersInput.js.map +1 -1
- package/Cameras/Inputs/flyCameraKeyboardInput.js +199 -168
- package/Cameras/Inputs/flyCameraKeyboardInput.js.map +1 -1
- package/Cameras/Inputs/flyCameraMouseInput.js +243 -229
- package/Cameras/Inputs/flyCameraMouseInput.js.map +1 -1
- package/Cameras/Inputs/followCameraKeyboardMoveInput.js +311 -266
- package/Cameras/Inputs/followCameraKeyboardMoveInput.js.map +1 -1
- package/Cameras/Inputs/followCameraMouseWheelInput.js +139 -119
- package/Cameras/Inputs/followCameraMouseWheelInput.js.map +1 -1
- package/Cameras/Inputs/followCameraPointersInput.js +239 -203
- package/Cameras/Inputs/followCameraPointersInput.js.map +1 -1
- package/Cameras/Inputs/freeCameraGamepadInput.js +127 -114
- package/Cameras/Inputs/freeCameraGamepadInput.js.map +1 -1
- package/Cameras/Inputs/freeCameraKeyboardMoveInput.js +278 -244
- package/Cameras/Inputs/freeCameraKeyboardMoveInput.js.map +1 -1
- package/Cameras/Inputs/freeCameraMouseInput.js +216 -202
- package/Cameras/Inputs/freeCameraMouseInput.js.map +1 -1
- package/Cameras/Inputs/freeCameraMouseWheelInput.js +368 -353
- package/Cameras/Inputs/freeCameraMouseWheelInput.js.map +1 -1
- package/Cameras/Inputs/freeCameraTouchInput.js +185 -172
- package/Cameras/Inputs/freeCameraTouchInput.js.map +1 -1
- package/Cameras/Inputs/geospatialCameraKeyboardInput.d.ts +2 -0
- package/Cameras/Inputs/geospatialCameraKeyboardInput.js +291 -246
- package/Cameras/Inputs/geospatialCameraKeyboardInput.js.map +1 -1
- package/Cameras/Inputs/geospatialCameraPointersInput.d.ts +11 -1
- package/Cameras/Inputs/geospatialCameraPointersInput.js +18 -2
- package/Cameras/Inputs/geospatialCameraPointersInput.js.map +1 -1
- package/Cameras/Inputs/orbitCameraPointersInput.js +112 -96
- package/Cameras/Inputs/orbitCameraPointersInput.js.map +1 -1
- package/Cameras/VR/vrExperienceHelper.d.ts +0 -2
- package/Cameras/VR/vrExperienceHelper.js +0 -2
- package/Cameras/VR/vrExperienceHelper.js.map +1 -1
- package/Cameras/VR/vrExperienceHelper.pure.js +5 -0
- package/Cameras/VR/vrExperienceHelper.pure.js.map +1 -1
- package/Cameras/arcRotateCamera.pure.js +1559 -1479
- package/Cameras/arcRotateCamera.pure.js.map +1 -1
- package/Cameras/camera.pure.js +1225 -1178
- package/Cameras/camera.pure.js.map +1 -1
- package/Cameras/flyCamera.pure.js +369 -351
- package/Cameras/flyCamera.pure.js.map +1 -1
- package/Cameras/followCamera.pure.js +229 -192
- package/Cameras/followCamera.pure.js.map +1 -1
- package/Cameras/freeCamera.pure.js +373 -351
- package/Cameras/freeCamera.pure.js.map +1 -1
- package/Cameras/geospatialCamera.pure.d.ts +30 -7
- package/Cameras/geospatialCamera.pure.js +502 -457
- package/Cameras/geospatialCamera.pure.js.map +1 -1
- package/Cameras/geospatialCameraMovement.js +2 -2
- package/Cameras/geospatialCameraMovement.js.map +1 -1
- package/Cameras/targetCamera.pure.d.ts +7 -0
- package/Cameras/targetCamera.pure.js +550 -509
- package/Cameras/targetCamera.pure.js.map +1 -1
- package/Cameras/universalCamera.pure.js +98 -85
- package/Cameras/universalCamera.pure.js.map +1 -1
- package/Collisions/gpuPicker.d.ts +111 -4
- package/Collisions/gpuPicker.js +696 -119
- package/Collisions/gpuPicker.js.map +1 -1
- package/Compute/computeShader.pure.js +372 -355
- package/Compute/computeShader.pure.js.map +1 -1
- package/Culling/Helper/transformFeedbackBoundingHelper.pure.js +2 -2
- package/Decorators/nodeDecorator.d.ts +11 -1
- package/Decorators/nodeDecorator.js +43 -6
- package/Decorators/nodeDecorator.js.map +1 -1
- package/Engines/AbstractEngine/abstractEngine.loadFile.pure.js +8 -0
- package/Engines/AbstractEngine/abstractEngine.loadFile.pure.js.map +1 -1
- package/Engines/Native/nativeHelpers.js +15 -0
- package/Engines/Native/nativeHelpers.js.map +1 -1
- package/Engines/Native/nativeInterfaces.d.ts +7 -2
- package/Engines/Native/nativeInterfaces.js.map +1 -1
- package/Engines/Native/nativeRenderTargetWrapper.d.ts +5 -0
- package/Engines/Native/nativeRenderTargetWrapper.js +35 -1
- package/Engines/Native/nativeRenderTargetWrapper.js.map +1 -1
- package/Engines/Processors/shaderProcessor.js +5 -3
- package/Engines/Processors/shaderProcessor.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.videoTexture.pure.js +16 -3
- package/Engines/WebGPU/Extensions/engine.videoTexture.pure.js.map +1 -1
- package/Engines/WebGPU/webgpuClearQuad.pure.js +7 -1
- package/Engines/WebGPU/webgpuClearQuad.pure.js.map +1 -1
- package/Engines/abstractEngine.functions.d.ts +8 -2
- package/Engines/abstractEngine.functions.js +12 -4
- package/Engines/abstractEngine.functions.js.map +1 -1
- package/Engines/abstractEngine.pure.d.ts +20 -1
- package/Engines/abstractEngine.pure.js +21 -134
- package/Engines/abstractEngine.pure.js.map +1 -1
- package/Engines/engine.d.ts +208 -0
- package/Engines/engine.pure.js +0 -15
- package/Engines/engine.pure.js.map +1 -1
- package/Engines/nullEngine.pure.d.ts +66 -0
- package/Engines/nullEngine.pure.js +97 -0
- package/Engines/nullEngine.pure.js.map +1 -1
- package/Engines/thinEngine.pure.d.ts +0 -13
- package/Engines/thinEngine.pure.js +4 -23
- package/Engines/thinEngine.pure.js.map +1 -1
- package/Engines/thinNativeEngine.d.ts +0 -1
- package/Engines/thinNativeEngine.js +0 -1
- package/Engines/thinNativeEngine.js.map +1 -1
- package/Engines/thinNativeEngine.pure.d.ts +27 -0
- package/Engines/thinNativeEngine.pure.js +383 -17
- package/Engines/thinNativeEngine.pure.js.map +1 -1
- package/Engines/webgpuEngine.d.ts +1 -0
- package/Engines/webgpuEngine.js +1 -0
- package/Engines/webgpuEngine.js.map +1 -1
- package/Engines/webgpuEngine.pure.d.ts +9 -0
- package/Engines/webgpuEngine.pure.js +7 -0
- package/Engines/webgpuEngine.pure.js.map +1 -1
- package/FlowGraph/flowGraph.js +9 -0
- package/FlowGraph/flowGraph.js.map +1 -1
- package/FlowGraph/flowGraphContext.js +597 -584
- package/FlowGraph/flowGraphContext.js.map +1 -1
- package/FlowGraph/flowGraphDataConnection.pure.d.ts +14 -0
- package/FlowGraph/flowGraphDataConnection.pure.js +38 -1
- package/FlowGraph/flowGraphDataConnection.pure.js.map +1 -1
- package/FlowGraph/serialization.d.ts +11 -0
- package/FlowGraph/serialization.js +11 -1
- package/FlowGraph/serialization.js.map +1 -1
- package/FrameGraph/Node/Blocks/Layers/glowLayerBlock.pure.js +182 -170
- package/FrameGraph/Node/Blocks/Layers/glowLayerBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/Layers/highlightLayerBlock.pure.js +196 -184
- package/FrameGraph/Node/Blocks/Layers/highlightLayerBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/Layers/selectionOutlineLayerBlock.pure.js +222 -210
- package/FrameGraph/Node/Blocks/Layers/selectionOutlineLayerBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/basePostProcessBlock.js +123 -111
- package/FrameGraph/Node/Blocks/PostProcesses/basePostProcessBlock.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/baseWithPropertiesPostProcessBlock.js +158 -146
- package/FrameGraph/Node/Blocks/PostProcesses/baseWithPropertiesPostProcessBlock.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/blackAndWhitePostProcessBlock.pure.js +63 -51
- package/FrameGraph/Node/Blocks/PostProcesses/blackAndWhitePostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/bloomPostProcessBlock.pure.js +122 -110
- package/FrameGraph/Node/Blocks/PostProcesses/bloomPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/blurPostProcessBlock.pure.js +76 -64
- package/FrameGraph/Node/Blocks/PostProcesses/blurPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/chromaticAberrationPostProcessBlock.pure.js +89 -77
- package/FrameGraph/Node/Blocks/PostProcesses/chromaticAberrationPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/circleOfConfusionPostProcessBlock.pure.js +134 -122
- package/FrameGraph/Node/Blocks/PostProcesses/circleOfConfusionPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/colorCorrectionPostProcessBlock.pure.js +58 -46
- package/FrameGraph/Node/Blocks/PostProcesses/colorCorrectionPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/convolutionPostProcessBlock.pure.js +107 -95
- package/FrameGraph/Node/Blocks/PostProcesses/convolutionPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/depthOfFieldPostProcessBlock.pure.js +181 -169
- package/FrameGraph/Node/Blocks/PostProcesses/depthOfFieldPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/extractHighlightsPostProcessBlock.pure.js +63 -51
- package/FrameGraph/Node/Blocks/PostProcesses/extractHighlightsPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/filterPostProcessBlock.pure.js +63 -51
- package/FrameGraph/Node/Blocks/PostProcesses/filterPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/grainPostProcessBlock.pure.js +76 -64
- package/FrameGraph/Node/Blocks/PostProcesses/grainPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/imageProcessingPostProcessBlock.pure.js +246 -234
- package/FrameGraph/Node/Blocks/PostProcesses/imageProcessingPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/motionBlurPostProcessBlock.pure.js +108 -96
- package/FrameGraph/Node/Blocks/PostProcesses/motionBlurPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/screenSpaceCurvaturePostProcessBlock.pure.js +87 -75
- package/FrameGraph/Node/Blocks/PostProcesses/screenSpaceCurvaturePostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/sharpenPostProcessBlock.pure.js +76 -64
- package/FrameGraph/Node/Blocks/PostProcesses/sharpenPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/ssao2PostProcessBlock.pure.js +313 -301
- package/FrameGraph/Node/Blocks/PostProcesses/ssao2PostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/ssrPostProcessBlock.pure.js +502 -490
- package/FrameGraph/Node/Blocks/PostProcesses/ssrPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/taaPostProcessBlock.pure.js +147 -135
- package/FrameGraph/Node/Blocks/PostProcesses/taaPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/tonemapPostProcessBlock.pure.js +90 -78
- package/FrameGraph/Node/Blocks/PostProcesses/tonemapPostProcessBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/volumetricLightingBlock.pure.js +179 -167
- package/FrameGraph/Node/Blocks/PostProcesses/volumetricLightingBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/Rendering/baseObjectRendererBlock.js +462 -451
- package/FrameGraph/Node/Blocks/Rendering/baseObjectRendererBlock.js.map +1 -1
- package/FrameGraph/Node/Blocks/Rendering/baseShadowGeneratorBlock.js +265 -253
- package/FrameGraph/Node/Blocks/Rendering/baseShadowGeneratorBlock.js.map +1 -1
- package/FrameGraph/Node/Blocks/Rendering/csmShadowGeneratorBlock.pure.js +204 -192
- package/FrameGraph/Node/Blocks/Rendering/csmShadowGeneratorBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/Rendering/geometryRendererBlock.pure.js +611 -550
- package/FrameGraph/Node/Blocks/Rendering/geometryRendererBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/Rendering/iblShadowsRendererBlock.pure.js +320 -308
- package/FrameGraph/Node/Blocks/Rendering/iblShadowsRendererBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/Rendering/utilityLayerRendererBlock.pure.js +87 -75
- package/FrameGraph/Node/Blocks/Rendering/utilityLayerRendererBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/Textures/clearBlock.pure.js +154 -142
- package/FrameGraph/Node/Blocks/Textures/clearBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/Textures/copyTextureBlock.pure.js +150 -138
- package/FrameGraph/Node/Blocks/Textures/copyTextureBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/inputBlock.pure.js +270 -256
- package/FrameGraph/Node/Blocks/inputBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/lightingVolumeBlock.pure.js +95 -83
- package/FrameGraph/Node/Blocks/lightingVolumeBlock.pure.js.map +1 -1
- package/FrameGraph/Node/nodeRenderGraph.js +715 -693
- package/FrameGraph/Node/nodeRenderGraph.js.map +1 -1
- package/FrameGraph/Node/nodeRenderGraphBlock.js +548 -533
- package/FrameGraph/Node/nodeRenderGraphBlock.js.map +1 -1
- package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.d.ts +2 -2
- package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.js +43 -51
- package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.js.map +1 -1
- package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.d.ts +0 -1
- package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.js +0 -1
- package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.js.map +1 -1
- package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure.d.ts +0 -1
- package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure.js +66 -35
- package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure.js.map +1 -1
- package/Helpers/environmentHelper.js +2 -2
- package/Helpers/environmentHelper.js.map +1 -1
- package/Layers/effectLayer.js +529 -519
- package/Layers/effectLayer.js.map +1 -1
- package/Layers/glowLayer.pure.js +428 -413
- package/Layers/glowLayer.pure.js.map +1 -1
- package/Layers/highlightLayer.pure.js +473 -458
- package/Layers/highlightLayer.pure.js.map +1 -1
- package/Layers/selectionOutlineLayer.pure.js +360 -345
- package/Layers/selectionOutlineLayer.pure.js.map +1 -1
- package/Lights/Clustered/clusteredLightContainer.pure.d.ts +1 -1
- package/Lights/Clustered/clusteredLightContainer.pure.js +583 -558
- package/Lights/Clustered/clusteredLightContainer.pure.js.map +1 -1
- package/Lights/Shadows/shadowGenerator.js +6 -1
- package/Lights/Shadows/shadowGenerator.js.map +1 -1
- package/Lights/areaLight.pure.js +61 -39
- package/Lights/areaLight.pure.js.map +1 -1
- package/Lights/directionalLight.pure.js +308 -284
- package/Lights/directionalLight.pure.js.map +1 -1
- package/Lights/hemisphericLight.pure.js +123 -104
- package/Lights/hemisphericLight.pure.js.map +1 -1
- package/Lights/light.d.ts +5 -3
- package/Lights/light.js +869 -827
- package/Lights/light.js.map +1 -1
- package/Lights/pointLight.pure.js +185 -174
- package/Lights/pointLight.pure.js.map +1 -1
- package/Lights/rectAreaLight.pure.d.ts +17 -0
- package/Lights/rectAreaLight.pure.js +238 -159
- package/Lights/rectAreaLight.pure.js.map +1 -1
- package/Lights/shadowLight.js +280 -268
- package/Lights/shadowLight.js.map +1 -1
- package/Lights/spotLight.pure.js +460 -427
- package/Lights/spotLight.pure.js.map +1 -1
- package/Loading/Plugins/babylonFileLoader.pure.js +17 -5
- package/Loading/Plugins/babylonFileLoader.pure.js.map +1 -1
- package/Loading/sceneLoader.d.ts +5 -1
- package/Loading/sceneLoader.js +299 -402
- package/Loading/sceneLoader.js.map +1 -1
- package/Materials/Background/backgroundMaterial.pure.d.ts +18 -18
- package/Materials/Background/backgroundMaterial.pure.js +949 -794
- package/Materials/Background/backgroundMaterial.pure.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.d.ts +15 -0
- package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.js +34 -1
- package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.d.ts +9 -0
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.js +26 -2
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.d.ts +2 -1
- package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.js +169 -149
- package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.js.map +1 -1
- package/Materials/Node/Blocks/Dual/imageSourceBlock.pure.js +1 -1
- package/Materials/Node/Blocks/Dual/lightBlock.pure.js +442 -429
- package/Materials/Node/Blocks/Dual/lightBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.pure.js +396 -383
- package/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/Dual/sceneDepthBlock.pure.js +237 -220
- package/Materials/Node/Blocks/Dual/sceneDepthBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/Dual/textureBlock.pure.js +1 -1
- package/Materials/Node/Blocks/Fragment/ambientOcclusionBlock.pure.js +150 -133
- package/Materials/Node/Blocks/Fragment/ambientOcclusionBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/Fragment/fragmentOutputBlock.pure.js +265 -250
- package/Materials/Node/Blocks/Fragment/fragmentOutputBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/Fragment/heightToNormalBlock.pure.js +159 -142
- package/Materials/Node/Blocks/Fragment/heightToNormalBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/Fragment/imageProcessingBlock.pure.js +214 -201
- package/Materials/Node/Blocks/Fragment/imageProcessingBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/Fragment/perturbNormalBlock.pure.js +419 -400
- package/Materials/Node/Blocks/Fragment/perturbNormalBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.pure.js +3 -1
- package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/PBR/clearCoatBlock.pure.js +302 -289
- package/Materials/Node/Blocks/PBR/clearCoatBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.pure.js +1327 -1272
- package/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/PBR/reflectionBlock.pure.js +352 -337
- package/Materials/Node/Blocks/PBR/reflectionBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/PBR/refractionBlock.pure.js +297 -277
- package/Materials/Node/Blocks/PBR/refractionBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/PBR/sheenBlock.pure.js +146 -131
- package/Materials/Node/Blocks/PBR/sheenBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/PBR/subSurfaceBlock.pure.js +158 -145
- package/Materials/Node/Blocks/PBR/subSurfaceBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/clampBlock.pure.js +92 -77
- package/Materials/Node/Blocks/clampBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/cloudBlock.pure.js +145 -132
- package/Materials/Node/Blocks/cloudBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/conditionalBlock.pure.js +182 -169
- package/Materials/Node/Blocks/conditionalBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/curveBlock.pure.js +259 -246
- package/Materials/Node/Blocks/curveBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/debugBlock.pure.js +119 -106
- package/Materials/Node/Blocks/debugBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/loopBlock.pure.js +123 -110
- package/Materials/Node/Blocks/loopBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/meshAttributeExistsBlock.pure.js +185 -172
- package/Materials/Node/Blocks/meshAttributeExistsBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/remapBlock.pure.js +127 -112
- package/Materials/Node/Blocks/remapBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/transformBlock.pure.js +196 -185
- package/Materials/Node/Blocks/transformBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/triPlanarBlock.pure.js +451 -438
- package/Materials/Node/Blocks/triPlanarBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/trigonometryBlock.pure.js +184 -171
- package/Materials/Node/Blocks/trigonometryBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/waveBlock.pure.js +97 -84
- package/Materials/Node/Blocks/waveBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/worleyNoise3DBlock.pure.js +276 -263
- package/Materials/Node/Blocks/worleyNoise3DBlock.pure.js.map +1 -1
- package/Materials/Node/nodeMaterial.pure.js +1765 -1737
- package/Materials/Node/nodeMaterial.pure.js.map +1 -1
- package/Materials/Node/nodeMaterialBuildState.d.ts +3 -3
- package/Materials/PBR/openpbrMaterial.pure.d.ts +102 -102
- package/Materials/PBR/openpbrMaterial.pure.js +3115 -2243
- package/Materials/PBR/openpbrMaterial.pure.js.map +1 -1
- package/Materials/PBR/pbrAnisotropicConfiguration.d.ts +3 -3
- package/Materials/PBR/pbrAnisotropicConfiguration.js +255 -227
- package/Materials/PBR/pbrAnisotropicConfiguration.js.map +1 -1
- package/Materials/PBR/pbrBRDFConfiguration.d.ts +9 -9
- package/Materials/PBR/pbrBRDFConfiguration.js +203 -155
- package/Materials/PBR/pbrBRDFConfiguration.js.map +1 -1
- package/Materials/PBR/pbrBaseMaterial.pure.d.ts +1 -1
- package/Materials/PBR/pbrBaseMaterial.pure.js +1751 -1736
- package/Materials/PBR/pbrBaseMaterial.pure.js.map +1 -1
- package/Materials/PBR/pbrBaseSimpleMaterial.d.ts +13 -13
- package/Materials/PBR/pbrBaseSimpleMaterial.js +205 -117
- package/Materials/PBR/pbrBaseSimpleMaterial.js.map +1 -1
- package/Materials/PBR/pbrClearCoatConfiguration.d.ts +9 -9
- package/Materials/PBR/pbrClearCoatConfiguration.js +464 -406
- package/Materials/PBR/pbrClearCoatConfiguration.js.map +1 -1
- package/Materials/PBR/pbrIridescenceConfiguration.d.ts +3 -3
- package/Materials/PBR/pbrIridescenceConfiguration.js +271 -239
- package/Materials/PBR/pbrIridescenceConfiguration.js.map +1 -1
- package/Materials/PBR/pbrMaterial.pure.d.ts +66 -66
- package/Materials/PBR/pbrMaterial.pure.js +1041 -685
- package/Materials/PBR/pbrMaterial.pure.js.map +1 -1
- package/Materials/PBR/pbrMetallicRoughnessMaterial.pure.d.ts +5 -5
- package/Materials/PBR/pbrMetallicRoughnessMaterial.pure.js +176 -115
- package/Materials/PBR/pbrMetallicRoughnessMaterial.pure.js.map +1 -1
- package/Materials/PBR/pbrSheenConfiguration.d.ts +7 -7
- package/Materials/PBR/pbrSheenConfiguration.js +314 -270
- package/Materials/PBR/pbrSheenConfiguration.js.map +1 -1
- package/Materials/PBR/pbrSpecularGlossinessMaterial.pure.d.ts +5 -5
- package/Materials/PBR/pbrSpecularGlossinessMaterial.pure.js +172 -117
- package/Materials/PBR/pbrSpecularGlossinessMaterial.pure.js.map +1 -1
- package/Materials/PBR/pbrSubSurfaceConfiguration.d.ts +16 -16
- package/Materials/PBR/pbrSubSurfaceConfiguration.js +864 -764
- package/Materials/PBR/pbrSubSurfaceConfiguration.js.map +1 -1
- package/Materials/Textures/HTML/htmlInCanvasPolyfill.d.ts +43 -0
- package/Materials/Textures/HTML/htmlInCanvasPolyfill.js +64 -0
- package/Materials/Textures/HTML/htmlInCanvasPolyfill.js.map +1 -0
- package/Materials/Textures/HTML/htmlInteractionManager.d.ts +69 -0
- package/Materials/Textures/HTML/htmlInteractionManager.js +130 -0
- package/Materials/Textures/HTML/htmlInteractionManager.js.map +1 -0
- package/Materials/Textures/HTML/htmlRaycastInteractionManager.d.ts +84 -0
- package/Materials/Textures/HTML/htmlRaycastInteractionManager.js +246 -0
- package/Materials/Textures/HTML/htmlRaycastInteractionManager.js.map +1 -0
- package/Materials/Textures/HTML/htmlTexture.d.ts +148 -0
- package/Materials/Textures/HTML/htmlTexture.js +455 -0
- package/Materials/Textures/HTML/htmlTexture.js.map +1 -0
- package/Materials/Textures/HTML/index.d.ts +4 -0
- package/Materials/Textures/HTML/index.js +5 -0
- package/Materials/Textures/HTML/index.js.map +1 -0
- package/Materials/Textures/HTML/pure.d.ts +5 -0
- package/Materials/Textures/HTML/pure.js +6 -0
- package/Materials/Textures/HTML/pure.js.map +1 -0
- package/Materials/Textures/Procedurals/proceduralTexture.pure.js +671 -643
- package/Materials/Textures/Procedurals/proceduralTexture.pure.js.map +1 -1
- package/Materials/Textures/baseTexture.pure.js +880 -825
- package/Materials/Textures/baseTexture.pure.js.map +1 -1
- package/Materials/Textures/cubeTexture.d.ts +0 -1
- package/Materials/Textures/cubeTexture.js +0 -1
- package/Materials/Textures/cubeTexture.js.map +1 -1
- package/Materials/Textures/cubeTexture.pure.js +368 -333
- package/Materials/Textures/cubeTexture.pure.js.map +1 -1
- package/Materials/Textures/dynamicTexture.d.ts +0 -1
- package/Materials/Textures/dynamicTexture.js +0 -1
- package/Materials/Textures/dynamicTexture.js.map +1 -1
- package/Materials/Textures/dynamicTexture.pure.js +2 -0
- package/Materials/Textures/dynamicTexture.pure.js.map +1 -1
- package/Materials/Textures/htmlElementTexture.d.ts +0 -2
- package/Materials/Textures/htmlElementTexture.js +0 -2
- package/Materials/Textures/htmlElementTexture.js.map +1 -1
- package/Materials/Textures/htmlElementTexture.pure.js +4 -0
- package/Materials/Textures/htmlElementTexture.pure.js.map +1 -1
- package/Materials/Textures/index.d.ts +1 -0
- package/Materials/Textures/index.js +1 -1
- package/Materials/Textures/index.js.map +1 -1
- package/Materials/Textures/multiRenderTarget.d.ts +0 -1
- package/Materials/Textures/multiRenderTarget.js +0 -1
- package/Materials/Textures/multiRenderTarget.js.map +1 -1
- package/Materials/Textures/multiRenderTarget.pure.js +2 -0
- package/Materials/Textures/multiRenderTarget.pure.js.map +1 -1
- package/Materials/Textures/pure.d.ts +1 -0
- package/Materials/Textures/pure.js +1 -0
- package/Materials/Textures/pure.js.map +1 -1
- package/Materials/Textures/texture.pure.js +961 -923
- package/Materials/Textures/texture.pure.js.map +1 -1
- package/Materials/Textures/videoTexture.pure.d.ts +3 -0
- package/Materials/Textures/videoTexture.pure.js +450 -401
- package/Materials/Textures/videoTexture.pure.js.map +1 -1
- package/Materials/colorCurves.pure.js +510 -477
- package/Materials/colorCurves.pure.js.map +1 -1
- package/Materials/effect.pure.js +0 -7
- package/Materials/effect.pure.js.map +1 -1
- package/Materials/imageProcessing.js +12 -4
- package/Materials/imageProcessing.js.map +1 -1
- package/Materials/imageProcessingConfiguration.pure.js +647 -587
- package/Materials/imageProcessingConfiguration.pure.js.map +1 -1
- package/Materials/material.decalMapConfiguration.pure.d.ts +2 -2
- package/Materials/material.decalMapConfiguration.pure.js +149 -130
- package/Materials/material.decalMapConfiguration.pure.js.map +1 -1
- package/Materials/material.detailMapConfiguration.d.ts +3 -3
- package/Materials/material.detailMapConfiguration.js +213 -175
- package/Materials/material.detailMapConfiguration.js.map +1 -1
- package/Materials/material.pure.js +1815 -1721
- package/Materials/material.pure.js.map +1 -1
- package/Materials/materialPluginBase.pure.js +270 -249
- package/Materials/materialPluginBase.pure.js.map +1 -1
- package/Materials/materialPluginManager.pure.js +18 -8
- package/Materials/materialPluginManager.pure.js.map +1 -1
- package/Materials/materialStencilState.js +211 -200
- package/Materials/materialStencilState.js.map +1 -1
- package/Materials/meshDebugPluginMaterial.pure.d.ts +2 -2
- package/Materials/meshDebugPluginMaterial.pure.js +397 -275
- package/Materials/meshDebugPluginMaterial.pure.js.map +1 -1
- package/Materials/standardMaterial.pure.d.ts +32 -32
- package/Materials/standardMaterial.pure.js +1804 -1394
- package/Materials/standardMaterial.pure.js.map +1 -1
- package/Maths/math.color.pure.js +5 -5
- package/Maths/math.functions.js +38 -30
- package/Maths/math.functions.js.map +1 -1
- package/Maths/math.vector.pure.js +25 -25
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js +18 -8
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +86 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +255 -104
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.d.ts +39 -0
- package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js +322 -0
- package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js.map +1 -0
- package/Meshes/GreasedLine/greasedLineMesh.pure.js +4 -4
- package/Meshes/GreasedLine/greasedLineRibbonMesh.pure.js +3 -3
- package/Meshes/Node/Blocks/Instances/instantiateBaseBlock.js +107 -94
- package/Meshes/Node/Blocks/Instances/instantiateBaseBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.pure.js +276 -263
- package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.pure.js +247 -232
- package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.pure.js +299 -284
- package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Set/aggregatorBlock.pure.js +196 -181
- package/Meshes/Node/Blocks/Set/aggregatorBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Set/latticeBlock.pure.js +198 -179
- package/Meshes/Node/Blocks/Set/latticeBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setColorsBlock.pure.js +151 -138
- package/Meshes/Node/Blocks/Set/setColorsBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setMaterialIDBlock.pure.js +107 -94
- package/Meshes/Node/Blocks/Set/setMaterialIDBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setNormalsBlock.pure.js +138 -125
- package/Meshes/Node/Blocks/Set/setNormalsBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setPositionsBlock.pure.js +213 -200
- package/Meshes/Node/Blocks/Set/setPositionsBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setTangentsBlock.pure.js +138 -125
- package/Meshes/Node/Blocks/Set/setTangentsBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setUVsBlock.pure.js +179 -164
- package/Meshes/Node/Blocks/Set/setUVsBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/boxBlock.pure.js +183 -170
- package/Meshes/Node/Blocks/Sources/boxBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/capsuleBlock.pure.js +125 -112
- package/Meshes/Node/Blocks/Sources/capsuleBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/cylinderBlock.pure.js +153 -140
- package/Meshes/Node/Blocks/Sources/cylinderBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/discBlock.pure.js +112 -99
- package/Meshes/Node/Blocks/Sources/discBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/gridBlock.pure.js +133 -120
- package/Meshes/Node/Blocks/Sources/gridBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/icoSphereBlock.pure.js +128 -115
- package/Meshes/Node/Blocks/Sources/icoSphereBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/meshBlock.pure.js +116 -103
- package/Meshes/Node/Blocks/Sources/meshBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/planeBlock.pure.js +160 -147
- package/Meshes/Node/Blocks/Sources/planeBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/sphereBlock.pure.js +144 -131
- package/Meshes/Node/Blocks/Sources/sphereBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/torusBlock.pure.js +112 -99
- package/Meshes/Node/Blocks/Sources/torusBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/Textures/geometryTextureFetchBlock.pure.js +200 -185
- package/Meshes/Node/Blocks/Textures/geometryTextureFetchBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/bevelBlock.pure.js +111 -98
- package/Meshes/Node/Blocks/bevelBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/booleanGeometryBlock.pure.js +182 -165
- package/Meshes/Node/Blocks/booleanGeometryBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/cleanGeometryBlock.pure.js +89 -76
- package/Meshes/Node/Blocks/cleanGeometryBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/conditionBlock.pure.js +184 -169
- package/Meshes/Node/Blocks/conditionBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/extrudeGeometryBlock.pure.js +270 -255
- package/Meshes/Node/Blocks/extrudeGeometryBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/geometryCollectionBlock.pure.js +172 -159
- package/Meshes/Node/Blocks/geometryCollectionBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/geometryCurveBlock.pure.js +230 -217
- package/Meshes/Node/Blocks/geometryCurveBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/geometryEaseBlock.pure.js +256 -245
- package/Meshes/Node/Blocks/geometryEaseBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/geometryOptimizeBlock.pure.js +206 -189
- package/Meshes/Node/Blocks/geometryOptimizeBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/geometryTransformBlock.pure.js +166 -153
- package/Meshes/Node/Blocks/geometryTransformBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/geometryTrigonometryBlock.pure.js +221 -208
- package/Meshes/Node/Blocks/geometryTrigonometryBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/mappingBlock.pure.js +150 -137
- package/Meshes/Node/Blocks/mappingBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/mathBlock.pure.js +269 -256
- package/Meshes/Node/Blocks/mathBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/mergeGeometryBlock.pure.js +141 -128
- package/Meshes/Node/Blocks/mergeGeometryBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/randomBlock.pure.js +161 -148
- package/Meshes/Node/Blocks/randomBlock.pure.js.map +1 -1
- package/Meshes/Node/Blocks/subdivideBlock.pure.js +102 -87
- package/Meshes/Node/Blocks/subdivideBlock.pure.js.map +1 -1
- package/Meshes/Node/nodeGeometry.js +560 -538
- package/Meshes/Node/nodeGeometry.js.map +1 -1
- package/Meshes/Node/nodeGeometryBlock.js +473 -458
- package/Meshes/Node/nodeGeometryBlock.js.map +1 -1
- package/Meshes/abstractMesh.pure.js +2218 -2207
- package/Meshes/abstractMesh.pure.js.map +1 -1
- package/Meshes/geometry.js +30 -15
- package/Meshes/geometry.js.map +1 -1
- package/Meshes/mesh.pure.js +26 -14
- package/Meshes/mesh.pure.js.map +1 -1
- package/Meshes/mesh.vertexData.js +1665 -1655
- package/Meshes/mesh.vertexData.js.map +1 -1
- package/Meshes/transformNode.pure.js +1400 -1372
- package/Meshes/transformNode.pure.js.map +1 -1
- package/Misc/decorators.d.ts +34 -19
- package/Misc/decorators.functions.d.ts +33 -2
- package/Misc/decorators.functions.js +114 -35
- package/Misc/decorators.functions.js.map +1 -1
- package/Misc/decorators.js +96 -68
- package/Misc/decorators.js.map +1 -1
- package/Misc/decorators.serialization.js +47 -40
- package/Misc/decorators.serialization.js.map +1 -1
- package/Misc/decorators.serializationUtilities.d.ts +24 -0
- package/Misc/decorators.serializationUtilities.js +20 -0
- package/Misc/decorators.serializationUtilities.js.map +1 -0
- package/Misc/dumpTools.pure.js +43 -33
- package/Misc/dumpTools.pure.js.map +1 -1
- package/Misc/fileTools.pure.js +8 -0
- package/Misc/fileTools.pure.js.map +1 -1
- package/Misc/observable.pure.js +0 -7
- package/Misc/observable.pure.js.map +1 -1
- package/Misc/snapshotRenderingHelper.d.ts +4 -1
- package/Misc/snapshotRenderingHelper.js.map +1 -1
- package/Misc/symbolMetadataPolyfill.d.ts +11 -0
- package/Misc/symbolMetadataPolyfill.js +22 -0
- package/Misc/symbolMetadataPolyfill.js.map +1 -0
- package/Misc/tools.pure.js +2 -2
- package/Misc/tools.pure.js.map +1 -1
- package/Morph/morphTarget.js +382 -365
- package/Morph/morphTarget.js.map +1 -1
- package/Particles/Node/Blocks/Conditions/particleConditionBlock.pure.js +160 -145
- package/Particles/Node/Blocks/Conditions/particleConditionBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/Emitters/coneShapeBlock.pure.js +187 -174
- package/Particles/Node/Blocks/Emitters/coneShapeBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/Emitters/meshShapeBlock.pure.js +238 -219
- package/Particles/Node/Blocks/Emitters/meshShapeBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/Emitters/setupSpriteSheetBlock.pure.js +140 -115
- package/Particles/Node/Blocks/Emitters/setupSpriteSheetBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/Emitters/sphereShapeBlock.pure.js +157 -144
- package/Particles/Node/Blocks/Emitters/sphereShapeBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/Triggers/particleTriggerBlock.pure.js +133 -119
- package/Particles/Node/Blocks/Triggers/particleTriggerBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/Update/alignAngleBlock.pure.js +93 -80
- package/Particles/Node/Blocks/Update/alignAngleBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/particleDebugBlock.pure.js +117 -105
- package/Particles/Node/Blocks/particleDebugBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/particleFloatToIntBlock.pure.js +105 -92
- package/Particles/Node/Blocks/particleFloatToIntBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/particleGradientValueBlock.pure.js +82 -69
- package/Particles/Node/Blocks/particleGradientValueBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/particleLocalVariableBlock.pure.js +113 -101
- package/Particles/Node/Blocks/particleLocalVariableBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/particleMathBlock.pure.js +278 -265
- package/Particles/Node/Blocks/particleMathBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/particleNumberMathBlock.pure.js +155 -142
- package/Particles/Node/Blocks/particleNumberMathBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/particleRandomBlock.pure.js +156 -143
- package/Particles/Node/Blocks/particleRandomBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/particleTrigonometryBlock.pure.js +217 -204
- package/Particles/Node/Blocks/particleTrigonometryBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/particleVectorMathBlock.pure.js +106 -93
- package/Particles/Node/Blocks/particleVectorMathBlock.pure.js.map +1 -1
- package/Particles/Node/Blocks/systemBlock.pure.js +366 -330
- package/Particles/Node/Blocks/systemBlock.pure.js.map +1 -1
- package/Particles/Node/nodeParticleBlock.js +339 -324
- package/Particles/Node/nodeParticleBlock.js.map +1 -1
- package/Particles/Node/nodeParticleSystemSet.js +494 -473
- package/Particles/Node/nodeParticleSystemSet.js.map +1 -1
- package/Particles/gpuParticleSystem.d.ts +0 -1
- package/Particles/gpuParticleSystem.js +0 -1
- package/Particles/gpuParticleSystem.js.map +1 -1
- package/Particles/gpuParticleSystem.pure.d.ts +4 -3
- package/Particles/gpuParticleSystem.pure.js +27 -16
- package/Particles/gpuParticleSystem.pure.js.map +1 -1
- package/Particles/particleSystem.pure.js +57 -2
- package/Particles/particleSystem.pure.js.map +1 -1
- package/Particles/thinParticleSystem.d.ts +0 -1
- package/Particles/thinParticleSystem.js +0 -1
- package/Particles/thinParticleSystem.js.map +1 -1
- package/Particles/thinParticleSystem.pure.js +2 -0
- package/Particles/thinParticleSystem.pure.js.map +1 -1
- package/Particles/webgl2ParticleSystem.pure.js +2 -0
- package/Particles/webgl2ParticleSystem.pure.js.map +1 -1
- package/Physics/v1/physicsImpostor.pure.js +4 -4
- package/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.pure.js +675 -656
- package/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.pure.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.d.ts +0 -1
- package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js +0 -1
- package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.pure.js +521 -486
- package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.pure.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.d.ts +0 -1
- package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js +0 -1
- package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.pure.js +241 -220
- package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.pure.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.pure.js +852 -835
- package/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.pure.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.pure.js +1135 -1073
- package/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.pure.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.pure.js +319 -303
- package/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.pure.js.map +1 -1
- package/PostProcesses/RenderPipeline/postProcessRenderPipeline.js +212 -199
- package/PostProcesses/RenderPipeline/postProcessRenderPipeline.js.map +1 -1
- package/PostProcesses/blackAndWhitePostProcess.pure.js +67 -55
- package/PostProcesses/blackAndWhitePostProcess.pure.js.map +1 -1
- package/PostProcesses/bloomMergePostProcess.pure.js +74 -62
- package/PostProcesses/bloomMergePostProcess.pure.js.map +1 -1
- package/PostProcesses/blurPostProcess.pure.js +127 -115
- package/PostProcesses/blurPostProcess.pure.js.map +1 -1
- package/PostProcesses/chromaticAberrationPostProcess.pure.js +130 -118
- package/PostProcesses/chromaticAberrationPostProcess.pure.js.map +1 -1
- package/PostProcesses/circleOfConfusionPostProcess.pure.js +115 -104
- package/PostProcesses/circleOfConfusionPostProcess.pure.js.map +1 -1
- package/PostProcesses/colorCorrectionPostProcess.pure.js +55 -43
- package/PostProcesses/colorCorrectionPostProcess.pure.js.map +1 -1
- package/PostProcesses/convolutionPostProcess.pure.js +96 -84
- package/PostProcesses/convolutionPostProcess.pure.js.map +1 -1
- package/PostProcesses/extractHighlightsPostProcess.pure.js +68 -57
- package/PostProcesses/extractHighlightsPostProcess.pure.js.map +1 -1
- package/PostProcesses/filterPostProcess.pure.js +66 -54
- package/PostProcesses/filterPostProcess.pure.js.map +1 -1
- package/PostProcesses/fxaaPostProcess.pure.js.map +1 -1
- package/PostProcesses/grainPostProcess.pure.js +82 -70
- package/PostProcesses/grainPostProcess.pure.js.map +1 -1
- package/PostProcesses/imageProcessingPostProcess.js +334 -322
- package/PostProcesses/imageProcessingPostProcess.js.map +1 -1
- package/PostProcesses/motionBlurPostProcess.pure.js +246 -235
- package/PostProcesses/motionBlurPostProcess.pure.js.map +1 -1
- package/PostProcesses/passPostProcess.pure.js +75 -63
- package/PostProcesses/passPostProcess.pure.js.map +1 -1
- package/PostProcesses/postProcess.pure.js +899 -835
- package/PostProcesses/postProcess.pure.js.map +1 -1
- package/PostProcesses/refractionPostProcess.pure.js +114 -87
- package/PostProcesses/refractionPostProcess.pure.js.map +1 -1
- package/PostProcesses/screenSpaceCurvaturePostProcess.pure.js +108 -96
- package/PostProcesses/screenSpaceCurvaturePostProcess.pure.js.map +1 -1
- package/PostProcesses/screenSpaceReflectionPostProcess.pure.js +241 -220
- package/PostProcesses/screenSpaceReflectionPostProcess.pure.js.map +1 -1
- package/PostProcesses/sharpenPostProcess.pure.js +86 -74
- package/PostProcesses/sharpenPostProcess.pure.js.map +1 -1
- package/PostProcesses/tonemapPostProcess.pure.js +82 -70
- package/PostProcesses/tonemapPostProcess.pure.js.map +1 -1
- package/PostProcesses/volumetricLightScatteringPostProcess.pure.js +500 -465
- package/PostProcesses/volumetricLightScatteringPostProcess.pure.js.map +1 -1
- package/PostProcesses/vrMultiviewToSingleviewPostProcess.d.ts +0 -1
- package/PostProcesses/vrMultiviewToSingleviewPostProcess.js +0 -1
- package/PostProcesses/vrMultiviewToSingleviewPostProcess.js.map +1 -1
- package/PostProcesses/vrMultiviewToSingleviewPostProcess.pure.js +2 -0
- package/PostProcesses/vrMultiviewToSingleviewPostProcess.pure.js.map +1 -1
- package/Probes/reflectionProbe.pure.js +238 -224
- package/Probes/reflectionProbe.pure.js.map +1 -1
- package/Rendering/GlobalIllumination/giRSMManager.pure.d.ts +1 -1
- package/Rendering/GlobalIllumination/giRSMManager.pure.js +138 -105
- package/Rendering/GlobalIllumination/giRSMManager.pure.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsPluginMaterial.pure.d.ts +1 -1
- package/Rendering/IBLShadows/iblShadowsPluginMaterial.pure.js +155 -138
- package/Rendering/IBLShadows/iblShadowsPluginMaterial.pure.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.d.ts +0 -2
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.js +0 -2
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.pure.js +5 -0
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.pure.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.d.ts +0 -1
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js +0 -1
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.d.ts +1 -0
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.js +34 -0
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.js.map +1 -1
- package/Rendering/edgesRenderer.pure.js.map +1 -1
- package/Rendering/prePassRenderer.d.ts +0 -2
- package/Rendering/prePassRenderer.js +0 -2
- package/Rendering/prePassRenderer.js.map +1 -1
- package/Rendering/prePassRenderer.pure.js +2 -0
- package/Rendering/prePassRenderer.pure.js.map +1 -1
- package/Rendering/reflectiveShadowMap.pure.d.ts +1 -1
- package/Rendering/reflectiveShadowMap.pure.js +151 -130
- package/Rendering/reflectiveShadowMap.pure.js.map +1 -1
- package/Rendering/thinDepthPeelingRenderer.d.ts +0 -1
- package/Rendering/thinDepthPeelingRenderer.js +0 -1
- package/Rendering/thinDepthPeelingRenderer.js.map +1 -1
- package/Shaders/ShadersInclude/gaussianSplatting.js +1 -0
- package/Shaders/ShadersInclude/gaussianSplatting.js.map +1 -1
- package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js +35 -5
- package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
- package/Shaders/gaussianSplatting.fragment.js +17 -1
- package/Shaders/gaussianSplatting.fragment.js.map +1 -1
- package/Shaders/gaussianSplatting.vertex.js +1 -1
- package/Shaders/gaussianSplatting.vertex.js.map +1 -1
- package/Shaders/gaussianSplattingDepth.vertex.js +1 -1
- package/Shaders/gaussianSplattingDepth.vertex.js.map +1 -1
- package/Shaders/picking.fragment.js +39 -3
- package/Shaders/picking.fragment.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/gaussianSplatting.js +3 -1
- package/ShadersWGSL/ShadersInclude/gaussianSplatting.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/helperFunctions.js +2 -2
- package/ShadersWGSL/ShadersInclude/helperFunctions.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js +39 -7
- package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/openpbrIblFunctions.js +4 -3
- package/ShadersWGSL/ShadersInclude/openpbrIblFunctions.js.map +1 -1
- package/ShadersWGSL/gaussianSplatting.fragment.js +14 -1
- package/ShadersWGSL/gaussianSplatting.fragment.js.map +1 -1
- package/ShadersWGSL/gaussianSplatting.vertex.js +2 -2
- package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
- package/ShadersWGSL/gaussianSplattingDepth.vertex.js +2 -2
- package/ShadersWGSL/gaussianSplattingDepth.vertex.js.map +1 -1
- package/ShadersWGSL/lightingVolume.compute.js +2 -2
- package/ShadersWGSL/lightingVolume.compute.js.map +1 -1
- package/ShadersWGSL/picking.fragment.js +22 -1
- package/ShadersWGSL/picking.fragment.js.map +1 -1
- package/XR/features/Layers/WebXRCompositionLayer.d.ts +3 -2
- package/XR/features/Layers/WebXRCompositionLayer.js +2 -2
- package/XR/features/Layers/WebXRCompositionLayer.js.map +1 -1
- package/XR/features/Layers/WebXRWebGPUCompositionLayer.d.ts +59 -0
- package/XR/features/Layers/WebXRWebGPUCompositionLayer.js +120 -0
- package/XR/features/Layers/WebXRWebGPUCompositionLayer.js.map +1 -0
- package/XR/features/Layers/WebXRWebGPUProjectionLayer.d.ts +25 -0
- package/XR/features/Layers/WebXRWebGPUProjectionLayer.js +69 -0
- package/XR/features/Layers/WebXRWebGPUProjectionLayer.js.map +1 -0
- package/XR/features/WebXRLayers.pure.d.ts +8 -0
- package/XR/features/WebXRLayers.pure.js +43 -6
- package/XR/features/WebXRLayers.pure.js.map +1 -1
- package/XR/native/nativeXRRenderTarget.d.ts +2 -2
- package/XR/native/nativeXRRenderTarget.js +2 -2
- package/XR/native/nativeXRRenderTarget.js.map +1 -1
- package/XR/webXRExperienceHelper.js +10 -1
- package/XR/webXRExperienceHelper.js.map +1 -1
- package/XR/webXRGraphicsBinding.d.ts +90 -0
- package/XR/webXRGraphicsBinding.js +85 -0
- package/XR/webXRGraphicsBinding.js.map +1 -0
- package/XR/webXRLayerRenderTargetTexture.d.ts +24 -0
- package/XR/webXRLayerRenderTargetTexture.js +30 -0
- package/XR/webXRLayerRenderTargetTexture.js.map +1 -0
- package/XR/webXRManagedOutputCanvas.d.ts +14 -0
- package/XR/webXRManagedOutputCanvas.js +24 -5
- package/XR/webXRManagedOutputCanvas.js.map +1 -1
- package/XR/webXRRenderTargetTextureProvider.d.ts +25 -4
- package/XR/webXRRenderTargetTextureProvider.js +33 -35
- package/XR/webXRRenderTargetTextureProvider.js.map +1 -1
- package/XR/webXRSessionManager.d.ts +11 -0
- package/XR/webXRSessionManager.js +37 -0
- package/XR/webXRSessionManager.js.map +1 -1
- package/XR/webXRTypes.d.ts +9 -6
- package/XR/webXRTypes.js.map +1 -1
- package/XR/webXRWebGLLayer.d.ts +2 -2
- package/XR/webXRWebGLLayer.js +2 -2
- package/XR/webXRWebGLLayer.js.map +1 -1
- package/XR/webXRWebGLRenderTargetTextureProvider.d.ts +12 -0
- package/XR/webXRWebGLRenderTargetTextureProvider.js +58 -0
- package/XR/webXRWebGLRenderTargetTextureProvider.js.map +1 -0
- package/XR/webXRWebGPURenderTargetTextureProvider.d.ts +69 -0
- package/XR/webXRWebGPURenderTargetTextureProvider.js +148 -0
- package/XR/webXRWebGPURenderTargetTextureProvider.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/node.js +878 -845
- package/node.js.map +1 -1
- package/package.json +8 -14
- package/scene.pure.d.ts +12 -0
- package/scene.pure.js +36 -0
- package/scene.pure.js.map +1 -1
- package/tslib.es6.js +304 -150
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** This file must only contain pure code and pure imports */
|
|
2
|
-
import {
|
|
2
|
+
import { __esDecorate, __runInitializers } from "../../tslib.es6.js";
|
|
3
3
|
import { PushMaterial } from "../pushMaterial.js";
|
|
4
4
|
import { Matrix, Vector2 } from "../../Maths/math.vector.pure.js";
|
|
5
5
|
import { Color3, Color4 } from "../../Maths/math.color.pure.js";
|
|
@@ -44,6 +44,7 @@ import { Material } from "../material.pure.js";
|
|
|
44
44
|
import { Logger } from "../../Misc/logger.js";
|
|
45
45
|
import { PrepareDefinesForCamera, PrepareDefinesForPrePass, AreLightsTexturesReady } from "../materialHelper.functions.js";
|
|
46
46
|
import { ImageProcessingDefinesMixin } from "../imageProcessingConfiguration.defines.js";
|
|
47
|
+
import { RegisterImageProcessingConfiguration } from "../imageProcessingConfiguration.pure.js";
|
|
47
48
|
import { AbstractEngine } from "../../Engines/abstractEngine.pure.js";
|
|
48
49
|
import { MaterialHelperGeometryRendering } from "../materialHelper.geometryrendering.js";
|
|
49
50
|
import { UVDefinesMixin } from "../uv.defines.js";
|
|
@@ -175,1805 +176,1830 @@ class NodeMaterialBase extends ImageProcessingMixin(PushMaterial) {
|
|
|
175
176
|
/**
|
|
176
177
|
* Class used to create a node based material built by assembling shader blocks
|
|
177
178
|
*/
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
set options(options) {
|
|
224
|
-
this._options = options;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Gets or sets the mode property
|
|
228
|
-
*/
|
|
229
|
-
get mode() {
|
|
230
|
-
return this._mode;
|
|
231
|
-
}
|
|
232
|
-
set mode(value) {
|
|
233
|
-
this._mode = value;
|
|
234
|
-
}
|
|
235
|
-
/** Gets or sets the unique identifier used to identified the effect associated with the material */
|
|
236
|
-
get buildId() {
|
|
237
|
-
return this._buildId;
|
|
238
|
-
}
|
|
239
|
-
set buildId(value) {
|
|
240
|
-
this._buildId = value;
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Create a new node based material
|
|
244
|
-
* @param name defines the material name
|
|
245
|
-
* @param scene defines the hosting scene
|
|
246
|
-
* @param options defines creation option
|
|
247
|
-
*/
|
|
248
|
-
constructor(name, scene, options = {}) {
|
|
249
|
-
super(name, scene || EngineStore.LastCreatedScene);
|
|
250
|
-
this._buildId = NodeMaterial._BuildIdGenerator++;
|
|
251
|
-
this._buildWasSuccessful = false;
|
|
252
|
-
this._cachedWorldViewMatrix = new Matrix();
|
|
253
|
-
this._cachedWorldViewProjectionMatrix = new Matrix();
|
|
254
|
-
this._optimizers = new Array();
|
|
255
|
-
this._animationFrame = -1;
|
|
256
|
-
this._buildIsInProgress = false;
|
|
257
|
-
this.BJSNODEMATERIALEDITOR = this._getGlobalNodeMaterialEditor();
|
|
258
|
-
/** @internal */
|
|
259
|
-
this._useAdditionalColor = false;
|
|
260
|
-
/**
|
|
261
|
-
* Gets or sets data used by visual editor
|
|
262
|
-
* @see https://nme.babylonjs.com
|
|
263
|
-
*/
|
|
264
|
-
this.editorData = null;
|
|
265
|
-
/**
|
|
266
|
-
* Gets or sets a boolean indicating that alpha value must be ignored (This will turn alpha blending off even if an alpha value is produced by the material)
|
|
267
|
-
*/
|
|
268
|
-
this.ignoreAlpha = false;
|
|
269
|
-
/**
|
|
270
|
-
* Defines the maximum number of lights that can be used in the material
|
|
271
|
-
*/
|
|
272
|
-
this.maxSimultaneousLights = 4;
|
|
273
|
-
/**
|
|
274
|
-
* Observable raised when the material is built
|
|
275
|
-
*/
|
|
276
|
-
this.onBuildObservable = new Observable();
|
|
277
|
-
/**
|
|
278
|
-
* Observable raised when an error is detected
|
|
279
|
-
*/
|
|
280
|
-
this.onBuildErrorObservable = new Observable();
|
|
281
|
-
/**
|
|
282
|
-
* Gets or sets the root nodes of the material vertex shader
|
|
283
|
-
*/
|
|
284
|
-
this._vertexOutputNodes = new Array();
|
|
285
|
-
/**
|
|
286
|
-
* Gets or sets the root nodes of the material fragment (pixel) shader
|
|
287
|
-
*/
|
|
288
|
-
this._fragmentOutputNodes = new Array();
|
|
289
|
-
/**
|
|
290
|
-
* Gets an array of blocks that needs to be serialized even if they are not yet connected
|
|
291
|
-
*/
|
|
292
|
-
this.attachedBlocks = [];
|
|
293
|
-
/**
|
|
294
|
-
* Specifies the mode of the node material
|
|
295
|
-
* @internal
|
|
296
|
-
*/
|
|
297
|
-
this._mode = NodeMaterialModes.Material;
|
|
298
|
-
/**
|
|
299
|
-
* Gets or sets a boolean indicating that alpha blending must be enabled no matter what alpha value or alpha channel of the FragmentBlock are
|
|
300
|
-
*/
|
|
301
|
-
this.forceAlphaBlending = false;
|
|
302
|
-
if (!NodeMaterial.UseNativeShaderLanguageOfEngine && options && options.shaderLanguage === 1 /* ShaderLanguage.WGSL */ && !this.getScene().getEngine().isWebGPU) {
|
|
303
|
-
throw new Error("WebGPU shader language is only supported with WebGPU engine");
|
|
304
|
-
}
|
|
305
|
-
this._options = {
|
|
306
|
-
emitComments: false,
|
|
307
|
-
shaderLanguage: NodeMaterial.DefaultShaderLanguage,
|
|
308
|
-
...options,
|
|
309
|
-
};
|
|
310
|
-
if (NodeMaterial.UseNativeShaderLanguageOfEngine) {
|
|
311
|
-
this._options.shaderLanguage = this.getScene().getEngine().isWebGPU ? 1 /* ShaderLanguage.WGSL */ : 0 /* ShaderLanguage.GLSL */;
|
|
312
|
-
}
|
|
313
|
-
// Setup the default processing configuration to the scene.
|
|
314
|
-
this._attachImageProcessingConfiguration(null);
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Gets the current class name of the material e.g. "NodeMaterial"
|
|
318
|
-
* @returns the class name
|
|
319
|
-
*/
|
|
320
|
-
getClassName() {
|
|
321
|
-
return "NodeMaterial";
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Get a block by its name
|
|
325
|
-
* @param name defines the name of the block to retrieve
|
|
326
|
-
* @returns the required block or null if not found
|
|
327
|
-
*/
|
|
328
|
-
getBlockByName(name) {
|
|
329
|
-
let result = null;
|
|
330
|
-
for (const block of this.attachedBlocks) {
|
|
331
|
-
if (block.name === name) {
|
|
332
|
-
if (!result) {
|
|
333
|
-
result = block;
|
|
179
|
+
let NodeMaterial = (() => {
|
|
180
|
+
var _a;
|
|
181
|
+
let _classSuper = NodeMaterialBase;
|
|
182
|
+
let _ignoreAlpha_decorators;
|
|
183
|
+
let _ignoreAlpha_initializers = [];
|
|
184
|
+
let _ignoreAlpha_extraInitializers = [];
|
|
185
|
+
let _maxSimultaneousLights_decorators;
|
|
186
|
+
let _maxSimultaneousLights_initializers = [];
|
|
187
|
+
let _maxSimultaneousLights_extraInitializers = [];
|
|
188
|
+
let __mode_decorators;
|
|
189
|
+
let __mode_initializers = [];
|
|
190
|
+
let __mode_extraInitializers = [];
|
|
191
|
+
let _comment_decorators;
|
|
192
|
+
let _comment_initializers = [];
|
|
193
|
+
let _comment_extraInitializers = [];
|
|
194
|
+
let _forceAlphaBlending_decorators;
|
|
195
|
+
let _forceAlphaBlending_initializers = [];
|
|
196
|
+
let _forceAlphaBlending_extraInitializers = [];
|
|
197
|
+
return _a = class NodeMaterial extends _classSuper {
|
|
198
|
+
/** Gets whether the node material is currently building */
|
|
199
|
+
get buildIsInProgress() {
|
|
200
|
+
return this._buildIsInProgress;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Sets whether glow mode is enabled
|
|
204
|
+
* @param value - the value to set
|
|
205
|
+
*/
|
|
206
|
+
set _glowModeEnabled(value) {
|
|
207
|
+
this._useAdditionalColor = value;
|
|
208
|
+
}
|
|
209
|
+
/** Get the inspector from bundle or global
|
|
210
|
+
* @returns the global NME
|
|
211
|
+
*/
|
|
212
|
+
_getGlobalNodeMaterialEditor() {
|
|
213
|
+
// UMD global name detection from bundle metadata.
|
|
214
|
+
// Note: rollup-built UMD bundles do not expose the editor class
|
|
215
|
+
// directly on the namespace - it lives on `.default.NodeEditor` -
|
|
216
|
+
// so we unwrap that case before falling back to the BABYLON global.
|
|
217
|
+
if (typeof NODEEDITOR !== "undefined") {
|
|
218
|
+
if (NODEEDITOR.NodeEditor) {
|
|
219
|
+
return NODEEDITOR;
|
|
220
|
+
}
|
|
221
|
+
if (NODEEDITOR.default?.NodeEditor) {
|
|
222
|
+
return NODEEDITOR.default;
|
|
223
|
+
}
|
|
334
224
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
return
|
|
225
|
+
// In case of module let's check the global emitted from the editor entry point.
|
|
226
|
+
if (typeof BABYLON !== "undefined" && typeof BABYLON.NodeEditor !== "undefined") {
|
|
227
|
+
return BABYLON;
|
|
338
228
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Gets whether the glow layer is supported
|
|
476
|
-
* @returns true if the glow layer is supported
|
|
477
|
-
*/
|
|
478
|
-
get _supportGlowLayer() {
|
|
479
|
-
if (this._fragmentOutputNodes.length === 0) {
|
|
480
|
-
return false;
|
|
481
|
-
}
|
|
482
|
-
if (this._fragmentOutputNodes.some((f) => f.additionalColor && f.additionalColor.isConnected)) {
|
|
483
|
-
return true;
|
|
484
|
-
}
|
|
485
|
-
return false;
|
|
486
|
-
}
|
|
487
|
-
/**
|
|
488
|
-
* Specifies if the material will require alpha blending
|
|
489
|
-
* @returns a boolean specifying if alpha blending is needed
|
|
490
|
-
*/
|
|
491
|
-
needAlphaBlending() {
|
|
492
|
-
if (this.ignoreAlpha) {
|
|
493
|
-
return false;
|
|
494
|
-
}
|
|
495
|
-
return this.forceAlphaBlending || this.alpha < 1.0 || (this._sharedData && this._sharedData.hints.needAlphaBlending);
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Specifies if this material should be rendered in alpha test mode
|
|
499
|
-
* @returns a boolean specifying if an alpha test is needed.
|
|
500
|
-
*/
|
|
501
|
-
needAlphaTesting() {
|
|
502
|
-
return this._sharedData && this._sharedData.hints.needAlphaTesting;
|
|
503
|
-
}
|
|
504
|
-
_processInitializeOnLink(block, state, nodesToProcessForOtherBuildState, autoConfigure = true) {
|
|
505
|
-
if (block.target === NodeMaterialBlockTargets.VertexAndFragment) {
|
|
506
|
-
nodesToProcessForOtherBuildState.push(block);
|
|
507
|
-
}
|
|
508
|
-
else if (state.target === NodeMaterialBlockTargets.Fragment && block.target === NodeMaterialBlockTargets.Vertex && block._preparationId !== this._buildId) {
|
|
509
|
-
nodesToProcessForOtherBuildState.push(block);
|
|
510
|
-
}
|
|
511
|
-
this._initializeBlock(block, state, nodesToProcessForOtherBuildState, autoConfigure);
|
|
512
|
-
}
|
|
513
|
-
_attachBlock(node) {
|
|
514
|
-
if (this.attachedBlocks.indexOf(node) === -1) {
|
|
515
|
-
if (node.isUnique) {
|
|
516
|
-
const className = node.getClassName();
|
|
517
|
-
for (const other of this.attachedBlocks) {
|
|
518
|
-
if (other.getClassName() === className) {
|
|
519
|
-
this._sharedData.raiseBuildError(`Cannot have multiple blocks of type ${className} in the same NodeMaterial`);
|
|
520
|
-
return;
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
/** Gets or sets the active shader language */
|
|
232
|
+
get shaderLanguage() {
|
|
233
|
+
return this._options?.shaderLanguage || _a.DefaultShaderLanguage;
|
|
234
|
+
}
|
|
235
|
+
set shaderLanguage(value) {
|
|
236
|
+
this._options.shaderLanguage = value;
|
|
237
|
+
}
|
|
238
|
+
/** Gets or sets options to control the node material overall behavior */
|
|
239
|
+
get options() {
|
|
240
|
+
return this._options;
|
|
241
|
+
}
|
|
242
|
+
set options(options) {
|
|
243
|
+
this._options = options;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Gets or sets the mode property
|
|
247
|
+
*/
|
|
248
|
+
get mode() {
|
|
249
|
+
return this._mode;
|
|
250
|
+
}
|
|
251
|
+
set mode(value) {
|
|
252
|
+
this._mode = value;
|
|
253
|
+
}
|
|
254
|
+
/** Gets or sets the unique identifier used to identified the effect associated with the material */
|
|
255
|
+
get buildId() {
|
|
256
|
+
return this._buildId;
|
|
257
|
+
}
|
|
258
|
+
set buildId(value) {
|
|
259
|
+
this._buildId = value;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Create a new node based material
|
|
263
|
+
* @param name defines the material name
|
|
264
|
+
* @param scene defines the hosting scene
|
|
265
|
+
* @param options defines creation option
|
|
266
|
+
*/
|
|
267
|
+
constructor(name, scene, options = {}) {
|
|
268
|
+
super(name, scene || EngineStore.LastCreatedScene);
|
|
269
|
+
this._buildId = _a._BuildIdGenerator++;
|
|
270
|
+
this._buildWasSuccessful = false;
|
|
271
|
+
this._cachedWorldViewMatrix = new Matrix();
|
|
272
|
+
this._cachedWorldViewProjectionMatrix = new Matrix();
|
|
273
|
+
this._optimizers = new Array();
|
|
274
|
+
this._animationFrame = -1;
|
|
275
|
+
this._buildIsInProgress = false;
|
|
276
|
+
this.BJSNODEMATERIALEDITOR = this._getGlobalNodeMaterialEditor();
|
|
277
|
+
/** @internal */
|
|
278
|
+
this._useAdditionalColor = false;
|
|
279
|
+
/**
|
|
280
|
+
* Gets or sets data used by visual editor
|
|
281
|
+
* @see https://nme.babylonjs.com
|
|
282
|
+
*/
|
|
283
|
+
this.editorData = null;
|
|
284
|
+
/**
|
|
285
|
+
* Gets or sets a boolean indicating that alpha value must be ignored (This will turn alpha blending off even if an alpha value is produced by the material)
|
|
286
|
+
*/
|
|
287
|
+
this.ignoreAlpha = __runInitializers(this, _ignoreAlpha_initializers, false);
|
|
288
|
+
/**
|
|
289
|
+
* Defines the maximum number of lights that can be used in the material
|
|
290
|
+
*/
|
|
291
|
+
this.maxSimultaneousLights = (__runInitializers(this, _ignoreAlpha_extraInitializers), __runInitializers(this, _maxSimultaneousLights_initializers, 4));
|
|
292
|
+
/**
|
|
293
|
+
* Observable raised when the material is built
|
|
294
|
+
*/
|
|
295
|
+
this.onBuildObservable = (__runInitializers(this, _maxSimultaneousLights_extraInitializers), new Observable());
|
|
296
|
+
/**
|
|
297
|
+
* Observable raised when an error is detected
|
|
298
|
+
*/
|
|
299
|
+
this.onBuildErrorObservable = new Observable();
|
|
300
|
+
/**
|
|
301
|
+
* Gets or sets the root nodes of the material vertex shader
|
|
302
|
+
*/
|
|
303
|
+
this._vertexOutputNodes = new Array();
|
|
304
|
+
/**
|
|
305
|
+
* Gets or sets the root nodes of the material fragment (pixel) shader
|
|
306
|
+
*/
|
|
307
|
+
this._fragmentOutputNodes = new Array();
|
|
308
|
+
/**
|
|
309
|
+
* Gets an array of blocks that needs to be serialized even if they are not yet connected
|
|
310
|
+
*/
|
|
311
|
+
this.attachedBlocks = [];
|
|
312
|
+
/**
|
|
313
|
+
* Specifies the mode of the node material
|
|
314
|
+
* @internal
|
|
315
|
+
*/
|
|
316
|
+
this._mode = __runInitializers(this, __mode_initializers, NodeMaterialModes.Material);
|
|
317
|
+
/**
|
|
318
|
+
* A free comment about the material
|
|
319
|
+
*/
|
|
320
|
+
this.comment = (__runInitializers(this, __mode_extraInitializers), __runInitializers(this, _comment_initializers, void 0));
|
|
321
|
+
/**
|
|
322
|
+
* Gets or sets a boolean indicating that alpha blending must be enabled no matter what alpha value or alpha channel of the FragmentBlock are
|
|
323
|
+
*/
|
|
324
|
+
this.forceAlphaBlending = (__runInitializers(this, _comment_extraInitializers), __runInitializers(this, _forceAlphaBlending_initializers, false));
|
|
325
|
+
__runInitializers(this, _forceAlphaBlending_extraInitializers);
|
|
326
|
+
if (!_a.UseNativeShaderLanguageOfEngine && options && options.shaderLanguage === 1 /* ShaderLanguage.WGSL */ && !this.getScene().getEngine().isWebGPU) {
|
|
327
|
+
throw new Error("WebGPU shader language is only supported with WebGPU engine");
|
|
328
|
+
}
|
|
329
|
+
this._options = {
|
|
330
|
+
emitComments: false,
|
|
331
|
+
shaderLanguage: _a.DefaultShaderLanguage,
|
|
332
|
+
...options,
|
|
333
|
+
};
|
|
334
|
+
if (_a.UseNativeShaderLanguageOfEngine) {
|
|
335
|
+
this._options.shaderLanguage = this.getScene().getEngine().isWebGPU ? 1 /* ShaderLanguage.WGSL */ : 0 /* ShaderLanguage.GLSL */;
|
|
336
|
+
}
|
|
337
|
+
// Setup the default processing configuration to the scene.
|
|
338
|
+
this._attachImageProcessingConfiguration(null);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Gets the current class name of the material e.g. "NodeMaterial"
|
|
342
|
+
* @returns the class name
|
|
343
|
+
*/
|
|
344
|
+
getClassName() {
|
|
345
|
+
return "NodeMaterial";
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Get a block by its name
|
|
349
|
+
* @param name defines the name of the block to retrieve
|
|
350
|
+
* @returns the required block or null if not found
|
|
351
|
+
*/
|
|
352
|
+
getBlockByName(name) {
|
|
353
|
+
let result = null;
|
|
354
|
+
for (const block of this.attachedBlocks) {
|
|
355
|
+
if (block.name === name) {
|
|
356
|
+
if (!result) {
|
|
357
|
+
result = block;
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
Logger.Warn("More than one block was found with the name `" + name + "`");
|
|
361
|
+
return result;
|
|
362
|
+
}
|
|
521
363
|
}
|
|
522
364
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
input.associatedVariableName = "";
|
|
536
|
-
const connectedPoint = input.connectedPoint;
|
|
537
|
-
if (connectedPoint && !connectedPoint._preventBubbleUp) {
|
|
538
|
-
const block = connectedPoint.ownerBlock;
|
|
539
|
-
if (block !== node) {
|
|
540
|
-
this._processInitializeOnLink(block, state, nodesToProcessForOtherBuildState, autoConfigure);
|
|
365
|
+
return result;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Get a block using a predicate
|
|
369
|
+
* @param predicate defines the predicate used to find the good candidate
|
|
370
|
+
* @returns the required block or null if not found
|
|
371
|
+
*/
|
|
372
|
+
getBlockByPredicate(predicate) {
|
|
373
|
+
for (const block of this.attachedBlocks) {
|
|
374
|
+
if (predicate(block)) {
|
|
375
|
+
return block;
|
|
376
|
+
}
|
|
541
377
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
if (block.
|
|
552
|
-
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Get an input block using a predicate
|
|
382
|
+
* @param predicate defines the predicate used to find the good candidate
|
|
383
|
+
* @returns the required input block or null if not found
|
|
384
|
+
*/
|
|
385
|
+
getInputBlockByPredicate(predicate) {
|
|
386
|
+
for (const block of this.attachedBlocks) {
|
|
387
|
+
if (block.isInput && predicate(block)) {
|
|
388
|
+
return block;
|
|
553
389
|
}
|
|
554
|
-
state._terminalBlocks.add(block); // Attach the storage write only
|
|
555
|
-
this._processInitializeOnLink(block, state, nodesToProcessForOtherBuildState, autoConfigure);
|
|
556
390
|
}
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Gets the list of input blocks attached to this material
|
|
395
|
+
* @returns an array of InputBlocks
|
|
396
|
+
*/
|
|
397
|
+
getInputBlocks() {
|
|
398
|
+
const blocks = [];
|
|
399
|
+
for (const block of this.attachedBlocks) {
|
|
400
|
+
if (block.isInput) {
|
|
401
|
+
blocks.push(block);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return blocks;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Adds a new optimizer to the list of optimizers
|
|
408
|
+
* @param optimizer defines the optimizers to add
|
|
409
|
+
* @returns the current material
|
|
410
|
+
*/
|
|
411
|
+
registerOptimizer(optimizer) {
|
|
412
|
+
const index = this._optimizers.indexOf(optimizer);
|
|
413
|
+
if (index > -1) {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
this._optimizers.push(optimizer);
|
|
417
|
+
return this;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Remove an optimizer from the list of optimizers
|
|
421
|
+
* @param optimizer defines the optimizers to remove
|
|
422
|
+
* @returns the current material
|
|
423
|
+
*/
|
|
424
|
+
unregisterOptimizer(optimizer) {
|
|
425
|
+
const index = this._optimizers.indexOf(optimizer);
|
|
426
|
+
if (index === -1) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
this._optimizers.splice(index, 1);
|
|
430
|
+
return this;
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Add a new block to the list of output nodes
|
|
434
|
+
* @param node defines the node to add
|
|
435
|
+
* @returns the current material
|
|
436
|
+
*/
|
|
437
|
+
addOutputNode(node) {
|
|
438
|
+
if (node.target === null) {
|
|
439
|
+
throw new Error("This node is not meant to be an output node. You may want to explicitly set its target value.");
|
|
440
|
+
}
|
|
441
|
+
if ((node.target & NodeMaterialBlockTargets.Vertex) !== 0) {
|
|
442
|
+
this._addVertexOutputNode(node);
|
|
443
|
+
}
|
|
444
|
+
if ((node.target & NodeMaterialBlockTargets.Fragment) !== 0) {
|
|
445
|
+
this._addFragmentOutputNode(node);
|
|
446
|
+
}
|
|
447
|
+
return this;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Remove a block from the list of root nodes
|
|
451
|
+
* @param node defines the node to remove
|
|
452
|
+
* @returns the current material
|
|
453
|
+
*/
|
|
454
|
+
removeOutputNode(node) {
|
|
455
|
+
if (node.target === null) {
|
|
456
|
+
return this;
|
|
457
|
+
}
|
|
458
|
+
if ((node.target & NodeMaterialBlockTargets.Vertex) !== 0) {
|
|
459
|
+
this._removeVertexOutputNode(node);
|
|
460
|
+
}
|
|
461
|
+
if ((node.target & NodeMaterialBlockTargets.Fragment) !== 0) {
|
|
462
|
+
this._removeFragmentOutputNode(node);
|
|
463
|
+
}
|
|
464
|
+
return this;
|
|
557
465
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
this.
|
|
466
|
+
_addVertexOutputNode(node) {
|
|
467
|
+
if (this._vertexOutputNodes.indexOf(node) !== -1) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
node.target = NodeMaterialBlockTargets.Vertex;
|
|
471
|
+
this._vertexOutputNodes.push(node);
|
|
472
|
+
return this;
|
|
564
473
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
}
|
|
570
|
-
_resetDualBlocks(node, id) {
|
|
571
|
-
if (node.target === NodeMaterialBlockTargets.VertexAndFragment) {
|
|
572
|
-
node.buildId = id;
|
|
573
|
-
}
|
|
574
|
-
for (const input of node.inputs) {
|
|
575
|
-
const connectedPoint = input.connectedPoint;
|
|
576
|
-
if (connectedPoint && !connectedPoint._preventBubbleUp) {
|
|
577
|
-
const block = connectedPoint.ownerBlock;
|
|
578
|
-
if (block !== node) {
|
|
579
|
-
this._resetDualBlocks(block, id);
|
|
474
|
+
_removeVertexOutputNode(node) {
|
|
475
|
+
const index = this._vertexOutputNodes.indexOf(node);
|
|
476
|
+
if (index === -1) {
|
|
477
|
+
return;
|
|
580
478
|
}
|
|
479
|
+
this._vertexOutputNodes.splice(index, 1);
|
|
480
|
+
return this;
|
|
581
481
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
this.
|
|
482
|
+
_addFragmentOutputNode(node) {
|
|
483
|
+
if (this._fragmentOutputNodes.indexOf(node) !== -1) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
node.target = NodeMaterialBlockTargets.Fragment;
|
|
487
|
+
this._fragmentOutputNodes.push(node);
|
|
488
|
+
return this;
|
|
588
489
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
490
|
+
_removeFragmentOutputNode(node) {
|
|
491
|
+
const index = this._fragmentOutputNodes.indexOf(node);
|
|
492
|
+
if (index === -1) {
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
this._fragmentOutputNodes.splice(index, 1);
|
|
496
|
+
return this;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Gets whether the glow layer is supported
|
|
500
|
+
* @returns true if the glow layer is supported
|
|
501
|
+
*/
|
|
502
|
+
get _supportGlowLayer() {
|
|
503
|
+
if (this._fragmentOutputNodes.length === 0) {
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
if (this._fragmentOutputNodes.some((f) => f.additionalColor && f.additionalColor.isConnected)) {
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
return false;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Specifies if the material will require alpha blending
|
|
513
|
+
* @returns a boolean specifying if alpha blending is needed
|
|
514
|
+
*/
|
|
515
|
+
needAlphaBlending() {
|
|
516
|
+
if (this.ignoreAlpha) {
|
|
517
|
+
return false;
|
|
518
|
+
}
|
|
519
|
+
return this.forceAlphaBlending || this.alpha < 1.0 || (this._sharedData && this._sharedData.hints.needAlphaBlending);
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Specifies if this material should be rendered in alpha test mode
|
|
523
|
+
* @returns a boolean specifying if an alpha test is needed.
|
|
524
|
+
*/
|
|
525
|
+
needAlphaTesting() {
|
|
526
|
+
return this._sharedData && this._sharedData.hints.needAlphaTesting;
|
|
527
|
+
}
|
|
528
|
+
_processInitializeOnLink(block, state, nodesToProcessForOtherBuildState, autoConfigure = true) {
|
|
529
|
+
if (block.target === NodeMaterialBlockTargets.VertexAndFragment) {
|
|
530
|
+
nodesToProcessForOtherBuildState.push(block);
|
|
531
|
+
}
|
|
532
|
+
else if (state.target === NodeMaterialBlockTargets.Fragment && block.target === NodeMaterialBlockTargets.Vertex && block._preparationId !== this._buildId) {
|
|
533
|
+
nodesToProcessForOtherBuildState.push(block);
|
|
534
|
+
}
|
|
535
|
+
this._initializeBlock(block, state, nodesToProcessForOtherBuildState, autoConfigure);
|
|
536
|
+
}
|
|
537
|
+
_attachBlock(node) {
|
|
538
|
+
if (this.attachedBlocks.indexOf(node) === -1) {
|
|
539
|
+
if (node.isUnique) {
|
|
540
|
+
const className = node.getClassName();
|
|
541
|
+
for (const other of this.attachedBlocks) {
|
|
542
|
+
if (other.getClassName() === className) {
|
|
543
|
+
this._sharedData.raiseBuildError(`Cannot have multiple blocks of type ${className} in the same NodeMaterial`);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
598
547
|
}
|
|
599
|
-
this.
|
|
548
|
+
this.attachedBlocks.push(node);
|
|
600
549
|
}
|
|
601
550
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
/**
|
|
618
|
-
* Build the material and generates the inner effect
|
|
619
|
-
* @param verbose defines if the build should log activity
|
|
620
|
-
* @param updateBuildId defines if the internal build Id should be updated (default is true)
|
|
621
|
-
* @param autoConfigure defines if the autoConfigure method should be called when initializing blocks (default is false)
|
|
622
|
-
*/
|
|
623
|
-
build(verbose = false, updateBuildId = true, autoConfigure = false) {
|
|
624
|
-
if (this._buildIsInProgress) {
|
|
625
|
-
Logger.Warn("Build is already in progress, You can use NodeMaterial.onBuildObservable to determine when the build is completed.");
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
this._buildIsInProgress = true;
|
|
629
|
-
// First time?
|
|
630
|
-
if (!this._vertexCompilationState && !autoConfigure) {
|
|
631
|
-
autoConfigure = true;
|
|
632
|
-
}
|
|
633
|
-
this._buildWasSuccessful = false;
|
|
634
|
-
const engine = this.getScene().getEngine();
|
|
635
|
-
const allowEmptyVertexProgram = this._mode === NodeMaterialModes.Particle || this._mode === NodeMaterialModes.SFE;
|
|
636
|
-
if (this._vertexOutputNodes.length === 0 && !allowEmptyVertexProgram) {
|
|
637
|
-
this.onBuildErrorObservable.notifyObservers("You must define at least one vertexOutputNode");
|
|
638
|
-
this._buildIsInProgress = false;
|
|
639
|
-
return;
|
|
640
|
-
}
|
|
641
|
-
if (this._fragmentOutputNodes.length === 0) {
|
|
642
|
-
this.onBuildErrorObservable.notifyObservers("You must define at least one fragmentOutputNode");
|
|
643
|
-
this._buildIsInProgress = false;
|
|
644
|
-
return;
|
|
645
|
-
}
|
|
646
|
-
// Compilation state
|
|
647
|
-
this._vertexCompilationState = new NodeMaterialBuildState();
|
|
648
|
-
this._vertexCompilationState.supportUniformBuffers = engine.supportsUniformBuffers;
|
|
649
|
-
this._vertexCompilationState.target = NodeMaterialBlockTargets.Vertex;
|
|
650
|
-
this._fragmentCompilationState = new NodeMaterialBuildState();
|
|
651
|
-
this._fragmentCompilationState.supportUniformBuffers = engine.supportsUniformBuffers;
|
|
652
|
-
this._fragmentCompilationState.target = NodeMaterialBlockTargets.Fragment;
|
|
653
|
-
// Shared data
|
|
654
|
-
const needToPurgeList = this._fragmentOutputNodes.filter((n) => n._isFinalOutputAndActive).length > 1;
|
|
655
|
-
let fragmentOutputNodes = this._fragmentOutputNodes;
|
|
656
|
-
if (needToPurgeList) {
|
|
657
|
-
// Get all but the final output nodes
|
|
658
|
-
fragmentOutputNodes = this._fragmentOutputNodes.filter((n) => !n._isFinalOutputAndActive);
|
|
659
|
-
// Get the first with precedence on
|
|
660
|
-
fragmentOutputNodes.push(this._fragmentOutputNodes.filter((n) => n._isFinalOutputAndActive && n._hasPrecedence)[0]);
|
|
661
|
-
}
|
|
662
|
-
this._sharedData = new NodeMaterialBuildStateSharedData();
|
|
663
|
-
this._sharedData.nodeMaterial = this;
|
|
664
|
-
this._sharedData.fragmentOutputNodes = fragmentOutputNodes;
|
|
665
|
-
this._vertexCompilationState.sharedData = this._sharedData;
|
|
666
|
-
this._fragmentCompilationState.sharedData = this._sharedData;
|
|
667
|
-
this._sharedData.buildId = this._buildId;
|
|
668
|
-
this._sharedData.emitComments = this._options.emitComments;
|
|
669
|
-
this._sharedData.verbose = verbose;
|
|
670
|
-
this._sharedData.scene = this.getScene();
|
|
671
|
-
this._sharedData.allowEmptyVertexProgram = allowEmptyVertexProgram;
|
|
672
|
-
// Initialize blocks
|
|
673
|
-
const vertexNodes = [];
|
|
674
|
-
const fragmentNodes = [];
|
|
675
|
-
for (const vertexOutputNode of this._vertexOutputNodes) {
|
|
676
|
-
vertexNodes.push(vertexOutputNode);
|
|
677
|
-
this._initializeBlock(vertexOutputNode, this._vertexCompilationState, fragmentNodes, autoConfigure);
|
|
678
|
-
}
|
|
679
|
-
for (const fragmentOutputNode of fragmentOutputNodes) {
|
|
680
|
-
fragmentNodes.push(fragmentOutputNode);
|
|
681
|
-
this._initializeBlock(fragmentOutputNode, this._fragmentCompilationState, vertexNodes, autoConfigure);
|
|
682
|
-
}
|
|
683
|
-
// Are blocks code ready?
|
|
684
|
-
let waitingNodeCount = 0;
|
|
685
|
-
for (const node of this.attachedBlocks) {
|
|
686
|
-
if (!node.codeIsReady) {
|
|
687
|
-
waitingNodeCount++;
|
|
688
|
-
node.onCodeIsReadyObservable.addOnce(() => {
|
|
689
|
-
waitingNodeCount--;
|
|
690
|
-
if (waitingNodeCount === 0) {
|
|
691
|
-
this._finishBuildProcess(verbose, updateBuildId, vertexNodes, fragmentNodes);
|
|
551
|
+
_initializeBlock(node, state, nodesToProcessForOtherBuildState, autoConfigure = true) {
|
|
552
|
+
node.initialize(state);
|
|
553
|
+
if (autoConfigure) {
|
|
554
|
+
node.autoConfigure(this);
|
|
555
|
+
}
|
|
556
|
+
node._preparationId = this._buildId;
|
|
557
|
+
this._attachBlock(node);
|
|
558
|
+
for (const input of node.inputs) {
|
|
559
|
+
input.associatedVariableName = "";
|
|
560
|
+
const connectedPoint = input.connectedPoint;
|
|
561
|
+
if (connectedPoint && !connectedPoint._preventBubbleUp) {
|
|
562
|
+
const block = connectedPoint.ownerBlock;
|
|
563
|
+
if (block !== node) {
|
|
564
|
+
this._processInitializeOnLink(block, state, nodesToProcessForOtherBuildState, autoConfigure);
|
|
565
|
+
}
|
|
692
566
|
}
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
if (waitingNodeCount !== 0) {
|
|
697
|
-
return;
|
|
698
|
-
}
|
|
699
|
-
this._finishBuildProcess(verbose, updateBuildId, vertexNodes, fragmentNodes);
|
|
700
|
-
}
|
|
701
|
-
_finishBuildProcess(verbose = false, updateBuildId = true, vertexNodes, fragmentNodes) {
|
|
702
|
-
// Optimize
|
|
703
|
-
this.optimize();
|
|
704
|
-
// Vertex
|
|
705
|
-
for (const vertexOutputNode of vertexNodes) {
|
|
706
|
-
vertexOutputNode.build(this._vertexCompilationState, vertexNodes);
|
|
707
|
-
}
|
|
708
|
-
// Fragment
|
|
709
|
-
this._fragmentCompilationState.uniforms = this._vertexCompilationState.uniforms.slice(0);
|
|
710
|
-
this._fragmentCompilationState._uniformDeclaration = this._vertexCompilationState._uniformDeclaration;
|
|
711
|
-
this._fragmentCompilationState._constantDeclaration = this._vertexCompilationState._constantDeclaration;
|
|
712
|
-
this._fragmentCompilationState._vertexState = this._vertexCompilationState;
|
|
713
|
-
for (const fragmentOutputNode of fragmentNodes) {
|
|
714
|
-
this._resetDualBlocks(fragmentOutputNode, this._buildId - 1);
|
|
715
|
-
}
|
|
716
|
-
for (const fragmentOutputNode of fragmentNodes) {
|
|
717
|
-
fragmentOutputNode.build(this._fragmentCompilationState, fragmentNodes);
|
|
718
|
-
}
|
|
719
|
-
// Finalize
|
|
720
|
-
this._vertexCompilationState.finalize(this._vertexCompilationState);
|
|
721
|
-
this._fragmentCompilationState.finalize(this._fragmentCompilationState);
|
|
722
|
-
if (updateBuildId) {
|
|
723
|
-
this._buildId = NodeMaterial._BuildIdGenerator++;
|
|
724
|
-
}
|
|
725
|
-
if (verbose) {
|
|
726
|
-
Logger.Log("Vertex shader:");
|
|
727
|
-
Logger.Log(this._vertexCompilationState.compilationString);
|
|
728
|
-
Logger.Log("Fragment shader:");
|
|
729
|
-
Logger.Log(this._fragmentCompilationState.compilationString);
|
|
730
|
-
}
|
|
731
|
-
// Errors
|
|
732
|
-
const noError = this._sharedData.emitErrors();
|
|
733
|
-
this._buildIsInProgress = false;
|
|
734
|
-
if (noError) {
|
|
735
|
-
this._buildWasSuccessful = true;
|
|
736
|
-
this.onBuildObservable.notifyObservers(this);
|
|
737
|
-
}
|
|
738
|
-
// Wipe defines
|
|
739
|
-
const meshes = this.getScene().meshes;
|
|
740
|
-
for (const mesh of meshes) {
|
|
741
|
-
if (!mesh.subMeshes) {
|
|
742
|
-
continue;
|
|
743
|
-
}
|
|
744
|
-
for (const subMesh of mesh.subMeshes) {
|
|
745
|
-
if (subMesh.getMaterial() !== this) {
|
|
746
|
-
continue;
|
|
747
567
|
}
|
|
748
|
-
|
|
749
|
-
|
|
568
|
+
// Loop
|
|
569
|
+
if (node.isLoop) {
|
|
570
|
+
// We need to keep the storage write block in the active blocks
|
|
571
|
+
const loopBlock = node;
|
|
572
|
+
if (loopBlock.loopID.hasEndpoints) {
|
|
573
|
+
for (const endpoint of loopBlock.loopID.endpoints) {
|
|
574
|
+
const block = endpoint.ownerBlock;
|
|
575
|
+
if (block.outputs.length !== 0) {
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
state._terminalBlocks.add(block); // Attach the storage write only
|
|
579
|
+
this._processInitializeOnLink(block, state, nodesToProcessForOtherBuildState, autoConfigure);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
else if (node.isTeleportOut) {
|
|
584
|
+
// Teleportation
|
|
585
|
+
const teleport = node;
|
|
586
|
+
if (teleport.entryPoint) {
|
|
587
|
+
this._processInitializeOnLink(teleport.entryPoint, state, nodesToProcessForOtherBuildState, autoConfigure);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
for (const output of node.outputs) {
|
|
591
|
+
output.associatedVariableName = "";
|
|
750
592
|
}
|
|
751
|
-
const defines = subMesh.materialDefines;
|
|
752
|
-
defines.markAllAsDirty();
|
|
753
|
-
defines.reset();
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
if (this.prePassTextureInputs.length) {
|
|
757
|
-
this.getScene().enablePrePassRenderer();
|
|
758
|
-
}
|
|
759
|
-
const prePassRenderer = this.getScene().prePassRenderer;
|
|
760
|
-
if (prePassRenderer) {
|
|
761
|
-
prePassRenderer.markAsDirty();
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
/**
|
|
765
|
-
* Runs an optimization phase to try to improve the shader code
|
|
766
|
-
*/
|
|
767
|
-
optimize() {
|
|
768
|
-
for (const optimizer of this._optimizers) {
|
|
769
|
-
optimizer.optimize(this._vertexOutputNodes, this._fragmentOutputNodes);
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
_prepareDefinesForAttributes(mesh, defines) {
|
|
773
|
-
const oldNormal = defines["NORMAL"];
|
|
774
|
-
const oldTangent = defines["TANGENT"];
|
|
775
|
-
const oldColor = defines["VERTEXCOLOR_NME"];
|
|
776
|
-
defines["NORMAL"] = mesh.isVerticesDataPresent(VertexBuffer.NormalKind);
|
|
777
|
-
defines["TANGENT"] = mesh.isVerticesDataPresent(VertexBuffer.TangentKind);
|
|
778
|
-
const hasVertexColors = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);
|
|
779
|
-
defines["VERTEXCOLOR_NME"] = hasVertexColors;
|
|
780
|
-
let uvChanged = false;
|
|
781
|
-
for (let i = 1; i <= 6; ++i) {
|
|
782
|
-
const oldUV = defines["UV" + i];
|
|
783
|
-
defines["UV" + i] = mesh.isVerticesDataPresent(`uv${i === 1 ? "" : i}`);
|
|
784
|
-
uvChanged = uvChanged || defines["UV" + i] !== oldUV;
|
|
785
|
-
}
|
|
786
|
-
// PrePass
|
|
787
|
-
const oit = this.needAlphaBlendingForMesh(mesh) && this.getScene().useOrderIndependentTransparency;
|
|
788
|
-
PrepareDefinesForPrePass(this.getScene(), defines, !oit);
|
|
789
|
-
MaterialHelperGeometryRendering.PrepareDefines(this.getScene().getEngine().currentRenderPassId, mesh, defines);
|
|
790
|
-
if (oldNormal !== defines["NORMAL"] || oldTangent !== defines["TANGENT"] || oldColor !== defines["VERTEXCOLOR_NME"] || uvChanged) {
|
|
791
|
-
defines.markAsAttributesDirty();
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
/**
|
|
795
|
-
* Can this material render to prepass
|
|
796
|
-
*/
|
|
797
|
-
get isPrePassCapable() {
|
|
798
|
-
return true;
|
|
799
|
-
}
|
|
800
|
-
/**
|
|
801
|
-
* Outputs written to the prepass
|
|
802
|
-
*/
|
|
803
|
-
get prePassTextureOutputs() {
|
|
804
|
-
const prePassOutputBlock = this.getBlockByPredicate((block) => block.getClassName() === "PrePassOutputBlock");
|
|
805
|
-
const result = [4];
|
|
806
|
-
if (!prePassOutputBlock) {
|
|
807
|
-
return result;
|
|
808
|
-
}
|
|
809
|
-
// Cannot write to prepass if we alread read from prepass
|
|
810
|
-
if (this.prePassTextureInputs.length) {
|
|
811
|
-
return result;
|
|
812
|
-
}
|
|
813
|
-
if (prePassOutputBlock.viewDepth.isConnected) {
|
|
814
|
-
result.push(5);
|
|
815
|
-
}
|
|
816
|
-
if (prePassOutputBlock.screenDepth.isConnected) {
|
|
817
|
-
result.push(10);
|
|
818
|
-
}
|
|
819
|
-
if (prePassOutputBlock.viewNormal.isConnected) {
|
|
820
|
-
result.push(6);
|
|
821
|
-
}
|
|
822
|
-
if (prePassOutputBlock.worldNormal.isConnected) {
|
|
823
|
-
result.push(8);
|
|
824
|
-
}
|
|
825
|
-
if (prePassOutputBlock.worldPosition.isConnected) {
|
|
826
|
-
result.push(1);
|
|
827
|
-
}
|
|
828
|
-
if (prePassOutputBlock.localPosition.isConnected) {
|
|
829
|
-
result.push(9);
|
|
830
|
-
}
|
|
831
|
-
if (prePassOutputBlock.reflectivity.isConnected) {
|
|
832
|
-
result.push(3);
|
|
833
|
-
}
|
|
834
|
-
if (prePassOutputBlock.velocity.isConnected) {
|
|
835
|
-
result.push(2);
|
|
836
|
-
}
|
|
837
|
-
if (prePassOutputBlock.velocityLinear.isConnected) {
|
|
838
|
-
result.push(11);
|
|
839
|
-
}
|
|
840
|
-
return result;
|
|
841
|
-
}
|
|
842
|
-
/**
|
|
843
|
-
* Gets the list of prepass texture required
|
|
844
|
-
*/
|
|
845
|
-
get prePassTextureInputs() {
|
|
846
|
-
const prePassTextureBlocks = this.getAllTextureBlocks().filter((block) => block.getClassName() === "PrePassTextureBlock");
|
|
847
|
-
const result = [];
|
|
848
|
-
for (const block of prePassTextureBlocks) {
|
|
849
|
-
if (block.position.isConnected && !result.includes(1)) {
|
|
850
|
-
result.push(1);
|
|
851
593
|
}
|
|
852
|
-
|
|
853
|
-
|
|
594
|
+
_resetDualBlocks(node, id) {
|
|
595
|
+
if (node.target === NodeMaterialBlockTargets.VertexAndFragment) {
|
|
596
|
+
node.buildId = id;
|
|
597
|
+
}
|
|
598
|
+
for (const input of node.inputs) {
|
|
599
|
+
const connectedPoint = input.connectedPoint;
|
|
600
|
+
if (connectedPoint && !connectedPoint._preventBubbleUp) {
|
|
601
|
+
const block = connectedPoint.ownerBlock;
|
|
602
|
+
if (block !== node) {
|
|
603
|
+
this._resetDualBlocks(block, id);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
// If this is a teleport out, we need to reset the connected block
|
|
608
|
+
if (node.isTeleportOut) {
|
|
609
|
+
const teleportOut = node;
|
|
610
|
+
if (teleportOut.entryPoint) {
|
|
611
|
+
this._resetDualBlocks(teleportOut.entryPoint, id);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
else if (node.isLoop) {
|
|
615
|
+
// Loop
|
|
616
|
+
const loopBlock = node;
|
|
617
|
+
if (loopBlock.loopID.hasEndpoints) {
|
|
618
|
+
for (const endpoint of loopBlock.loopID.endpoints) {
|
|
619
|
+
const block = endpoint.ownerBlock;
|
|
620
|
+
if (block.outputs.length !== 0) {
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
this._resetDualBlocks(block, id);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
854
627
|
}
|
|
855
|
-
|
|
856
|
-
|
|
628
|
+
/**
|
|
629
|
+
* Remove a block from the current node material
|
|
630
|
+
* @param block defines the block to remove
|
|
631
|
+
*/
|
|
632
|
+
removeBlock(block) {
|
|
633
|
+
const attachedBlockIndex = this.attachedBlocks.indexOf(block);
|
|
634
|
+
if (attachedBlockIndex > -1) {
|
|
635
|
+
this.attachedBlocks.splice(attachedBlockIndex, 1);
|
|
636
|
+
}
|
|
637
|
+
if (block.isFinalMerger) {
|
|
638
|
+
this.removeOutputNode(block);
|
|
639
|
+
}
|
|
857
640
|
}
|
|
858
|
-
|
|
859
|
-
|
|
641
|
+
/**
|
|
642
|
+
* Build the material and generates the inner effect
|
|
643
|
+
* @param verbose defines if the build should log activity
|
|
644
|
+
* @param updateBuildId defines if the internal build Id should be updated (default is true)
|
|
645
|
+
* @param autoConfigure defines if the autoConfigure method should be called when initializing blocks (default is false)
|
|
646
|
+
*/
|
|
647
|
+
build(verbose = false, updateBuildId = true, autoConfigure = false) {
|
|
648
|
+
if (this._buildIsInProgress) {
|
|
649
|
+
Logger.Warn("Build is already in progress, You can use NodeMaterial.onBuildObservable to determine when the build is completed.");
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
this._buildIsInProgress = true;
|
|
653
|
+
// First time?
|
|
654
|
+
if (!this._vertexCompilationState && !autoConfigure) {
|
|
655
|
+
autoConfigure = true;
|
|
656
|
+
}
|
|
657
|
+
this._buildWasSuccessful = false;
|
|
658
|
+
const engine = this.getScene().getEngine();
|
|
659
|
+
const allowEmptyVertexProgram = this._mode === NodeMaterialModes.Particle || this._mode === NodeMaterialModes.SFE;
|
|
660
|
+
if (this._vertexOutputNodes.length === 0 && !allowEmptyVertexProgram) {
|
|
661
|
+
this.onBuildErrorObservable.notifyObservers("You must define at least one vertexOutputNode");
|
|
662
|
+
this._buildIsInProgress = false;
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
if (this._fragmentOutputNodes.length === 0) {
|
|
666
|
+
this.onBuildErrorObservable.notifyObservers("You must define at least one fragmentOutputNode");
|
|
667
|
+
this._buildIsInProgress = false;
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
// Compilation state
|
|
671
|
+
this._vertexCompilationState = new NodeMaterialBuildState();
|
|
672
|
+
this._vertexCompilationState.supportUniformBuffers = engine.supportsUniformBuffers;
|
|
673
|
+
this._vertexCompilationState.target = NodeMaterialBlockTargets.Vertex;
|
|
674
|
+
this._fragmentCompilationState = new NodeMaterialBuildState();
|
|
675
|
+
this._fragmentCompilationState.supportUniformBuffers = engine.supportsUniformBuffers;
|
|
676
|
+
this._fragmentCompilationState.target = NodeMaterialBlockTargets.Fragment;
|
|
677
|
+
// Shared data
|
|
678
|
+
const needToPurgeList = this._fragmentOutputNodes.filter((n) => n._isFinalOutputAndActive).length > 1;
|
|
679
|
+
let fragmentOutputNodes = this._fragmentOutputNodes;
|
|
680
|
+
if (needToPurgeList) {
|
|
681
|
+
// Get all but the final output nodes
|
|
682
|
+
fragmentOutputNodes = this._fragmentOutputNodes.filter((n) => !n._isFinalOutputAndActive);
|
|
683
|
+
// Get the first with precedence on
|
|
684
|
+
fragmentOutputNodes.push(this._fragmentOutputNodes.filter((n) => n._isFinalOutputAndActive && n._hasPrecedence)[0]);
|
|
685
|
+
}
|
|
686
|
+
this._sharedData = new NodeMaterialBuildStateSharedData();
|
|
687
|
+
this._sharedData.nodeMaterial = this;
|
|
688
|
+
this._sharedData.fragmentOutputNodes = fragmentOutputNodes;
|
|
689
|
+
this._vertexCompilationState.sharedData = this._sharedData;
|
|
690
|
+
this._fragmentCompilationState.sharedData = this._sharedData;
|
|
691
|
+
this._sharedData.buildId = this._buildId;
|
|
692
|
+
this._sharedData.emitComments = this._options.emitComments;
|
|
693
|
+
this._sharedData.verbose = verbose;
|
|
694
|
+
this._sharedData.scene = this.getScene();
|
|
695
|
+
this._sharedData.allowEmptyVertexProgram = allowEmptyVertexProgram;
|
|
696
|
+
// Initialize blocks
|
|
697
|
+
const vertexNodes = [];
|
|
698
|
+
const fragmentNodes = [];
|
|
699
|
+
for (const vertexOutputNode of this._vertexOutputNodes) {
|
|
700
|
+
vertexNodes.push(vertexOutputNode);
|
|
701
|
+
this._initializeBlock(vertexOutputNode, this._vertexCompilationState, fragmentNodes, autoConfigure);
|
|
702
|
+
}
|
|
703
|
+
for (const fragmentOutputNode of fragmentOutputNodes) {
|
|
704
|
+
fragmentNodes.push(fragmentOutputNode);
|
|
705
|
+
this._initializeBlock(fragmentOutputNode, this._fragmentCompilationState, vertexNodes, autoConfigure);
|
|
706
|
+
}
|
|
707
|
+
// Are blocks code ready?
|
|
708
|
+
let waitingNodeCount = 0;
|
|
709
|
+
for (const node of this.attachedBlocks) {
|
|
710
|
+
if (!node.codeIsReady) {
|
|
711
|
+
waitingNodeCount++;
|
|
712
|
+
node.onCodeIsReadyObservable.addOnce(() => {
|
|
713
|
+
waitingNodeCount--;
|
|
714
|
+
if (waitingNodeCount === 0) {
|
|
715
|
+
this._finishBuildProcess(verbose, updateBuildId, vertexNodes, fragmentNodes);
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
if (waitingNodeCount !== 0) {
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
this._finishBuildProcess(verbose, updateBuildId, vertexNodes, fragmentNodes);
|
|
724
|
+
}
|
|
725
|
+
_finishBuildProcess(verbose = false, updateBuildId = true, vertexNodes, fragmentNodes) {
|
|
726
|
+
// Optimize
|
|
727
|
+
this.optimize();
|
|
728
|
+
// Vertex
|
|
729
|
+
for (const vertexOutputNode of vertexNodes) {
|
|
730
|
+
vertexOutputNode.build(this._vertexCompilationState, vertexNodes);
|
|
731
|
+
}
|
|
732
|
+
// Fragment
|
|
733
|
+
this._fragmentCompilationState.uniforms = this._vertexCompilationState.uniforms.slice(0);
|
|
734
|
+
this._fragmentCompilationState._uniformDeclaration = this._vertexCompilationState._uniformDeclaration;
|
|
735
|
+
this._fragmentCompilationState._constantDeclaration = this._vertexCompilationState._constantDeclaration;
|
|
736
|
+
this._fragmentCompilationState._vertexState = this._vertexCompilationState;
|
|
737
|
+
for (const fragmentOutputNode of fragmentNodes) {
|
|
738
|
+
this._resetDualBlocks(fragmentOutputNode, this._buildId - 1);
|
|
739
|
+
}
|
|
740
|
+
for (const fragmentOutputNode of fragmentNodes) {
|
|
741
|
+
fragmentOutputNode.build(this._fragmentCompilationState, fragmentNodes);
|
|
742
|
+
}
|
|
743
|
+
// Finalize
|
|
744
|
+
this._vertexCompilationState.finalize(this._vertexCompilationState);
|
|
745
|
+
this._fragmentCompilationState.finalize(this._fragmentCompilationState);
|
|
746
|
+
if (updateBuildId) {
|
|
747
|
+
this._buildId = _a._BuildIdGenerator++;
|
|
748
|
+
}
|
|
749
|
+
if (verbose) {
|
|
750
|
+
Logger.Log("Vertex shader:");
|
|
751
|
+
Logger.Log(this._vertexCompilationState.compilationString);
|
|
752
|
+
Logger.Log("Fragment shader:");
|
|
753
|
+
Logger.Log(this._fragmentCompilationState.compilationString);
|
|
754
|
+
}
|
|
755
|
+
// Errors
|
|
756
|
+
const noError = this._sharedData.emitErrors();
|
|
757
|
+
this._buildIsInProgress = false;
|
|
758
|
+
if (noError) {
|
|
759
|
+
this._buildWasSuccessful = true;
|
|
760
|
+
this.onBuildObservable.notifyObservers(this);
|
|
761
|
+
}
|
|
762
|
+
// Wipe defines
|
|
763
|
+
const meshes = this.getScene().meshes;
|
|
764
|
+
for (const mesh of meshes) {
|
|
765
|
+
if (!mesh.subMeshes) {
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
for (const subMesh of mesh.subMeshes) {
|
|
769
|
+
if (subMesh.getMaterial() !== this) {
|
|
770
|
+
continue;
|
|
771
|
+
}
|
|
772
|
+
if (!subMesh.materialDefines) {
|
|
773
|
+
continue;
|
|
774
|
+
}
|
|
775
|
+
const defines = subMesh.materialDefines;
|
|
776
|
+
defines.markAllAsDirty();
|
|
777
|
+
defines.reset();
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (this.prePassTextureInputs.length) {
|
|
781
|
+
this.getScene().enablePrePassRenderer();
|
|
782
|
+
}
|
|
783
|
+
const prePassRenderer = this.getScene().prePassRenderer;
|
|
784
|
+
if (prePassRenderer) {
|
|
785
|
+
prePassRenderer.markAsDirty();
|
|
786
|
+
}
|
|
860
787
|
}
|
|
861
|
-
|
|
862
|
-
|
|
788
|
+
/**
|
|
789
|
+
* Runs an optimization phase to try to improve the shader code
|
|
790
|
+
*/
|
|
791
|
+
optimize() {
|
|
792
|
+
for (const optimizer of this._optimizers) {
|
|
793
|
+
optimizer.optimize(this._vertexOutputNodes, this._fragmentOutputNodes);
|
|
794
|
+
}
|
|
863
795
|
}
|
|
864
|
-
|
|
865
|
-
|
|
796
|
+
_prepareDefinesForAttributes(mesh, defines) {
|
|
797
|
+
const oldNormal = defines["NORMAL"];
|
|
798
|
+
const oldTangent = defines["TANGENT"];
|
|
799
|
+
const oldColor = defines["VERTEXCOLOR_NME"];
|
|
800
|
+
defines["NORMAL"] = mesh.isVerticesDataPresent(VertexBuffer.NormalKind);
|
|
801
|
+
defines["TANGENT"] = mesh.isVerticesDataPresent(VertexBuffer.TangentKind);
|
|
802
|
+
const hasVertexColors = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);
|
|
803
|
+
defines["VERTEXCOLOR_NME"] = hasVertexColors;
|
|
804
|
+
let uvChanged = false;
|
|
805
|
+
for (let i = 1; i <= 6; ++i) {
|
|
806
|
+
const oldUV = defines["UV" + i];
|
|
807
|
+
defines["UV" + i] = mesh.isVerticesDataPresent(`uv${i === 1 ? "" : i}`);
|
|
808
|
+
uvChanged = uvChanged || defines["UV" + i] !== oldUV;
|
|
809
|
+
}
|
|
810
|
+
// PrePass
|
|
811
|
+
const oit = this.needAlphaBlendingForMesh(mesh) && this.getScene().useOrderIndependentTransparency;
|
|
812
|
+
PrepareDefinesForPrePass(this.getScene(), defines, !oit);
|
|
813
|
+
MaterialHelperGeometryRendering.PrepareDefines(this.getScene().getEngine().currentRenderPassId, mesh, defines);
|
|
814
|
+
if (oldNormal !== defines["NORMAL"] || oldTangent !== defines["TANGENT"] || oldColor !== defines["VERTEXCOLOR_NME"] || uvChanged) {
|
|
815
|
+
defines.markAsAttributesDirty();
|
|
816
|
+
}
|
|
866
817
|
}
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
* @param prePassRenderer defines the prepass renderer to set
|
|
873
|
-
* @returns true if the pre pass is needed
|
|
874
|
-
*/
|
|
875
|
-
setPrePassRenderer(prePassRenderer) {
|
|
876
|
-
const prePassTexturesRequired = this.prePassTextureInputs.concat(this.prePassTextureOutputs);
|
|
877
|
-
if (prePassRenderer && prePassTexturesRequired.length > 1) {
|
|
878
|
-
let cfg = prePassRenderer.getEffectConfiguration("nodeMaterial");
|
|
879
|
-
if (!cfg) {
|
|
880
|
-
cfg = prePassRenderer.addEffectConfiguration({
|
|
881
|
-
enabled: true,
|
|
882
|
-
needsImageProcessing: false,
|
|
883
|
-
name: "nodeMaterial",
|
|
884
|
-
texturesRequired: [],
|
|
885
|
-
});
|
|
818
|
+
/**
|
|
819
|
+
* Can this material render to prepass
|
|
820
|
+
*/
|
|
821
|
+
get isPrePassCapable() {
|
|
822
|
+
return true;
|
|
886
823
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
824
|
+
/**
|
|
825
|
+
* Outputs written to the prepass
|
|
826
|
+
*/
|
|
827
|
+
get prePassTextureOutputs() {
|
|
828
|
+
const prePassOutputBlock = this.getBlockByPredicate((block) => block.getClassName() === "PrePassOutputBlock");
|
|
829
|
+
const result = [4];
|
|
830
|
+
if (!prePassOutputBlock) {
|
|
831
|
+
return result;
|
|
832
|
+
}
|
|
833
|
+
// Cannot write to prepass if we alread read from prepass
|
|
834
|
+
if (this.prePassTextureInputs.length) {
|
|
835
|
+
return result;
|
|
836
|
+
}
|
|
837
|
+
if (prePassOutputBlock.viewDepth.isConnected) {
|
|
838
|
+
result.push(5);
|
|
839
|
+
}
|
|
840
|
+
if (prePassOutputBlock.screenDepth.isConnected) {
|
|
841
|
+
result.push(10);
|
|
842
|
+
}
|
|
843
|
+
if (prePassOutputBlock.viewNormal.isConnected) {
|
|
844
|
+
result.push(6);
|
|
845
|
+
}
|
|
846
|
+
if (prePassOutputBlock.worldNormal.isConnected) {
|
|
847
|
+
result.push(8);
|
|
848
|
+
}
|
|
849
|
+
if (prePassOutputBlock.worldPosition.isConnected) {
|
|
850
|
+
result.push(1);
|
|
851
|
+
}
|
|
852
|
+
if (prePassOutputBlock.localPosition.isConnected) {
|
|
853
|
+
result.push(9);
|
|
854
|
+
}
|
|
855
|
+
if (prePassOutputBlock.reflectivity.isConnected) {
|
|
856
|
+
result.push(3);
|
|
857
|
+
}
|
|
858
|
+
if (prePassOutputBlock.velocity.isConnected) {
|
|
859
|
+
result.push(2);
|
|
860
|
+
}
|
|
861
|
+
if (prePassOutputBlock.velocityLinear.isConnected) {
|
|
862
|
+
result.push(11);
|
|
863
|
+
}
|
|
864
|
+
return result;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Gets the list of prepass texture required
|
|
868
|
+
*/
|
|
869
|
+
get prePassTextureInputs() {
|
|
870
|
+
const prePassTextureBlocks = this.getAllTextureBlocks().filter((block) => block.getClassName() === "PrePassTextureBlock");
|
|
871
|
+
const result = [];
|
|
872
|
+
for (const block of prePassTextureBlocks) {
|
|
873
|
+
if (block.position.isConnected && !result.includes(1)) {
|
|
874
|
+
result.push(1);
|
|
875
|
+
}
|
|
876
|
+
if (block.localPosition.isConnected && !result.includes(9)) {
|
|
877
|
+
result.push(9);
|
|
878
|
+
}
|
|
879
|
+
if (block.depth.isConnected && !result.includes(5)) {
|
|
880
|
+
result.push(5);
|
|
881
|
+
}
|
|
882
|
+
if (block.screenDepth.isConnected && !result.includes(10)) {
|
|
883
|
+
result.push(10);
|
|
884
|
+
}
|
|
885
|
+
if (block.normal.isConnected && !result.includes(6)) {
|
|
886
|
+
result.push(6);
|
|
887
|
+
}
|
|
888
|
+
if (block.worldNormal.isConnected && !result.includes(8)) {
|
|
889
|
+
result.push(8);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
return result;
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Sets the required values to the prepass renderer.
|
|
896
|
+
* @param prePassRenderer defines the prepass renderer to set
|
|
897
|
+
* @returns true if the pre pass is needed
|
|
898
|
+
*/
|
|
899
|
+
setPrePassRenderer(prePassRenderer) {
|
|
900
|
+
const prePassTexturesRequired = this.prePassTextureInputs.concat(this.prePassTextureOutputs);
|
|
901
|
+
if (prePassRenderer && prePassTexturesRequired.length > 1) {
|
|
902
|
+
let cfg = prePassRenderer.getEffectConfiguration("nodeMaterial");
|
|
903
|
+
if (!cfg) {
|
|
904
|
+
cfg = prePassRenderer.addEffectConfiguration({
|
|
905
|
+
enabled: true,
|
|
906
|
+
needsImageProcessing: false,
|
|
907
|
+
name: "nodeMaterial",
|
|
908
|
+
texturesRequired: [],
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
for (const prePassTexture of prePassTexturesRequired) {
|
|
912
|
+
if (!cfg.texturesRequired.includes(prePassTexture)) {
|
|
913
|
+
cfg.texturesRequired.push(prePassTexture);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
cfg.enabled = true;
|
|
917
|
+
}
|
|
918
|
+
// COLOR_TEXTURE is always required for prepass, length > 1 means
|
|
919
|
+
// we actually need to write to special prepass textures
|
|
920
|
+
return prePassTexturesRequired.length > 1;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Create a post process from the material
|
|
924
|
+
* @param camera The camera to apply the render pass to.
|
|
925
|
+
* @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
|
|
926
|
+
* @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
|
|
927
|
+
* @param engine The engine which the post process will be applied. (default: current engine)
|
|
928
|
+
* @param reusable If the post process can be reused on the same frame. (default: false)
|
|
929
|
+
* @param textureType Type of textures used when performing the post process. (default: 0)
|
|
930
|
+
* @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)
|
|
931
|
+
* @returns the post process created
|
|
932
|
+
*/
|
|
933
|
+
createPostProcess(camera, options = 1, samplingMode = 1, engine, reusable, textureType = 0, textureFormat = 5) {
|
|
934
|
+
if (this.mode !== NodeMaterialModes.PostProcess && this.mode !== NodeMaterialModes.SFE) {
|
|
935
|
+
Logger.Log("Incompatible material mode");
|
|
936
|
+
return null;
|
|
937
|
+
}
|
|
938
|
+
return this._createEffectForPostProcess(null, camera, options, samplingMode, engine, reusable, textureType, textureFormat);
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Create the post process effect from the material
|
|
942
|
+
* @param postProcess The post process to create the effect for
|
|
943
|
+
*/
|
|
944
|
+
createEffectForPostProcess(postProcess) {
|
|
945
|
+
this._createEffectForPostProcess(postProcess);
|
|
946
|
+
}
|
|
947
|
+
_createEffectForPostProcess(postProcess, camera, options = 1, samplingMode = 1, engine, reusable, textureType = 0, textureFormat = 5) {
|
|
948
|
+
// The post process effect is built from the shader code produced by the node graph. That code
|
|
949
|
+
// is only available once the build has completed. Some blocks (e.g. CurrentScreenBlock) load
|
|
950
|
+
// their shader sources asynchronously, so the build may still be running when this is called
|
|
951
|
+
// (for instance right after a synchronous NodeMaterial.Parse). Registering the still empty
|
|
952
|
+
// shaders would make the engine try to fetch them from a URL and fail with a 404, leaving the
|
|
953
|
+
// post process blank. Defer the effect creation until the build has completed.
|
|
954
|
+
if (!this._buildWasSuccessful) {
|
|
955
|
+
if (!postProcess) {
|
|
956
|
+
// Create the handle now with compilation blocked so callers can attach their observers;
|
|
957
|
+
// the actual effect is created once the build completes.
|
|
958
|
+
postProcess = new PostProcess(this.name + "PostProcess", "postprocess", null, null, options, camera, samplingMode, engine, reusable, null, textureType, "postprocess", undefined, true, textureFormat, this.shaderLanguage);
|
|
959
|
+
postProcess.nodeMaterialSource = this;
|
|
960
|
+
}
|
|
961
|
+
const deferredPostProcess = postProcess;
|
|
962
|
+
this.onBuildObservable.addOnce(() => {
|
|
963
|
+
this._createEffectForPostProcess(deferredPostProcess, camera, options, samplingMode, engine, reusable, textureType, textureFormat);
|
|
964
|
+
});
|
|
965
|
+
if (!this._buildIsInProgress) {
|
|
966
|
+
this.build();
|
|
967
|
+
}
|
|
968
|
+
return postProcess;
|
|
969
|
+
}
|
|
970
|
+
let tempName = this.name + this._buildId;
|
|
971
|
+
const defines = new NodeMaterialDefines();
|
|
972
|
+
let buildId = this._buildId;
|
|
973
|
+
this._processDefines(defines);
|
|
974
|
+
// If no vertex shader emitted, fallback to default postprocess vertex shader
|
|
975
|
+
const vertexCode = this._sharedData.checks.emitVertex ? this._vertexCompilationState._builtCompilationString : undefined;
|
|
976
|
+
Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, vertexCode, this.shaderLanguage);
|
|
977
|
+
if (!postProcess) {
|
|
978
|
+
postProcess = new PostProcess(this.name + "PostProcess", tempName, this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, options, camera, samplingMode, engine, reusable, defines.toString(), textureType, vertexCode ? tempName : "postprocess", { maxSimultaneousLights: this.maxSimultaneousLights }, false, textureFormat, this.shaderLanguage);
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
postProcess.updateEffect(defines.toString(), this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, { maxSimultaneousLights: this.maxSimultaneousLights }, undefined, undefined, vertexCode ? tempName : "postprocess", tempName);
|
|
890
982
|
}
|
|
891
|
-
}
|
|
892
|
-
cfg.enabled = true;
|
|
893
|
-
}
|
|
894
|
-
// COLOR_TEXTURE is always required for prepass, length > 1 means
|
|
895
|
-
// we actually need to write to special prepass textures
|
|
896
|
-
return prePassTexturesRequired.length > 1;
|
|
897
|
-
}
|
|
898
|
-
/**
|
|
899
|
-
* Create a post process from the material
|
|
900
|
-
* @param camera The camera to apply the render pass to.
|
|
901
|
-
* @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
|
|
902
|
-
* @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
|
|
903
|
-
* @param engine The engine which the post process will be applied. (default: current engine)
|
|
904
|
-
* @param reusable If the post process can be reused on the same frame. (default: false)
|
|
905
|
-
* @param textureType Type of textures used when performing the post process. (default: 0)
|
|
906
|
-
* @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)
|
|
907
|
-
* @returns the post process created
|
|
908
|
-
*/
|
|
909
|
-
createPostProcess(camera, options = 1, samplingMode = 1, engine, reusable, textureType = 0, textureFormat = 5) {
|
|
910
|
-
if (this.mode !== NodeMaterialModes.PostProcess && this.mode !== NodeMaterialModes.SFE) {
|
|
911
|
-
Logger.Log("Incompatible material mode");
|
|
912
|
-
return null;
|
|
913
|
-
}
|
|
914
|
-
return this._createEffectForPostProcess(null, camera, options, samplingMode, engine, reusable, textureType, textureFormat);
|
|
915
|
-
}
|
|
916
|
-
/**
|
|
917
|
-
* Create the post process effect from the material
|
|
918
|
-
* @param postProcess The post process to create the effect for
|
|
919
|
-
*/
|
|
920
|
-
createEffectForPostProcess(postProcess) {
|
|
921
|
-
this._createEffectForPostProcess(postProcess);
|
|
922
|
-
}
|
|
923
|
-
_createEffectForPostProcess(postProcess, camera, options = 1, samplingMode = 1, engine, reusable, textureType = 0, textureFormat = 5) {
|
|
924
|
-
// The post process effect is built from the shader code produced by the node graph. That code
|
|
925
|
-
// is only available once the build has completed. Some blocks (e.g. CurrentScreenBlock) load
|
|
926
|
-
// their shader sources asynchronously, so the build may still be running when this is called
|
|
927
|
-
// (for instance right after a synchronous NodeMaterial.Parse). Registering the still empty
|
|
928
|
-
// shaders would make the engine try to fetch them from a URL and fail with a 404, leaving the
|
|
929
|
-
// post process blank. Defer the effect creation until the build has completed.
|
|
930
|
-
if (!this._buildWasSuccessful) {
|
|
931
|
-
if (!postProcess) {
|
|
932
|
-
// Create the handle now with compilation blocked so callers can attach their observers;
|
|
933
|
-
// the actual effect is created once the build completes.
|
|
934
|
-
postProcess = new PostProcess(this.name + "PostProcess", "postprocess", null, null, options, camera, samplingMode, engine, reusable, null, textureType, "postprocess", undefined, true, textureFormat, this.shaderLanguage);
|
|
935
983
|
postProcess.nodeMaterialSource = this;
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
if (buildId !== this._buildId) {
|
|
999
|
-
delete Effect.ShadersStore[tempName + "VertexShader"];
|
|
1000
|
-
delete Effect.ShadersStore[tempName + "PixelShader"];
|
|
1001
|
-
tempName = this.name + this._buildId;
|
|
1002
|
-
defines.markAllAsDirty();
|
|
1003
|
-
buildId = this._buildId;
|
|
1004
|
-
}
|
|
1005
|
-
const result = this._processDefines(defines);
|
|
1006
|
-
if (result) {
|
|
1007
|
-
Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, this._vertexCompilationState._builtCompilationString, this.shaderLanguage);
|
|
1008
|
-
TimingTools.SetImmediate(() => {
|
|
1009
|
-
// The material may have been disposed before this deferred effect creation runs.
|
|
1010
|
-
if (!this._fragmentCompilationState) {
|
|
1011
|
-
return;
|
|
984
|
+
postProcess.onApplyObservable.add((effect) => {
|
|
985
|
+
if (buildId !== this._buildId) {
|
|
986
|
+
delete Effect.ShadersStore[tempName + "VertexShader"];
|
|
987
|
+
delete Effect.ShadersStore[tempName + "PixelShader"];
|
|
988
|
+
tempName = this.name + this._buildId;
|
|
989
|
+
defines.markAllAsDirty();
|
|
990
|
+
buildId = this._buildId;
|
|
991
|
+
}
|
|
992
|
+
const result = this._processDefines(defines);
|
|
993
|
+
if (result) {
|
|
994
|
+
// Recompute the vertex emission for the current build (the graph may have been rebuilt),
|
|
995
|
+
// and register with the material's shader language so WGSL post processes use the WGSL store.
|
|
996
|
+
const currentVertexCode = this._sharedData.checks.emitVertex ? this._vertexCompilationState._builtCompilationString : undefined;
|
|
997
|
+
Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, currentVertexCode, this.shaderLanguage);
|
|
998
|
+
TimingTools.SetImmediate(() => postProcess.updateEffect(defines.toString(), this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, { maxSimultaneousLights: this.maxSimultaneousLights }, undefined, undefined, currentVertexCode ? tempName : "postprocess", tempName));
|
|
999
|
+
}
|
|
1000
|
+
this._checkInternals(effect);
|
|
1001
|
+
});
|
|
1002
|
+
return postProcess;
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Create a new procedural texture based on this node material
|
|
1006
|
+
* @param size defines the size of the texture
|
|
1007
|
+
* @param scene defines the hosting scene
|
|
1008
|
+
* @returns the new procedural texture attached to this node material
|
|
1009
|
+
*/
|
|
1010
|
+
createProceduralTexture(size, scene) {
|
|
1011
|
+
if (this.mode !== NodeMaterialModes.ProceduralTexture) {
|
|
1012
|
+
Logger.Log("Incompatible material mode");
|
|
1013
|
+
return null;
|
|
1014
|
+
}
|
|
1015
|
+
let tempName = this.name + this._buildId;
|
|
1016
|
+
const proceduralTexture = new ProceduralTexture(tempName, size, null, scene);
|
|
1017
|
+
proceduralTexture.nodeMaterialSource = this;
|
|
1018
|
+
const defines = new NodeMaterialDefines();
|
|
1019
|
+
let buildId = this._buildId;
|
|
1020
|
+
let effect;
|
|
1021
|
+
const refreshEffect = () => {
|
|
1022
|
+
if (buildId !== this._buildId) {
|
|
1023
|
+
delete Effect.ShadersStore[tempName + "VertexShader"];
|
|
1024
|
+
delete Effect.ShadersStore[tempName + "PixelShader"];
|
|
1025
|
+
tempName = this.name + this._buildId;
|
|
1026
|
+
defines.markAllAsDirty();
|
|
1027
|
+
buildId = this._buildId;
|
|
1028
|
+
}
|
|
1029
|
+
const result = this._processDefines(defines);
|
|
1030
|
+
if (result) {
|
|
1031
|
+
Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, this._vertexCompilationState._builtCompilationString, this.shaderLanguage);
|
|
1032
|
+
TimingTools.SetImmediate(() => {
|
|
1033
|
+
// The material may have been disposed before this deferred effect creation runs.
|
|
1034
|
+
if (!this._fragmentCompilationState) {
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
effect = this.getScene().getEngine().createEffect({
|
|
1038
|
+
vertexElement: tempName,
|
|
1039
|
+
fragmentElement: tempName,
|
|
1040
|
+
}, [VertexBuffer.PositionKind], this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, defines.toString(), result?.fallbacks, undefined, undefined, undefined, this.shaderLanguage);
|
|
1041
|
+
proceduralTexture._setEffect(effect);
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
if (effect) {
|
|
1045
|
+
this._checkInternals(effect);
|
|
1012
1046
|
}
|
|
1047
|
+
};
|
|
1048
|
+
proceduralTexture.onBeforeGenerationObservable.add(() => {
|
|
1049
|
+
refreshEffect();
|
|
1050
|
+
});
|
|
1051
|
+
// This is needed if the procedural texture is not set to refresh automatically
|
|
1052
|
+
this.onBuildObservable.add(() => {
|
|
1053
|
+
refreshEffect();
|
|
1054
|
+
});
|
|
1055
|
+
// The effect is built from the shader code produced by the node graph, which is only available
|
|
1056
|
+
// once the build has completed. Some blocks (e.g. CurrentScreenBlock) load their shader sources
|
|
1057
|
+
// asynchronously, so the build may still be running here (for instance right after a synchronous
|
|
1058
|
+
// NodeMaterial.Parse). Creating the effect now would register empty shaders and make the engine
|
|
1059
|
+
// fetch them from a URL, failing with a 404. Only create the effect once the build has
|
|
1060
|
+
// succeeded; otherwise the onBuildObservable hook above creates it when the build completes.
|
|
1061
|
+
if (this._buildWasSuccessful) {
|
|
1062
|
+
const result = this._processDefines(defines);
|
|
1063
|
+
Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, this._vertexCompilationState._builtCompilationString, this.shaderLanguage);
|
|
1013
1064
|
effect = this.getScene().getEngine().createEffect({
|
|
1014
1065
|
vertexElement: tempName,
|
|
1015
1066
|
fragmentElement: tempName,
|
|
1016
1067
|
}, [VertexBuffer.PositionKind], this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, defines.toString(), result?.fallbacks, undefined, undefined, undefined, this.shaderLanguage);
|
|
1017
1068
|
proceduralTexture._setEffect(effect);
|
|
1018
|
-
}
|
|
1069
|
+
}
|
|
1070
|
+
else if (!this._buildIsInProgress) {
|
|
1071
|
+
this.build();
|
|
1072
|
+
}
|
|
1073
|
+
return proceduralTexture;
|
|
1019
1074
|
}
|
|
1020
|
-
|
|
1021
|
-
this.
|
|
1075
|
+
_createEffectForParticles(particleSystem, blendMode, onCompiled, onError, effect, defines, particleSystemDefinesJoined = "") {
|
|
1076
|
+
let tempName = this.name + this._buildId + "_" + blendMode;
|
|
1077
|
+
if (!defines) {
|
|
1078
|
+
defines = new NodeMaterialDefines();
|
|
1079
|
+
}
|
|
1080
|
+
let buildId = this._buildId;
|
|
1081
|
+
const particleSystemDefines = [];
|
|
1082
|
+
let join = particleSystemDefinesJoined;
|
|
1083
|
+
if (!effect) {
|
|
1084
|
+
const result = this._processDefines(defines);
|
|
1085
|
+
Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, undefined, this.shaderLanguage);
|
|
1086
|
+
particleSystem.fillDefines(particleSystemDefines, blendMode, false);
|
|
1087
|
+
join = particleSystemDefines.join("\n");
|
|
1088
|
+
effect = this.getScene()
|
|
1089
|
+
.getEngine()
|
|
1090
|
+
.createEffectForParticles(tempName, this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, defines.toString() + "\n" + join, result?.fallbacks, onCompiled, onError, particleSystem, this.shaderLanguage);
|
|
1091
|
+
particleSystem.setCustomEffect(effect, blendMode);
|
|
1092
|
+
}
|
|
1093
|
+
effect.onBindObservable.add((effect) => {
|
|
1094
|
+
if (buildId !== this._buildId) {
|
|
1095
|
+
delete Effect.ShadersStore[tempName + "PixelShader"];
|
|
1096
|
+
tempName = this.name + this._buildId + "_" + blendMode;
|
|
1097
|
+
defines.markAllAsDirty();
|
|
1098
|
+
buildId = this._buildId;
|
|
1099
|
+
}
|
|
1100
|
+
particleSystemDefines.length = 0;
|
|
1101
|
+
particleSystem.fillDefines(particleSystemDefines, blendMode, false);
|
|
1102
|
+
const particleSystemDefinesJoinedCurrent = particleSystemDefines.join("\n");
|
|
1103
|
+
if (particleSystemDefinesJoinedCurrent !== join) {
|
|
1104
|
+
defines.markAllAsDirty();
|
|
1105
|
+
join = particleSystemDefinesJoinedCurrent;
|
|
1106
|
+
}
|
|
1107
|
+
const result = this._processDefines(defines);
|
|
1108
|
+
if (result) {
|
|
1109
|
+
Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, undefined, this.shaderLanguage);
|
|
1110
|
+
effect = this.getScene()
|
|
1111
|
+
.getEngine()
|
|
1112
|
+
.createEffectForParticles(tempName, this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, defines.toString() + "\n" + join, result?.fallbacks, onCompiled, onError, particleSystem);
|
|
1113
|
+
particleSystem.setCustomEffect(effect, blendMode);
|
|
1114
|
+
this._createEffectForParticles(particleSystem, blendMode, onCompiled, onError, effect, defines, particleSystemDefinesJoined); // add the effect.onBindObservable observer
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
this._checkInternals(effect);
|
|
1118
|
+
});
|
|
1022
1119
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
fragmentElement: tempName,
|
|
1043
|
-
}, [VertexBuffer.PositionKind], this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, defines.toString(), result?.fallbacks, undefined, undefined, undefined, this.shaderLanguage);
|
|
1044
|
-
proceduralTexture._setEffect(effect);
|
|
1045
|
-
}
|
|
1046
|
-
else if (!this._buildIsInProgress) {
|
|
1047
|
-
this.build();
|
|
1048
|
-
}
|
|
1049
|
-
return proceduralTexture;
|
|
1050
|
-
}
|
|
1051
|
-
_createEffectForParticles(particleSystem, blendMode, onCompiled, onError, effect, defines, particleSystemDefinesJoined = "") {
|
|
1052
|
-
let tempName = this.name + this._buildId + "_" + blendMode;
|
|
1053
|
-
if (!defines) {
|
|
1054
|
-
defines = new NodeMaterialDefines();
|
|
1055
|
-
}
|
|
1056
|
-
let buildId = this._buildId;
|
|
1057
|
-
const particleSystemDefines = [];
|
|
1058
|
-
let join = particleSystemDefinesJoined;
|
|
1059
|
-
if (!effect) {
|
|
1060
|
-
const result = this._processDefines(defines);
|
|
1061
|
-
Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, undefined, this.shaderLanguage);
|
|
1062
|
-
particleSystem.fillDefines(particleSystemDefines, blendMode, false);
|
|
1063
|
-
join = particleSystemDefines.join("\n");
|
|
1064
|
-
effect = this.getScene()
|
|
1065
|
-
.getEngine()
|
|
1066
|
-
.createEffectForParticles(tempName, this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, defines.toString() + "\n" + join, result?.fallbacks, onCompiled, onError, particleSystem, this.shaderLanguage);
|
|
1067
|
-
particleSystem.setCustomEffect(effect, blendMode);
|
|
1068
|
-
}
|
|
1069
|
-
effect.onBindObservable.add((effect) => {
|
|
1070
|
-
if (buildId !== this._buildId) {
|
|
1071
|
-
delete Effect.ShadersStore[tempName + "PixelShader"];
|
|
1072
|
-
tempName = this.name + this._buildId + "_" + blendMode;
|
|
1073
|
-
defines.markAllAsDirty();
|
|
1074
|
-
buildId = this._buildId;
|
|
1075
|
-
}
|
|
1076
|
-
particleSystemDefines.length = 0;
|
|
1077
|
-
particleSystem.fillDefines(particleSystemDefines, blendMode, false);
|
|
1078
|
-
const particleSystemDefinesJoinedCurrent = particleSystemDefines.join("\n");
|
|
1079
|
-
if (particleSystemDefinesJoinedCurrent !== join) {
|
|
1080
|
-
defines.markAllAsDirty();
|
|
1081
|
-
join = particleSystemDefinesJoinedCurrent;
|
|
1082
|
-
}
|
|
1083
|
-
const result = this._processDefines(defines);
|
|
1084
|
-
if (result) {
|
|
1085
|
-
Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, undefined, this.shaderLanguage);
|
|
1086
|
-
effect = this.getScene()
|
|
1087
|
-
.getEngine()
|
|
1088
|
-
.createEffectForParticles(tempName, this._fragmentCompilationState.uniforms, this._fragmentCompilationState.samplers, defines.toString() + "\n" + join, result?.fallbacks, onCompiled, onError, particleSystem);
|
|
1089
|
-
particleSystem.setCustomEffect(effect, blendMode);
|
|
1090
|
-
this._createEffectForParticles(particleSystem, blendMode, onCompiled, onError, effect, defines, particleSystemDefinesJoined); // add the effect.onBindObservable observer
|
|
1091
|
-
return;
|
|
1092
|
-
}
|
|
1093
|
-
this._checkInternals(effect);
|
|
1094
|
-
});
|
|
1095
|
-
}
|
|
1096
|
-
_checkInternals(effect) {
|
|
1097
|
-
// Animated blocks
|
|
1098
|
-
if (this._sharedData.animatedInputs) {
|
|
1099
|
-
const scene = this.getScene();
|
|
1100
|
-
const frameId = scene.getFrameId();
|
|
1101
|
-
if (this._animationFrame !== frameId) {
|
|
1102
|
-
for (const input of this._sharedData.animatedInputs) {
|
|
1103
|
-
input.animate(scene);
|
|
1120
|
+
_checkInternals(effect) {
|
|
1121
|
+
// Animated blocks
|
|
1122
|
+
if (this._sharedData.animatedInputs) {
|
|
1123
|
+
const scene = this.getScene();
|
|
1124
|
+
const frameId = scene.getFrameId();
|
|
1125
|
+
if (this._animationFrame !== frameId) {
|
|
1126
|
+
for (const input of this._sharedData.animatedInputs) {
|
|
1127
|
+
input.animate(scene);
|
|
1128
|
+
}
|
|
1129
|
+
this._animationFrame = frameId;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
// Bindable blocks
|
|
1133
|
+
for (const block of this._sharedData.bindableBlocks) {
|
|
1134
|
+
block.bind(effect, this);
|
|
1135
|
+
}
|
|
1136
|
+
// Connection points
|
|
1137
|
+
for (const inputBlock of this._sharedData.inputBlocks) {
|
|
1138
|
+
inputBlock._transmit(effect, this.getScene(), this);
|
|
1104
1139
|
}
|
|
1105
|
-
this._animationFrame = frameId;
|
|
1106
1140
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1141
|
+
/**
|
|
1142
|
+
* Create the effect to be used as the custom effect for a particle system
|
|
1143
|
+
* @param particleSystem Particle system to create the effect for
|
|
1144
|
+
* @param onCompiled defines a function to call when the effect creation is successful
|
|
1145
|
+
* @param onError defines a function to call when the effect creation has failed
|
|
1146
|
+
*/
|
|
1147
|
+
createEffectForParticles(particleSystem, onCompiled, onError) {
|
|
1148
|
+
if (this.mode !== NodeMaterialModes.Particle) {
|
|
1149
|
+
Logger.Log("Incompatible material mode");
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
this._createEffectForParticles(particleSystem, BaseParticleSystem.BLENDMODE_ONEONE, onCompiled, onError);
|
|
1153
|
+
this._createEffectForParticles(particleSystem, BaseParticleSystem.BLENDMODE_MULTIPLY, onCompiled, onError);
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* Use this material as the shadow depth wrapper of a target material
|
|
1157
|
+
* @param targetMaterial defines the target material
|
|
1158
|
+
*/
|
|
1159
|
+
createAsShadowDepthWrapper(targetMaterial) {
|
|
1160
|
+
if (this.mode !== NodeMaterialModes.Material) {
|
|
1161
|
+
Logger.Log("Incompatible material mode");
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
targetMaterial.shadowDepthWrapper = new BABYLON.ShadowDepthWrapper(this, this.getScene());
|
|
1165
|
+
}
|
|
1166
|
+
_processDefines(defines, mesh, useInstances = false, subMesh) {
|
|
1167
|
+
let result = null;
|
|
1168
|
+
// Global defines
|
|
1169
|
+
const scene = this.getScene();
|
|
1170
|
+
if (PrepareDefinesForCamera(scene, defines)) {
|
|
1171
|
+
defines.markAsMiscDirty();
|
|
1172
|
+
}
|
|
1173
|
+
// Shared defines
|
|
1174
|
+
for (const b of this._sharedData.blocksWithDefines) {
|
|
1175
|
+
b.initializeDefines(defines);
|
|
1176
|
+
}
|
|
1177
|
+
for (const b of this._sharedData.blocksWithDefines) {
|
|
1178
|
+
b.prepareDefines(defines, this, mesh, useInstances, subMesh);
|
|
1179
|
+
}
|
|
1180
|
+
for (const d in this._sharedData.defines) {
|
|
1181
|
+
defines[d] = this._sharedData.defines[d];
|
|
1182
|
+
}
|
|
1183
|
+
// Need to recompile?
|
|
1184
|
+
if (defines.isDirty) {
|
|
1185
|
+
const lightDisposed = defines._areLightsDisposed;
|
|
1186
|
+
defines.markAsProcessed();
|
|
1187
|
+
// Repeatable content generators
|
|
1188
|
+
this._vertexCompilationState.compilationString = this._vertexCompilationState._builtCompilationString;
|
|
1189
|
+
this._fragmentCompilationState.compilationString = this._fragmentCompilationState._builtCompilationString;
|
|
1190
|
+
for (const b of this._sharedData.repeatableContentBlocks) {
|
|
1191
|
+
b.replaceRepeatableContent(this._vertexCompilationState, defines, mesh);
|
|
1192
|
+
}
|
|
1193
|
+
// Uniforms
|
|
1194
|
+
const uniformBuffers = [];
|
|
1195
|
+
for (const b of this._sharedData.dynamicUniformBlocks) {
|
|
1196
|
+
b.updateUniformsAndSamples(this._vertexCompilationState, this, defines, uniformBuffers);
|
|
1197
|
+
}
|
|
1198
|
+
const mergedUniforms = this._vertexCompilationState.uniforms;
|
|
1199
|
+
for (const u of this._fragmentCompilationState.uniforms) {
|
|
1200
|
+
const index = mergedUniforms.indexOf(u);
|
|
1201
|
+
if (index === -1) {
|
|
1202
|
+
mergedUniforms.push(u);
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
// Samplers
|
|
1206
|
+
const mergedSamplers = this._vertexCompilationState.samplers;
|
|
1207
|
+
for (const s of this._fragmentCompilationState.samplers) {
|
|
1208
|
+
const index = mergedSamplers.indexOf(s);
|
|
1209
|
+
if (index === -1) {
|
|
1210
|
+
mergedSamplers.push(s);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
const fallbacks = new EffectFallbacks();
|
|
1214
|
+
for (const b of this._sharedData.blocksWithFallbacks) {
|
|
1215
|
+
b.provideFallbacks(fallbacks, mesh);
|
|
1216
|
+
}
|
|
1217
|
+
result = {
|
|
1218
|
+
lightDisposed,
|
|
1219
|
+
uniformBuffers,
|
|
1220
|
+
mergedUniforms,
|
|
1221
|
+
mergedSamplers,
|
|
1222
|
+
fallbacks,
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
return result;
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Get if the submesh is ready to be used and all its information available.
|
|
1229
|
+
* Child classes can use it to update shaders
|
|
1230
|
+
* @param mesh defines the mesh to check
|
|
1231
|
+
* @param subMesh defines which submesh to check
|
|
1232
|
+
* @param useInstances specifies that instances should be used
|
|
1233
|
+
* @returns a boolean indicating that the submesh is ready or not
|
|
1234
|
+
*/
|
|
1235
|
+
isReadyForSubMesh(mesh, subMesh, useInstances = false) {
|
|
1236
|
+
if (!this._buildWasSuccessful) {
|
|
1237
|
+
return false;
|
|
1238
|
+
}
|
|
1239
|
+
const scene = this.getScene();
|
|
1240
|
+
if (this._sharedData.animatedInputs) {
|
|
1241
|
+
const frameId = scene.getFrameId();
|
|
1242
|
+
if (this._animationFrame !== frameId) {
|
|
1243
|
+
for (const input of this._sharedData.animatedInputs) {
|
|
1244
|
+
input.animate(scene);
|
|
1245
|
+
}
|
|
1246
|
+
this._animationFrame = frameId;
|
|
1247
|
+
}
|
|
1179
1248
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
if (index === -1) {
|
|
1186
|
-
mergedSamplers.push(s);
|
|
1249
|
+
const drawWrapper = subMesh._drawWrapper;
|
|
1250
|
+
if (drawWrapper.effect && this.isFrozen) {
|
|
1251
|
+
if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {
|
|
1252
|
+
return true;
|
|
1253
|
+
}
|
|
1187
1254
|
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
for (const b of this._sharedData.blocksWithFallbacks) {
|
|
1191
|
-
b.provideFallbacks(fallbacks, mesh);
|
|
1192
|
-
}
|
|
1193
|
-
result = {
|
|
1194
|
-
lightDisposed,
|
|
1195
|
-
uniformBuffers,
|
|
1196
|
-
mergedUniforms,
|
|
1197
|
-
mergedSamplers,
|
|
1198
|
-
fallbacks,
|
|
1199
|
-
};
|
|
1200
|
-
}
|
|
1201
|
-
return result;
|
|
1202
|
-
}
|
|
1203
|
-
/**
|
|
1204
|
-
* Get if the submesh is ready to be used and all its information available.
|
|
1205
|
-
* Child classes can use it to update shaders
|
|
1206
|
-
* @param mesh defines the mesh to check
|
|
1207
|
-
* @param subMesh defines which submesh to check
|
|
1208
|
-
* @param useInstances specifies that instances should be used
|
|
1209
|
-
* @returns a boolean indicating that the submesh is ready or not
|
|
1210
|
-
*/
|
|
1211
|
-
isReadyForSubMesh(mesh, subMesh, useInstances = false) {
|
|
1212
|
-
if (!this._buildWasSuccessful) {
|
|
1213
|
-
return false;
|
|
1214
|
-
}
|
|
1215
|
-
const scene = this.getScene();
|
|
1216
|
-
if (this._sharedData.animatedInputs) {
|
|
1217
|
-
const frameId = scene.getFrameId();
|
|
1218
|
-
if (this._animationFrame !== frameId) {
|
|
1219
|
-
for (const input of this._sharedData.animatedInputs) {
|
|
1220
|
-
input.animate(scene);
|
|
1255
|
+
if (!subMesh.materialDefines) {
|
|
1256
|
+
subMesh.materialDefines = new NodeMaterialDefines();
|
|
1221
1257
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {
|
|
1278
|
-
defines.markAsUnprocessed();
|
|
1279
|
-
if (result.lightDisposed) {
|
|
1280
|
-
// re register in case it takes more than one frame.
|
|
1281
|
-
defines._areLightsDisposed = true;
|
|
1282
|
-
return false;
|
|
1258
|
+
const defines = subMesh.materialDefines;
|
|
1259
|
+
if (this._isReadyForSubMesh(subMesh)) {
|
|
1260
|
+
return true;
|
|
1261
|
+
}
|
|
1262
|
+
const engine = scene.getEngine();
|
|
1263
|
+
this._prepareDefinesForAttributes(mesh, defines);
|
|
1264
|
+
// Check if blocks are ready
|
|
1265
|
+
if (this._sharedData.blockingBlocks.some((b) => !b.isReady(mesh, this, defines, useInstances))) {
|
|
1266
|
+
return false;
|
|
1267
|
+
}
|
|
1268
|
+
if (!AreLightsTexturesReady(scene, mesh, this.maxSimultaneousLights)) {
|
|
1269
|
+
return false;
|
|
1270
|
+
}
|
|
1271
|
+
const result = this._processDefines(defines, mesh, useInstances, subMesh);
|
|
1272
|
+
if (result) {
|
|
1273
|
+
const previousEffect = subMesh.effect;
|
|
1274
|
+
// Compilation
|
|
1275
|
+
const join = defines.toString();
|
|
1276
|
+
const effect = engine.createEffect({
|
|
1277
|
+
vertex: "nodeMaterial" + this._buildId,
|
|
1278
|
+
fragment: "nodeMaterial" + this._buildId,
|
|
1279
|
+
vertexSource: this._vertexCompilationState.compilationString,
|
|
1280
|
+
fragmentSource: this._fragmentCompilationState.compilationString,
|
|
1281
|
+
}, {
|
|
1282
|
+
attributes: this._vertexCompilationState.attributes,
|
|
1283
|
+
uniformsNames: result.mergedUniforms,
|
|
1284
|
+
uniformBuffersNames: result.uniformBuffers,
|
|
1285
|
+
samplers: result.mergedSamplers,
|
|
1286
|
+
defines: join,
|
|
1287
|
+
fallbacks: result.fallbacks,
|
|
1288
|
+
onCompiled: this.onCompiled,
|
|
1289
|
+
onError: this.onError,
|
|
1290
|
+
multiTarget: defines.PREPASS,
|
|
1291
|
+
indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS },
|
|
1292
|
+
shaderLanguage: this.shaderLanguage,
|
|
1293
|
+
}, engine);
|
|
1294
|
+
if (effect) {
|
|
1295
|
+
if (this._onEffectCreatedObservable) {
|
|
1296
|
+
onCreatedEffectParameters.effect = effect;
|
|
1297
|
+
onCreatedEffectParameters.subMesh = subMesh;
|
|
1298
|
+
this._onEffectCreatedObservable.notifyObservers(onCreatedEffectParameters);
|
|
1299
|
+
}
|
|
1300
|
+
// Use previous effect while new one is compiling
|
|
1301
|
+
if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {
|
|
1302
|
+
defines.markAsUnprocessed();
|
|
1303
|
+
if (result.lightDisposed) {
|
|
1304
|
+
// re register in case it takes more than one frame.
|
|
1305
|
+
defines._areLightsDisposed = true;
|
|
1306
|
+
return false;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
else {
|
|
1310
|
+
scene.resetCachedMaterial();
|
|
1311
|
+
subMesh.setEffect(effect, defines, this._materialContext);
|
|
1312
|
+
}
|
|
1283
1313
|
}
|
|
1284
1314
|
}
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1315
|
+
// Check if lights are ready
|
|
1316
|
+
if (defines["AREALIGHTUSED"] || defines["CLUSTLIGHT_BATCH"]) {
|
|
1317
|
+
for (let index = 0; index < mesh.lightSources.length; index++) {
|
|
1318
|
+
if (!mesh.lightSources[index]._isReady()) {
|
|
1319
|
+
return false;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1288
1322
|
}
|
|
1289
|
-
|
|
1290
|
-
}
|
|
1291
|
-
// Check if lights are ready
|
|
1292
|
-
if (defines["AREALIGHTUSED"] || defines["CLUSTLIGHT_BATCH"]) {
|
|
1293
|
-
for (let index = 0; index < mesh.lightSources.length; index++) {
|
|
1294
|
-
if (!mesh.lightSources[index]._isReady()) {
|
|
1323
|
+
if (!subMesh.effect || !subMesh.effect.isReady()) {
|
|
1295
1324
|
return false;
|
|
1296
1325
|
}
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
}
|
|
1302
|
-
defines._renderId = scene.getRenderId();
|
|
1303
|
-
drawWrapper._wasPreviouslyReady = true;
|
|
1304
|
-
drawWrapper._wasPreviouslyUsingInstances = useInstances;
|
|
1305
|
-
this._checkScenePerformancePriority();
|
|
1306
|
-
return true;
|
|
1307
|
-
}
|
|
1308
|
-
/**
|
|
1309
|
-
* Get a string representing the shaders built by the current node graph
|
|
1310
|
-
*/
|
|
1311
|
-
get compiledShaders() {
|
|
1312
|
-
if (!this._buildWasSuccessful) {
|
|
1313
|
-
this.build();
|
|
1314
|
-
}
|
|
1315
|
-
return `// Vertex shader\n${this._vertexCompilationState.compilationString}\n\n// Fragment shader\n${this._fragmentCompilationState.compilationString}`;
|
|
1316
|
-
}
|
|
1317
|
-
/**
|
|
1318
|
-
* Get a string representing the fragment shader used by the engine for the current node graph
|
|
1319
|
-
* @internal
|
|
1320
|
-
*/
|
|
1321
|
-
async _getProcessedFragmentAsync() {
|
|
1322
|
-
if (!this._buildWasSuccessful) {
|
|
1323
|
-
this.build();
|
|
1324
|
-
}
|
|
1325
|
-
const defines = new NodeMaterialDefines();
|
|
1326
|
-
this._processDefines(defines);
|
|
1327
|
-
let processingDefines = defines.toString();
|
|
1328
|
-
if (this.mode === NodeMaterialModes.SFE) {
|
|
1329
|
-
processingDefines += `#define ${SfeModeDefine}\n`;
|
|
1330
|
-
}
|
|
1331
|
-
return await this._fragmentCompilationState.getProcessedShaderAsync(processingDefines);
|
|
1332
|
-
}
|
|
1333
|
-
/**
|
|
1334
|
-
* Binds the world matrix to the material
|
|
1335
|
-
* @param world defines the world transformation matrix
|
|
1336
|
-
*/
|
|
1337
|
-
bindOnlyWorldMatrix(world) {
|
|
1338
|
-
const scene = this.getScene();
|
|
1339
|
-
if (!this._activeEffect) {
|
|
1340
|
-
return;
|
|
1341
|
-
}
|
|
1342
|
-
const hints = this._sharedData.hints;
|
|
1343
|
-
if (hints.needWorldViewMatrix) {
|
|
1344
|
-
world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);
|
|
1345
|
-
}
|
|
1346
|
-
if (hints.needWorldViewProjectionMatrix) {
|
|
1347
|
-
world.multiplyToRef(scene.getTransformMatrix(), this._cachedWorldViewProjectionMatrix);
|
|
1348
|
-
}
|
|
1349
|
-
// Connection points
|
|
1350
|
-
for (const inputBlock of this._sharedData.inputBlocks) {
|
|
1351
|
-
inputBlock._transmitWorld(this._activeEffect, world, this._cachedWorldViewMatrix, this._cachedWorldViewProjectionMatrix);
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
/**
|
|
1355
|
-
* Binds the submesh to this material by preparing the effect and shader to draw
|
|
1356
|
-
* @param world defines the world transformation matrix
|
|
1357
|
-
* @param mesh defines the mesh containing the submesh
|
|
1358
|
-
* @param subMesh defines the submesh to bind the material to
|
|
1359
|
-
*/
|
|
1360
|
-
bindForSubMesh(world, mesh, subMesh) {
|
|
1361
|
-
const scene = this.getScene();
|
|
1362
|
-
const effect = subMesh.effect;
|
|
1363
|
-
if (!effect) {
|
|
1364
|
-
return;
|
|
1365
|
-
}
|
|
1366
|
-
this._activeEffect = effect;
|
|
1367
|
-
// Matrices
|
|
1368
|
-
this.bindOnlyWorldMatrix(world);
|
|
1369
|
-
const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);
|
|
1370
|
-
const sharedData = this._sharedData;
|
|
1371
|
-
if (mustRebind) {
|
|
1372
|
-
// Bindable blocks
|
|
1373
|
-
for (const block of sharedData.bindableBlocks) {
|
|
1374
|
-
block.bind(effect, this, mesh, subMesh);
|
|
1375
|
-
}
|
|
1376
|
-
for (const block of sharedData.forcedBindableBlocks) {
|
|
1377
|
-
block.bind(effect, this, mesh, subMesh);
|
|
1378
|
-
}
|
|
1379
|
-
// Connection points
|
|
1380
|
-
for (const inputBlock of sharedData.inputBlocks) {
|
|
1381
|
-
inputBlock._transmit(effect, scene, this);
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
else if (!this.isFrozen) {
|
|
1385
|
-
for (const block of sharedData.forcedBindableBlocks) {
|
|
1386
|
-
block.bind(effect, this, mesh, subMesh);
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
this._afterBind(mesh, this._activeEffect, subMesh);
|
|
1390
|
-
}
|
|
1391
|
-
/**
|
|
1392
|
-
* Gets the active textures from the material
|
|
1393
|
-
* @returns an array of textures
|
|
1394
|
-
*/
|
|
1395
|
-
getActiveTextures() {
|
|
1396
|
-
const activeTextures = super.getActiveTextures();
|
|
1397
|
-
if (this._sharedData) {
|
|
1398
|
-
activeTextures.push(...this._sharedData.textureBlocks.filter((tb) => tb.texture).map((tb) => tb.texture));
|
|
1399
|
-
}
|
|
1400
|
-
return activeTextures;
|
|
1401
|
-
}
|
|
1402
|
-
/**
|
|
1403
|
-
* Gets the list of texture blocks
|
|
1404
|
-
* Note that this method will only return blocks that are reachable from the final block(s) and only after the material has been built!
|
|
1405
|
-
* @returns an array of texture blocks
|
|
1406
|
-
*/
|
|
1407
|
-
getTextureBlocks() {
|
|
1408
|
-
if (!this._sharedData) {
|
|
1409
|
-
return [];
|
|
1410
|
-
}
|
|
1411
|
-
return this._sharedData.textureBlocks;
|
|
1412
|
-
}
|
|
1413
|
-
/**
|
|
1414
|
-
* Gets the list of all texture blocks
|
|
1415
|
-
* Note that this method will scan all attachedBlocks and return blocks that are texture blocks
|
|
1416
|
-
* @returns
|
|
1417
|
-
*/
|
|
1418
|
-
getAllTextureBlocks() {
|
|
1419
|
-
const textureBlocks = [];
|
|
1420
|
-
for (const block of this.attachedBlocks) {
|
|
1421
|
-
if (NodeMaterialBlockIsTextureBlock(block)) {
|
|
1422
|
-
textureBlocks.push(block);
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
return textureBlocks;
|
|
1426
|
-
}
|
|
1427
|
-
/**
|
|
1428
|
-
* Specifies if the material uses a texture
|
|
1429
|
-
* @param texture defines the texture to check against the material
|
|
1430
|
-
* @returns a boolean specifying if the material uses the texture
|
|
1431
|
-
*/
|
|
1432
|
-
hasTexture(texture) {
|
|
1433
|
-
if (super.hasTexture(texture)) {
|
|
1434
|
-
return true;
|
|
1435
|
-
}
|
|
1436
|
-
if (!this._sharedData) {
|
|
1437
|
-
return false;
|
|
1438
|
-
}
|
|
1439
|
-
for (const t of this._sharedData.textureBlocks) {
|
|
1440
|
-
if (t.texture === texture) {
|
|
1326
|
+
defines._renderId = scene.getRenderId();
|
|
1327
|
+
drawWrapper._wasPreviouslyReady = true;
|
|
1328
|
+
drawWrapper._wasPreviouslyUsingInstances = useInstances;
|
|
1329
|
+
this._checkScenePerformancePriority();
|
|
1441
1330
|
return true;
|
|
1442
1331
|
}
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1332
|
+
/**
|
|
1333
|
+
* Get a string representing the shaders built by the current node graph
|
|
1334
|
+
*/
|
|
1335
|
+
get compiledShaders() {
|
|
1336
|
+
if (!this._buildWasSuccessful) {
|
|
1337
|
+
this.build();
|
|
1338
|
+
}
|
|
1339
|
+
return `// Vertex shader\n${this._vertexCompilationState.compilationString}\n\n// Fragment shader\n${this._fragmentCompilationState.compilationString}`;
|
|
1340
|
+
}
|
|
1341
|
+
/**
|
|
1342
|
+
* Get a string representing the fragment shader used by the engine for the current node graph
|
|
1343
|
+
* @internal
|
|
1344
|
+
*/
|
|
1345
|
+
async _getProcessedFragmentAsync() {
|
|
1346
|
+
if (!this._buildWasSuccessful) {
|
|
1347
|
+
this.build();
|
|
1348
|
+
}
|
|
1349
|
+
const defines = new NodeMaterialDefines();
|
|
1350
|
+
this._processDefines(defines);
|
|
1351
|
+
let processingDefines = defines.toString();
|
|
1352
|
+
if (this.mode === NodeMaterialModes.SFE) {
|
|
1353
|
+
processingDefines += `#define ${SfeModeDefine}\n`;
|
|
1354
|
+
}
|
|
1355
|
+
return await this._fragmentCompilationState.getProcessedShaderAsync(processingDefines);
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Binds the world matrix to the material
|
|
1359
|
+
* @param world defines the world transformation matrix
|
|
1360
|
+
*/
|
|
1361
|
+
bindOnlyWorldMatrix(world) {
|
|
1362
|
+
const scene = this.getScene();
|
|
1363
|
+
if (!this._activeEffect) {
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
const hints = this._sharedData.hints;
|
|
1367
|
+
if (hints.needWorldViewMatrix) {
|
|
1368
|
+
world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);
|
|
1369
|
+
}
|
|
1370
|
+
if (hints.needWorldViewProjectionMatrix) {
|
|
1371
|
+
world.multiplyToRef(scene.getTransformMatrix(), this._cachedWorldViewProjectionMatrix);
|
|
1372
|
+
}
|
|
1373
|
+
// Connection points
|
|
1374
|
+
for (const inputBlock of this._sharedData.inputBlocks) {
|
|
1375
|
+
inputBlock._transmitWorld(this._activeEffect, world, this._cachedWorldViewMatrix, this._cachedWorldViewProjectionMatrix);
|
|
1376
|
+
}
|
|
1458
1377
|
}
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1378
|
+
/**
|
|
1379
|
+
* Binds the submesh to this material by preparing the effect and shader to draw
|
|
1380
|
+
* @param world defines the world transformation matrix
|
|
1381
|
+
* @param mesh defines the mesh containing the submesh
|
|
1382
|
+
* @param subMesh defines the submesh to bind the material to
|
|
1383
|
+
*/
|
|
1384
|
+
bindForSubMesh(world, mesh, subMesh) {
|
|
1385
|
+
const scene = this.getScene();
|
|
1386
|
+
const effect = subMesh.effect;
|
|
1387
|
+
if (!effect) {
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
this._activeEffect = effect;
|
|
1391
|
+
// Matrices
|
|
1392
|
+
this.bindOnlyWorldMatrix(world);
|
|
1393
|
+
const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);
|
|
1394
|
+
const sharedData = this._sharedData;
|
|
1395
|
+
if (mustRebind) {
|
|
1396
|
+
// Bindable blocks
|
|
1397
|
+
for (const block of sharedData.bindableBlocks) {
|
|
1398
|
+
block.bind(effect, this, mesh, subMesh);
|
|
1399
|
+
}
|
|
1400
|
+
for (const block of sharedData.forcedBindableBlocks) {
|
|
1401
|
+
block.bind(effect, this, mesh, subMesh);
|
|
1402
|
+
}
|
|
1403
|
+
// Connection points
|
|
1404
|
+
for (const inputBlock of sharedData.inputBlocks) {
|
|
1405
|
+
inputBlock._transmit(effect, scene, this);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
else if (!this.isFrozen) {
|
|
1409
|
+
for (const block of sharedData.forcedBindableBlocks) {
|
|
1410
|
+
block.bind(effect, this, mesh, subMesh);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
this._afterBind(mesh, this._activeEffect, subMesh);
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
* Gets the active textures from the material
|
|
1417
|
+
* @returns an array of textures
|
|
1418
|
+
*/
|
|
1419
|
+
getActiveTextures() {
|
|
1420
|
+
const activeTextures = super.getActiveTextures();
|
|
1421
|
+
if (this._sharedData) {
|
|
1422
|
+
activeTextures.push(...this._sharedData.textureBlocks.filter((tb) => tb.texture).map((tb) => tb.texture));
|
|
1423
|
+
}
|
|
1424
|
+
return activeTextures;
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Gets the list of texture blocks
|
|
1428
|
+
* Note that this method will only return blocks that are reachable from the final block(s) and only after the material has been built!
|
|
1429
|
+
* @returns an array of texture blocks
|
|
1430
|
+
*/
|
|
1431
|
+
getTextureBlocks() {
|
|
1432
|
+
if (!this._sharedData) {
|
|
1433
|
+
return [];
|
|
1434
|
+
}
|
|
1435
|
+
return this._sharedData.textureBlocks;
|
|
1436
|
+
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Gets the list of all texture blocks
|
|
1439
|
+
* Note that this method will scan all attachedBlocks and return blocks that are texture blocks
|
|
1440
|
+
* @returns
|
|
1441
|
+
*/
|
|
1442
|
+
getAllTextureBlocks() {
|
|
1443
|
+
const textureBlocks = [];
|
|
1444
|
+
for (const block of this.attachedBlocks) {
|
|
1445
|
+
if (NodeMaterialBlockIsTextureBlock(block)) {
|
|
1446
|
+
textureBlocks.push(block);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
return textureBlocks;
|
|
1450
|
+
}
|
|
1451
|
+
/**
|
|
1452
|
+
* Specifies if the material uses a texture
|
|
1453
|
+
* @param texture defines the texture to check against the material
|
|
1454
|
+
* @returns a boolean specifying if the material uses the texture
|
|
1455
|
+
*/
|
|
1456
|
+
hasTexture(texture) {
|
|
1457
|
+
if (super.hasTexture(texture)) {
|
|
1458
|
+
return true;
|
|
1459
|
+
}
|
|
1460
|
+
if (!this._sharedData) {
|
|
1461
|
+
return false;
|
|
1462
|
+
}
|
|
1463
|
+
for (const t of this._sharedData.textureBlocks) {
|
|
1464
|
+
if (t.texture === texture) {
|
|
1465
|
+
return true;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
return false;
|
|
1469
|
+
}
|
|
1470
|
+
/**
|
|
1471
|
+
* Disposes the material
|
|
1472
|
+
* @param forceDisposeEffect specifies if effects should be forcefully disposed
|
|
1473
|
+
* @param forceDisposeTextures specifies if textures should be forcefully disposed
|
|
1474
|
+
* @param notBoundToMesh specifies if the material that is being disposed is known to be not bound to any mesh
|
|
1475
|
+
*/
|
|
1476
|
+
dispose(forceDisposeEffect, forceDisposeTextures, notBoundToMesh) {
|
|
1477
|
+
if (forceDisposeTextures) {
|
|
1478
|
+
for (const texture of this.getTextureBlocks()
|
|
1479
|
+
.filter((tb) => tb.texture)
|
|
1480
|
+
.map((tb) => tb.texture)) {
|
|
1481
|
+
texture.dispose();
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
for (const block of this.attachedBlocks) {
|
|
1485
|
+
block.dispose();
|
|
1486
|
+
}
|
|
1487
|
+
this.attachedBlocks.length = 0;
|
|
1488
|
+
this._sharedData = null;
|
|
1489
|
+
this._vertexCompilationState = null;
|
|
1490
|
+
this._fragmentCompilationState = null;
|
|
1491
|
+
this.onBuildObservable.clear();
|
|
1492
|
+
this.onBuildErrorObservable.clear();
|
|
1493
|
+
if (this._imageProcessingObserver) {
|
|
1494
|
+
this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
|
|
1495
|
+
this._imageProcessingObserver = null;
|
|
1496
|
+
}
|
|
1497
|
+
super.dispose(forceDisposeEffect, forceDisposeTextures, notBoundToMesh);
|
|
1498
|
+
}
|
|
1499
|
+
/** Creates the node editor window.
|
|
1500
|
+
* @param additionalConfig Define the configuration of the editor
|
|
1501
|
+
*/
|
|
1502
|
+
_createNodeEditor(additionalConfig) {
|
|
1503
|
+
const nodeEditorConfig = {
|
|
1504
|
+
nodeMaterial: this,
|
|
1505
|
+
...additionalConfig,
|
|
1506
|
+
};
|
|
1507
|
+
this.BJSNODEMATERIALEDITOR.NodeEditor.Show(nodeEditorConfig);
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Launch the node material editor
|
|
1511
|
+
* @param config Define the configuration of the editor
|
|
1512
|
+
* @returns a promise fulfilled when the node editor is visible
|
|
1513
|
+
*/
|
|
1514
|
+
async edit(config) {
|
|
1515
|
+
return await new Promise((resolve) => {
|
|
1497
1516
|
this.BJSNODEMATERIALEDITOR = this.BJSNODEMATERIALEDITOR || this._getGlobalNodeMaterialEditor();
|
|
1498
|
-
this.
|
|
1499
|
-
|
|
1517
|
+
if (typeof this.BJSNODEMATERIALEDITOR == "undefined") {
|
|
1518
|
+
const editorUrl = config && config.editorURL ? config.editorURL : _a.EditorURL;
|
|
1519
|
+
// Load editor and add it to the DOM
|
|
1520
|
+
Tools.LoadBabylonScript(editorUrl, () => {
|
|
1521
|
+
this.BJSNODEMATERIALEDITOR = this.BJSNODEMATERIALEDITOR || this._getGlobalNodeMaterialEditor();
|
|
1522
|
+
this._createNodeEditor(config?.nodeEditorConfig);
|
|
1523
|
+
resolve();
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
else {
|
|
1527
|
+
// Otherwise creates the editor
|
|
1528
|
+
this._createNodeEditor(config?.nodeEditorConfig);
|
|
1529
|
+
resolve();
|
|
1530
|
+
}
|
|
1500
1531
|
});
|
|
1501
1532
|
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
*/
|
|
1663
|
-
async loadAsync(url, rootUrl = "") {
|
|
1664
|
-
return await NodeMaterialParseFromFileAsync("", url, this.getScene(), rootUrl, true, this);
|
|
1665
|
-
}
|
|
1666
|
-
_gatherBlocks(rootNode, list) {
|
|
1667
|
-
if (list.indexOf(rootNode) !== -1) {
|
|
1668
|
-
return;
|
|
1669
|
-
}
|
|
1670
|
-
list.push(rootNode);
|
|
1671
|
-
for (const input of rootNode.inputs) {
|
|
1672
|
-
const connectedPoint = input.connectedPoint;
|
|
1673
|
-
if (connectedPoint) {
|
|
1674
|
-
const block = connectedPoint.ownerBlock;
|
|
1675
|
-
if (block !== rootNode) {
|
|
1676
|
-
this._gatherBlocks(block, list);
|
|
1533
|
+
/**
|
|
1534
|
+
* Clear the current material
|
|
1535
|
+
*/
|
|
1536
|
+
clear() {
|
|
1537
|
+
this._vertexOutputNodes.length = 0;
|
|
1538
|
+
this._fragmentOutputNodes.length = 0;
|
|
1539
|
+
this.attachedBlocks.length = 0;
|
|
1540
|
+
this._buildIsInProgress = false;
|
|
1541
|
+
}
|
|
1542
|
+
/**
|
|
1543
|
+
* Clear the current material and set it to a default state
|
|
1544
|
+
*/
|
|
1545
|
+
setToDefault() {
|
|
1546
|
+
this.clear();
|
|
1547
|
+
this.editorData = null;
|
|
1548
|
+
const positionInput = new InputBlock("Position");
|
|
1549
|
+
positionInput.setAsAttribute("position");
|
|
1550
|
+
const worldInput = new InputBlock("World");
|
|
1551
|
+
worldInput.setAsSystemValue(NodeMaterialSystemValues.World);
|
|
1552
|
+
const worldPos = new TransformBlock("WorldPos");
|
|
1553
|
+
positionInput.connectTo(worldPos);
|
|
1554
|
+
worldInput.connectTo(worldPos);
|
|
1555
|
+
const viewProjectionInput = new InputBlock("ViewProjection");
|
|
1556
|
+
viewProjectionInput.setAsSystemValue(NodeMaterialSystemValues.ViewProjection);
|
|
1557
|
+
const worldPosdMultipliedByViewProjection = new TransformBlock("WorldPos * ViewProjectionTransform");
|
|
1558
|
+
worldPos.connectTo(worldPosdMultipliedByViewProjection);
|
|
1559
|
+
viewProjectionInput.connectTo(worldPosdMultipliedByViewProjection);
|
|
1560
|
+
const vertexOutput = new VertexOutputBlock("VertexOutput");
|
|
1561
|
+
worldPosdMultipliedByViewProjection.connectTo(vertexOutput);
|
|
1562
|
+
// Pixel
|
|
1563
|
+
const pixelColor = new InputBlock("color");
|
|
1564
|
+
pixelColor.value = new Color4(0.8, 0.8, 0.8, 1);
|
|
1565
|
+
const fragmentOutput = new FragmentOutputBlock("FragmentOutput");
|
|
1566
|
+
pixelColor.connectTo(fragmentOutput);
|
|
1567
|
+
// Add to nodes
|
|
1568
|
+
this.addOutputNode(vertexOutput);
|
|
1569
|
+
this.addOutputNode(fragmentOutput);
|
|
1570
|
+
this._mode = NodeMaterialModes.Material;
|
|
1571
|
+
}
|
|
1572
|
+
/**
|
|
1573
|
+
* Clear the current material and set it to a default state for post process
|
|
1574
|
+
*/
|
|
1575
|
+
setToDefaultPostProcess() {
|
|
1576
|
+
this.clear();
|
|
1577
|
+
this.editorData = null;
|
|
1578
|
+
const position = new InputBlock("Position");
|
|
1579
|
+
position.setAsAttribute("position2d");
|
|
1580
|
+
const const1 = new InputBlock("Constant1");
|
|
1581
|
+
const1.isConstant = true;
|
|
1582
|
+
const1.value = 1;
|
|
1583
|
+
const vmerger = new VectorMergerBlock("Position3D");
|
|
1584
|
+
position.connectTo(vmerger);
|
|
1585
|
+
const1.connectTo(vmerger, { input: "w" });
|
|
1586
|
+
const vertexOutput = new VertexOutputBlock("VertexOutput");
|
|
1587
|
+
vmerger.connectTo(vertexOutput);
|
|
1588
|
+
// Pixel
|
|
1589
|
+
const scale = new InputBlock("Scale");
|
|
1590
|
+
scale.visibleInInspector = true;
|
|
1591
|
+
scale.value = new Vector2(1, 1);
|
|
1592
|
+
const uv0 = new RemapBlock("uv0");
|
|
1593
|
+
position.connectTo(uv0);
|
|
1594
|
+
const uv = new MultiplyBlock("UV scale");
|
|
1595
|
+
uv0.connectTo(uv);
|
|
1596
|
+
scale.connectTo(uv);
|
|
1597
|
+
const currentScreen = new CurrentScreenBlock("CurrentScreen");
|
|
1598
|
+
uv.connectTo(currentScreen);
|
|
1599
|
+
const textureUrl = Tools.GetAssetUrl("https://assets.babylonjs.com/core/nme/currentScreenPostProcess.png");
|
|
1600
|
+
currentScreen.texture = new Texture(textureUrl, this.getScene());
|
|
1601
|
+
const fragmentOutput = new FragmentOutputBlock("FragmentOutput");
|
|
1602
|
+
currentScreen.connectTo(fragmentOutput, { output: "rgba" });
|
|
1603
|
+
// Add to nodes
|
|
1604
|
+
this.addOutputNode(vertexOutput);
|
|
1605
|
+
this.addOutputNode(fragmentOutput);
|
|
1606
|
+
this._mode = NodeMaterialModes.PostProcess;
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* Clear the current material and set it to a default state for procedural texture
|
|
1610
|
+
*/
|
|
1611
|
+
setToDefaultProceduralTexture() {
|
|
1612
|
+
this.clear();
|
|
1613
|
+
this.editorData = null;
|
|
1614
|
+
const position = new InputBlock("Position");
|
|
1615
|
+
position.setAsAttribute("position2d");
|
|
1616
|
+
const const1 = new InputBlock("Constant1");
|
|
1617
|
+
const1.isConstant = true;
|
|
1618
|
+
const1.value = 1;
|
|
1619
|
+
const vmerger = new VectorMergerBlock("Position3D");
|
|
1620
|
+
position.connectTo(vmerger);
|
|
1621
|
+
const1.connectTo(vmerger, { input: "w" });
|
|
1622
|
+
const vertexOutput = new VertexOutputBlock("VertexOutput");
|
|
1623
|
+
vmerger.connectTo(vertexOutput);
|
|
1624
|
+
// Pixel
|
|
1625
|
+
const time = new InputBlock("Time");
|
|
1626
|
+
time.value = 0;
|
|
1627
|
+
time.min = 0;
|
|
1628
|
+
time.max = 0;
|
|
1629
|
+
time.isBoolean = false;
|
|
1630
|
+
time.matrixMode = 0;
|
|
1631
|
+
time.animationType = AnimatedInputBlockTypes.Time;
|
|
1632
|
+
time.isConstant = false;
|
|
1633
|
+
const color = new InputBlock("Color3");
|
|
1634
|
+
color.value = new Color3(1, 1, 1);
|
|
1635
|
+
color.isConstant = false;
|
|
1636
|
+
const fragmentOutput = new FragmentOutputBlock("FragmentOutput");
|
|
1637
|
+
const vectorMerger = new VectorMergerBlock("VectorMerger");
|
|
1638
|
+
vectorMerger.visibleInInspector = false;
|
|
1639
|
+
const cos = new TrigonometryBlock("Cos");
|
|
1640
|
+
cos.operation = TrigonometryBlockOperations.Cos;
|
|
1641
|
+
position.connectTo(vectorMerger);
|
|
1642
|
+
time.output.connectTo(cos.input);
|
|
1643
|
+
cos.output.connectTo(vectorMerger.z);
|
|
1644
|
+
vectorMerger.xyzOut.connectTo(fragmentOutput.rgb);
|
|
1645
|
+
// Add to nodes
|
|
1646
|
+
this.addOutputNode(vertexOutput);
|
|
1647
|
+
this.addOutputNode(fragmentOutput);
|
|
1648
|
+
this._mode = NodeMaterialModes.ProceduralTexture;
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Clear the current material and set it to a default state for particle
|
|
1652
|
+
*/
|
|
1653
|
+
setToDefaultParticle() {
|
|
1654
|
+
this.clear();
|
|
1655
|
+
this.editorData = null;
|
|
1656
|
+
// Pixel
|
|
1657
|
+
const uv = new InputBlock("uv");
|
|
1658
|
+
uv.setAsAttribute("particle_uv");
|
|
1659
|
+
const texture = new ParticleTextureBlock("ParticleTexture");
|
|
1660
|
+
uv.connectTo(texture);
|
|
1661
|
+
const color = new InputBlock("Color");
|
|
1662
|
+
color.setAsAttribute("particle_color");
|
|
1663
|
+
const multiply = new MultiplyBlock("Texture * Color");
|
|
1664
|
+
texture.connectTo(multiply);
|
|
1665
|
+
color.connectTo(multiply);
|
|
1666
|
+
const rampGradient = new ParticleRampGradientBlock("ParticleRampGradient");
|
|
1667
|
+
multiply.connectTo(rampGradient);
|
|
1668
|
+
const cSplitter = new ColorSplitterBlock("ColorSplitter");
|
|
1669
|
+
color.connectTo(cSplitter);
|
|
1670
|
+
const blendMultiply = new ParticleBlendMultiplyBlock("ParticleBlendMultiply");
|
|
1671
|
+
rampGradient.connectTo(blendMultiply);
|
|
1672
|
+
texture.connectTo(blendMultiply, { output: "a" });
|
|
1673
|
+
cSplitter.connectTo(blendMultiply, { output: "a" });
|
|
1674
|
+
const fragmentOutput = new FragmentOutputBlock("FragmentOutput");
|
|
1675
|
+
blendMultiply.connectTo(fragmentOutput);
|
|
1676
|
+
// Add to nodes
|
|
1677
|
+
this.addOutputNode(fragmentOutput);
|
|
1678
|
+
this._mode = NodeMaterialModes.Particle;
|
|
1679
|
+
}
|
|
1680
|
+
/**
|
|
1681
|
+
* Loads the current Node Material from a url pointing to a file save by the Node Material Editor
|
|
1682
|
+
* @deprecated Please use NodeMaterial.ParseFromFileAsync instead
|
|
1683
|
+
* @param url defines the url to load from
|
|
1684
|
+
* @param rootUrl defines the root URL for nested url in the node material
|
|
1685
|
+
* @returns a promise that will fulfil when the material is fully loaded
|
|
1686
|
+
*/
|
|
1687
|
+
async loadAsync(url, rootUrl = "") {
|
|
1688
|
+
return await NodeMaterialParseFromFileAsync("", url, this.getScene(), rootUrl, true, this);
|
|
1689
|
+
}
|
|
1690
|
+
_gatherBlocks(rootNode, list) {
|
|
1691
|
+
if (list.indexOf(rootNode) !== -1) {
|
|
1692
|
+
return;
|
|
1677
1693
|
}
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
}
|
|
1688
|
-
/**
|
|
1689
|
-
* Generate a string containing the code declaration required to create an equivalent of this material
|
|
1690
|
-
* @returns a string
|
|
1691
|
-
*/
|
|
1692
|
-
generateCode() {
|
|
1693
|
-
let alreadyDumped = [];
|
|
1694
|
-
const vertexBlocks = [];
|
|
1695
|
-
const uniqueNames = ["const", "var", "let"];
|
|
1696
|
-
// Gets active blocks
|
|
1697
|
-
for (const outputNode of this._vertexOutputNodes) {
|
|
1698
|
-
this._gatherBlocks(outputNode, vertexBlocks);
|
|
1699
|
-
}
|
|
1700
|
-
const fragmentBlocks = [];
|
|
1701
|
-
for (const outputNode of this._fragmentOutputNodes) {
|
|
1702
|
-
this._gatherBlocks(outputNode, fragmentBlocks);
|
|
1703
|
-
}
|
|
1704
|
-
// Generate vertex shader
|
|
1705
|
-
let codeString = `var nodeMaterial = new BABYLON.NodeMaterial("${this.name || "node material"}");\n`;
|
|
1706
|
-
codeString += `nodeMaterial.mode = BABYLON.NodeMaterialModes.${NodeMaterialModes[this.mode]};\n`;
|
|
1707
|
-
for (const node of vertexBlocks) {
|
|
1708
|
-
if (node.isInput && alreadyDumped.indexOf(node) === -1) {
|
|
1709
|
-
codeString += node._dumpCode(uniqueNames, alreadyDumped);
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
// Generate fragment shader
|
|
1713
|
-
for (const node of fragmentBlocks) {
|
|
1714
|
-
if (node.isInput && alreadyDumped.indexOf(node) === -1) {
|
|
1715
|
-
codeString += node._dumpCode(uniqueNames, alreadyDumped);
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
// Connections
|
|
1719
|
-
alreadyDumped = [];
|
|
1720
|
-
codeString += "\n// Connections\n";
|
|
1721
|
-
for (const node of this._vertexOutputNodes) {
|
|
1722
|
-
codeString += node._dumpCodeForOutputConnections(alreadyDumped);
|
|
1723
|
-
}
|
|
1724
|
-
for (const node of this._fragmentOutputNodes) {
|
|
1725
|
-
codeString += node._dumpCodeForOutputConnections(alreadyDumped);
|
|
1726
|
-
}
|
|
1727
|
-
// Output nodes
|
|
1728
|
-
codeString += "\n// Output nodes\n";
|
|
1729
|
-
for (const node of this._vertexOutputNodes) {
|
|
1730
|
-
codeString += `nodeMaterial.addOutputNode(${node._codeVariableName});\n`;
|
|
1731
|
-
}
|
|
1732
|
-
for (const node of this._fragmentOutputNodes) {
|
|
1733
|
-
codeString += `nodeMaterial.addOutputNode(${node._codeVariableName});\n`;
|
|
1734
|
-
}
|
|
1735
|
-
codeString += `nodeMaterial.build();\n`;
|
|
1736
|
-
return codeString;
|
|
1737
|
-
}
|
|
1738
|
-
/**
|
|
1739
|
-
* Serializes this material in a JSON representation
|
|
1740
|
-
* @param selectedBlocks defines an optional list of blocks to serialize
|
|
1741
|
-
* @returns the serialized material object
|
|
1742
|
-
*/
|
|
1743
|
-
serialize(selectedBlocks) {
|
|
1744
|
-
const serializationObject = selectedBlocks ? {} : SerializationHelper.Serialize(this);
|
|
1745
|
-
serializationObject.editorData = JSON.parse(JSON.stringify(this.editorData)); // Copy
|
|
1746
|
-
let blocks = [];
|
|
1747
|
-
if (selectedBlocks) {
|
|
1748
|
-
blocks = selectedBlocks;
|
|
1749
|
-
}
|
|
1750
|
-
else {
|
|
1751
|
-
serializationObject.customType = "BABYLON.NodeMaterial";
|
|
1752
|
-
serializationObject.outputNodes = [];
|
|
1753
|
-
// Outputs
|
|
1754
|
-
for (const outputNode of this._vertexOutputNodes) {
|
|
1755
|
-
this._gatherBlocks(outputNode, blocks);
|
|
1756
|
-
serializationObject.outputNodes.push(outputNode.uniqueId);
|
|
1757
|
-
}
|
|
1758
|
-
for (const outputNode of this._fragmentOutputNodes) {
|
|
1759
|
-
this._gatherBlocks(outputNode, blocks);
|
|
1760
|
-
if (serializationObject.outputNodes.indexOf(outputNode.uniqueId) === -1) {
|
|
1761
|
-
serializationObject.outputNodes.push(outputNode.uniqueId);
|
|
1694
|
+
list.push(rootNode);
|
|
1695
|
+
for (const input of rootNode.inputs) {
|
|
1696
|
+
const connectedPoint = input.connectedPoint;
|
|
1697
|
+
if (connectedPoint) {
|
|
1698
|
+
const block = connectedPoint.ownerBlock;
|
|
1699
|
+
if (block !== rootNode) {
|
|
1700
|
+
this._gatherBlocks(block, list);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1762
1703
|
}
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
}
|
|
1770
|
-
if (!selectedBlocks) {
|
|
1771
|
-
for (const block of this.attachedBlocks) {
|
|
1772
|
-
if (blocks.indexOf(block) !== -1) {
|
|
1773
|
-
continue;
|
|
1704
|
+
// Teleportation
|
|
1705
|
+
if (rootNode.isTeleportOut) {
|
|
1706
|
+
const block = rootNode;
|
|
1707
|
+
if (block.entryPoint) {
|
|
1708
|
+
this._gatherBlocks(block.entryPoint, list);
|
|
1709
|
+
}
|
|
1774
1710
|
}
|
|
1775
|
-
serializationObject.blocks.push(block.serialize());
|
|
1776
1711
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
const
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1712
|
+
/**
|
|
1713
|
+
* Generate a string containing the code declaration required to create an equivalent of this material
|
|
1714
|
+
* @returns a string
|
|
1715
|
+
*/
|
|
1716
|
+
generateCode() {
|
|
1717
|
+
let alreadyDumped = [];
|
|
1718
|
+
const vertexBlocks = [];
|
|
1719
|
+
const uniqueNames = ["const", "var", "let"];
|
|
1720
|
+
// Gets active blocks
|
|
1721
|
+
for (const outputNode of this._vertexOutputNodes) {
|
|
1722
|
+
this._gatherBlocks(outputNode, vertexBlocks);
|
|
1723
|
+
}
|
|
1724
|
+
const fragmentBlocks = [];
|
|
1725
|
+
for (const outputNode of this._fragmentOutputNodes) {
|
|
1726
|
+
this._gatherBlocks(outputNode, fragmentBlocks);
|
|
1727
|
+
}
|
|
1728
|
+
// Generate vertex shader
|
|
1729
|
+
let codeString = `var nodeMaterial = new BABYLON.NodeMaterial("${this.name || "node material"}");\n`;
|
|
1730
|
+
codeString += `nodeMaterial.mode = BABYLON.NodeMaterialModes.${NodeMaterialModes[this.mode]};\n`;
|
|
1731
|
+
for (const node of vertexBlocks) {
|
|
1732
|
+
if (node.isInput && alreadyDumped.indexOf(node) === -1) {
|
|
1733
|
+
codeString += node._dumpCode(uniqueNames, alreadyDumped);
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
// Generate fragment shader
|
|
1737
|
+
for (const node of fragmentBlocks) {
|
|
1738
|
+
if (node.isInput && alreadyDumped.indexOf(node) === -1) {
|
|
1739
|
+
codeString += node._dumpCode(uniqueNames, alreadyDumped);
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
// Connections
|
|
1743
|
+
alreadyDumped = [];
|
|
1744
|
+
codeString += "\n// Connections\n";
|
|
1745
|
+
for (const node of this._vertexOutputNodes) {
|
|
1746
|
+
codeString += node._dumpCodeForOutputConnections(alreadyDumped);
|
|
1747
|
+
}
|
|
1748
|
+
for (const node of this._fragmentOutputNodes) {
|
|
1749
|
+
codeString += node._dumpCodeForOutputConnections(alreadyDumped);
|
|
1750
|
+
}
|
|
1751
|
+
// Output nodes
|
|
1752
|
+
codeString += "\n// Output nodes\n";
|
|
1753
|
+
for (const node of this._vertexOutputNodes) {
|
|
1754
|
+
codeString += `nodeMaterial.addOutputNode(${node._codeVariableName});\n`;
|
|
1755
|
+
}
|
|
1756
|
+
for (const node of this._fragmentOutputNodes) {
|
|
1757
|
+
codeString += `nodeMaterial.addOutputNode(${node._codeVariableName});\n`;
|
|
1758
|
+
}
|
|
1759
|
+
codeString += `nodeMaterial.build();\n`;
|
|
1760
|
+
return codeString;
|
|
1761
|
+
}
|
|
1762
|
+
/**
|
|
1763
|
+
* Serializes this material in a JSON representation
|
|
1764
|
+
* @param selectedBlocks defines an optional list of blocks to serialize
|
|
1765
|
+
* @returns the serialized material object
|
|
1766
|
+
*/
|
|
1767
|
+
serialize(selectedBlocks) {
|
|
1768
|
+
const serializationObject = selectedBlocks ? {} : SerializationHelper.Serialize(this);
|
|
1769
|
+
serializationObject.editorData = JSON.parse(JSON.stringify(this.editorData)); // Copy
|
|
1770
|
+
let blocks = [];
|
|
1771
|
+
if (selectedBlocks) {
|
|
1772
|
+
blocks = selectedBlocks;
|
|
1773
|
+
}
|
|
1774
|
+
else {
|
|
1775
|
+
serializationObject.customType = "BABYLON.NodeMaterial";
|
|
1776
|
+
serializationObject.outputNodes = [];
|
|
1777
|
+
// Outputs
|
|
1778
|
+
for (const outputNode of this._vertexOutputNodes) {
|
|
1779
|
+
this._gatherBlocks(outputNode, blocks);
|
|
1780
|
+
serializationObject.outputNodes.push(outputNode.uniqueId);
|
|
1781
|
+
}
|
|
1782
|
+
for (const outputNode of this._fragmentOutputNodes) {
|
|
1783
|
+
this._gatherBlocks(outputNode, blocks);
|
|
1784
|
+
if (serializationObject.outputNodes.indexOf(outputNode.uniqueId) === -1) {
|
|
1785
|
+
serializationObject.outputNodes.push(outputNode.uniqueId);
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
// Blocks
|
|
1790
|
+
serializationObject.blocks = [];
|
|
1791
|
+
for (const block of blocks) {
|
|
1792
|
+
serializationObject.blocks.push(block.serialize());
|
|
1793
|
+
}
|
|
1794
|
+
if (!selectedBlocks) {
|
|
1795
|
+
for (const block of this.attachedBlocks) {
|
|
1796
|
+
if (blocks.indexOf(block) !== -1) {
|
|
1792
1797
|
continue;
|
|
1793
1798
|
}
|
|
1794
|
-
|
|
1795
|
-
this._restoreConnections(target, source, map);
|
|
1796
|
-
continue;
|
|
1799
|
+
serializationObject.blocks.push(block.serialize());
|
|
1797
1800
|
}
|
|
1798
1801
|
}
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
this._imageProcessingConfiguration = previousImageProcessingConfiguration;
|
|
1822
|
-
this._imageProcessingObserver = previousImageProcessingObserver;
|
|
1823
|
-
this._attachImageProcessingConfiguration(parsedImageProcessingConfiguration);
|
|
1824
|
-
}
|
|
1825
|
-
this.id = id;
|
|
1826
|
-
this.uniqueId = uniqueId;
|
|
1827
|
-
const map = {};
|
|
1828
|
-
// Create blocks
|
|
1829
|
-
for (const parsedBlock of source.blocks) {
|
|
1830
|
-
const blockType = GetClass(parsedBlock.customType);
|
|
1831
|
-
if (blockType) {
|
|
1832
|
-
const block = new blockType();
|
|
1833
|
-
block._deserialize(parsedBlock, this.getScene(), rootUrl, urlRewriter);
|
|
1834
|
-
map[parsedBlock.id] = block;
|
|
1835
|
-
this.attachedBlocks.push(block);
|
|
1836
|
-
}
|
|
1837
|
-
}
|
|
1838
|
-
// Reconnect teleportation
|
|
1839
|
-
for (const block of this.attachedBlocks) {
|
|
1840
|
-
if (block.isTeleportOut) {
|
|
1841
|
-
const teleportOut = block;
|
|
1842
|
-
const id = teleportOut._tempEntryPointUniqueId;
|
|
1843
|
-
if (id) {
|
|
1844
|
-
const source = map[id];
|
|
1845
|
-
source.attachToEndpoint(teleportOut);
|
|
1802
|
+
serializationObject.uniqueId = this.uniqueId;
|
|
1803
|
+
return serializationObject;
|
|
1804
|
+
}
|
|
1805
|
+
_restoreConnections(block, source, map) {
|
|
1806
|
+
for (const outputPoint of block.outputs) {
|
|
1807
|
+
for (const candidate of source.blocks) {
|
|
1808
|
+
const target = map[candidate.id];
|
|
1809
|
+
if (!target) {
|
|
1810
|
+
continue;
|
|
1811
|
+
}
|
|
1812
|
+
for (const input of candidate.inputs) {
|
|
1813
|
+
if (map[input.targetBlockId] === block && input.targetConnectionName === outputPoint.name) {
|
|
1814
|
+
const inputPoint = target.getInputByName(input.inputName);
|
|
1815
|
+
if (!inputPoint || inputPoint.isConnected) {
|
|
1816
|
+
continue;
|
|
1817
|
+
}
|
|
1818
|
+
outputPoint.connectTo(inputPoint, true);
|
|
1819
|
+
this._restoreConnections(target, source, map);
|
|
1820
|
+
continue;
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1846
1824
|
}
|
|
1847
1825
|
}
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
this.
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1826
|
+
/**
|
|
1827
|
+
* Clear the current graph and load a new one from a serialization object
|
|
1828
|
+
* @param source defines the JSON representation of the material
|
|
1829
|
+
* @param rootUrl defines the root URL to use to load textures and relative dependencies
|
|
1830
|
+
* @param merge defines whether or not the source must be merged or replace the current content
|
|
1831
|
+
* @param urlRewriter defines a function used to rewrite urls
|
|
1832
|
+
*/
|
|
1833
|
+
parseSerializedObject(source, rootUrl = "", merge = false, urlRewriter) {
|
|
1834
|
+
if (!merge) {
|
|
1835
|
+
this.clear();
|
|
1836
|
+
}
|
|
1837
|
+
const id = this.id;
|
|
1838
|
+
const uniqueId = this.uniqueId;
|
|
1839
|
+
const previousImageProcessingConfiguration = this._imageProcessingConfiguration;
|
|
1840
|
+
const previousImageProcessingObserver = this._imageProcessingObserver;
|
|
1841
|
+
const hasSerializedImageProcessingConfiguration = Object.prototype.hasOwnProperty.call(source, "_imageProcessingConfiguration");
|
|
1842
|
+
SerializationHelper.ParseProperties(source, this, this.getScene(), rootUrl);
|
|
1843
|
+
const parsedImageProcessingConfiguration = this._imageProcessingConfiguration;
|
|
1844
|
+
if (hasSerializedImageProcessingConfiguration) {
|
|
1845
|
+
this._imageProcessingConfiguration = previousImageProcessingConfiguration;
|
|
1846
|
+
this._imageProcessingObserver = previousImageProcessingObserver;
|
|
1847
|
+
this._attachImageProcessingConfiguration(parsedImageProcessingConfiguration);
|
|
1848
|
+
}
|
|
1849
|
+
this.id = id;
|
|
1850
|
+
this.uniqueId = uniqueId;
|
|
1851
|
+
const map = {};
|
|
1852
|
+
// Create blocks
|
|
1853
|
+
for (const parsedBlock of source.blocks) {
|
|
1854
|
+
const blockType = GetClass(parsedBlock.customType);
|
|
1855
|
+
if (blockType) {
|
|
1856
|
+
const block = new blockType();
|
|
1857
|
+
block._deserialize(parsedBlock, this.getScene(), rootUrl, urlRewriter);
|
|
1858
|
+
map[parsedBlock.id] = block;
|
|
1859
|
+
this.attachedBlocks.push(block);
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
// Reconnect teleportation
|
|
1863
|
+
for (const block of this.attachedBlocks) {
|
|
1864
|
+
if (block.isTeleportOut) {
|
|
1865
|
+
const teleportOut = block;
|
|
1866
|
+
const id = teleportOut._tempEntryPointUniqueId;
|
|
1867
|
+
if (id) {
|
|
1868
|
+
const source = map[id];
|
|
1869
|
+
source.attachToEndpoint(teleportOut);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
// Connections - Starts with input blocks only (except if in "merge" mode where we scan all blocks)
|
|
1874
|
+
for (let blockIndex = 0; blockIndex < source.blocks.length; blockIndex++) {
|
|
1875
|
+
const parsedBlock = source.blocks[blockIndex];
|
|
1876
|
+
const block = map[parsedBlock.id];
|
|
1877
|
+
if (!block) {
|
|
1878
|
+
continue;
|
|
1879
|
+
}
|
|
1880
|
+
if (block.inputs.length && !merge) {
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
this._restoreConnections(block, source, map);
|
|
1884
|
+
}
|
|
1885
|
+
// Outputs
|
|
1886
|
+
if (source.outputNodes) {
|
|
1887
|
+
for (const outputNodeId of source.outputNodes) {
|
|
1888
|
+
this.addOutputNode(map[outputNodeId]);
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
// UI related info
|
|
1892
|
+
if (source.locations || (source.editorData && source.editorData.locations)) {
|
|
1893
|
+
const locations = source.locations || source.editorData.locations;
|
|
1894
|
+
for (const location of locations) {
|
|
1895
|
+
if (map[location.blockId]) {
|
|
1896
|
+
location.blockId = map[location.blockId].uniqueId;
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
if (merge && this.editorData && this.editorData.locations) {
|
|
1900
|
+
locations.concat(this.editorData.locations);
|
|
1901
|
+
}
|
|
1902
|
+
if (source.locations) {
|
|
1903
|
+
this.editorData = {
|
|
1904
|
+
locations: locations,
|
|
1905
|
+
};
|
|
1906
|
+
}
|
|
1907
|
+
else {
|
|
1908
|
+
this.editorData = source.editorData;
|
|
1909
|
+
this.editorData.locations = locations;
|
|
1910
|
+
}
|
|
1911
|
+
const blockMap = {};
|
|
1912
|
+
for (const key in map) {
|
|
1913
|
+
blockMap[key] = map[key].uniqueId;
|
|
1914
|
+
}
|
|
1915
|
+
this.editorData.map = blockMap;
|
|
1916
|
+
}
|
|
1917
|
+
Material.ParseAlphaMode(source, this);
|
|
1918
|
+
if (!merge) {
|
|
1919
|
+
this._mode = source.mode ?? NodeMaterialModes.Material;
|
|
1873
1920
|
}
|
|
1874
1921
|
}
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
NodeMaterial
|
|
1956
|
-
/** Gets or sets a boolean indicating that render target textures can be serialized */
|
|
1957
|
-
NodeMaterial.AllowSerializationOfRenderTargetTextures = false;
|
|
1958
|
-
/** Defines default shader language when no option is defined */
|
|
1959
|
-
NodeMaterial.DefaultShaderLanguage = 0 /* ShaderLanguage.GLSL */;
|
|
1960
|
-
/** If true, the node material will use GLSL if the engine is WebGL and WGSL if it's WebGPU. It takes priority over DefaultShaderLanguage if it's true */
|
|
1961
|
-
NodeMaterial.UseNativeShaderLanguageOfEngine = false;
|
|
1962
|
-
__decorate([
|
|
1963
|
-
serialize()
|
|
1964
|
-
], NodeMaterial.prototype, "ignoreAlpha", void 0);
|
|
1965
|
-
__decorate([
|
|
1966
|
-
serialize()
|
|
1967
|
-
], NodeMaterial.prototype, "maxSimultaneousLights", void 0);
|
|
1968
|
-
__decorate([
|
|
1969
|
-
serialize("mode")
|
|
1970
|
-
], NodeMaterial.prototype, "_mode", void 0);
|
|
1971
|
-
__decorate([
|
|
1972
|
-
serialize("comment")
|
|
1973
|
-
], NodeMaterial.prototype, "comment", void 0);
|
|
1974
|
-
__decorate([
|
|
1975
|
-
serialize()
|
|
1976
|
-
], NodeMaterial.prototype, "forceAlphaBlending", void 0);
|
|
1922
|
+
/**
|
|
1923
|
+
* Clear the current graph and load a new one from a serialization object
|
|
1924
|
+
* @param source defines the JSON representation of the material
|
|
1925
|
+
* @param rootUrl defines the root URL to use to load textures and relative dependencies
|
|
1926
|
+
* @param merge defines whether or not the source must be merged or replace the current content
|
|
1927
|
+
* @deprecated Please use the parseSerializedObject method instead
|
|
1928
|
+
*/
|
|
1929
|
+
loadFromSerialization(source, rootUrl = "", merge = false) {
|
|
1930
|
+
this.parseSerializedObject(source, rootUrl, merge);
|
|
1931
|
+
}
|
|
1932
|
+
/**
|
|
1933
|
+
* Makes a duplicate of the current material.
|
|
1934
|
+
* @param name defines the name to use for the new material
|
|
1935
|
+
* @param shareEffect defines if the clone material should share the same effect (default is false)
|
|
1936
|
+
* @returns the cloned material
|
|
1937
|
+
*/
|
|
1938
|
+
clone(name, shareEffect = false) {
|
|
1939
|
+
const serializationObject = this.serialize();
|
|
1940
|
+
const clone = SerializationHelper.Clone(() => new _a(name, this.getScene(), this.options), this);
|
|
1941
|
+
clone.parseSerializedObject(serializationObject);
|
|
1942
|
+
clone.id = name;
|
|
1943
|
+
clone.name = name;
|
|
1944
|
+
clone._buildId = this._buildId;
|
|
1945
|
+
clone.build(false, !shareEffect);
|
|
1946
|
+
return clone;
|
|
1947
|
+
}
|
|
1948
|
+
/**
|
|
1949
|
+
* Awaits for all the material textures to be ready before resolving the returned promise.
|
|
1950
|
+
* @returns A promise that resolves when the textures are ready.
|
|
1951
|
+
*/
|
|
1952
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax
|
|
1953
|
+
whenTexturesReadyAsync() {
|
|
1954
|
+
// Ensures all textures are ready to render.
|
|
1955
|
+
const textureReadyPromises = [];
|
|
1956
|
+
const activeTextures = this.getActiveTextures();
|
|
1957
|
+
for (const texture of activeTextures) {
|
|
1958
|
+
const internalTexture = texture.getInternalTexture();
|
|
1959
|
+
if (internalTexture && !internalTexture.isReady) {
|
|
1960
|
+
textureReadyPromises.push(new Promise((textureResolve, textureReject) => {
|
|
1961
|
+
internalTexture.onLoadedObservable.addOnce(() => {
|
|
1962
|
+
textureResolve();
|
|
1963
|
+
});
|
|
1964
|
+
internalTexture.onErrorObservable.addOnce((e) => {
|
|
1965
|
+
textureReject(_ErrorFromReason(e));
|
|
1966
|
+
});
|
|
1967
|
+
}));
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
return Promise.all(textureReadyPromises);
|
|
1971
|
+
}
|
|
1972
|
+
},
|
|
1973
|
+
(() => {
|
|
1974
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
1975
|
+
_ignoreAlpha_decorators = [serialize()];
|
|
1976
|
+
_maxSimultaneousLights_decorators = [serialize()];
|
|
1977
|
+
__mode_decorators = [serialize("mode")];
|
|
1978
|
+
_comment_decorators = [serialize("comment")];
|
|
1979
|
+
_forceAlphaBlending_decorators = [serialize()];
|
|
1980
|
+
__esDecorate(null, null, _ignoreAlpha_decorators, { kind: "field", name: "ignoreAlpha", static: false, private: false, access: { has: obj => "ignoreAlpha" in obj, get: obj => obj.ignoreAlpha, set: (obj, value) => { obj.ignoreAlpha = value; } }, metadata: _metadata }, _ignoreAlpha_initializers, _ignoreAlpha_extraInitializers);
|
|
1981
|
+
__esDecorate(null, null, _maxSimultaneousLights_decorators, { kind: "field", name: "maxSimultaneousLights", static: false, private: false, access: { has: obj => "maxSimultaneousLights" in obj, get: obj => obj.maxSimultaneousLights, set: (obj, value) => { obj.maxSimultaneousLights = value; } }, metadata: _metadata }, _maxSimultaneousLights_initializers, _maxSimultaneousLights_extraInitializers);
|
|
1982
|
+
__esDecorate(null, null, __mode_decorators, { kind: "field", name: "_mode", static: false, private: false, access: { has: obj => "_mode" in obj, get: obj => obj._mode, set: (obj, value) => { obj._mode = value; } }, metadata: _metadata }, __mode_initializers, __mode_extraInitializers);
|
|
1983
|
+
__esDecorate(null, null, _comment_decorators, { kind: "field", name: "comment", static: false, private: false, access: { has: obj => "comment" in obj, get: obj => obj.comment, set: (obj, value) => { obj.comment = value; } }, metadata: _metadata }, _comment_initializers, _comment_extraInitializers);
|
|
1984
|
+
__esDecorate(null, null, _forceAlphaBlending_decorators, { kind: "field", name: "forceAlphaBlending", static: false, private: false, access: { has: obj => "forceAlphaBlending" in obj, get: obj => obj.forceAlphaBlending, set: (obj, value) => { obj.forceAlphaBlending = value; } }, metadata: _metadata }, _forceAlphaBlending_initializers, _forceAlphaBlending_extraInitializers);
|
|
1985
|
+
if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
1986
|
+
})(),
|
|
1987
|
+
_a._BuildIdGenerator = 0,
|
|
1988
|
+
/** Define the Url to load node editor script */
|
|
1989
|
+
_a.EditorURL = `${Tools._DefaultCdnUrl}/v${AbstractEngine.Version}/nodeEditor/babylon.nodeEditor.js`,
|
|
1990
|
+
/** Define the Url to load snippets */
|
|
1991
|
+
_a.SnippetUrl = `https://snippet.babylonjs.com`,
|
|
1992
|
+
/** Gets or sets a boolean indicating that node materials should not deserialize textures from json / snippet content */
|
|
1993
|
+
_a.IgnoreTexturesAtLoadTime = false,
|
|
1994
|
+
/** Gets or sets a boolean indicating that render target textures can be serialized */
|
|
1995
|
+
_a.AllowSerializationOfRenderTargetTextures = false,
|
|
1996
|
+
/** Defines default shader language when no option is defined */
|
|
1997
|
+
_a.DefaultShaderLanguage = 0 /* ShaderLanguage.GLSL */,
|
|
1998
|
+
/** If true, the node material will use GLSL if the engine is WebGL and WGSL if it's WebGPU. It takes priority over DefaultShaderLanguage if it's true */
|
|
1999
|
+
_a.UseNativeShaderLanguageOfEngine = false,
|
|
2000
|
+
_a;
|
|
2001
|
+
})();
|
|
2002
|
+
export { NodeMaterial };
|
|
1977
2003
|
/**
|
|
1978
2004
|
* Checks if a block is a texture block
|
|
1979
2005
|
* @param block The block to check
|
|
@@ -2139,6 +2165,8 @@ export function RegisterNodeMaterial() {
|
|
|
2139
2165
|
return;
|
|
2140
2166
|
}
|
|
2141
2167
|
_Registered = true;
|
|
2168
|
+
// NodeMaterial serializes its image processing configuration, so the parser must be registered for clone/parse to work.
|
|
2169
|
+
RegisterImageProcessingConfiguration();
|
|
2142
2170
|
NodeMaterial._BlockIsTextureBlock = NodeMaterialBlockIsTextureBlock;
|
|
2143
2171
|
NodeMaterial.Parse = NodeMaterialParse;
|
|
2144
2172
|
NodeMaterial.ParseFromFileAsync = NodeMaterialParseFromFileAsync;
|