@onerjs/core 8.56.3 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Animations/animatable.core.js +36 -0
- package/Animations/animatable.core.js.map +1 -1
- package/Animations/animationGroup.pure.d.ts +61 -1
- package/Animations/animationGroup.pure.js +191 -2
- package/Animations/animationGroup.pure.js.map +1 -1
- package/Animations/index.d.ts +1 -0
- package/Animations/index.js +1 -0
- package/Animations/index.js.map +1 -1
- package/Animations/pure.d.ts +1 -0
- package/Animations/pure.js +1 -0
- package/Animations/pure.js.map +1 -1
- package/Animations/rootMotion.d.ts +560 -0
- package/Animations/rootMotion.js +1709 -0
- package/Animations/rootMotion.js.map +1 -0
- package/Animations/runtimeAnimation.d.ts +57 -0
- package/Animations/runtimeAnimation.js +127 -3
- package/Animations/runtimeAnimation.js.map +1 -1
- package/Cameras/arcRotateCamera.pure.d.ts +2 -0
- package/Cameras/arcRotateCamera.pure.js +2 -0
- package/Cameras/arcRotateCamera.pure.js.map +1 -1
- package/Cameras/camera.pure.js +4 -0
- package/Cameras/camera.pure.js.map +1 -1
- package/Cameras/targetCamera.pure.d.ts +2 -0
- package/Cameras/targetCamera.pure.js +7 -1
- package/Cameras/targetCamera.pure.js.map +1 -1
- package/Collisions/gpuPicker.js +5 -5
- package/Collisions/gpuPicker.js.map +1 -1
- package/Engines/AbstractEngine/abstractEngine.query.pure.js +4 -2
- package/Engines/AbstractEngine/abstractEngine.query.pure.js.map +1 -1
- package/Engines/AbstractEngine/abstractEngine.query.types.d.ts +11 -2
- package/Engines/AbstractEngine/abstractEngine.query.types.js.map +1 -1
- package/Engines/AbstractEngine/abstractEngine.renderPass.pure.js +1 -0
- package/Engines/AbstractEngine/abstractEngine.renderPass.pure.js.map +1 -1
- package/Engines/Extensions/engine.multiRender.pure.js +63 -0
- package/Engines/Extensions/engine.multiRender.pure.js.map +1 -1
- package/Engines/Extensions/engine.multiRender.types.d.ts +13 -0
- package/Engines/Extensions/engine.multiRender.types.js.map +1 -1
- package/Engines/Extensions/engine.prefilteredCubeTexture.pure.js +2 -2
- package/Engines/Extensions/engine.prefilteredCubeTexture.pure.js.map +1 -1
- package/Engines/Extensions/engine.prefilteredCubeTexture.types.d.ts +2 -1
- package/Engines/Extensions/engine.prefilteredCubeTexture.types.js.map +1 -1
- package/Engines/Extensions/index.d.ts +1 -0
- package/Engines/Extensions/index.js +1 -0
- package/Engines/Extensions/index.js.map +1 -1
- package/Engines/Extensions/pure.d.ts +1 -1
- package/Engines/Extensions/pure.js +1 -1
- package/Engines/Extensions/pure.js.map +1 -1
- package/Engines/Native/Extensions/nativeEngine.cubeTexture.pure.js +88 -39
- package/Engines/Native/Extensions/nativeEngine.cubeTexture.pure.js.map +1 -1
- package/Engines/Native/Extensions/nativeEngine.cubeTexture.types.d.ts +20 -2
- package/Engines/Native/Extensions/nativeEngine.cubeTexture.types.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.multiRender.pure.js +4 -0
- package/Engines/WebGPU/Extensions/engine.multiRender.pure.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.multiRender.types.d.ts +13 -0
- package/Engines/WebGPU/Extensions/engine.multiRender.types.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.query.pure.js +11 -3
- package/Engines/WebGPU/Extensions/engine.query.pure.js.map +1 -1
- package/Engines/WebGPU/Extensions/index.d.ts +1 -0
- package/Engines/WebGPU/Extensions/index.js +1 -0
- package/Engines/WebGPU/Extensions/index.js.map +1 -1
- package/Engines/WebGPU/Extensions/pure.d.ts +1 -1
- package/Engines/WebGPU/Extensions/pure.js +1 -1
- package/Engines/WebGPU/Extensions/pure.js.map +1 -1
- package/Engines/WebGPU/webgpuBundleList.d.ts +2 -0
- package/Engines/WebGPU/webgpuBundleList.js +4 -0
- package/Engines/WebGPU/webgpuBundleList.js.map +1 -1
- package/Engines/WebGPU/webgpuCacheRenderPipeline.js +5 -2
- package/Engines/WebGPU/webgpuCacheRenderPipeline.js.map +1 -1
- package/Engines/WebGPU/webgpuHardwareTexture.js +3 -1
- package/Engines/WebGPU/webgpuHardwareTexture.js.map +1 -1
- package/Engines/WebGPU/webgpuOcclusionQuery.js +1 -1
- package/Engines/WebGPU/webgpuOcclusionQuery.js.map +1 -1
- package/Engines/WebGPU/webgpuSnapshotRendering.d.ts +4 -0
- package/Engines/WebGPU/webgpuSnapshotRendering.js +40 -7
- package/Engines/WebGPU/webgpuSnapshotRendering.js.map +1 -1
- package/Engines/WebGPU/webgpuTextureHelper.d.ts +1 -1
- package/Engines/WebGPU/webgpuTextureHelper.js +2 -2
- package/Engines/WebGPU/webgpuTextureHelper.js.map +1 -1
- package/Engines/WebGPU/webgpuTextureManager.d.ts +2 -0
- package/Engines/WebGPU/webgpuTextureManager.js +286 -13
- package/Engines/WebGPU/webgpuTextureManager.js.map +1 -1
- package/Engines/abstractEngine.pure.d.ts +2 -0
- package/Engines/abstractEngine.pure.js +7 -3
- package/Engines/abstractEngine.pure.js.map +1 -1
- package/Engines/constants.d.ts +4 -0
- package/Engines/constants.js +4 -0
- package/Engines/constants.js.map +1 -1
- package/Engines/thinEngine.pure.d.ts +14 -0
- package/Engines/thinEngine.pure.js +48 -12
- package/Engines/thinEngine.pure.js.map +1 -1
- package/Engines/thinNativeEngine.pure.d.ts +1 -0
- package/Engines/thinNativeEngine.pure.js +7 -1
- package/Engines/thinNativeEngine.pure.js.map +1 -1
- package/Engines/thinWebGPUEngine.d.ts +4 -0
- package/Engines/thinWebGPUEngine.js +10 -1
- package/Engines/thinWebGPUEngine.js.map +1 -1
- package/Engines/webgpuEngine.pure.d.ts +5 -2
- package/Engines/webgpuEngine.pure.js +48 -13
- package/Engines/webgpuEngine.pure.js.map +1 -1
- package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.js +2 -2
- package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.js.map +1 -1
- package/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.d.ts +11 -2
- package/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.js +1 -1
- package/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.pure.d.ts +9 -1
- package/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.pure.js +6 -8
- package/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphPointerOutEventBlock.pure.d.ts +2 -0
- package/FlowGraph/Blocks/Event/flowGraphPointerOutEventBlock.pure.js +5 -1
- package/FlowGraph/Blocks/Event/flowGraphPointerOutEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphPointerOverEventBlock.pure.d.ts +2 -0
- package/FlowGraph/Blocks/Event/flowGraphPointerOverEventBlock.pure.js +5 -1
- package/FlowGraph/Blocks/Event/flowGraphPointerOverEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.d.ts +9 -0
- package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.js +34 -9
- package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.d.ts +2 -0
- package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.js +4 -0
- package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.d.ts +2 -0
- package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.js +4 -0
- package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphSendCustomEventBlock.pure.js +19 -7
- package/FlowGraph/Blocks/Event/flowGraphSendCustomEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.d.ts +20 -2
- package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.js +53 -10
- package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.d.ts +16 -1
- package/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.js +64 -14
- package/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Execution/flowGraphConsoleLogBlock.pure.js +64 -16
- package/FlowGraph/Blocks/Execution/flowGraphConsoleLogBlock.pure.js.map +1 -1
- package/FlowGraph/flowGraph.d.ts +4 -0
- package/FlowGraph/flowGraph.js +38 -7
- package/FlowGraph/flowGraph.js.map +1 -1
- package/FlowGraph/flowGraphBlock.js +3 -0
- package/FlowGraph/flowGraphBlock.js.map +1 -1
- package/FlowGraph/flowGraphConnection.d.ts +7 -0
- package/FlowGraph/flowGraphConnection.js +7 -0
- package/FlowGraph/flowGraphConnection.js.map +1 -1
- package/FlowGraph/flowGraphContext.d.ts +2 -1
- package/FlowGraph/flowGraphContext.js +4 -3
- package/FlowGraph/flowGraphContext.js.map +1 -1
- package/FlowGraph/flowGraphCoordinator.d.ts +15 -1
- package/FlowGraph/flowGraphCoordinator.js +47 -16
- package/FlowGraph/flowGraphCoordinator.js.map +1 -1
- package/FlowGraph/flowGraphEventBlock.d.ts +5 -0
- package/FlowGraph/flowGraphEventBlock.js +7 -0
- package/FlowGraph/flowGraphEventBlock.js.map +1 -1
- package/FlowGraph/flowGraphHostResolver.d.ts +2 -1
- package/FlowGraph/flowGraphHostResolver.js.map +1 -1
- package/FlowGraph/flowGraphParser.js +60 -2
- package/FlowGraph/flowGraphParser.js.map +1 -1
- package/FlowGraph/serialization.d.ts +2 -0
- package/FlowGraph/serialization.js +10 -22
- package/FlowGraph/serialization.js.map +1 -1
- package/FlowGraph/typeDefinitions.d.ts +8 -0
- package/FlowGraph/typeDefinitions.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/meshBlendingPostProcessBlock.d.ts +5 -0
- package/FrameGraph/Node/Blocks/PostProcesses/meshBlendingPostProcessBlock.js +8 -0
- package/FrameGraph/Node/Blocks/PostProcesses/meshBlendingPostProcessBlock.js.map +1 -0
- package/FrameGraph/Node/Blocks/PostProcesses/meshBlendingPostProcessBlock.pure.d.ts +87 -0
- package/FrameGraph/Node/Blocks/PostProcesses/meshBlendingPostProcessBlock.pure.js +295 -0
- package/FrameGraph/Node/Blocks/PostProcesses/meshBlendingPostProcessBlock.pure.js.map +1 -0
- package/FrameGraph/Node/Blocks/PostProcesses/pure.d.ts +1 -0
- package/FrameGraph/Node/Blocks/PostProcesses/pure.js +1 -0
- package/FrameGraph/Node/Blocks/PostProcesses/pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/Rendering/baseObjectRendererBlock.js +4 -4
- package/FrameGraph/Node/Blocks/Rendering/baseObjectRendererBlock.js.map +1 -1
- package/FrameGraph/Node/Blocks/Rendering/geometryRendererBlock.pure.d.ts +5 -1
- package/FrameGraph/Node/Blocks/Rendering/geometryRendererBlock.pure.js +13 -1
- package/FrameGraph/Node/Blocks/Rendering/geometryRendererBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/allBlocks.pure.js +2 -0
- package/FrameGraph/Node/Blocks/allBlocks.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/index.d.ts +1 -0
- package/FrameGraph/Node/Blocks/index.js +1 -0
- package/FrameGraph/Node/Blocks/index.js.map +1 -1
- package/FrameGraph/Node/Blocks/inputBlock.pure.js +20 -1
- package/FrameGraph/Node/Blocks/inputBlock.pure.js.map +1 -1
- package/FrameGraph/Node/Blocks/pure.d.ts +1 -0
- package/FrameGraph/Node/Blocks/pure.js +1 -0
- package/FrameGraph/Node/Blocks/pure.js.map +1 -1
- package/FrameGraph/Node/Types/nodeRenderGraphTypes.d.ts +4 -2
- package/FrameGraph/Node/Types/nodeRenderGraphTypes.js +4 -2
- package/FrameGraph/Node/Types/nodeRenderGraphTypes.js.map +1 -1
- package/FrameGraph/Node/nodeRenderGraph.js +1 -1
- package/FrameGraph/Node/nodeRenderGraph.js.map +1 -1
- package/FrameGraph/Tasks/Layers/selectionOutlineTask.js +1 -0
- package/FrameGraph/Tasks/Layers/selectionOutlineTask.js.map +1 -1
- package/FrameGraph/Tasks/Misc/cullObjectsTask.js +5 -1
- package/FrameGraph/Tasks/Misc/cullObjectsTask.js.map +1 -1
- package/FrameGraph/Tasks/Misc/lightingVolumeTask.js +1 -0
- package/FrameGraph/Tasks/Misc/lightingVolumeTask.js.map +1 -1
- package/FrameGraph/Tasks/PostProcesses/meshBlendingTask.d.ts +69 -0
- package/FrameGraph/Tasks/PostProcesses/meshBlendingTask.js +223 -0
- package/FrameGraph/Tasks/PostProcesses/meshBlendingTask.js.map +1 -0
- package/FrameGraph/Tasks/Rendering/geometryRendererTask.d.ts +25 -3
- package/FrameGraph/Tasks/Rendering/geometryRendererTask.js +69 -33
- package/FrameGraph/Tasks/Rendering/geometryRendererTask.js.map +1 -1
- package/FrameGraph/Tasks/Rendering/objectRendererTask.js +3 -1
- package/FrameGraph/Tasks/Rendering/objectRendererTask.js.map +1 -1
- package/FrameGraph/frameGraphObjectList.d.ts +6 -1
- package/FrameGraph/frameGraphObjectList.js.map +1 -1
- package/FrameGraph/frameGraphRenderContext.d.ts +3 -1
- package/FrameGraph/frameGraphRenderContext.js +5 -5
- package/FrameGraph/frameGraphRenderContext.js.map +1 -1
- package/FrameGraph/index.d.ts +1 -0
- package/FrameGraph/index.js +1 -0
- package/FrameGraph/index.js.map +1 -1
- package/FrameGraph/pure.d.ts +1 -0
- package/FrameGraph/pure.js +1 -0
- package/FrameGraph/pure.js.map +1 -1
- package/Inputs/scene.inputManager.d.ts +4 -0
- package/Inputs/scene.inputManager.js +50 -8
- package/Inputs/scene.inputManager.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js +5 -5
- package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.js +5 -5
- package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.d.ts +26 -1
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.js +151 -47
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.js +5 -5
- package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.js.map +1 -1
- package/Materials/Node/Blocks/Fragment/fragmentOutputBlock.pure.js +11 -1
- package/Materials/Node/Blocks/Fragment/fragmentOutputBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/Fragment/prePassOutputBlock.pure.js +17 -2
- package/Materials/Node/Blocks/Fragment/prePassOutputBlock.pure.js.map +1 -1
- package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.pure.js +2 -2
- package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.pure.js.map +1 -1
- package/Materials/Node/nodeMaterial.pure.d.ts +4 -0
- package/Materials/Node/nodeMaterial.pure.js +4 -0
- package/Materials/Node/nodeMaterial.pure.js.map +1 -1
- package/Materials/Node/nodeMaterialBuildState.d.ts +1 -1
- package/Materials/Node/nodeMaterialBuildState.js +25 -3
- package/Materials/Node/nodeMaterialBuildState.js.map +1 -1
- package/Materials/PBR/openpbrMaterial.pure.d.ts +2 -0
- package/Materials/PBR/pbrBaseMaterial.pure.d.ts +2 -0
- package/Materials/Textures/Procedurals/proceduralTexture.pure.d.ts +13 -14
- package/Materials/Textures/Procedurals/proceduralTexture.pure.js +6 -6
- package/Materials/Textures/Procedurals/proceduralTexture.pure.js.map +1 -1
- package/Materials/Textures/baseTexture.pure.js +3 -0
- package/Materials/Textures/baseTexture.pure.js.map +1 -1
- package/Materials/Textures/cubeTexture.pure.js +1 -1
- package/Materials/Textures/cubeTexture.pure.js.map +1 -1
- package/Materials/Textures/internalTexture.d.ts +8 -1
- package/Materials/Textures/internalTexture.js +9 -2
- package/Materials/Textures/internalTexture.js.map +1 -1
- package/Materials/Textures/rawTexture2DArray.functions.d.ts +3 -3
- package/Materials/Textures/rawTexture2DArray.functions.js.map +1 -1
- package/Materials/Textures/rawTexture3D.d.ts +1 -1
- package/Materials/Textures/rawTexture3D.js +1 -1
- package/Materials/Textures/rawTexture3D.js.map +1 -1
- package/Materials/Textures/textureHelper.functions.d.ts +14 -0
- package/Materials/Textures/textureHelper.functions.js +24 -0
- package/Materials/Textures/textureHelper.functions.js.map +1 -1
- package/Materials/ditheredTileFadeMaterialPlugin.d.ts +210 -0
- package/Materials/ditheredTileFadeMaterialPlugin.js +509 -0
- package/Materials/ditheredTileFadeMaterialPlugin.js.map +1 -0
- package/Materials/index.d.ts +1 -0
- package/Materials/index.js +1 -0
- package/Materials/index.js.map +1 -1
- package/Materials/materialHelper.geometryrendering.d.ts +46 -1
- package/Materials/materialHelper.geometryrendering.js +105 -8
- package/Materials/materialHelper.geometryrendering.js.map +1 -1
- package/Materials/prepass.defines.d.ts +2 -0
- package/Materials/prepass.defines.js +2 -0
- package/Materials/prepass.defines.js.map +1 -1
- package/Materials/pure.d.ts +1 -0
- package/Materials/pure.js +1 -0
- package/Materials/pure.js.map +1 -1
- package/Materials/standardMaterial.pure.d.ts +2 -0
- package/Materials/standardMaterial.pure.js +6 -3
- package/Materials/standardMaterial.pure.js.map +1 -1
- package/Meshes/Builders/polygonBuilder.pure.d.ts +4 -0
- package/Meshes/Builders/polygonBuilder.pure.js +4 -1
- package/Meshes/Builders/polygonBuilder.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplatting.functions.d.ts +19 -0
- package/Meshes/GaussianSplatting/gaussianSplatting.functions.js +23 -0
- package/Meshes/GaussianSplatting/gaussianSplatting.functions.js.map +1 -0
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.d.ts +3 -14
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js +20 -24
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +2 -0
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +11 -4
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
- package/Meshes/abstractMesh.pure.d.ts +18 -0
- package/Meshes/abstractMesh.pure.js +22 -0
- package/Meshes/abstractMesh.pure.js.map +1 -1
- package/Meshes/index.d.ts +1 -0
- package/Meshes/index.js +1 -0
- package/Meshes/index.js.map +1 -1
- package/Meshes/instancedMesh.pure.d.ts +5 -0
- package/Meshes/instancedMesh.pure.js +12 -0
- package/Meshes/instancedMesh.pure.js.map +1 -1
- package/Meshes/mesh.pure.js +23 -8
- package/Meshes/mesh.pure.js.map +1 -1
- package/Meshes/meshBlendingTag.d.ts +47 -0
- package/Meshes/meshBlendingTag.js +64 -0
- package/Meshes/meshBlendingTag.js.map +1 -0
- package/Meshes/polygonMesh.js +2 -2
- package/Meshes/polygonMesh.js.map +1 -1
- package/Meshes/pure.d.ts +1 -0
- package/Meshes/pure.js +1 -0
- package/Meshes/pure.js.map +1 -1
- package/Misc/fileTools.pure.js +21 -0
- package/Misc/fileTools.pure.js.map +1 -1
- package/Misc/snapshotRenderingHelper.js +2 -2
- package/Misc/snapshotRenderingHelper.js.map +1 -1
- package/Misc/tools.pure.js +1 -1
- package/Misc/tools.pure.js.map +1 -1
- package/Particles/gpuParticleSystem.pure.d.ts +2 -0
- package/Particles/gpuParticleSystem.pure.js +89 -28
- package/Particles/gpuParticleSystem.pure.js.map +1 -1
- package/Particles/thinParticleSystem.pure.d.ts +2 -0
- package/Particles/thinParticleSystem.pure.js +84 -19
- package/Particles/thinParticleSystem.pure.js.map +1 -1
- package/Particles/webgl2ParticleSystem.pure.d.ts +1 -0
- package/Particles/webgl2ParticleSystem.pure.js +12 -4
- package/Particles/webgl2ParticleSystem.pure.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.pure.js +7 -0
- package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.pure.js.map +1 -1
- package/PostProcesses/index.d.ts +2 -0
- package/PostProcesses/index.js +2 -0
- package/PostProcesses/index.js.map +1 -1
- package/PostProcesses/meshBlendingBlueNoise.d.ts +15 -0
- package/PostProcesses/meshBlendingBlueNoise.js +77 -0
- package/PostProcesses/meshBlendingBlueNoise.js.map +1 -0
- package/PostProcesses/meshBlendingPostProcess.d.ts +131 -0
- package/PostProcesses/meshBlendingPostProcess.js +315 -0
- package/PostProcesses/meshBlendingPostProcess.js.map +1 -0
- package/PostProcesses/pure.d.ts +2 -0
- package/PostProcesses/pure.js +2 -0
- package/PostProcesses/pure.js.map +1 -1
- package/PostProcesses/thinMeshBlendingPostProcess.d.ts +339 -0
- package/PostProcesses/thinMeshBlendingPostProcess.js +771 -0
- package/PostProcesses/thinMeshBlendingPostProcess.js.map +1 -0
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.pure.js +6 -6
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.pure.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.js +8 -8
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.js.map +1 -1
- package/Rendering/boundingBoxRenderer.pure.js +2 -1
- package/Rendering/boundingBoxRenderer.pure.js.map +1 -1
- package/Rendering/depthRenderer.pure.js +3 -4
- package/Rendering/depthRenderer.pure.js.map +1 -1
- package/Rendering/edgesRenderer.pure.d.ts +4 -2
- package/Rendering/edgesRenderer.pure.js +11 -2
- package/Rendering/edgesRenderer.pure.js.map +1 -1
- package/Rendering/fluidRenderer/fluidRenderingObject.d.ts +10 -0
- package/Rendering/fluidRenderer/fluidRenderingObject.js +20 -0
- package/Rendering/fluidRenderer/fluidRenderingObject.js.map +1 -1
- package/Rendering/fluidRenderer/fluidRenderingObjectParticleSystem.d.ts +9 -3
- package/Rendering/fluidRenderer/fluidRenderingObjectParticleSystem.js +14 -9
- package/Rendering/fluidRenderer/fluidRenderingObjectParticleSystem.js.map +1 -1
- package/Rendering/geometryBufferRenderer.pure.d.ts +38 -4
- package/Rendering/geometryBufferRenderer.pure.js +126 -17
- package/Rendering/geometryBufferRenderer.pure.js.map +1 -1
- package/Rendering/objectRenderer.d.ts +7 -1
- package/Rendering/objectRenderer.js +45 -7
- package/Rendering/objectRenderer.js.map +1 -1
- package/Rendering/outlineRenderer.pure.js +6 -2
- package/Rendering/outlineRenderer.pure.js.map +1 -1
- package/Rendering/renderingManager.d.ts +1 -1
- package/Rendering/renderingManager.js +5 -4
- package/Rendering/renderingManager.js.map +1 -1
- package/Shaders/ShadersInclude/defaultFragmentAlpha.d.ts +5 -0
- package/Shaders/ShadersInclude/defaultFragmentAlpha.js +34 -0
- package/Shaders/ShadersInclude/defaultFragmentAlpha.js.map +1 -0
- package/Shaders/ShadersInclude/gaussianSplattingVertexDeclaration.js +5 -1
- package/Shaders/ShadersInclude/gaussianSplattingVertexDeclaration.js.map +1 -1
- package/Shaders/ShadersInclude/geometryRenderingFragment.d.ts +5 -0
- package/Shaders/ShadersInclude/geometryRenderingFragment.js +74 -0
- package/Shaders/ShadersInclude/geometryRenderingFragment.js.map +1 -0
- package/Shaders/ShadersInclude/mrtFragmentDeclaration.js +89 -0
- package/Shaders/ShadersInclude/mrtFragmentDeclaration.js.map +1 -1
- package/Shaders/ShadersInclude/openpbrBlockPrePass.js +24 -17
- package/Shaders/ShadersInclude/openpbrBlockPrePass.js.map +1 -1
- package/Shaders/ShadersInclude/pbrBlockPrePass.js +27 -20
- package/Shaders/ShadersInclude/pbrBlockPrePass.js.map +1 -1
- package/Shaders/ShadersInclude/pbrDebug.js +6 -2
- package/Shaders/ShadersInclude/pbrDebug.js.map +1 -1
- package/Shaders/ShadersInclude/prePassDeclaration.js +95 -2
- package/Shaders/ShadersInclude/prePassDeclaration.js.map +1 -1
- package/Shaders/default.fragment.js +31 -40
- package/Shaders/default.fragment.js.map +1 -1
- package/Shaders/depthOfField.fragment.js +13 -9
- package/Shaders/depthOfField.fragment.js.map +1 -1
- package/Shaders/fluidRenderingParticleDepth.vertex.js +16 -1
- package/Shaders/fluidRenderingParticleDepth.vertex.js.map +1 -1
- package/Shaders/fluidRenderingParticleThickness.vertex.js +16 -1
- package/Shaders/fluidRenderingParticleThickness.vertex.js.map +1 -1
- package/Shaders/gaussianSplatting.fragment.js +63 -3
- package/Shaders/gaussianSplatting.fragment.js.map +1 -1
- package/Shaders/gaussianSplatting.vertex.js +80 -0
- package/Shaders/gaussianSplatting.vertex.js.map +1 -1
- package/Shaders/geometry.fragment.js +17 -11
- package/Shaders/geometry.fragment.js.map +1 -1
- package/Shaders/gpuRenderParticles.fragment.js +43 -1
- package/Shaders/gpuRenderParticles.fragment.js.map +1 -1
- package/Shaders/gpuRenderParticles.vertex.js +96 -16
- package/Shaders/gpuRenderParticles.vertex.js.map +1 -1
- package/Shaders/meshBlending.fragment.d.ts +5 -0
- package/Shaders/meshBlending.fragment.js +519 -0
- package/Shaders/meshBlending.fragment.js.map +1 -0
- package/Shaders/particles.fragment.js +43 -1
- package/Shaders/particles.fragment.js.map +1 -1
- package/Shaders/particles.vertex.js +84 -3
- package/Shaders/particles.vertex.js.map +1 -1
- package/Shaders/sprites.fragment.js +52 -2
- package/Shaders/sprites.fragment.js.map +1 -1
- package/Shaders/sprites.vertex.js +62 -1
- package/Shaders/sprites.vertex.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/defaultFragmentAlpha.d.ts +5 -0
- package/ShadersWGSL/ShadersInclude/defaultFragmentAlpha.js +33 -0
- package/ShadersWGSL/ShadersInclude/defaultFragmentAlpha.js.map +1 -0
- package/ShadersWGSL/ShadersInclude/geometryRenderingFragment.d.ts +6 -0
- package/ShadersWGSL/ShadersInclude/geometryRenderingFragment.js +76 -0
- package/ShadersWGSL/ShadersInclude/geometryRenderingFragment.js.map +1 -0
- package/ShadersWGSL/ShadersInclude/lightFragment.js +1 -1
- package/ShadersWGSL/ShadersInclude/lightFragment.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/meshBlendTagFragmentOutput.d.ts +5 -0
- package/ShadersWGSL/ShadersInclude/meshBlendTagFragmentOutput.js +18 -0
- package/ShadersWGSL/ShadersInclude/meshBlendTagFragmentOutput.js.map +1 -0
- package/ShadersWGSL/ShadersInclude/openpbrBlockPrePass.d.ts +1 -0
- package/ShadersWGSL/ShadersInclude/openpbrBlockPrePass.js +11 -25
- package/ShadersWGSL/ShadersInclude/openpbrBlockPrePass.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/pbrBlockPrePass.d.ts +1 -0
- package/ShadersWGSL/ShadersInclude/pbrBlockPrePass.js +11 -25
- package/ShadersWGSL/ShadersInclude/pbrBlockPrePass.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/pbrDebug.js +5 -1
- package/ShadersWGSL/ShadersInclude/pbrDebug.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/prePassDeclaration.js +6 -1
- package/ShadersWGSL/ShadersInclude/prePassDeclaration.js.map +1 -1
- package/ShadersWGSL/default.fragment.js +17 -48
- package/ShadersWGSL/default.fragment.js.map +1 -1
- package/ShadersWGSL/fluidRenderingParticleDepth.vertex.js +15 -2
- package/ShadersWGSL/fluidRenderingParticleDepth.vertex.js.map +1 -1
- package/ShadersWGSL/fluidRenderingParticleThickness.vertex.js +15 -2
- package/ShadersWGSL/fluidRenderingParticleThickness.vertex.js.map +1 -1
- package/ShadersWGSL/gaussianSplatting.fragment.js +63 -2
- package/ShadersWGSL/gaussianSplatting.fragment.js.map +1 -1
- package/ShadersWGSL/gaussianSplatting.vertex.js +80 -0
- package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
- package/ShadersWGSL/geometry.fragment.js +37 -2
- package/ShadersWGSL/geometry.fragment.js.map +1 -1
- package/ShadersWGSL/gpuRenderParticles.fragment.js +47 -2
- package/ShadersWGSL/gpuRenderParticles.fragment.js.map +1 -1
- package/ShadersWGSL/gpuRenderParticles.vertex.js +110 -7
- package/ShadersWGSL/gpuRenderParticles.vertex.js.map +1 -1
- package/ShadersWGSL/meshBlending.fragment.d.ts +5 -0
- package/ShadersWGSL/meshBlending.fragment.js +576 -0
- package/ShadersWGSL/meshBlending.fragment.js.map +1 -0
- package/ShadersWGSL/openpbr.fragment.js +2 -1
- package/ShadersWGSL/openpbr.fragment.js.map +1 -1
- package/ShadersWGSL/particles.fragment.js +45 -1
- package/ShadersWGSL/particles.fragment.js.map +1 -1
- package/ShadersWGSL/particles.vertex.js +86 -4
- package/ShadersWGSL/particles.vertex.js.map +1 -1
- package/ShadersWGSL/pbr.fragment.js +2 -1
- package/ShadersWGSL/pbr.fragment.js.map +1 -1
- package/ShadersWGSL/sprites.fragment.js +56 -2
- package/ShadersWGSL/sprites.fragment.js.map +1 -1
- package/ShadersWGSL/sprites.vertex.js +62 -1
- package/ShadersWGSL/sprites.vertex.js.map +1 -1
- package/Sprites/spriteManager.d.ts +13 -0
- package/Sprites/spriteManager.js +15 -0
- package/Sprites/spriteManager.js.map +1 -1
- package/Sprites/spriteRenderer.d.ts +24 -1
- package/Sprites/spriteRenderer.js +368 -50
- package/Sprites/spriteRenderer.js.map +1 -1
- package/Sprites/thinSprite.d.ts +4 -0
- package/Sprites/thinSprite.js +4 -0
- package/Sprites/thinSprite.js.map +1 -1
- package/States/alphaCullingState.d.ts +3 -1
- package/States/alphaCullingState.js +18 -3
- package/States/alphaCullingState.js.map +1 -1
- package/XR/webXRDefaultExperience.d.ts +5 -1
- package/XR/webXRDefaultExperience.js.map +1 -1
- package/XR/webXREnterExitUI.d.ts +2 -1
- package/XR/webXREnterExitUI.js.map +1 -1
- package/package.json +1 -1
- package/scene.pure.d.ts +23 -0
- package/scene.pure.js +35 -0
- package/scene.pure.js.map +1 -1
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
// Do not edit.
|
|
2
|
+
import { ShaderStore } from "../Engines/shaderStore.js";
|
|
3
|
+
const name = "meshBlendingPixelShader";
|
|
4
|
+
const shader = `precision highp float;precision highp int;varying vec2 vUV;uniform sampler2D textureSampler;uniform highp usampler2D meshBlendTagSampler;uniform sampler2D meshBlendDepthSampler;
|
|
5
|
+
#ifdef MESH_BLEND_SHADOW_ESTIMATION
|
|
6
|
+
uniform sampler2D meshBlendBaseColorSampler;
|
|
7
|
+
#endif
|
|
8
|
+
uniform sampler2D meshBlendBlueNoiseSampler;uniform mat4 projection;uniform mat4 inverseProjection;uniform mat4 inverseView;uniform vec4 blendWorldRadii;uniform vec4 minimumProjectedRadii;uniform float meshBlendIsOrthographic;uniform float slopeFactor;
|
|
9
|
+
#ifndef MESH_BLEND_DIRECTION_COUNT
|
|
10
|
+
#define MESH_BLEND_DIRECTION_COUNT 3
|
|
11
|
+
#define MESH_BLEND_RADIAL_SAMPLE_COUNT 3
|
|
12
|
+
#define MESH_BLEND_DIRECTION_REFINEMENT_SAMPLE_COUNT 2
|
|
13
|
+
#define MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT 4
|
|
14
|
+
#define MESH_BLEND_EXACT_EDGE_SAMPLE_COUNT 8
|
|
15
|
+
#define MESH_BLEND_RADIUS_SCALE 0.9
|
|
16
|
+
#define MESH_BLEND_JITTER_FACTOR 0.5
|
|
17
|
+
#define MESH_BLEND_COLOR_INTERPOLATION_OKLAB
|
|
18
|
+
#endif
|
|
19
|
+
#define MESH_BLEND_TWO_PI 6.283185307179586
|
|
20
|
+
#define MESH_BLEND_EPSILON 0.00001
|
|
21
|
+
#define MESH_BLEND_DIRECTION_REFINEMENT_SECTOR_SCALE 0.2
|
|
22
|
+
#define MESH_BLEND_TINY_OBJECT_PROBE_COUNT 8
|
|
23
|
+
#define MESH_BLEND_MIN_SLOPE_SCALE 0.25
|
|
24
|
+
#define MESH_BLEND_BOUNDARY_SEPARATION_FACTOR 0.75
|
|
25
|
+
#define MESH_BLEND_BOUNDARY_PIXEL_TOLERANCE 3.0
|
|
26
|
+
#define MESH_BLEND_FOREGROUND_DEPTH_FACTOR 0.35
|
|
27
|
+
#define MESH_BLEND_FOREGROUND_LATERAL_FACTOR 2.0
|
|
28
|
+
#define MESH_BLEND_TARGET_SPAN_FACTOR 1.5
|
|
29
|
+
#define MESH_BLEND_TOTAL_SPAN_FACTOR 2.5
|
|
30
|
+
#define MESH_BLEND_NEAR_EDGE_TARGET_WEIGHT 0.35
|
|
31
|
+
#define MESH_BLEND_NEAR_SEAM_MAX_DISTANCE 1.25
|
|
32
|
+
#define MESH_BLEND_NEAR_SEAM_COLOR_DELTA 0.02
|
|
33
|
+
#define MESH_BLEND_BASE_LUMINANCE_EPSILON 0.00001
|
|
34
|
+
#define MESH_BLEND_TARGET_DARKER_RATIO 0.65
|
|
35
|
+
#define MESH_BLEND_TARGET_NON_DARK_RATIO 0.9
|
|
36
|
+
#define MESH_BLEND_SHADOW_DIFFERENCE_LOW 0.15
|
|
37
|
+
#define MESH_BLEND_SHADOW_DIFFERENCE_HIGH 0.5
|
|
38
|
+
#define MESH_BLEND_SHADOW_MIN_ATTENUATION 0.25
|
|
39
|
+
#define MESH_BLEND_REJECTION_NONE 0
|
|
40
|
+
#define MESH_BLEND_REJECTION_NO_CANDIDATE 1
|
|
41
|
+
#define MESH_BLEND_REJECTION_NO_CONTINUATION 2
|
|
42
|
+
#define MESH_BLEND_REJECTION_INVALID_DEPTH 3
|
|
43
|
+
#define MESH_BLEND_REJECTION_DEPTH_SEPARATION 4
|
|
44
|
+
#define MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND 5
|
|
45
|
+
#define MESH_BLEND_REJECTION_PHYSICAL_SPAN 6
|
|
46
|
+
#define MESH_BLEND_REJECTION_CONTACT_ANGLE 7
|
|
47
|
+
struct MeshBlendTag {uint groupId;uint radiusClass;};struct MeshBlendCandidate {uint targetGroupId;uint radiusClass;vec2 direction;float distancePixels;float searchRadiusPixels;float score;bool valid;};struct MeshBlendResult {MeshBlendCandidate candidate;ivec2 targetPixel;ivec2 targetFarPixel;vec3 currentViewPosition;float effectiveRadiusPixels;float fade;float tinyObjectRadiusRatio;int rejectionReason;int stageReached;bool valid;bool continuationFound;bool usedFallback;bool tinyObjectRadiusReduced;};struct MeshBlendTargetColorSamples {vec4 fartherColor;vec4 boundaryPlusOneColor;vec4 boundaryPlusTwoColor;vec4 conservativeNearColor;vec4 targetColor;
|
|
48
|
+
#ifdef MESH_BLEND_SHADOW_ESTIMATION
|
|
49
|
+
vec3 fartherBaseColor;vec3 conservativeNearBaseColor;
|
|
50
|
+
#endif
|
|
51
|
+
bool onePixelEdge;};struct MeshBlendColorEvaluation {MeshBlendTargetColorSamples samples;vec4 currentColor;vec4 blendedColor;
|
|
52
|
+
#ifdef MESH_BLEND_DEBUG_WORLD_POSITION
|
|
53
|
+
vec3 worldPosition;
|
|
54
|
+
#endif
|
|
55
|
+
float shadowAttenuation;float adjustedFade;bool nearSeamCorrected;};ivec2 clampPixel(ivec2 pixel,ivec2 renderSize) {return clamp(pixel,ivec2(0),renderSize-ivec2(1));}
|
|
56
|
+
bool isPixelInBounds(ivec2 pixel,ivec2 renderSize) {return pixel.x>=0 && pixel.y>=0 && pixel.x<renderSize.x && pixel.y<renderSize.y;}
|
|
57
|
+
vec2 pixelToUv(ivec2 pixel,ivec2 renderSize) {return (vec2(clampPixel(pixel,renderSize))+vec2(0.5))/vec2(renderSize);}
|
|
58
|
+
MeshBlendTag loadMeshBlendTag(ivec2 pixel,ivec2 renderSize) {uint packedTag=texelFetch(meshBlendTagSampler,clampPixel(pixel,renderSize),0).r;MeshBlendTag tag;tag.groupId=packedTag & 0x3fu;tag.radiusClass=packedTag>>6u;return tag;}
|
|
59
|
+
float loadMeshBlendDepth(ivec2 pixel,ivec2 renderSize) {return texelFetch(meshBlendDepthSampler,clampPixel(pixel,renderSize),0).r;}
|
|
60
|
+
float classValue(vec4 values,uint index) {if (index==0u) {return values.x;}
|
|
61
|
+
if (index==1u) {return values.y;}
|
|
62
|
+
if (index==2u) {return values.z;}
|
|
63
|
+
return values.w;}
|
|
64
|
+
float meshBlendDepthToNdc(float depth) {
|
|
65
|
+
#ifdef MESH_BLEND_DEPTH_SCREEN
|
|
66
|
+
#ifdef IS_NDC_HALF_ZRANGE
|
|
67
|
+
return depth;
|
|
68
|
+
#else
|
|
69
|
+
return depth*2.0-1.0;
|
|
70
|
+
#endif
|
|
71
|
+
#else
|
|
72
|
+
vec4 projectedDepth=projection*vec4(0.0,0.0,depth,1.0);return projectedDepth.z/projectedDepth.w;
|
|
73
|
+
#endif
|
|
74
|
+
}
|
|
75
|
+
vec3 reconstructMeshBlendViewPosition(ivec2 pixel,ivec2 renderSize,float depth) {vec2 ndcXY=pixelToUv(pixel,renderSize)*2.0-1.0;vec4 viewPosition=inverseProjection*vec4(ndcXY,meshBlendDepthToNdc(depth),1.0);return viewPosition.xyz/viewPosition.w;}
|
|
76
|
+
vec3 reconstructMeshBlendWorldPosition(vec3 viewPosition) {return (inverseView*vec4(viewPosition,1.0)).xyz;}
|
|
77
|
+
bool isValidMeshBlendPosition(vec3 position) {return !any(isnan(position)) && !any(isinf(position));}
|
|
78
|
+
float meshBlendProjectionScale(float renderHeight) {return max(0.5*renderHeight*abs(projection[1][1]),MESH_BLEND_EPSILON);}
|
|
79
|
+
float searchRadiusForClass(uint radiusClass,float viewDepth,float renderHeight) {float projectionScale=meshBlendProjectionScale(renderHeight);float projectedWorldRadius=classValue(blendWorldRadii,radiusClass)*projectionScale;if (meshBlendIsOrthographic<0.5) {projectedWorldRadius/=max(viewDepth,MESH_BLEND_EPSILON);}
|
|
80
|
+
float scaledRadius=max(projectedWorldRadius,classValue(minimumProjectedRadii,radiusClass))*MESH_BLEND_RADIUS_SCALE;return scaledRadius>0.0 ? max(1.0,scaledRadius) : 0.0;}
|
|
81
|
+
float worldUnitsPerPixel(float viewDepth,float renderHeight) {float unitsPerPixel=1.0/meshBlendProjectionScale(renderHeight);return meshBlendIsOrthographic>0.5 ? unitsPerPixel : unitsPerPixel*max(viewDepth,MESH_BLEND_EPSILON);}
|
|
82
|
+
float calculateSlopeScale(float oppositeFacing) {if (slopeFactor<=1.0) {return 1.0;}
|
|
83
|
+
return MESH_BLEND_MIN_SLOPE_SCALE +
|
|
84
|
+
(1.0-MESH_BLEND_MIN_SLOPE_SCALE)*pow(clamp(oppositeFacing,0.0,1.0),slopeFactor-1.0);}
|
|
85
|
+
vec2 loadStableBlueNoise(ivec2 pixel) {ivec2 noiseSize=textureSize(meshBlendBlueNoiseSampler,0);ivec2 wrappedPixel=ivec2(pixel.x % noiseSize.x,pixel.y % noiseSize.y);return texelFetch(meshBlendBlueNoiseSampler,wrappedPixel,0).rg;}
|
|
86
|
+
vec2 directionAt(int index,float rotation,float sectorAngle,vec2 direction0,vec2 direction1,vec2 direction2) {
|
|
87
|
+
#if MESH_BLEND_DIRECTION_COUNT==3
|
|
88
|
+
if (index==0) {return direction0;}
|
|
89
|
+
if (index==1) {return direction1;}
|
|
90
|
+
return direction2;
|
|
91
|
+
#else
|
|
92
|
+
float angle=rotation+sectorAngle*float(index);return vec2(cos(angle),sin(angle));
|
|
93
|
+
#endif
|
|
94
|
+
}
|
|
95
|
+
MeshBlendCandidate invalidCandidate() {MeshBlendCandidate candidate;candidate.targetGroupId=0u;candidate.radiusClass=0u;candidate.direction=vec2(0.0);candidate.distancePixels=0.0;candidate.searchRadiusPixels=0.0;candidate.score=-1.0;candidate.valid=false;return candidate;}
|
|
96
|
+
MeshBlendResult invalidBlendResult() {MeshBlendResult result;result.candidate=invalidCandidate();result.targetPixel=ivec2(0);result.targetFarPixel=ivec2(0);result.currentViewPosition=vec3(0.0);result.effectiveRadiusPixels=0.0;result.fade=0.0;result.tinyObjectRadiusRatio=1.0;result.rejectionReason=MESH_BLEND_REJECTION_NO_CANDIDATE;result.stageReached=1;result.valid=false;result.continuationFound=false;result.usedFallback=false;result.tinyObjectRadiusReduced=false;return result;}
|
|
97
|
+
MeshBlendCandidate findInitialCandidate(
|
|
98
|
+
ivec2 pixel,
|
|
99
|
+
ivec2 renderSize,
|
|
100
|
+
MeshBlendTag currentTag,
|
|
101
|
+
float currentSearchRadius,
|
|
102
|
+
float viewDepth,
|
|
103
|
+
uint ignoredGroupId,
|
|
104
|
+
vec2 randomValues,
|
|
105
|
+
float rotation,
|
|
106
|
+
float sectorAngle,
|
|
107
|
+
vec2 direction0,
|
|
108
|
+
vec2 direction1,
|
|
109
|
+
vec2 direction2
|
|
110
|
+
) {MeshBlendCandidate best=invalidCandidate();float radialJitter=mix(0.5,randomValues.y,MESH_BLEND_JITTER_FACTOR);for (int radialIndex=0; radialIndex<MESH_BLEND_RADIAL_SAMPLE_COUNT; ++radialIndex) {float normalizedDistance=(float(radialIndex)+radialJitter)/float(MESH_BLEND_RADIAL_SAMPLE_COUNT);float distancePixels=max(1.0,ceil(normalizedDistance*normalizedDistance*normalizedDistance*currentSearchRadius));for (int directionIndex=0; directionIndex<MESH_BLEND_DIRECTION_COUNT; ++directionIndex) {vec2 direction=directionAt(directionIndex,rotation,sectorAngle,direction0,direction1,direction2);ivec2 samplePixel=pixel+ivec2(round(direction*distancePixels));MeshBlendTag candidateTag=loadMeshBlendTag(samplePixel,renderSize);if (candidateTag.groupId==0u || candidateTag.groupId==currentTag.groupId || candidateTag.groupId==ignoredGroupId) {continue;}
|
|
111
|
+
uint seamRadiusClass=min(currentTag.radiusClass,candidateTag.radiusClass);float candidateSearchRadius=searchRadiusForClass(seamRadiusClass,viewDepth,float(renderSize.y));if (distancePixels>candidateSearchRadius) {continue;}
|
|
112
|
+
float score=1.0-clamp(distancePixels/max(candidateSearchRadius,MESH_BLEND_EPSILON),0.0,1.0);if (score>best.score) {best.targetGroupId=candidateTag.groupId;best.radiusClass=seamRadiusClass;best.direction=direction;best.distancePixels=distancePixels;best.searchRadiusPixels=candidateSearchRadius;best.score=score;best.valid=true;}}
|
|
113
|
+
if (best.valid) {break;}}
|
|
114
|
+
return best;}
|
|
115
|
+
MeshBlendCandidate refineCandidateDirection(ivec2 pixel,ivec2 renderSize,MeshBlendCandidate candidate,vec2 randomValues) {if (candidate.distancePixels<=2.0) {return candidate;}
|
|
116
|
+
float centerAngle=atan(candidate.direction.y,candidate.direction.x);float angularHalfWidth=(MESH_BLEND_TWO_PI/float(MESH_BLEND_DIRECTION_COUNT))*MESH_BLEND_DIRECTION_REFINEMENT_SECTOR_SCALE;float stepSize=max(1.0,candidate.distancePixels/float(MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT+1));for (int sampleIndex=0; sampleIndex<MESH_BLEND_DIRECTION_REFINEMENT_SAMPLE_COUNT; ++sampleIndex) {float sampleRandom=fract(randomValues.y+randomValues.x*0.754877666+float(sampleIndex)*0.618033989);float angle=centerAngle+mix(-angularHalfWidth,angularHalfWidth,sampleRandom);vec2 direction=vec2(cos(angle),sin(angle));float testDistance=candidate.distancePixels-stepSize;for (int stepIndex=0; stepIndex<MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT; ++stepIndex) {if (testDistance<=0.0) {break;}
|
|
117
|
+
ivec2 samplePixel=pixel+ivec2(round(direction*testDistance));MeshBlendTag sampleTag=loadMeshBlendTag(samplePixel,renderSize);if (sampleTag.groupId != candidate.targetGroupId) {break;}
|
|
118
|
+
candidate.direction=direction;candidate.distancePixels=testDistance;testDistance-=stepSize;}}
|
|
119
|
+
return candidate;}
|
|
120
|
+
MeshBlendCandidate refineExactBoundary(ivec2 pixel,ivec2 renderSize,MeshBlendCandidate candidate) {float distancePixels=candidate.distancePixels;for (int sampleIndex=0; sampleIndex<MESH_BLEND_EXACT_EDGE_SAMPLE_COUNT; ++sampleIndex) {distancePixels-=1.0;if (distancePixels<=0.0) {break;}
|
|
121
|
+
ivec2 samplePixel=pixel+ivec2(round(candidate.direction*distancePixels));MeshBlendTag sampleTag=loadMeshBlendTag(samplePixel,renderSize);if (sampleTag.groupId != candidate.targetGroupId) {break;}
|
|
122
|
+
candidate.distancePixels=distancePixels;}
|
|
123
|
+
return candidate;}
|
|
124
|
+
bool hasTargetContinuation(ivec2 pixel,ivec2 renderSize,MeshBlendCandidate candidate,out ivec2 continuationPixel) {float continuationDistance=max(candidate.distancePixels*2.0,candidate.distancePixels+1.0);continuationPixel=pixel+ivec2(round(candidate.direction*continuationDistance));if (!isPixelInBounds(continuationPixel,renderSize)) {return false;}
|
|
125
|
+
return loadMeshBlendTag(continuationPixel,renderSize).groupId==candidate.targetGroupId;}
|
|
126
|
+
bool applyTargetRadiusClass(ivec2 targetPixel,ivec2 renderSize,float viewDepth,inout MeshBlendCandidate candidate) {MeshBlendTag targetTag=loadMeshBlendTag(targetPixel,renderSize);candidate.radiusClass=min(candidate.radiusClass,targetTag.radiusClass);candidate.searchRadiusPixels=min(candidate.searchRadiusPixels,searchRadiusForClass(candidate.radiusClass,viewDepth,float(renderSize.y)));return candidate.distancePixels<=candidate.searchRadiusPixels;}
|
|
127
|
+
#ifdef MESH_BLEND_FOUR_NEIGHBOR_FALLBACK
|
|
128
|
+
MeshBlendCandidate findImmediateNeighborCandidate(
|
|
129
|
+
ivec2 pixel,
|
|
130
|
+
ivec2 renderSize,
|
|
131
|
+
MeshBlendTag currentTag,
|
|
132
|
+
float viewDepth,
|
|
133
|
+
uint ignoredGroupId,
|
|
134
|
+
uint preferredGroupId
|
|
135
|
+
) {MeshBlendCandidate best=invalidCandidate();for (int neighborIndex=0; neighborIndex<4; ++neighborIndex) {ivec2 offset;if (neighborIndex==0) {offset=ivec2(1,0);} else if (neighborIndex==1) {offset=ivec2(-1,0);} else if (neighborIndex==2) {offset=ivec2(0,1);} else {offset=ivec2(0,-1);}
|
|
136
|
+
MeshBlendTag neighborTag=loadMeshBlendTag(pixel+offset,renderSize);if (neighborTag.groupId==0u || neighborTag.groupId==currentTag.groupId || neighborTag.groupId==ignoredGroupId) {continue;}
|
|
137
|
+
uint seamRadiusClass=min(currentTag.radiusClass,neighborTag.radiusClass);float candidateSearchRadius=searchRadiusForClass(seamRadiusClass,viewDepth,float(renderSize.y));if (candidateSearchRadius<1.0) {continue;}
|
|
138
|
+
float score=1.0-1.0/max(candidateSearchRadius,1.0);if (neighborTag.groupId==preferredGroupId) {score+=1.0;}
|
|
139
|
+
if (score>best.score) {best.targetGroupId=neighborTag.groupId;best.radiusClass=seamRadiusClass;best.direction=vec2(offset);best.distancePixels=1.0;best.searchRadiusPixels=candidateSearchRadius;best.score=score;best.valid=true;}}
|
|
140
|
+
return best;}
|
|
141
|
+
#endif
|
|
142
|
+
#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD
|
|
143
|
+
float reduceRadiusForTinyObject(
|
|
144
|
+
ivec2 pixel,
|
|
145
|
+
ivec2 renderSize,
|
|
146
|
+
MeshBlendTag currentTag,
|
|
147
|
+
MeshBlendCandidate candidate,
|
|
148
|
+
out bool radiusReduced
|
|
149
|
+
) {float measuredThickness=candidate.searchRadiusPixels;bool foundOppositeBoundary=false;for (int probeIndex=1; probeIndex<=MESH_BLEND_TINY_OBJECT_PROBE_COUNT; ++probeIndex) {float probeDistance=max(1.0,candidate.searchRadiusPixels*float(probeIndex)/float(MESH_BLEND_TINY_OBJECT_PROBE_COUNT));MeshBlendTag oppositeTag=loadMeshBlendTag(pixel-ivec2(round(candidate.direction*probeDistance)),renderSize);if (oppositeTag.groupId != currentTag.groupId) {measuredThickness=probeDistance;foundOppositeBoundary=true;break;}}
|
|
150
|
+
int outsideDirectionCount=0;for (int neighborIndex=0; neighborIndex<4; ++neighborIndex) {vec2 direction;if (neighborIndex==0) {direction=vec2(1.0,0.0);} else if (neighborIndex==1) {direction=vec2(-1.0,0.0);} else if (neighborIndex==2) {direction=vec2(0.0,1.0);} else {direction=vec2(0.0,-1.0);}
|
|
151
|
+
MeshBlendTag radiusTag=loadMeshBlendTag(pixel+ivec2(round(direction*candidate.searchRadiusPixels)),renderSize);if (radiusTag.groupId != currentTag.groupId) {outsideDirectionCount++;}}
|
|
152
|
+
radiusReduced=foundOppositeBoundary && outsideDirectionCount>=3;if (!radiusReduced) {return candidate.searchRadiusPixels;}
|
|
153
|
+
float thicknessRadius=max(1.0,measuredThickness*1.25);return max(candidate.distancePixels,min(candidate.searchRadiusPixels,thicknessRadius));}
|
|
154
|
+
#endif
|
|
155
|
+
int validateMeshBlendContact(
|
|
156
|
+
ivec2 pixelA,
|
|
157
|
+
ivec2 pixelE,
|
|
158
|
+
ivec2 pixelB,
|
|
159
|
+
ivec2 pixelC,
|
|
160
|
+
ivec2 renderSize,
|
|
161
|
+
MeshBlendTag currentTag,
|
|
162
|
+
MeshBlendCandidate candidate,
|
|
163
|
+
bool allowMissingContinuation,
|
|
164
|
+
out float narrowedSearchRadius,
|
|
165
|
+
out vec3 currentViewPosition
|
|
166
|
+
) {currentViewPosition=vec3(0.0);MeshBlendTag tagE=loadMeshBlendTag(pixelE,renderSize);MeshBlendTag tagB=loadMeshBlendTag(pixelB,renderSize);MeshBlendTag tagC=loadMeshBlendTag(pixelC,renderSize);if (
|
|
167
|
+
tagE.groupId != currentTag.groupId ||
|
|
168
|
+
tagB.groupId != candidate.targetGroupId ||
|
|
169
|
+
(!allowMissingContinuation && tagC.groupId != candidate.targetGroupId)
|
|
170
|
+
) {return MESH_BLEND_REJECTION_NO_CONTINUATION;}
|
|
171
|
+
float depthA=loadMeshBlendDepth(pixelA,renderSize);float depthE=loadMeshBlendDepth(pixelE,renderSize);float depthB=loadMeshBlendDepth(pixelB,renderSize);float depthC=loadMeshBlendDepth(pixelC,renderSize);vec3 positionA=reconstructMeshBlendViewPosition(pixelA,renderSize,depthA);vec3 positionE=reconstructMeshBlendViewPosition(pixelE,renderSize,depthE);vec3 positionB=reconstructMeshBlendViewPosition(pixelB,renderSize,depthB);vec3 positionC=reconstructMeshBlendViewPosition(pixelC,renderSize,depthC);if (!isValidMeshBlendPosition(positionA) || !isValidMeshBlendPosition(positionE) || !isValidMeshBlendPosition(positionB) || !isValidMeshBlendPosition(positionC)) {return MESH_BLEND_REJECTION_INVALID_DEPTH;}
|
|
172
|
+
currentViewPosition=positionA;float viewDepth=abs(positionA.z);float unitsPerPixel=worldUnitsPerPixel(viewDepth,float(renderSize.y));float effectiveWorldRadius=candidate.searchRadiusPixels*unitsPerPixel;float pixelTolerance=unitsPerPixel*MESH_BLEND_BOUNDARY_PIXEL_TOLERANCE;vec3 boundarySpan=positionB-positionE;float boundarySeparation=length(boundarySpan);if (boundarySeparation>effectiveWorldRadius*MESH_BLEND_BOUNDARY_SEPARATION_FACTOR+pixelTolerance) {return MESH_BLEND_REJECTION_DEPTH_SEPARATION;}
|
|
173
|
+
float boundaryDepthDelta=abs(abs(positionB.z)-abs(positionE.z));float boundaryLateralSpan=length(boundarySpan.xy);if (
|
|
174
|
+
boundaryDepthDelta>max(effectiveWorldRadius*MESH_BLEND_FOREGROUND_DEPTH_FACTOR,pixelTolerance) &&
|
|
175
|
+
boundaryDepthDelta>boundaryLateralSpan*MESH_BLEND_FOREGROUND_LATERAL_FACTOR
|
|
176
|
+
) {return MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND;}
|
|
177
|
+
float targetSpan=distance(positionB,positionC);float totalSpan=distance(positionA,positionC);if (
|
|
178
|
+
targetSpan>effectiveWorldRadius*MESH_BLEND_TARGET_SPAN_FACTOR+pixelTolerance ||
|
|
179
|
+
totalSpan>effectiveWorldRadius*MESH_BLEND_TOTAL_SPAN_FACTOR+pixelTolerance
|
|
180
|
+
) {return MESH_BLEND_REJECTION_PHYSICAL_SPAN;}
|
|
181
|
+
vec3 currentDirection=positionA-positionB;vec3 targetDirection=positionC-positionB;float currentLength=length(currentDirection);float targetLength=length(targetDirection);float oppositeFacing=1.0;if (currentLength>MESH_BLEND_EPSILON && targetLength>MESH_BLEND_EPSILON) {oppositeFacing=-dot(currentDirection/currentLength,targetDirection/targetLength);}
|
|
182
|
+
narrowedSearchRadius=candidate.searchRadiusPixels*calculateSlopeScale(oppositeFacing);if (candidate.distancePixels>narrowedSearchRadius) {return MESH_BLEND_REJECTION_CONTACT_ANGLE;}
|
|
183
|
+
return MESH_BLEND_REJECTION_NONE;}
|
|
184
|
+
float calculateMeshBlendFade(float distancePixels,float searchRadiusPixels) {float boundaryDistance=max(distancePixels-0.5,0.0);float normalizedDistance=clamp(boundaryDistance/max(searchRadiusPixels,MESH_BLEND_EPSILON),0.0,1.0);float inverseDistance=1.0-normalizedDistance;float fade=mix(inverseDistance*inverseDistance,inverseDistance,clamp(inverseDistance-0.75,0.0,1.0));return fade*0.5;}
|
|
185
|
+
MeshBlendResult evaluateMeshBlend(
|
|
186
|
+
ivec2 pixel,
|
|
187
|
+
ivec2 renderSize,
|
|
188
|
+
MeshBlendTag currentTag,
|
|
189
|
+
float currentSearchRadius,
|
|
190
|
+
float viewDepth,
|
|
191
|
+
uint ignoredGroupId,
|
|
192
|
+
vec2 randomValues,
|
|
193
|
+
float rotation,
|
|
194
|
+
float sectorAngle,
|
|
195
|
+
vec2 direction0,
|
|
196
|
+
vec2 direction1,
|
|
197
|
+
vec2 direction2
|
|
198
|
+
) {MeshBlendResult result=invalidBlendResult();MeshBlendCandidate candidate=findInitialCandidate(
|
|
199
|
+
pixel,
|
|
200
|
+
renderSize,
|
|
201
|
+
currentTag,
|
|
202
|
+
currentSearchRadius,
|
|
203
|
+
viewDepth,
|
|
204
|
+
ignoredGroupId,
|
|
205
|
+
randomValues,
|
|
206
|
+
rotation,
|
|
207
|
+
sectorAngle,
|
|
208
|
+
direction0,
|
|
209
|
+
direction1,
|
|
210
|
+
direction2
|
|
211
|
+
);result.candidate=candidate;if (!candidate.valid) {return result;}
|
|
212
|
+
result.stageReached=2;candidate=refineCandidateDirection(pixel,renderSize,candidate,randomValues);candidate=refineExactBoundary(pixel,renderSize,candidate);result.candidate=candidate;result.stageReached=3;ivec2 refinedTargetPixel=clampPixel(pixel+ivec2(round(candidate.direction*candidate.distancePixels)),renderSize);if (!applyTargetRadiusClass(refinedTargetPixel,renderSize,viewDepth,candidate)) {result.candidate=candidate;result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}
|
|
213
|
+
result.candidate=candidate;ivec2 continuationPixel;bool continuationFound=hasTargetContinuation(pixel,renderSize,candidate,continuationPixel);if (!continuationFound) {
|
|
214
|
+
#ifdef MESH_BLEND_FOUR_NEIGHBOR_FALLBACK
|
|
215
|
+
MeshBlendCandidate fallbackCandidate=findImmediateNeighborCandidate(
|
|
216
|
+
pixel,
|
|
217
|
+
renderSize,
|
|
218
|
+
currentTag,
|
|
219
|
+
viewDepth,
|
|
220
|
+
ignoredGroupId,
|
|
221
|
+
candidate.targetGroupId
|
|
222
|
+
);if (!fallbackCandidate.valid) {result.rejectionReason=MESH_BLEND_REJECTION_NO_CONTINUATION;return result;}
|
|
223
|
+
candidate=fallbackCandidate;result.candidate=candidate;result.usedFallback=true;continuationFound=hasTargetContinuation(pixel,renderSize,candidate,continuationPixel);
|
|
224
|
+
#else
|
|
225
|
+
result.rejectionReason=MESH_BLEND_REJECTION_NO_CONTINUATION;return result;
|
|
226
|
+
#endif
|
|
227
|
+
}
|
|
228
|
+
result.continuationFound=continuationFound;result.stageReached=4;if (continuationFound && !applyTargetRadiusClass(continuationPixel,renderSize,viewDepth,candidate)) {result.candidate=candidate;result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}
|
|
229
|
+
result.candidate=candidate;float originalSearchRadius=candidate.searchRadiusPixels;
|
|
230
|
+
#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD
|
|
231
|
+
candidate.searchRadiusPixels=reduceRadiusForTinyObject(pixel,renderSize,currentTag,candidate,result.tinyObjectRadiusReduced);result.stageReached=5;
|
|
232
|
+
#endif
|
|
233
|
+
result.candidate=candidate;result.effectiveRadiusPixels=candidate.searchRadiusPixels;result.tinyObjectRadiusRatio=candidate.searchRadiusPixels/max(originalSearchRadius,MESH_BLEND_EPSILON);ivec2 pixelB=clampPixel(pixel+ivec2(round(candidate.direction*candidate.distancePixels)),renderSize);ivec2 pixelE=clampPixel(pixel+ivec2(round(candidate.direction*max(candidate.distancePixels-2.0,0.0))),renderSize);ivec2 pixelC=continuationFound ? continuationPixel : pixelB;float narrowedSearchRadius=candidate.searchRadiusPixels;result.rejectionReason=validateMeshBlendContact(
|
|
234
|
+
pixel,
|
|
235
|
+
pixelE,
|
|
236
|
+
pixelB,
|
|
237
|
+
pixelC,
|
|
238
|
+
renderSize,
|
|
239
|
+
currentTag,
|
|
240
|
+
candidate,
|
|
241
|
+
result.usedFallback && !continuationFound,
|
|
242
|
+
narrowedSearchRadius,
|
|
243
|
+
result.currentViewPosition
|
|
244
|
+
);result.stageReached=6;result.effectiveRadiusPixels=narrowedSearchRadius;if (result.rejectionReason != MESH_BLEND_REJECTION_NONE) {return result;}
|
|
245
|
+
result.fade=calculateMeshBlendFade(candidate.distancePixels,narrowedSearchRadius);if (result.fade<=0.0) {result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}
|
|
246
|
+
result.targetPixel=pixelB;result.targetFarPixel=continuationFound ? continuationPixel : pixelB;result.stageReached=7;result.valid=true;return result;}
|
|
247
|
+
float meshBlendLinearToSrgbChannel(float value) {return value<=0.0031308 ? value*12.92 : 1.055*pow(value,1.0/2.4)-0.055;}
|
|
248
|
+
float meshBlendSrgbToLinearChannel(float value) {return value<=0.04045 ? value/12.92 : pow((value+0.055)/1.055,2.4);}
|
|
249
|
+
vec3 meshBlendLinearToSrgb(vec3 color) {return vec3(
|
|
250
|
+
meshBlendLinearToSrgbChannel(color.r),
|
|
251
|
+
meshBlendLinearToSrgbChannel(color.g),
|
|
252
|
+
meshBlendLinearToSrgbChannel(color.b)
|
|
253
|
+
);}
|
|
254
|
+
vec3 meshBlendSrgbToLinear(vec3 color) {return vec3(
|
|
255
|
+
meshBlendSrgbToLinearChannel(color.r),
|
|
256
|
+
meshBlendSrgbToLinearChannel(color.g),
|
|
257
|
+
meshBlendSrgbToLinearChannel(color.b)
|
|
258
|
+
);}
|
|
259
|
+
float meshBlendSignedCubeRoot(float value) {return sign(value)*pow(abs(value),1.0/3.0);}
|
|
260
|
+
vec3 meshBlendLinearSrgbToOklab(vec3 color) {float longResponse=0.4122214708*color.r+0.5363325363*color.g+0.0514459929*color.b;float mediumResponse=0.2119034982*color.r+0.6806995451*color.g+0.1073969566*color.b;float shortResponse=0.0883024619*color.r+0.2817188376*color.g+0.6299787005*color.b;float longRoot=meshBlendSignedCubeRoot(longResponse);float mediumRoot=meshBlendSignedCubeRoot(mediumResponse);float shortRoot=meshBlendSignedCubeRoot(shortResponse);return vec3(
|
|
261
|
+
0.2104542553*longRoot+0.7936177850*mediumRoot-0.0040720468*shortRoot,
|
|
262
|
+
1.9779984951*longRoot-2.4285922050*mediumRoot+0.4505937099*shortRoot,
|
|
263
|
+
0.0259040371*longRoot+0.7827717662*mediumRoot-0.8086757660*shortRoot
|
|
264
|
+
);}
|
|
265
|
+
vec3 meshBlendOklabToLinearSrgb(vec3 color) {float longRoot=color.x+0.3963377774*color.y+0.2158037573*color.z;float mediumRoot=color.x-0.1055613458*color.y-0.0638541728*color.z;float shortRoot=color.x-0.0894841775*color.y-1.2914855480*color.z;float longResponse=longRoot*longRoot*longRoot;float mediumResponse=mediumRoot*mediumRoot*mediumRoot;float shortResponse=shortRoot*shortRoot*shortRoot;return vec3(
|
|
266
|
+
4.0767416621*longResponse-3.3077115913*mediumResponse+0.2309699292*shortResponse,
|
|
267
|
+
-1.2684380046*longResponse+2.6097574011*mediumResponse-0.3413193965*shortResponse,
|
|
268
|
+
-0.0041960863*longResponse-0.7034186147*mediumResponse+1.7076147010*shortResponse
|
|
269
|
+
);}
|
|
270
|
+
vec3 interpolateMeshBlendColor(vec3 currentColor,vec3 targetColor,float factor) {
|
|
271
|
+
#ifdef MESH_BLEND_COLOR_INTERPOLATION_SRGB
|
|
272
|
+
return meshBlendSrgbToLinear(mix(meshBlendLinearToSrgb(currentColor),meshBlendLinearToSrgb(targetColor),factor));
|
|
273
|
+
#else
|
|
274
|
+
return meshBlendOklabToLinearSrgb(mix(meshBlendLinearSrgbToOklab(currentColor),meshBlendLinearSrgbToOklab(targetColor),factor));
|
|
275
|
+
#endif
|
|
276
|
+
}
|
|
277
|
+
float meshBlendLuminance(vec3 srgbColor) {return dot(srgbColor,vec3(0.2126,0.7152,0.0722));}
|
|
278
|
+
MeshBlendTargetColorSamples constructMeshBlendTargetColorSamples(ivec2 renderSize,MeshBlendResult result) {MeshBlendTargetColorSamples samples;ivec2 boundaryPlusOnePixel=clampPixel(result.targetPixel+ivec2(round(result.candidate.direction)),renderSize);ivec2 boundaryPlusTwoPixel=clampPixel(result.targetPixel+ivec2(round(result.candidate.direction*2.0)),renderSize);MeshBlendTag boundaryPlusOneTag=loadMeshBlendTag(boundaryPlusOnePixel,renderSize);MeshBlendTag boundaryPlusTwoTag=loadMeshBlendTag(boundaryPlusTwoPixel,renderSize);samples.fartherColor=texelFetch(textureSampler,result.targetFarPixel,0);samples.boundaryPlusOneColor=texelFetch(textureSampler,boundaryPlusOnePixel,0);samples.boundaryPlusTwoColor=texelFetch(textureSampler,boundaryPlusTwoPixel,0);
|
|
279
|
+
#ifdef MESH_BLEND_SHADOW_ESTIMATION
|
|
280
|
+
samples.fartherBaseColor=texelFetch(meshBlendBaseColorSampler,result.targetFarPixel,0).rgb;vec3 boundaryPlusOneBaseColor=texelFetch(meshBlendBaseColorSampler,boundaryPlusOnePixel,0).rgb;vec3 boundaryPlusTwoBaseColor=texelFetch(meshBlendBaseColorSampler,boundaryPlusTwoPixel,0).rgb;
|
|
281
|
+
#endif
|
|
282
|
+
samples.onePixelEdge=boundaryPlusOneTag.groupId != result.candidate.targetGroupId;if (samples.onePixelEdge) {samples.conservativeNearColor=samples.fartherColor;
|
|
283
|
+
#ifdef MESH_BLEND_SHADOW_ESTIMATION
|
|
284
|
+
samples.conservativeNearBaseColor=samples.fartherBaseColor;
|
|
285
|
+
#endif
|
|
286
|
+
samples.targetColor=samples.fartherColor;return samples;}
|
|
287
|
+
bool secondNearSampleIsTarget=boundaryPlusTwoTag.groupId==result.candidate.targetGroupId;float firstNearLuminance=meshBlendLuminance(meshBlendLinearToSrgb(samples.boundaryPlusOneColor.rgb));float secondNearLuminance=meshBlendLuminance(meshBlendLinearToSrgb(samples.boundaryPlusTwoColor.rgb));bool useSecondNearSample=secondNearSampleIsTarget && secondNearLuminance<firstNearLuminance;samples.conservativeNearColor=useSecondNearSample ? samples.boundaryPlusTwoColor : samples.boundaryPlusOneColor;
|
|
288
|
+
#ifdef MESH_BLEND_SHADOW_ESTIMATION
|
|
289
|
+
samples.conservativeNearBaseColor=useSecondNearSample ? boundaryPlusTwoBaseColor : boundaryPlusOneBaseColor;
|
|
290
|
+
#endif
|
|
291
|
+
samples.targetColor=mix(samples.fartherColor,samples.conservativeNearColor,MESH_BLEND_NEAR_EDGE_TARGET_WEIGHT);return samples;}
|
|
292
|
+
vec4 applyMeshBlendNearSeamCorrection(
|
|
293
|
+
ivec2 pixel,
|
|
294
|
+
ivec2 renderSize,
|
|
295
|
+
MeshBlendTag currentTag,
|
|
296
|
+
MeshBlendResult result,
|
|
297
|
+
MeshBlendTargetColorSamples samples,
|
|
298
|
+
vec4 currentColor,
|
|
299
|
+
out bool corrected
|
|
300
|
+
) {corrected=false;if (!samples.onePixelEdge || result.candidate.distancePixels>MESH_BLEND_NEAR_SEAM_MAX_DISTANCE) {return currentColor;}
|
|
301
|
+
ivec2 oppositePixel=clampPixel(pixel-ivec2(round(result.candidate.direction)),renderSize);MeshBlendTag oppositeTag=loadMeshBlendTag(oppositePixel,renderSize);if (oppositeTag.groupId != currentTag.groupId) {return currentColor;}
|
|
302
|
+
vec4 oppositeColor=texelFetch(textureSampler,oppositePixel,0);float currentTargetDistance=distance(currentColor.rgb,samples.targetColor.rgb);float oppositeTargetDistance=distance(oppositeColor.rgb,samples.targetColor.rgb);if (currentTargetDistance+MESH_BLEND_NEAR_SEAM_COLOR_DELTA>=oppositeTargetDistance) {return currentColor;}
|
|
303
|
+
corrected=true;return oppositeColor;}
|
|
304
|
+
#ifdef MESH_BLEND_SHADOW_ESTIMATION
|
|
305
|
+
float estimateMeshBlendShadow(vec3 renderedLinear,vec3 baseColorLinear) {float renderedLuminance=meshBlendLuminance(meshBlendLinearToSrgb(renderedLinear));float baseLuminance=meshBlendLuminance(meshBlendLinearToSrgb(baseColorLinear));if (baseLuminance<=MESH_BLEND_BASE_LUMINANCE_EPSILON) {return 1.0;}
|
|
306
|
+
return renderedLuminance/baseLuminance;}
|
|
307
|
+
float calculateMeshBlendShadowAttenuation(vec3 currentColor,MeshBlendTargetColorSamples samples) {float fartherShadow=estimateMeshBlendShadow(samples.fartherColor.rgb,samples.fartherBaseColor);float nearShadow=estimateMeshBlendShadow(samples.conservativeNearColor.rgb,samples.conservativeNearBaseColor);float shadowDifference=abs(fartherShadow-nearShadow);float shadowMismatch=smoothstep(MESH_BLEND_SHADOW_DIFFERENCE_LOW,MESH_BLEND_SHADOW_DIFFERENCE_HIGH,shadowDifference);float currentLuminance=meshBlendLuminance(meshBlendLinearToSrgb(currentColor));float targetLuminance=meshBlendLuminance(meshBlendLinearToSrgb(samples.targetColor.rgb));float targetToCurrentRatio=targetLuminance/max(currentLuminance,MESH_BLEND_BASE_LUMINANCE_EPSILON);float targetIsNotDark=smoothstep(MESH_BLEND_TARGET_DARKER_RATIO,MESH_BLEND_TARGET_NON_DARK_RATIO,targetToCurrentRatio);return mix(1.0,MESH_BLEND_SHADOW_MIN_ATTENUATION,shadowMismatch*targetIsNotDark);}
|
|
308
|
+
#endif
|
|
309
|
+
MeshBlendColorEvaluation evaluateMeshBlendColor(
|
|
310
|
+
ivec2 pixel,
|
|
311
|
+
ivec2 renderSize,
|
|
312
|
+
MeshBlendTag currentTag,
|
|
313
|
+
MeshBlendResult result
|
|
314
|
+
) {MeshBlendColorEvaluation evaluation;evaluation.samples=constructMeshBlendTargetColorSamples(renderSize,result);
|
|
315
|
+
#ifdef MESH_BLEND_DEBUG_WORLD_POSITION
|
|
316
|
+
evaluation.worldPosition=reconstructMeshBlendWorldPosition(result.currentViewPosition);
|
|
317
|
+
#endif
|
|
318
|
+
vec4 currentSceneColor=texelFetch(textureSampler,pixel,0);evaluation.currentColor=applyMeshBlendNearSeamCorrection(
|
|
319
|
+
pixel,
|
|
320
|
+
renderSize,
|
|
321
|
+
currentTag,
|
|
322
|
+
result,
|
|
323
|
+
evaluation.samples,
|
|
324
|
+
currentSceneColor,
|
|
325
|
+
evaluation.nearSeamCorrected
|
|
326
|
+
);evaluation.shadowAttenuation=1.0;
|
|
327
|
+
#ifdef MESH_BLEND_SHADOW_ESTIMATION
|
|
328
|
+
evaluation.shadowAttenuation=calculateMeshBlendShadowAttenuation(evaluation.currentColor.rgb,evaluation.samples);
|
|
329
|
+
#endif
|
|
330
|
+
evaluation.adjustedFade=result.fade*evaluation.shadowAttenuation;evaluation.blendedColor=vec4(
|
|
331
|
+
interpolateMeshBlendColor(evaluation.currentColor.rgb,evaluation.samples.targetColor.rgb,evaluation.adjustedFade),
|
|
332
|
+
mix(evaluation.currentColor.a,evaluation.samples.targetColor.a,evaluation.adjustedFade)
|
|
333
|
+
);return evaluation;}
|
|
334
|
+
vec3 radiusClassDebugColor(uint radiusClass) {if (radiusClass==0u) {return vec3(0.15,0.55,1.0);}
|
|
335
|
+
if (radiusClass==1u) {return vec3(0.15,0.9,0.35);}
|
|
336
|
+
if (radiusClass==2u) {return vec3(1.0,0.65,0.1);}
|
|
337
|
+
return vec3(0.95,0.2,0.65);}
|
|
338
|
+
vec3 validationDebugColor(int rejectionReason,float narrowedRadiusRatio) {if (rejectionReason==MESH_BLEND_REJECTION_NONE) {return mix(vec3(0.1,0.55,1.0),vec3(0.2,1.0,0.25),narrowedRadiusRatio);}
|
|
339
|
+
if (rejectionReason==MESH_BLEND_REJECTION_NO_CANDIDATE) {return vec3(0.12);}
|
|
340
|
+
if (rejectionReason==MESH_BLEND_REJECTION_NO_CONTINUATION) {return vec3(0.75,0.1,0.85);}
|
|
341
|
+
if (rejectionReason==MESH_BLEND_REJECTION_INVALID_DEPTH) {return vec3(1.0,0.0,1.0);}
|
|
342
|
+
if (rejectionReason==MESH_BLEND_REJECTION_DEPTH_SEPARATION) {return vec3(1.0,0.1,0.1);}
|
|
343
|
+
if (rejectionReason==MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND) {return vec3(1.0,0.4,0.05);}
|
|
344
|
+
if (rejectionReason==MESH_BLEND_REJECTION_PHYSICAL_SPAN) {return vec3(1.0,0.9,0.05);}
|
|
345
|
+
return vec3(0.05,0.8,1.0);}
|
|
346
|
+
vec3 processingStageDebugColor(int stageReached) {if (stageReached<=0) {return vec3(0.03);}
|
|
347
|
+
if (stageReached==1) {return vec3(0.1,0.15,0.45);}
|
|
348
|
+
if (stageReached==2) {return vec3(0.1,0.35,0.7);}
|
|
349
|
+
if (stageReached==3) {return vec3(0.05,0.65,0.8);}
|
|
350
|
+
if (stageReached==4) {return vec3(0.1,0.8,0.55);}
|
|
351
|
+
if (stageReached==5) {return vec3(0.45,0.9,0.25);}
|
|
352
|
+
if (stageReached==6) {return vec3(0.95,0.75,0.1);}
|
|
353
|
+
return vec3(0.15,1.0,0.25);}
|
|
354
|
+
vec3 candidateDebugColor(MeshBlendResult result) {if (!result.candidate.valid) {return vec3(0.04);}
|
|
355
|
+
float normalizedDistance=clamp(
|
|
356
|
+
result.candidate.distancePixels/max(result.candidate.searchRadiusPixels,MESH_BLEND_EPSILON),
|
|
357
|
+
0.0,
|
|
358
|
+
1.0
|
|
359
|
+
);return vec3(result.candidate.direction*0.5+0.5,1.0-normalizedDistance);}
|
|
360
|
+
#define CUSTOM_FRAGMENT_DEFINITIONS
|
|
361
|
+
void main(void) {ivec2 renderSize=textureSize(meshBlendDepthSampler,0);ivec2 pixel=clampPixel(ivec2(floor(vUV*vec2(renderSize))),renderSize);MeshBlendTag currentTag=loadMeshBlendTag(pixel,renderSize);
|
|
362
|
+
#ifdef MESH_BLEND_DEBUG_PACKED_TAG
|
|
363
|
+
float groupVariation=0.45+0.55*fract(float(currentTag.groupId)*0.61803398875);vec3 tagColor=radiusClassDebugColor(currentTag.radiusClass)*groupVariation;gl_FragColor=currentTag.groupId==0u ? vec4(0.0,0.0,0.0,1.0) : vec4(tagColor,1.0);return;
|
|
364
|
+
#endif
|
|
365
|
+
if (currentTag.groupId==0u) {
|
|
366
|
+
#ifdef MESH_BLEND_DEBUG_SEAM_FADE
|
|
367
|
+
gl_FragColor=vec4(0.0,0.0,0.0,1.0);
|
|
368
|
+
#elif defined(MESH_BLEND_DEBUG_ENABLED)
|
|
369
|
+
gl_FragColor=vec4(0.04,0.04,0.04,1.0);
|
|
370
|
+
#else
|
|
371
|
+
gl_FragColor=texelFetch(textureSampler,pixel,0);
|
|
372
|
+
#endif
|
|
373
|
+
return;}
|
|
374
|
+
float sizingDepth=loadMeshBlendDepth(pixel,renderSize);vec3 sizingPosition=reconstructMeshBlendViewPosition(pixel,renderSize,sizingDepth);if (!isValidMeshBlendPosition(sizingPosition)) {
|
|
375
|
+
#ifdef MESH_BLEND_DEBUG_REJECTION_REASON
|
|
376
|
+
gl_FragColor=vec4(validationDebugColor(MESH_BLEND_REJECTION_INVALID_DEPTH,0.0),1.0);
|
|
377
|
+
#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)
|
|
378
|
+
gl_FragColor=vec4(0.45,0.1,0.1,1.0);
|
|
379
|
+
#elif defined(MESH_BLEND_DEBUG_ENABLED)
|
|
380
|
+
gl_FragColor=vec4(0.4,0.05,0.4,1.0);
|
|
381
|
+
#else
|
|
382
|
+
gl_FragColor=texelFetch(textureSampler,pixel,0);
|
|
383
|
+
#endif
|
|
384
|
+
return;}
|
|
385
|
+
float currentViewDepth=abs(sizingPosition.z);float currentSearchRadius=searchRadiusForClass(currentTag.radiusClass,currentViewDepth,float(renderSize.y));if (currentSearchRadius<1.0) {
|
|
386
|
+
#ifdef MESH_BLEND_DEBUG_SEAM_FADE
|
|
387
|
+
gl_FragColor=vec4(radiusClassDebugColor(currentTag.radiusClass)*0.25,1.0);
|
|
388
|
+
#elif defined(MESH_BLEND_DEBUG_REJECTION_REASON)
|
|
389
|
+
gl_FragColor=vec4(validationDebugColor(MESH_BLEND_REJECTION_PHYSICAL_SPAN,0.0),1.0);
|
|
390
|
+
#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)
|
|
391
|
+
gl_FragColor=vec4(0.2,0.2,0.65,1.0);
|
|
392
|
+
#elif defined(MESH_BLEND_DEBUG_ENABLED)
|
|
393
|
+
gl_FragColor=vec4(0.04,0.04,0.04,1.0);
|
|
394
|
+
#else
|
|
395
|
+
gl_FragColor=texelFetch(textureSampler,pixel,0);
|
|
396
|
+
#endif
|
|
397
|
+
return;}
|
|
398
|
+
vec2 randomValues=loadStableBlueNoise(pixel);float sectorAngle=MESH_BLEND_TWO_PI/float(MESH_BLEND_DIRECTION_COUNT);float rotation;
|
|
399
|
+
#ifdef MESH_BLEND_FULL_RANDOM_ROTATION
|
|
400
|
+
rotation=randomValues.x*sectorAngle;
|
|
401
|
+
#else
|
|
402
|
+
rotation=floor(randomValues.x*8.0)*0.125*sectorAngle;
|
|
403
|
+
#endif
|
|
404
|
+
vec2 direction0=vec2(cos(rotation),sin(rotation));vec2 direction1=vec2(cos(rotation+sectorAngle),sin(rotation+sectorAngle));vec2 direction2=vec2(cos(rotation+sectorAngle*2.0),sin(rotation+sectorAngle*2.0));MeshBlendResult primaryResult=evaluateMeshBlend(
|
|
405
|
+
pixel,
|
|
406
|
+
renderSize,
|
|
407
|
+
currentTag,
|
|
408
|
+
currentSearchRadius,
|
|
409
|
+
currentViewDepth,
|
|
410
|
+
0u,
|
|
411
|
+
randomValues,
|
|
412
|
+
rotation,
|
|
413
|
+
sectorAngle,
|
|
414
|
+
direction0,
|
|
415
|
+
direction1,
|
|
416
|
+
direction2
|
|
417
|
+
);MeshBlendResult secondaryResult=invalidBlendResult();
|
|
418
|
+
#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND
|
|
419
|
+
if (primaryResult.valid) {secondaryResult=evaluateMeshBlend(
|
|
420
|
+
pixel,
|
|
421
|
+
renderSize,
|
|
422
|
+
currentTag,
|
|
423
|
+
currentSearchRadius,
|
|
424
|
+
currentViewDepth,
|
|
425
|
+
primaryResult.candidate.targetGroupId,
|
|
426
|
+
randomValues,
|
|
427
|
+
rotation,
|
|
428
|
+
sectorAngle,
|
|
429
|
+
direction0,
|
|
430
|
+
direction1,
|
|
431
|
+
direction2
|
|
432
|
+
);}
|
|
433
|
+
#endif
|
|
434
|
+
#ifdef MESH_BLEND_DEBUG_CANDIDATE_DIRECTION_DISTANCE
|
|
435
|
+
gl_FragColor=vec4(candidateDebugColor(primaryResult),1.0);return;
|
|
436
|
+
#elif defined(MESH_BLEND_DEBUG_CONTINUATION)
|
|
437
|
+
if (!primaryResult.candidate.valid) {gl_FragColor=vec4(0.04,0.04,0.04,1.0);} else if (primaryResult.rejectionReason==MESH_BLEND_REJECTION_NO_CONTINUATION) {gl_FragColor=vec4(0.85,0.05,0.7,1.0);} else if (primaryResult.usedFallback) {gl_FragColor=vec4(1.0,0.75,0.05,1.0);} else {gl_FragColor=vec4(0.1,0.9,0.25,1.0);}
|
|
438
|
+
return;
|
|
439
|
+
#elif defined(MESH_BLEND_DEBUG_TINY_OBJECT)
|
|
440
|
+
#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD
|
|
441
|
+
if (!primaryResult.candidate.valid) {gl_FragColor=vec4(0.04,0.04,0.04,1.0);} else {vec3 radiusColor=mix(vec3(1.0,0.1,0.05),vec3(0.1,0.65,1.0),primaryResult.tinyObjectRadiusRatio);gl_FragColor=vec4(primaryResult.tinyObjectRadiusReduced ? radiusColor : radiusColor*0.45,1.0);}
|
|
442
|
+
#else
|
|
443
|
+
gl_FragColor=vec4(0.04,0.04,0.04,1.0);
|
|
444
|
+
#endif
|
|
445
|
+
return;
|
|
446
|
+
#elif defined(MESH_BLEND_DEBUG_MULTI_TARGET)
|
|
447
|
+
#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND
|
|
448
|
+
if (secondaryResult.valid) {gl_FragColor=vec4(0.95,0.95,1.0,1.0);} else if (secondaryResult.candidate.valid) {gl_FragColor=vec4(0.8,0.15,0.75,1.0);} else if (primaryResult.valid) {gl_FragColor=vec4(0.1,0.45,0.95,1.0);} else {gl_FragColor=vec4(0.04,0.04,0.04,1.0);}
|
|
449
|
+
#else
|
|
450
|
+
gl_FragColor=primaryResult.valid ? vec4(0.1,0.45,0.95,1.0) : vec4(0.04,0.04,0.04,1.0);
|
|
451
|
+
#endif
|
|
452
|
+
return;
|
|
453
|
+
#elif defined(MESH_BLEND_DEBUG_REJECTION_REASON)
|
|
454
|
+
float narrowedRadiusRatio=primaryResult.candidate.valid
|
|
455
|
+
? primaryResult.effectiveRadiusPixels/max(primaryResult.candidate.searchRadiusPixels,MESH_BLEND_EPSILON)
|
|
456
|
+
: 0.0;gl_FragColor=vec4(validationDebugColor(primaryResult.rejectionReason,narrowedRadiusRatio),1.0);return;
|
|
457
|
+
#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)
|
|
458
|
+
int stageReached=primaryResult.stageReached;
|
|
459
|
+
#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND
|
|
460
|
+
stageReached=max(stageReached,secondaryResult.stageReached);
|
|
461
|
+
#endif
|
|
462
|
+
gl_FragColor=vec4(processingStageDebugColor(stageReached),1.0);return;
|
|
463
|
+
#endif
|
|
464
|
+
if (!primaryResult.valid) {
|
|
465
|
+
#ifdef MESH_BLEND_DEBUG_SEAM_FADE
|
|
466
|
+
uint debugRadiusClass=primaryResult.candidate.valid ? primaryResult.candidate.radiusClass : currentTag.radiusClass;gl_FragColor=vec4(radiusClassDebugColor(debugRadiusClass)*0.25,1.0);
|
|
467
|
+
#elif defined(MESH_BLEND_DEBUG_TARGET_COLOR) || defined(MESH_BLEND_DEBUG_SHADOW_ATTENUATION) || defined(MESH_BLEND_DEBUG_COLOR_INTERPOLATION) || defined(MESH_BLEND_DEBUG_WORLD_POSITION)
|
|
468
|
+
gl_FragColor=vec4(0.04,0.04,0.04,1.0);
|
|
469
|
+
#else
|
|
470
|
+
gl_FragColor=texelFetch(textureSampler,pixel,0);
|
|
471
|
+
#endif
|
|
472
|
+
return;}
|
|
473
|
+
#ifdef MESH_BLEND_DEBUG_SEAM_FADE
|
|
474
|
+
float debugFade=primaryResult.fade;
|
|
475
|
+
#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND
|
|
476
|
+
if (secondaryResult.valid) {debugFade=min(0.5,primaryResult.fade+secondaryResult.fade);}
|
|
477
|
+
#endif
|
|
478
|
+
vec3 classColor=radiusClassDebugColor(primaryResult.candidate.radiusClass)*0.25;gl_FragColor=vec4(mix(classColor,vec3(1.0),clamp(debugFade*2.0,0.0,1.0)),1.0);return;
|
|
479
|
+
#else
|
|
480
|
+
MeshBlendColorEvaluation primaryColorEvaluation=evaluateMeshBlendColor(pixel,renderSize,currentTag,primaryResult);
|
|
481
|
+
#ifdef MESH_BLEND_DEBUG_WORLD_POSITION
|
|
482
|
+
gl_FragColor=vec4(fract(primaryColorEvaluation.worldPosition*0.1),1.0);return;
|
|
483
|
+
#elif defined(MESH_BLEND_DEBUG_TARGET_COLOR)
|
|
484
|
+
int targetSampleIndex=(pixel.x/4) % 4;if (targetSampleIndex==0) {gl_FragColor=primaryColorEvaluation.samples.fartherColor;} else if (targetSampleIndex==1) {gl_FragColor=primaryColorEvaluation.samples.boundaryPlusOneColor;} else if (targetSampleIndex==2) {gl_FragColor=primaryColorEvaluation.samples.boundaryPlusTwoColor;} else {gl_FragColor=primaryColorEvaluation.samples.targetColor;}
|
|
485
|
+
return;
|
|
486
|
+
#elif defined(MESH_BLEND_DEBUG_SHADOW_ATTENUATION)
|
|
487
|
+
gl_FragColor=vec4(
|
|
488
|
+
1.0-primaryColorEvaluation.shadowAttenuation,
|
|
489
|
+
primaryColorEvaluation.shadowAttenuation,
|
|
490
|
+
primaryColorEvaluation.nearSeamCorrected ? 1.0 : 0.0,
|
|
491
|
+
1.0
|
|
492
|
+
);return;
|
|
493
|
+
#elif defined(MESH_BLEND_DEBUG_COLOR_INTERPOLATION)
|
|
494
|
+
#ifdef MESH_BLEND_COLOR_INTERPOLATION_SRGB
|
|
495
|
+
vec3 interpolationModeColor=vec3(1.0,0.4,0.05);
|
|
496
|
+
#else
|
|
497
|
+
vec3 interpolationModeColor=vec3(0.1,0.75,1.0);
|
|
498
|
+
#endif
|
|
499
|
+
float interpolationStage=mix(0.35,1.0,clamp(primaryColorEvaluation.adjustedFade*2.0,0.0,1.0));gl_FragColor=vec4(interpolationModeColor*interpolationStage,1.0);return;
|
|
500
|
+
#else
|
|
501
|
+
#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND
|
|
502
|
+
if (secondaryResult.valid) {MeshBlendColorEvaluation secondaryColorEvaluation=evaluateMeshBlendColor(pixel,renderSize,currentTag,secondaryResult);float totalBoundaryDistance=max(
|
|
503
|
+
primaryResult.candidate.distancePixels+secondaryResult.candidate.distancePixels,
|
|
504
|
+
MESH_BLEND_EPSILON
|
|
505
|
+
);float primaryRelativeProximity=secondaryResult.candidate.distancePixels/totalBoundaryDistance;float secondaryRelativeProximity=primaryResult.candidate.distancePixels/totalBoundaryDistance;float primaryWeight=primaryColorEvaluation.adjustedFade*primaryRelativeProximity;float secondaryWeight=secondaryColorEvaluation.adjustedFade*secondaryRelativeProximity;float combinedWeight=primaryWeight+secondaryWeight;if (combinedWeight<=MESH_BLEND_EPSILON) {gl_FragColor=texelFetch(textureSampler,pixel,0);return;}
|
|
506
|
+
gl_FragColor=(primaryColorEvaluation.blendedColor*primaryWeight+secondaryColorEvaluation.blendedColor*secondaryWeight)/combinedWeight;return;}
|
|
507
|
+
#endif
|
|
508
|
+
gl_FragColor=primaryColorEvaluation.blendedColor;
|
|
509
|
+
#endif
|
|
510
|
+
#endif
|
|
511
|
+
}
|
|
512
|
+
`;
|
|
513
|
+
// Sideeffect
|
|
514
|
+
if (!ShaderStore.ShadersStore[name]) {
|
|
515
|
+
ShaderStore.ShadersStore[name] = shader;
|
|
516
|
+
}
|
|
517
|
+
/** @internal */
|
|
518
|
+
export const meshBlendingPixelShader = { name, shader };
|
|
519
|
+
//# sourceMappingURL=meshBlending.fragment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meshBlending.fragment.js","sourceRoot":"","sources":["../../../../dev/core/src/Shaders/meshBlending.fragment.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,IAAI,GAAG,yBAAyB,CAAC;AACvC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4fd,CAAC;AACF,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IAClC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAC5C,CAAC;AAED,gBAAgB;AAChB,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshBlendingPixelShader\";\nconst shader = `precision highp float;precision highp int;varying vec2 vUV;uniform sampler2D textureSampler;uniform highp usampler2D meshBlendTagSampler;uniform sampler2D meshBlendDepthSampler;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nuniform sampler2D meshBlendBaseColorSampler;\n#endif\nuniform sampler2D meshBlendBlueNoiseSampler;uniform mat4 projection;uniform mat4 inverseProjection;uniform mat4 inverseView;uniform vec4 blendWorldRadii;uniform vec4 minimumProjectedRadii;uniform float meshBlendIsOrthographic;uniform float slopeFactor;\n#ifndef MESH_BLEND_DIRECTION_COUNT\n#define MESH_BLEND_DIRECTION_COUNT 3\n#define MESH_BLEND_RADIAL_SAMPLE_COUNT 3\n#define MESH_BLEND_DIRECTION_REFINEMENT_SAMPLE_COUNT 2\n#define MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT 4\n#define MESH_BLEND_EXACT_EDGE_SAMPLE_COUNT 8\n#define MESH_BLEND_RADIUS_SCALE 0.9\n#define MESH_BLEND_JITTER_FACTOR 0.5\n#define MESH_BLEND_COLOR_INTERPOLATION_OKLAB\n#endif\n#define MESH_BLEND_TWO_PI 6.283185307179586\n#define MESH_BLEND_EPSILON 0.00001\n#define MESH_BLEND_DIRECTION_REFINEMENT_SECTOR_SCALE 0.2\n#define MESH_BLEND_TINY_OBJECT_PROBE_COUNT 8\n#define MESH_BLEND_MIN_SLOPE_SCALE 0.25\n#define MESH_BLEND_BOUNDARY_SEPARATION_FACTOR 0.75\n#define MESH_BLEND_BOUNDARY_PIXEL_TOLERANCE 3.0\n#define MESH_BLEND_FOREGROUND_DEPTH_FACTOR 0.35\n#define MESH_BLEND_FOREGROUND_LATERAL_FACTOR 2.0\n#define MESH_BLEND_TARGET_SPAN_FACTOR 1.5\n#define MESH_BLEND_TOTAL_SPAN_FACTOR 2.5\n#define MESH_BLEND_NEAR_EDGE_TARGET_WEIGHT 0.35\n#define MESH_BLEND_NEAR_SEAM_MAX_DISTANCE 1.25\n#define MESH_BLEND_NEAR_SEAM_COLOR_DELTA 0.02\n#define MESH_BLEND_BASE_LUMINANCE_EPSILON 0.00001\n#define MESH_BLEND_TARGET_DARKER_RATIO 0.65\n#define MESH_BLEND_TARGET_NON_DARK_RATIO 0.9\n#define MESH_BLEND_SHADOW_DIFFERENCE_LOW 0.15\n#define MESH_BLEND_SHADOW_DIFFERENCE_HIGH 0.5\n#define MESH_BLEND_SHADOW_MIN_ATTENUATION 0.25\n#define MESH_BLEND_REJECTION_NONE 0\n#define MESH_BLEND_REJECTION_NO_CANDIDATE 1\n#define MESH_BLEND_REJECTION_NO_CONTINUATION 2\n#define MESH_BLEND_REJECTION_INVALID_DEPTH 3\n#define MESH_BLEND_REJECTION_DEPTH_SEPARATION 4\n#define MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND 5\n#define MESH_BLEND_REJECTION_PHYSICAL_SPAN 6\n#define MESH_BLEND_REJECTION_CONTACT_ANGLE 7\nstruct MeshBlendTag {uint groupId;uint radiusClass;};struct MeshBlendCandidate {uint targetGroupId;uint radiusClass;vec2 direction;float distancePixels;float searchRadiusPixels;float score;bool valid;};struct MeshBlendResult {MeshBlendCandidate candidate;ivec2 targetPixel;ivec2 targetFarPixel;vec3 currentViewPosition;float effectiveRadiusPixels;float fade;float tinyObjectRadiusRatio;int rejectionReason;int stageReached;bool valid;bool continuationFound;bool usedFallback;bool tinyObjectRadiusReduced;};struct MeshBlendTargetColorSamples {vec4 fartherColor;vec4 boundaryPlusOneColor;vec4 boundaryPlusTwoColor;vec4 conservativeNearColor;vec4 targetColor;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nvec3 fartherBaseColor;vec3 conservativeNearBaseColor;\n#endif\nbool onePixelEdge;};struct MeshBlendColorEvaluation {MeshBlendTargetColorSamples samples;vec4 currentColor;vec4 blendedColor;\n#ifdef MESH_BLEND_DEBUG_WORLD_POSITION\nvec3 worldPosition;\n#endif\nfloat shadowAttenuation;float adjustedFade;bool nearSeamCorrected;};ivec2 clampPixel(ivec2 pixel,ivec2 renderSize) {return clamp(pixel,ivec2(0),renderSize-ivec2(1));}\nbool isPixelInBounds(ivec2 pixel,ivec2 renderSize) {return pixel.x>=0 && pixel.y>=0 && pixel.x<renderSize.x && pixel.y<renderSize.y;}\nvec2 pixelToUv(ivec2 pixel,ivec2 renderSize) {return (vec2(clampPixel(pixel,renderSize))+vec2(0.5))/vec2(renderSize);}\nMeshBlendTag loadMeshBlendTag(ivec2 pixel,ivec2 renderSize) {uint packedTag=texelFetch(meshBlendTagSampler,clampPixel(pixel,renderSize),0).r;MeshBlendTag tag;tag.groupId=packedTag & 0x3fu;tag.radiusClass=packedTag>>6u;return tag;}\nfloat loadMeshBlendDepth(ivec2 pixel,ivec2 renderSize) {return texelFetch(meshBlendDepthSampler,clampPixel(pixel,renderSize),0).r;}\nfloat classValue(vec4 values,uint index) {if (index==0u) {return values.x;}\nif (index==1u) {return values.y;}\nif (index==2u) {return values.z;}\nreturn values.w;}\nfloat meshBlendDepthToNdc(float depth) {\n#ifdef MESH_BLEND_DEPTH_SCREEN\n#ifdef IS_NDC_HALF_ZRANGE\nreturn depth;\n#else\nreturn depth*2.0-1.0;\n#endif\n#else\nvec4 projectedDepth=projection*vec4(0.0,0.0,depth,1.0);return projectedDepth.z/projectedDepth.w;\n#endif\n}\nvec3 reconstructMeshBlendViewPosition(ivec2 pixel,ivec2 renderSize,float depth) {vec2 ndcXY=pixelToUv(pixel,renderSize)*2.0-1.0;vec4 viewPosition=inverseProjection*vec4(ndcXY,meshBlendDepthToNdc(depth),1.0);return viewPosition.xyz/viewPosition.w;}\nvec3 reconstructMeshBlendWorldPosition(vec3 viewPosition) {return (inverseView*vec4(viewPosition,1.0)).xyz;}\nbool isValidMeshBlendPosition(vec3 position) {return !any(isnan(position)) && !any(isinf(position));}\nfloat meshBlendProjectionScale(float renderHeight) {return max(0.5*renderHeight*abs(projection[1][1]),MESH_BLEND_EPSILON);}\nfloat searchRadiusForClass(uint radiusClass,float viewDepth,float renderHeight) {float projectionScale=meshBlendProjectionScale(renderHeight);float projectedWorldRadius=classValue(blendWorldRadii,radiusClass)*projectionScale;if (meshBlendIsOrthographic<0.5) {projectedWorldRadius/=max(viewDepth,MESH_BLEND_EPSILON);}\nfloat scaledRadius=max(projectedWorldRadius,classValue(minimumProjectedRadii,radiusClass))*MESH_BLEND_RADIUS_SCALE;return scaledRadius>0.0 ? max(1.0,scaledRadius) : 0.0;}\nfloat worldUnitsPerPixel(float viewDepth,float renderHeight) {float unitsPerPixel=1.0/meshBlendProjectionScale(renderHeight);return meshBlendIsOrthographic>0.5 ? unitsPerPixel : unitsPerPixel*max(viewDepth,MESH_BLEND_EPSILON);}\nfloat calculateSlopeScale(float oppositeFacing) {if (slopeFactor<=1.0) {return 1.0;}\nreturn MESH_BLEND_MIN_SLOPE_SCALE +\n(1.0-MESH_BLEND_MIN_SLOPE_SCALE)*pow(clamp(oppositeFacing,0.0,1.0),slopeFactor-1.0);}\nvec2 loadStableBlueNoise(ivec2 pixel) {ivec2 noiseSize=textureSize(meshBlendBlueNoiseSampler,0);ivec2 wrappedPixel=ivec2(pixel.x % noiseSize.x,pixel.y % noiseSize.y);return texelFetch(meshBlendBlueNoiseSampler,wrappedPixel,0).rg;}\nvec2 directionAt(int index,float rotation,float sectorAngle,vec2 direction0,vec2 direction1,vec2 direction2) {\n#if MESH_BLEND_DIRECTION_COUNT==3\nif (index==0) {return direction0;}\nif (index==1) {return direction1;}\nreturn direction2;\n#else\nfloat angle=rotation+sectorAngle*float(index);return vec2(cos(angle),sin(angle));\n#endif\n}\nMeshBlendCandidate invalidCandidate() {MeshBlendCandidate candidate;candidate.targetGroupId=0u;candidate.radiusClass=0u;candidate.direction=vec2(0.0);candidate.distancePixels=0.0;candidate.searchRadiusPixels=0.0;candidate.score=-1.0;candidate.valid=false;return candidate;}\nMeshBlendResult invalidBlendResult() {MeshBlendResult result;result.candidate=invalidCandidate();result.targetPixel=ivec2(0);result.targetFarPixel=ivec2(0);result.currentViewPosition=vec3(0.0);result.effectiveRadiusPixels=0.0;result.fade=0.0;result.tinyObjectRadiusRatio=1.0;result.rejectionReason=MESH_BLEND_REJECTION_NO_CANDIDATE;result.stageReached=1;result.valid=false;result.continuationFound=false;result.usedFallback=false;result.tinyObjectRadiusReduced=false;return result;}\nMeshBlendCandidate findInitialCandidate(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nfloat currentSearchRadius,\nfloat viewDepth,\nuint ignoredGroupId,\nvec2 randomValues,\nfloat rotation,\nfloat sectorAngle,\nvec2 direction0,\nvec2 direction1,\nvec2 direction2\n) {MeshBlendCandidate best=invalidCandidate();float radialJitter=mix(0.5,randomValues.y,MESH_BLEND_JITTER_FACTOR);for (int radialIndex=0; radialIndex<MESH_BLEND_RADIAL_SAMPLE_COUNT; ++radialIndex) {float normalizedDistance=(float(radialIndex)+radialJitter)/float(MESH_BLEND_RADIAL_SAMPLE_COUNT);float distancePixels=max(1.0,ceil(normalizedDistance*normalizedDistance*normalizedDistance*currentSearchRadius));for (int directionIndex=0; directionIndex<MESH_BLEND_DIRECTION_COUNT; ++directionIndex) {vec2 direction=directionAt(directionIndex,rotation,sectorAngle,direction0,direction1,direction2);ivec2 samplePixel=pixel+ivec2(round(direction*distancePixels));MeshBlendTag candidateTag=loadMeshBlendTag(samplePixel,renderSize);if (candidateTag.groupId==0u || candidateTag.groupId==currentTag.groupId || candidateTag.groupId==ignoredGroupId) {continue;}\nuint seamRadiusClass=min(currentTag.radiusClass,candidateTag.radiusClass);float candidateSearchRadius=searchRadiusForClass(seamRadiusClass,viewDepth,float(renderSize.y));if (distancePixels>candidateSearchRadius) {continue;}\nfloat score=1.0-clamp(distancePixels/max(candidateSearchRadius,MESH_BLEND_EPSILON),0.0,1.0);if (score>best.score) {best.targetGroupId=candidateTag.groupId;best.radiusClass=seamRadiusClass;best.direction=direction;best.distancePixels=distancePixels;best.searchRadiusPixels=candidateSearchRadius;best.score=score;best.valid=true;}}\nif (best.valid) {break;}}\nreturn best;}\nMeshBlendCandidate refineCandidateDirection(ivec2 pixel,ivec2 renderSize,MeshBlendCandidate candidate,vec2 randomValues) {if (candidate.distancePixels<=2.0) {return candidate;}\nfloat centerAngle=atan(candidate.direction.y,candidate.direction.x);float angularHalfWidth=(MESH_BLEND_TWO_PI/float(MESH_BLEND_DIRECTION_COUNT))*MESH_BLEND_DIRECTION_REFINEMENT_SECTOR_SCALE;float stepSize=max(1.0,candidate.distancePixels/float(MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT+1));for (int sampleIndex=0; sampleIndex<MESH_BLEND_DIRECTION_REFINEMENT_SAMPLE_COUNT; ++sampleIndex) {float sampleRandom=fract(randomValues.y+randomValues.x*0.754877666+float(sampleIndex)*0.618033989);float angle=centerAngle+mix(-angularHalfWidth,angularHalfWidth,sampleRandom);vec2 direction=vec2(cos(angle),sin(angle));float testDistance=candidate.distancePixels-stepSize;for (int stepIndex=0; stepIndex<MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT; ++stepIndex) {if (testDistance<=0.0) {break;}\nivec2 samplePixel=pixel+ivec2(round(direction*testDistance));MeshBlendTag sampleTag=loadMeshBlendTag(samplePixel,renderSize);if (sampleTag.groupId != candidate.targetGroupId) {break;}\ncandidate.direction=direction;candidate.distancePixels=testDistance;testDistance-=stepSize;}}\nreturn candidate;}\nMeshBlendCandidate refineExactBoundary(ivec2 pixel,ivec2 renderSize,MeshBlendCandidate candidate) {float distancePixels=candidate.distancePixels;for (int sampleIndex=0; sampleIndex<MESH_BLEND_EXACT_EDGE_SAMPLE_COUNT; ++sampleIndex) {distancePixels-=1.0;if (distancePixels<=0.0) {break;}\nivec2 samplePixel=pixel+ivec2(round(candidate.direction*distancePixels));MeshBlendTag sampleTag=loadMeshBlendTag(samplePixel,renderSize);if (sampleTag.groupId != candidate.targetGroupId) {break;}\ncandidate.distancePixels=distancePixels;}\nreturn candidate;}\nbool hasTargetContinuation(ivec2 pixel,ivec2 renderSize,MeshBlendCandidate candidate,out ivec2 continuationPixel) {float continuationDistance=max(candidate.distancePixels*2.0,candidate.distancePixels+1.0);continuationPixel=pixel+ivec2(round(candidate.direction*continuationDistance));if (!isPixelInBounds(continuationPixel,renderSize)) {return false;}\nreturn loadMeshBlendTag(continuationPixel,renderSize).groupId==candidate.targetGroupId;}\nbool applyTargetRadiusClass(ivec2 targetPixel,ivec2 renderSize,float viewDepth,inout MeshBlendCandidate candidate) {MeshBlendTag targetTag=loadMeshBlendTag(targetPixel,renderSize);candidate.radiusClass=min(candidate.radiusClass,targetTag.radiusClass);candidate.searchRadiusPixels=min(candidate.searchRadiusPixels,searchRadiusForClass(candidate.radiusClass,viewDepth,float(renderSize.y)));return candidate.distancePixels<=candidate.searchRadiusPixels;}\n#ifdef MESH_BLEND_FOUR_NEIGHBOR_FALLBACK\nMeshBlendCandidate findImmediateNeighborCandidate(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nfloat viewDepth,\nuint ignoredGroupId,\nuint preferredGroupId\n) {MeshBlendCandidate best=invalidCandidate();for (int neighborIndex=0; neighborIndex<4; ++neighborIndex) {ivec2 offset;if (neighborIndex==0) {offset=ivec2(1,0);} else if (neighborIndex==1) {offset=ivec2(-1,0);} else if (neighborIndex==2) {offset=ivec2(0,1);} else {offset=ivec2(0,-1);}\nMeshBlendTag neighborTag=loadMeshBlendTag(pixel+offset,renderSize);if (neighborTag.groupId==0u || neighborTag.groupId==currentTag.groupId || neighborTag.groupId==ignoredGroupId) {continue;}\nuint seamRadiusClass=min(currentTag.radiusClass,neighborTag.radiusClass);float candidateSearchRadius=searchRadiusForClass(seamRadiusClass,viewDepth,float(renderSize.y));if (candidateSearchRadius<1.0) {continue;}\nfloat score=1.0-1.0/max(candidateSearchRadius,1.0);if (neighborTag.groupId==preferredGroupId) {score+=1.0;}\nif (score>best.score) {best.targetGroupId=neighborTag.groupId;best.radiusClass=seamRadiusClass;best.direction=vec2(offset);best.distancePixels=1.0;best.searchRadiusPixels=candidateSearchRadius;best.score=score;best.valid=true;}}\nreturn best;}\n#endif\n#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD\nfloat reduceRadiusForTinyObject(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nMeshBlendCandidate candidate,\nout bool radiusReduced\n) {float measuredThickness=candidate.searchRadiusPixels;bool foundOppositeBoundary=false;for (int probeIndex=1; probeIndex<=MESH_BLEND_TINY_OBJECT_PROBE_COUNT; ++probeIndex) {float probeDistance=max(1.0,candidate.searchRadiusPixels*float(probeIndex)/float(MESH_BLEND_TINY_OBJECT_PROBE_COUNT));MeshBlendTag oppositeTag=loadMeshBlendTag(pixel-ivec2(round(candidate.direction*probeDistance)),renderSize);if (oppositeTag.groupId != currentTag.groupId) {measuredThickness=probeDistance;foundOppositeBoundary=true;break;}}\nint outsideDirectionCount=0;for (int neighborIndex=0; neighborIndex<4; ++neighborIndex) {vec2 direction;if (neighborIndex==0) {direction=vec2(1.0,0.0);} else if (neighborIndex==1) {direction=vec2(-1.0,0.0);} else if (neighborIndex==2) {direction=vec2(0.0,1.0);} else {direction=vec2(0.0,-1.0);}\nMeshBlendTag radiusTag=loadMeshBlendTag(pixel+ivec2(round(direction*candidate.searchRadiusPixels)),renderSize);if (radiusTag.groupId != currentTag.groupId) {outsideDirectionCount++;}}\nradiusReduced=foundOppositeBoundary && outsideDirectionCount>=3;if (!radiusReduced) {return candidate.searchRadiusPixels;}\nfloat thicknessRadius=max(1.0,measuredThickness*1.25);return max(candidate.distancePixels,min(candidate.searchRadiusPixels,thicknessRadius));}\n#endif\nint validateMeshBlendContact(\nivec2 pixelA,\nivec2 pixelE,\nivec2 pixelB,\nivec2 pixelC,\nivec2 renderSize,\nMeshBlendTag currentTag,\nMeshBlendCandidate candidate,\nbool allowMissingContinuation,\nout float narrowedSearchRadius,\nout vec3 currentViewPosition\n) {currentViewPosition=vec3(0.0);MeshBlendTag tagE=loadMeshBlendTag(pixelE,renderSize);MeshBlendTag tagB=loadMeshBlendTag(pixelB,renderSize);MeshBlendTag tagC=loadMeshBlendTag(pixelC,renderSize);if (\ntagE.groupId != currentTag.groupId ||\ntagB.groupId != candidate.targetGroupId ||\n(!allowMissingContinuation && tagC.groupId != candidate.targetGroupId)\n) {return MESH_BLEND_REJECTION_NO_CONTINUATION;}\nfloat depthA=loadMeshBlendDepth(pixelA,renderSize);float depthE=loadMeshBlendDepth(pixelE,renderSize);float depthB=loadMeshBlendDepth(pixelB,renderSize);float depthC=loadMeshBlendDepth(pixelC,renderSize);vec3 positionA=reconstructMeshBlendViewPosition(pixelA,renderSize,depthA);vec3 positionE=reconstructMeshBlendViewPosition(pixelE,renderSize,depthE);vec3 positionB=reconstructMeshBlendViewPosition(pixelB,renderSize,depthB);vec3 positionC=reconstructMeshBlendViewPosition(pixelC,renderSize,depthC);if (!isValidMeshBlendPosition(positionA) || !isValidMeshBlendPosition(positionE) || !isValidMeshBlendPosition(positionB) || !isValidMeshBlendPosition(positionC)) {return MESH_BLEND_REJECTION_INVALID_DEPTH;}\ncurrentViewPosition=positionA;float viewDepth=abs(positionA.z);float unitsPerPixel=worldUnitsPerPixel(viewDepth,float(renderSize.y));float effectiveWorldRadius=candidate.searchRadiusPixels*unitsPerPixel;float pixelTolerance=unitsPerPixel*MESH_BLEND_BOUNDARY_PIXEL_TOLERANCE;vec3 boundarySpan=positionB-positionE;float boundarySeparation=length(boundarySpan);if (boundarySeparation>effectiveWorldRadius*MESH_BLEND_BOUNDARY_SEPARATION_FACTOR+pixelTolerance) {return MESH_BLEND_REJECTION_DEPTH_SEPARATION;}\nfloat boundaryDepthDelta=abs(abs(positionB.z)-abs(positionE.z));float boundaryLateralSpan=length(boundarySpan.xy);if (\nboundaryDepthDelta>max(effectiveWorldRadius*MESH_BLEND_FOREGROUND_DEPTH_FACTOR,pixelTolerance) &&\nboundaryDepthDelta>boundaryLateralSpan*MESH_BLEND_FOREGROUND_LATERAL_FACTOR\n) {return MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND;}\nfloat targetSpan=distance(positionB,positionC);float totalSpan=distance(positionA,positionC);if (\ntargetSpan>effectiveWorldRadius*MESH_BLEND_TARGET_SPAN_FACTOR+pixelTolerance ||\ntotalSpan>effectiveWorldRadius*MESH_BLEND_TOTAL_SPAN_FACTOR+pixelTolerance\n) {return MESH_BLEND_REJECTION_PHYSICAL_SPAN;}\nvec3 currentDirection=positionA-positionB;vec3 targetDirection=positionC-positionB;float currentLength=length(currentDirection);float targetLength=length(targetDirection);float oppositeFacing=1.0;if (currentLength>MESH_BLEND_EPSILON && targetLength>MESH_BLEND_EPSILON) {oppositeFacing=-dot(currentDirection/currentLength,targetDirection/targetLength);}\nnarrowedSearchRadius=candidate.searchRadiusPixels*calculateSlopeScale(oppositeFacing);if (candidate.distancePixels>narrowedSearchRadius) {return MESH_BLEND_REJECTION_CONTACT_ANGLE;}\nreturn MESH_BLEND_REJECTION_NONE;}\nfloat calculateMeshBlendFade(float distancePixels,float searchRadiusPixels) {float boundaryDistance=max(distancePixels-0.5,0.0);float normalizedDistance=clamp(boundaryDistance/max(searchRadiusPixels,MESH_BLEND_EPSILON),0.0,1.0);float inverseDistance=1.0-normalizedDistance;float fade=mix(inverseDistance*inverseDistance,inverseDistance,clamp(inverseDistance-0.75,0.0,1.0));return fade*0.5;}\nMeshBlendResult evaluateMeshBlend(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nfloat currentSearchRadius,\nfloat viewDepth,\nuint ignoredGroupId,\nvec2 randomValues,\nfloat rotation,\nfloat sectorAngle,\nvec2 direction0,\nvec2 direction1,\nvec2 direction2\n) {MeshBlendResult result=invalidBlendResult();MeshBlendCandidate candidate=findInitialCandidate(\npixel,\nrenderSize,\ncurrentTag,\ncurrentSearchRadius,\nviewDepth,\nignoredGroupId,\nrandomValues,\nrotation,\nsectorAngle,\ndirection0,\ndirection1,\ndirection2\n);result.candidate=candidate;if (!candidate.valid) {return result;}\nresult.stageReached=2;candidate=refineCandidateDirection(pixel,renderSize,candidate,randomValues);candidate=refineExactBoundary(pixel,renderSize,candidate);result.candidate=candidate;result.stageReached=3;ivec2 refinedTargetPixel=clampPixel(pixel+ivec2(round(candidate.direction*candidate.distancePixels)),renderSize);if (!applyTargetRadiusClass(refinedTargetPixel,renderSize,viewDepth,candidate)) {result.candidate=candidate;result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}\nresult.candidate=candidate;ivec2 continuationPixel;bool continuationFound=hasTargetContinuation(pixel,renderSize,candidate,continuationPixel);if (!continuationFound) {\n#ifdef MESH_BLEND_FOUR_NEIGHBOR_FALLBACK\nMeshBlendCandidate fallbackCandidate=findImmediateNeighborCandidate(\npixel,\nrenderSize,\ncurrentTag,\nviewDepth,\nignoredGroupId,\ncandidate.targetGroupId\n);if (!fallbackCandidate.valid) {result.rejectionReason=MESH_BLEND_REJECTION_NO_CONTINUATION;return result;}\ncandidate=fallbackCandidate;result.candidate=candidate;result.usedFallback=true;continuationFound=hasTargetContinuation(pixel,renderSize,candidate,continuationPixel);\n#else\nresult.rejectionReason=MESH_BLEND_REJECTION_NO_CONTINUATION;return result;\n#endif\n}\nresult.continuationFound=continuationFound;result.stageReached=4;if (continuationFound && !applyTargetRadiusClass(continuationPixel,renderSize,viewDepth,candidate)) {result.candidate=candidate;result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}\nresult.candidate=candidate;float originalSearchRadius=candidate.searchRadiusPixels;\n#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD\ncandidate.searchRadiusPixels=reduceRadiusForTinyObject(pixel,renderSize,currentTag,candidate,result.tinyObjectRadiusReduced);result.stageReached=5;\n#endif\nresult.candidate=candidate;result.effectiveRadiusPixels=candidate.searchRadiusPixels;result.tinyObjectRadiusRatio=candidate.searchRadiusPixels/max(originalSearchRadius,MESH_BLEND_EPSILON);ivec2 pixelB=clampPixel(pixel+ivec2(round(candidate.direction*candidate.distancePixels)),renderSize);ivec2 pixelE=clampPixel(pixel+ivec2(round(candidate.direction*max(candidate.distancePixels-2.0,0.0))),renderSize);ivec2 pixelC=continuationFound ? continuationPixel : pixelB;float narrowedSearchRadius=candidate.searchRadiusPixels;result.rejectionReason=validateMeshBlendContact(\npixel,\npixelE,\npixelB,\npixelC,\nrenderSize,\ncurrentTag,\ncandidate,\nresult.usedFallback && !continuationFound,\nnarrowedSearchRadius,\nresult.currentViewPosition\n);result.stageReached=6;result.effectiveRadiusPixels=narrowedSearchRadius;if (result.rejectionReason != MESH_BLEND_REJECTION_NONE) {return result;}\nresult.fade=calculateMeshBlendFade(candidate.distancePixels,narrowedSearchRadius);if (result.fade<=0.0) {result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}\nresult.targetPixel=pixelB;result.targetFarPixel=continuationFound ? continuationPixel : pixelB;result.stageReached=7;result.valid=true;return result;}\nfloat meshBlendLinearToSrgbChannel(float value) {return value<=0.0031308 ? value*12.92 : 1.055*pow(value,1.0/2.4)-0.055;}\nfloat meshBlendSrgbToLinearChannel(float value) {return value<=0.04045 ? value/12.92 : pow((value+0.055)/1.055,2.4);}\nvec3 meshBlendLinearToSrgb(vec3 color) {return vec3(\nmeshBlendLinearToSrgbChannel(color.r),\nmeshBlendLinearToSrgbChannel(color.g),\nmeshBlendLinearToSrgbChannel(color.b)\n);}\nvec3 meshBlendSrgbToLinear(vec3 color) {return vec3(\nmeshBlendSrgbToLinearChannel(color.r),\nmeshBlendSrgbToLinearChannel(color.g),\nmeshBlendSrgbToLinearChannel(color.b)\n);}\nfloat meshBlendSignedCubeRoot(float value) {return sign(value)*pow(abs(value),1.0/3.0);}\nvec3 meshBlendLinearSrgbToOklab(vec3 color) {float longResponse=0.4122214708*color.r+0.5363325363*color.g+0.0514459929*color.b;float mediumResponse=0.2119034982*color.r+0.6806995451*color.g+0.1073969566*color.b;float shortResponse=0.0883024619*color.r+0.2817188376*color.g+0.6299787005*color.b;float longRoot=meshBlendSignedCubeRoot(longResponse);float mediumRoot=meshBlendSignedCubeRoot(mediumResponse);float shortRoot=meshBlendSignedCubeRoot(shortResponse);return vec3(\n0.2104542553*longRoot+0.7936177850*mediumRoot-0.0040720468*shortRoot,\n1.9779984951*longRoot-2.4285922050*mediumRoot+0.4505937099*shortRoot,\n0.0259040371*longRoot+0.7827717662*mediumRoot-0.8086757660*shortRoot\n);}\nvec3 meshBlendOklabToLinearSrgb(vec3 color) {float longRoot=color.x+0.3963377774*color.y+0.2158037573*color.z;float mediumRoot=color.x-0.1055613458*color.y-0.0638541728*color.z;float shortRoot=color.x-0.0894841775*color.y-1.2914855480*color.z;float longResponse=longRoot*longRoot*longRoot;float mediumResponse=mediumRoot*mediumRoot*mediumRoot;float shortResponse=shortRoot*shortRoot*shortRoot;return vec3(\n4.0767416621*longResponse-3.3077115913*mediumResponse+0.2309699292*shortResponse,\n-1.2684380046*longResponse+2.6097574011*mediumResponse-0.3413193965*shortResponse,\n-0.0041960863*longResponse-0.7034186147*mediumResponse+1.7076147010*shortResponse\n);}\nvec3 interpolateMeshBlendColor(vec3 currentColor,vec3 targetColor,float factor) {\n#ifdef MESH_BLEND_COLOR_INTERPOLATION_SRGB\nreturn meshBlendSrgbToLinear(mix(meshBlendLinearToSrgb(currentColor),meshBlendLinearToSrgb(targetColor),factor));\n#else\nreturn meshBlendOklabToLinearSrgb(mix(meshBlendLinearSrgbToOklab(currentColor),meshBlendLinearSrgbToOklab(targetColor),factor));\n#endif\n}\nfloat meshBlendLuminance(vec3 srgbColor) {return dot(srgbColor,vec3(0.2126,0.7152,0.0722));}\nMeshBlendTargetColorSamples constructMeshBlendTargetColorSamples(ivec2 renderSize,MeshBlendResult result) {MeshBlendTargetColorSamples samples;ivec2 boundaryPlusOnePixel=clampPixel(result.targetPixel+ivec2(round(result.candidate.direction)),renderSize);ivec2 boundaryPlusTwoPixel=clampPixel(result.targetPixel+ivec2(round(result.candidate.direction*2.0)),renderSize);MeshBlendTag boundaryPlusOneTag=loadMeshBlendTag(boundaryPlusOnePixel,renderSize);MeshBlendTag boundaryPlusTwoTag=loadMeshBlendTag(boundaryPlusTwoPixel,renderSize);samples.fartherColor=texelFetch(textureSampler,result.targetFarPixel,0);samples.boundaryPlusOneColor=texelFetch(textureSampler,boundaryPlusOnePixel,0);samples.boundaryPlusTwoColor=texelFetch(textureSampler,boundaryPlusTwoPixel,0);\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.fartherBaseColor=texelFetch(meshBlendBaseColorSampler,result.targetFarPixel,0).rgb;vec3 boundaryPlusOneBaseColor=texelFetch(meshBlendBaseColorSampler,boundaryPlusOnePixel,0).rgb;vec3 boundaryPlusTwoBaseColor=texelFetch(meshBlendBaseColorSampler,boundaryPlusTwoPixel,0).rgb;\n#endif\nsamples.onePixelEdge=boundaryPlusOneTag.groupId != result.candidate.targetGroupId;if (samples.onePixelEdge) {samples.conservativeNearColor=samples.fartherColor;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.conservativeNearBaseColor=samples.fartherBaseColor;\n#endif\nsamples.targetColor=samples.fartherColor;return samples;}\nbool secondNearSampleIsTarget=boundaryPlusTwoTag.groupId==result.candidate.targetGroupId;float firstNearLuminance=meshBlendLuminance(meshBlendLinearToSrgb(samples.boundaryPlusOneColor.rgb));float secondNearLuminance=meshBlendLuminance(meshBlendLinearToSrgb(samples.boundaryPlusTwoColor.rgb));bool useSecondNearSample=secondNearSampleIsTarget && secondNearLuminance<firstNearLuminance;samples.conservativeNearColor=useSecondNearSample ? samples.boundaryPlusTwoColor : samples.boundaryPlusOneColor;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.conservativeNearBaseColor=useSecondNearSample ? boundaryPlusTwoBaseColor : boundaryPlusOneBaseColor;\n#endif\nsamples.targetColor=mix(samples.fartherColor,samples.conservativeNearColor,MESH_BLEND_NEAR_EDGE_TARGET_WEIGHT);return samples;}\nvec4 applyMeshBlendNearSeamCorrection(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nMeshBlendResult result,\nMeshBlendTargetColorSamples samples,\nvec4 currentColor,\nout bool corrected\n) {corrected=false;if (!samples.onePixelEdge || result.candidate.distancePixels>MESH_BLEND_NEAR_SEAM_MAX_DISTANCE) {return currentColor;}\nivec2 oppositePixel=clampPixel(pixel-ivec2(round(result.candidate.direction)),renderSize);MeshBlendTag oppositeTag=loadMeshBlendTag(oppositePixel,renderSize);if (oppositeTag.groupId != currentTag.groupId) {return currentColor;}\nvec4 oppositeColor=texelFetch(textureSampler,oppositePixel,0);float currentTargetDistance=distance(currentColor.rgb,samples.targetColor.rgb);float oppositeTargetDistance=distance(oppositeColor.rgb,samples.targetColor.rgb);if (currentTargetDistance+MESH_BLEND_NEAR_SEAM_COLOR_DELTA>=oppositeTargetDistance) {return currentColor;}\ncorrected=true;return oppositeColor;}\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nfloat estimateMeshBlendShadow(vec3 renderedLinear,vec3 baseColorLinear) {float renderedLuminance=meshBlendLuminance(meshBlendLinearToSrgb(renderedLinear));float baseLuminance=meshBlendLuminance(meshBlendLinearToSrgb(baseColorLinear));if (baseLuminance<=MESH_BLEND_BASE_LUMINANCE_EPSILON) {return 1.0;}\nreturn renderedLuminance/baseLuminance;}\nfloat calculateMeshBlendShadowAttenuation(vec3 currentColor,MeshBlendTargetColorSamples samples) {float fartherShadow=estimateMeshBlendShadow(samples.fartherColor.rgb,samples.fartherBaseColor);float nearShadow=estimateMeshBlendShadow(samples.conservativeNearColor.rgb,samples.conservativeNearBaseColor);float shadowDifference=abs(fartherShadow-nearShadow);float shadowMismatch=smoothstep(MESH_BLEND_SHADOW_DIFFERENCE_LOW,MESH_BLEND_SHADOW_DIFFERENCE_HIGH,shadowDifference);float currentLuminance=meshBlendLuminance(meshBlendLinearToSrgb(currentColor));float targetLuminance=meshBlendLuminance(meshBlendLinearToSrgb(samples.targetColor.rgb));float targetToCurrentRatio=targetLuminance/max(currentLuminance,MESH_BLEND_BASE_LUMINANCE_EPSILON);float targetIsNotDark=smoothstep(MESH_BLEND_TARGET_DARKER_RATIO,MESH_BLEND_TARGET_NON_DARK_RATIO,targetToCurrentRatio);return mix(1.0,MESH_BLEND_SHADOW_MIN_ATTENUATION,shadowMismatch*targetIsNotDark);}\n#endif\nMeshBlendColorEvaluation evaluateMeshBlendColor(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nMeshBlendResult result\n) {MeshBlendColorEvaluation evaluation;evaluation.samples=constructMeshBlendTargetColorSamples(renderSize,result);\n#ifdef MESH_BLEND_DEBUG_WORLD_POSITION\nevaluation.worldPosition=reconstructMeshBlendWorldPosition(result.currentViewPosition);\n#endif\nvec4 currentSceneColor=texelFetch(textureSampler,pixel,0);evaluation.currentColor=applyMeshBlendNearSeamCorrection(\npixel,\nrenderSize,\ncurrentTag,\nresult,\nevaluation.samples,\ncurrentSceneColor,\nevaluation.nearSeamCorrected\n);evaluation.shadowAttenuation=1.0;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nevaluation.shadowAttenuation=calculateMeshBlendShadowAttenuation(evaluation.currentColor.rgb,evaluation.samples);\n#endif\nevaluation.adjustedFade=result.fade*evaluation.shadowAttenuation;evaluation.blendedColor=vec4(\ninterpolateMeshBlendColor(evaluation.currentColor.rgb,evaluation.samples.targetColor.rgb,evaluation.adjustedFade),\nmix(evaluation.currentColor.a,evaluation.samples.targetColor.a,evaluation.adjustedFade)\n);return evaluation;}\nvec3 radiusClassDebugColor(uint radiusClass) {if (radiusClass==0u) {return vec3(0.15,0.55,1.0);}\nif (radiusClass==1u) {return vec3(0.15,0.9,0.35);}\nif (radiusClass==2u) {return vec3(1.0,0.65,0.1);}\nreturn vec3(0.95,0.2,0.65);}\nvec3 validationDebugColor(int rejectionReason,float narrowedRadiusRatio) {if (rejectionReason==MESH_BLEND_REJECTION_NONE) {return mix(vec3(0.1,0.55,1.0),vec3(0.2,1.0,0.25),narrowedRadiusRatio);}\nif (rejectionReason==MESH_BLEND_REJECTION_NO_CANDIDATE) {return vec3(0.12);}\nif (rejectionReason==MESH_BLEND_REJECTION_NO_CONTINUATION) {return vec3(0.75,0.1,0.85);}\nif (rejectionReason==MESH_BLEND_REJECTION_INVALID_DEPTH) {return vec3(1.0,0.0,1.0);}\nif (rejectionReason==MESH_BLEND_REJECTION_DEPTH_SEPARATION) {return vec3(1.0,0.1,0.1);}\nif (rejectionReason==MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND) {return vec3(1.0,0.4,0.05);}\nif (rejectionReason==MESH_BLEND_REJECTION_PHYSICAL_SPAN) {return vec3(1.0,0.9,0.05);}\nreturn vec3(0.05,0.8,1.0);}\nvec3 processingStageDebugColor(int stageReached) {if (stageReached<=0) {return vec3(0.03);}\nif (stageReached==1) {return vec3(0.1,0.15,0.45);}\nif (stageReached==2) {return vec3(0.1,0.35,0.7);}\nif (stageReached==3) {return vec3(0.05,0.65,0.8);}\nif (stageReached==4) {return vec3(0.1,0.8,0.55);}\nif (stageReached==5) {return vec3(0.45,0.9,0.25);}\nif (stageReached==6) {return vec3(0.95,0.75,0.1);}\nreturn vec3(0.15,1.0,0.25);}\nvec3 candidateDebugColor(MeshBlendResult result) {if (!result.candidate.valid) {return vec3(0.04);}\nfloat normalizedDistance=clamp(\nresult.candidate.distancePixels/max(result.candidate.searchRadiusPixels,MESH_BLEND_EPSILON),\n0.0,\n1.0\n);return vec3(result.candidate.direction*0.5+0.5,1.0-normalizedDistance);}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {ivec2 renderSize=textureSize(meshBlendDepthSampler,0);ivec2 pixel=clampPixel(ivec2(floor(vUV*vec2(renderSize))),renderSize);MeshBlendTag currentTag=loadMeshBlendTag(pixel,renderSize);\n#ifdef MESH_BLEND_DEBUG_PACKED_TAG\nfloat groupVariation=0.45+0.55*fract(float(currentTag.groupId)*0.61803398875);vec3 tagColor=radiusClassDebugColor(currentTag.radiusClass)*groupVariation;gl_FragColor=currentTag.groupId==0u ? vec4(0.0,0.0,0.0,1.0) : vec4(tagColor,1.0);return;\n#endif\nif (currentTag.groupId==0u) {\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\ngl_FragColor=vec4(0.0,0.0,0.0,1.0);\n#elif defined(MESH_BLEND_DEBUG_ENABLED)\ngl_FragColor=vec4(0.04,0.04,0.04,1.0);\n#else\ngl_FragColor=texelFetch(textureSampler,pixel,0);\n#endif\nreturn;}\nfloat sizingDepth=loadMeshBlendDepth(pixel,renderSize);vec3 sizingPosition=reconstructMeshBlendViewPosition(pixel,renderSize,sizingDepth);if (!isValidMeshBlendPosition(sizingPosition)) {\n#ifdef MESH_BLEND_DEBUG_REJECTION_REASON\ngl_FragColor=vec4(validationDebugColor(MESH_BLEND_REJECTION_INVALID_DEPTH,0.0),1.0);\n#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)\ngl_FragColor=vec4(0.45,0.1,0.1,1.0);\n#elif defined(MESH_BLEND_DEBUG_ENABLED)\ngl_FragColor=vec4(0.4,0.05,0.4,1.0);\n#else\ngl_FragColor=texelFetch(textureSampler,pixel,0);\n#endif\nreturn;}\nfloat currentViewDepth=abs(sizingPosition.z);float currentSearchRadius=searchRadiusForClass(currentTag.radiusClass,currentViewDepth,float(renderSize.y));if (currentSearchRadius<1.0) {\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\ngl_FragColor=vec4(radiusClassDebugColor(currentTag.radiusClass)*0.25,1.0);\n#elif defined(MESH_BLEND_DEBUG_REJECTION_REASON)\ngl_FragColor=vec4(validationDebugColor(MESH_BLEND_REJECTION_PHYSICAL_SPAN,0.0),1.0);\n#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)\ngl_FragColor=vec4(0.2,0.2,0.65,1.0);\n#elif defined(MESH_BLEND_DEBUG_ENABLED)\ngl_FragColor=vec4(0.04,0.04,0.04,1.0);\n#else\ngl_FragColor=texelFetch(textureSampler,pixel,0);\n#endif\nreturn;}\nvec2 randomValues=loadStableBlueNoise(pixel);float sectorAngle=MESH_BLEND_TWO_PI/float(MESH_BLEND_DIRECTION_COUNT);float rotation;\n#ifdef MESH_BLEND_FULL_RANDOM_ROTATION\nrotation=randomValues.x*sectorAngle;\n#else\nrotation=floor(randomValues.x*8.0)*0.125*sectorAngle;\n#endif\nvec2 direction0=vec2(cos(rotation),sin(rotation));vec2 direction1=vec2(cos(rotation+sectorAngle),sin(rotation+sectorAngle));vec2 direction2=vec2(cos(rotation+sectorAngle*2.0),sin(rotation+sectorAngle*2.0));MeshBlendResult primaryResult=evaluateMeshBlend(\npixel,\nrenderSize,\ncurrentTag,\ncurrentSearchRadius,\ncurrentViewDepth,\n0u,\nrandomValues,\nrotation,\nsectorAngle,\ndirection0,\ndirection1,\ndirection2\n);MeshBlendResult secondaryResult=invalidBlendResult();\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (primaryResult.valid) {secondaryResult=evaluateMeshBlend(\npixel,\nrenderSize,\ncurrentTag,\ncurrentSearchRadius,\ncurrentViewDepth,\nprimaryResult.candidate.targetGroupId,\nrandomValues,\nrotation,\nsectorAngle,\ndirection0,\ndirection1,\ndirection2\n);}\n#endif\n#ifdef MESH_BLEND_DEBUG_CANDIDATE_DIRECTION_DISTANCE\ngl_FragColor=vec4(candidateDebugColor(primaryResult),1.0);return;\n#elif defined(MESH_BLEND_DEBUG_CONTINUATION)\nif (!primaryResult.candidate.valid) {gl_FragColor=vec4(0.04,0.04,0.04,1.0);} else if (primaryResult.rejectionReason==MESH_BLEND_REJECTION_NO_CONTINUATION) {gl_FragColor=vec4(0.85,0.05,0.7,1.0);} else if (primaryResult.usedFallback) {gl_FragColor=vec4(1.0,0.75,0.05,1.0);} else {gl_FragColor=vec4(0.1,0.9,0.25,1.0);}\nreturn;\n#elif defined(MESH_BLEND_DEBUG_TINY_OBJECT)\n#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD\nif (!primaryResult.candidate.valid) {gl_FragColor=vec4(0.04,0.04,0.04,1.0);} else {vec3 radiusColor=mix(vec3(1.0,0.1,0.05),vec3(0.1,0.65,1.0),primaryResult.tinyObjectRadiusRatio);gl_FragColor=vec4(primaryResult.tinyObjectRadiusReduced ? radiusColor : radiusColor*0.45,1.0);}\n#else\ngl_FragColor=vec4(0.04,0.04,0.04,1.0);\n#endif\nreturn;\n#elif defined(MESH_BLEND_DEBUG_MULTI_TARGET)\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (secondaryResult.valid) {gl_FragColor=vec4(0.95,0.95,1.0,1.0);} else if (secondaryResult.candidate.valid) {gl_FragColor=vec4(0.8,0.15,0.75,1.0);} else if (primaryResult.valid) {gl_FragColor=vec4(0.1,0.45,0.95,1.0);} else {gl_FragColor=vec4(0.04,0.04,0.04,1.0);}\n#else\ngl_FragColor=primaryResult.valid ? vec4(0.1,0.45,0.95,1.0) : vec4(0.04,0.04,0.04,1.0);\n#endif\nreturn;\n#elif defined(MESH_BLEND_DEBUG_REJECTION_REASON)\nfloat narrowedRadiusRatio=primaryResult.candidate.valid\n? primaryResult.effectiveRadiusPixels/max(primaryResult.candidate.searchRadiusPixels,MESH_BLEND_EPSILON)\n: 0.0;gl_FragColor=vec4(validationDebugColor(primaryResult.rejectionReason,narrowedRadiusRatio),1.0);return;\n#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)\nint stageReached=primaryResult.stageReached;\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nstageReached=max(stageReached,secondaryResult.stageReached);\n#endif\ngl_FragColor=vec4(processingStageDebugColor(stageReached),1.0);return;\n#endif\nif (!primaryResult.valid) {\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\nuint debugRadiusClass=primaryResult.candidate.valid ? primaryResult.candidate.radiusClass : currentTag.radiusClass;gl_FragColor=vec4(radiusClassDebugColor(debugRadiusClass)*0.25,1.0);\n#elif defined(MESH_BLEND_DEBUG_TARGET_COLOR) || defined(MESH_BLEND_DEBUG_SHADOW_ATTENUATION) || defined(MESH_BLEND_DEBUG_COLOR_INTERPOLATION) || defined(MESH_BLEND_DEBUG_WORLD_POSITION)\ngl_FragColor=vec4(0.04,0.04,0.04,1.0);\n#else\ngl_FragColor=texelFetch(textureSampler,pixel,0);\n#endif\nreturn;}\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\nfloat debugFade=primaryResult.fade;\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (secondaryResult.valid) {debugFade=min(0.5,primaryResult.fade+secondaryResult.fade);}\n#endif\nvec3 classColor=radiusClassDebugColor(primaryResult.candidate.radiusClass)*0.25;gl_FragColor=vec4(mix(classColor,vec3(1.0),clamp(debugFade*2.0,0.0,1.0)),1.0);return;\n#else\nMeshBlendColorEvaluation primaryColorEvaluation=evaluateMeshBlendColor(pixel,renderSize,currentTag,primaryResult);\n#ifdef MESH_BLEND_DEBUG_WORLD_POSITION\ngl_FragColor=vec4(fract(primaryColorEvaluation.worldPosition*0.1),1.0);return;\n#elif defined(MESH_BLEND_DEBUG_TARGET_COLOR)\nint targetSampleIndex=(pixel.x/4) % 4;if (targetSampleIndex==0) {gl_FragColor=primaryColorEvaluation.samples.fartherColor;} else if (targetSampleIndex==1) {gl_FragColor=primaryColorEvaluation.samples.boundaryPlusOneColor;} else if (targetSampleIndex==2) {gl_FragColor=primaryColorEvaluation.samples.boundaryPlusTwoColor;} else {gl_FragColor=primaryColorEvaluation.samples.targetColor;}\nreturn;\n#elif defined(MESH_BLEND_DEBUG_SHADOW_ATTENUATION)\ngl_FragColor=vec4(\n1.0-primaryColorEvaluation.shadowAttenuation,\nprimaryColorEvaluation.shadowAttenuation,\nprimaryColorEvaluation.nearSeamCorrected ? 1.0 : 0.0,\n1.0\n);return;\n#elif defined(MESH_BLEND_DEBUG_COLOR_INTERPOLATION)\n#ifdef MESH_BLEND_COLOR_INTERPOLATION_SRGB\nvec3 interpolationModeColor=vec3(1.0,0.4,0.05);\n#else\nvec3 interpolationModeColor=vec3(0.1,0.75,1.0);\n#endif\nfloat interpolationStage=mix(0.35,1.0,clamp(primaryColorEvaluation.adjustedFade*2.0,0.0,1.0));gl_FragColor=vec4(interpolationModeColor*interpolationStage,1.0);return;\n#else\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (secondaryResult.valid) {MeshBlendColorEvaluation secondaryColorEvaluation=evaluateMeshBlendColor(pixel,renderSize,currentTag,secondaryResult);float totalBoundaryDistance=max(\nprimaryResult.candidate.distancePixels+secondaryResult.candidate.distancePixels,\nMESH_BLEND_EPSILON\n);float primaryRelativeProximity=secondaryResult.candidate.distancePixels/totalBoundaryDistance;float secondaryRelativeProximity=primaryResult.candidate.distancePixels/totalBoundaryDistance;float primaryWeight=primaryColorEvaluation.adjustedFade*primaryRelativeProximity;float secondaryWeight=secondaryColorEvaluation.adjustedFade*secondaryRelativeProximity;float combinedWeight=primaryWeight+secondaryWeight;if (combinedWeight<=MESH_BLEND_EPSILON) {gl_FragColor=texelFetch(textureSampler,pixel,0);return;}\ngl_FragColor=(primaryColorEvaluation.blendedColor*primaryWeight+secondaryColorEvaluation.blendedColor*secondaryWeight)/combinedWeight;return;}\n#endif\ngl_FragColor=primaryColorEvaluation.blendedColor;\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const meshBlendingPixelShader = { name, shader };\n"]}
|