@aura3d/engine 3.0.0 → 3.0.1
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/README.md +24 -5
- package/dist/animation/AnimationMixer.d.ts +4 -1
- package/dist/animation/AnimationMixer.d.ts.map +1 -1
- package/dist/animation/AnimationMixer.js +36 -29
- package/dist/animation/AnimationMixer.js.map +1 -1
- package/dist/animation/FootIk.d.ts +9 -0
- package/dist/animation/FootIk.d.ts.map +1 -1
- package/dist/animation/FootIk.js +22 -8
- package/dist/animation/FootIk.js.map +1 -1
- package/dist/animation/HumanoidRetargeting.d.ts +6 -2
- package/dist/animation/HumanoidRetargeting.d.ts.map +1 -1
- package/dist/animation/HumanoidRetargeting.js +18 -8
- package/dist/animation/HumanoidRetargeting.js.map +1 -1
- package/dist/animation/LocomotionEvidence.d.ts +34 -0
- package/dist/animation/LocomotionEvidence.d.ts.map +1 -0
- package/dist/animation/LocomotionEvidence.js +48 -0
- package/dist/animation/LocomotionEvidence.js.map +1 -0
- package/dist/animation/RootMotion.d.ts +13 -4
- package/dist/animation/RootMotion.d.ts.map +1 -1
- package/dist/animation/RootMotion.js +21 -1
- package/dist/animation/RootMotion.js.map +1 -1
- package/dist/animation/index.d.ts +1 -0
- package/dist/animation/index.d.ts.map +1 -1
- package/dist/animation/index.js +1 -0
- package/dist/animation/index.js.map +1 -1
- package/dist/assets/GLTFAnimationRuntime.d.ts +84 -4
- package/dist/assets/GLTFAnimationRuntime.d.ts.map +1 -1
- package/dist/assets/GLTFAnimationRuntime.js +308 -23
- package/dist/assets/GLTFAnimationRuntime.js.map +1 -1
- package/dist/assets/GLTFCompressionDecoders.d.ts +1 -0
- package/dist/assets/GLTFCompressionDecoders.d.ts.map +1 -1
- package/dist/assets/GLTFCompressionDecoders.js +20 -5
- package/dist/assets/GLTFCompressionDecoders.js.map +1 -1
- package/dist/assets/GLTFLoader.d.ts.map +1 -1
- package/dist/assets/GLTFLoader.js +21 -7
- package/dist/assets/GLTFLoader.js.map +1 -1
- package/dist/assets/KTX2BasisTextureTranscoder.d.ts.map +1 -1
- package/dist/assets/KTX2BasisTextureTranscoder.js +8 -0
- package/dist/assets/KTX2BasisTextureTranscoder.js.map +1 -1
- package/dist/controls/MapControls.d.ts +1 -1
- package/dist/controls/MapControls.d.ts.map +1 -1
- package/dist/controls/MapControls.js +3 -3
- package/dist/controls/MapControls.js.map +1 -1
- package/dist/controls/OrbitControls.d.ts +17 -3
- package/dist/controls/OrbitControls.d.ts.map +1 -1
- package/dist/controls/OrbitControls.js +24 -7
- package/dist/controls/OrbitControls.js.map +1 -1
- package/dist/controls/TrackballControls.d.ts.map +1 -1
- package/dist/controls/TrackballControls.js +2 -0
- package/dist/controls/TrackballControls.js.map +1 -1
- package/dist/create-aura3d/index.js +1 -1
- package/dist/engine/agent-api/AnimationController.d.ts +5 -1
- package/dist/engine/agent-api/AnimationController.d.ts.map +1 -1
- package/dist/engine/agent-api/AnimationController.js +5 -0
- package/dist/engine/agent-api/AnimationController.js.map +1 -1
- package/dist/engine/agent-api/CameraProjection.d.ts +2 -0
- package/dist/engine/agent-api/CameraProjection.d.ts.map +1 -0
- package/dist/engine/agent-api/CameraProjection.js +2 -0
- package/dist/engine/agent-api/CameraProjection.js.map +1 -0
- package/dist/engine/agent-api/DeferredFrameResources.d.ts +2 -0
- package/dist/engine/agent-api/DeferredFrameResources.d.ts.map +1 -0
- package/dist/engine/agent-api/DeferredFrameResources.js +2 -0
- package/dist/engine/agent-api/DeferredFrameResources.js.map +1 -0
- package/dist/engine/agent-api/FootPlanting.d.ts +6 -0
- package/dist/engine/agent-api/FootPlanting.d.ts.map +1 -1
- package/dist/engine/agent-api/FootPlanting.js +2 -1
- package/dist/engine/agent-api/FootPlanting.js.map +1 -1
- package/dist/engine/agent-api/GameCameraRigs.d.ts.map +1 -1
- package/dist/engine/agent-api/GameCameraRigs.js +7 -2
- package/dist/engine/agent-api/GameCameraRigs.js.map +1 -1
- package/dist/engine/agent-api/LabelTelemetry.d.ts +8 -2
- package/dist/engine/agent-api/LabelTelemetry.d.ts.map +1 -1
- package/dist/engine/agent-api/LabelTelemetry.js +18 -4
- package/dist/engine/agent-api/LabelTelemetry.js.map +1 -1
- package/dist/engine/agent-api/ModelInstanceMatrices.d.ts +2 -0
- package/dist/engine/agent-api/ModelInstanceMatrices.d.ts.map +1 -0
- package/dist/engine/agent-api/ModelInstanceMatrices.js +2 -0
- package/dist/engine/agent-api/ModelInstanceMatrices.js.map +1 -0
- package/dist/engine/agent-api/NavigationCrowds.d.ts +28 -0
- package/dist/engine/agent-api/NavigationCrowds.d.ts.map +1 -1
- package/dist/engine/agent-api/NavigationCrowds.js +73 -1
- package/dist/engine/agent-api/NavigationCrowds.js.map +1 -1
- package/dist/engine/agent-api/PngTexturePixels.d.ts +9 -0
- package/dist/engine/agent-api/PngTexturePixels.d.ts.map +1 -0
- package/dist/engine/agent-api/PngTexturePixels.js +53 -0
- package/dist/engine/agent-api/PngTexturePixels.js.map +1 -0
- package/dist/engine/agent-api/RootDiagnosticSnapshot.d.ts +2 -0
- package/dist/engine/agent-api/RootDiagnosticSnapshot.d.ts.map +1 -0
- package/dist/engine/agent-api/RootDiagnosticSnapshot.js +2 -0
- package/dist/engine/agent-api/RootDiagnosticSnapshot.js.map +1 -0
- package/dist/engine/agent-api/RootFrameClock.d.ts +2 -0
- package/dist/engine/agent-api/RootFrameClock.d.ts.map +1 -0
- package/dist/engine/agent-api/RootFrameClock.js +2 -0
- package/dist/engine/agent-api/RootFrameClock.js.map +1 -0
- package/dist/engine/agent-api/RootPerformanceQuality.d.ts +2 -0
- package/dist/engine/agent-api/RootPerformanceQuality.d.ts.map +1 -0
- package/dist/engine/agent-api/RootPerformanceQuality.js +2 -0
- package/dist/engine/agent-api/RootPerformanceQuality.js.map +1 -0
- package/dist/engine/agent-api/RootRuntimeSupport.d.ts +61 -0
- package/dist/engine/agent-api/RootRuntimeSupport.d.ts.map +1 -0
- package/dist/engine/agent-api/RootRuntimeSupport.js +127 -0
- package/dist/engine/agent-api/RootRuntimeSupport.js.map +1 -0
- package/dist/engine/agent-api/RuntimeNodeHandle.d.ts +22 -0
- package/dist/engine/agent-api/RuntimeNodeHandle.d.ts.map +1 -1
- package/dist/engine/agent-api/RuntimeNodeHandle.js.map +1 -1
- package/dist/engine/agent-api/WorldLabelRenderer.d.ts +13 -2
- package/dist/engine/agent-api/WorldLabelRenderer.d.ts.map +1 -1
- package/dist/engine/agent-api/WorldLabelRenderer.js +58 -26
- package/dist/engine/agent-api/WorldLabelRenderer.js.map +1 -1
- package/dist/engine/agent-api/index.d.ts +103 -8
- package/dist/engine/agent-api/index.d.ts.map +1 -1
- package/dist/engine/agent-api/index.js +750 -242
- package/dist/engine/agent-api/index.js.map +1 -1
- package/dist/engine/agent-api/product-viewer-runtime.d.ts.map +1 -1
- package/dist/engine/production-runtime/RootGpuParticleWorkload.d.ts +34 -0
- package/dist/engine/production-runtime/RootGpuParticleWorkload.d.ts.map +1 -0
- package/dist/engine/production-runtime/RootGpuParticleWorkload.js +117 -0
- package/dist/engine/production-runtime/RootGpuParticleWorkload.js.map +1 -0
- package/dist/engine/production-runtime/RootRenderSourceBridge.d.ts +2 -0
- package/dist/engine/production-runtime/RootRenderSourceBridge.d.ts.map +1 -0
- package/dist/engine/production-runtime/RootRenderSourceBridge.js +2 -0
- package/dist/engine/production-runtime/RootRenderSourceBridge.js.map +1 -0
- package/dist/engine/production-runtime/TypedGLBActor.d.ts +6 -0
- package/dist/engine/production-runtime/TypedGLBActor.d.ts.map +1 -1
- package/dist/engine/production-runtime/TypedGLBActor.js +13 -0
- package/dist/engine/production-runtime/TypedGLBActor.js.map +1 -1
- package/dist/engine/production-runtime/index.d.ts +2 -0
- package/dist/engine/production-runtime/index.d.ts.map +1 -1
- package/dist/engine/production-runtime/index.js +2 -0
- package/dist/engine/production-runtime/index.js.map +1 -1
- package/dist/input/Haptics.d.ts +1 -1
- package/dist/input/Haptics.js +1 -1
- package/dist/input/InputSystem.d.ts.map +1 -1
- package/dist/input/InputSystem.js +1 -0
- package/dist/input/InputSystem.js.map +1 -1
- package/dist/input/PointerDevice.d.ts +1 -0
- package/dist/input/PointerDevice.d.ts.map +1 -1
- package/dist/input/PointerDevice.js +1 -1
- package/dist/input/PointerDevice.js.map +1 -1
- package/dist/input/controls/OrbitControls.d.ts +44 -1
- package/dist/input/controls/OrbitControls.d.ts.map +1 -1
- package/dist/input/controls/OrbitControls.js +151 -12
- package/dist/input/controls/OrbitControls.js.map +1 -1
- package/dist/lean/base.d.ts +1 -1
- package/dist/lean/base.d.ts.map +1 -1
- package/dist/lean/base.js +1 -1
- package/dist/lean/base.js.map +1 -1
- package/dist/lean/index.js +1 -1
- package/dist/lean/index.js.map +1 -1
- package/dist/navigation-recast/index.d.ts +116 -0
- package/dist/navigation-recast/index.d.ts.map +1 -0
- package/dist/navigation-recast/index.js +247 -0
- package/dist/navigation-recast/index.js.map +1 -0
- package/dist/physics-rapier/HeightfieldLayout.d.ts +12 -0
- package/dist/physics-rapier/HeightfieldLayout.d.ts.map +1 -0
- package/dist/physics-rapier/HeightfieldLayout.js +19 -0
- package/dist/physics-rapier/HeightfieldLayout.js.map +1 -0
- package/dist/physics-rapier/index.d.ts.map +1 -1
- package/dist/physics-rapier/index.js +2 -1
- package/dist/physics-rapier/index.js.map +1 -1
- package/dist/rendering/CascadedShadowMaps.d.ts.map +1 -1
- package/dist/rendering/CascadedShadowMaps.js +3 -1
- package/dist/rendering/CascadedShadowMaps.js.map +1 -1
- package/dist/rendering/ExtensionScalarAtlas.d.ts +18 -0
- package/dist/rendering/ExtensionScalarAtlas.d.ts.map +1 -0
- package/dist/rendering/ExtensionScalarAtlas.js +107 -0
- package/dist/rendering/ExtensionScalarAtlas.js.map +1 -0
- package/dist/rendering/LeanWebGL2Device.d.ts +265 -0
- package/dist/rendering/LeanWebGL2Device.d.ts.map +1 -0
- package/dist/rendering/LeanWebGL2Device.js +4001 -0
- package/dist/rendering/LeanWebGL2Device.js.map +1 -0
- package/dist/rendering/MaterialBinding.js +1 -1
- package/dist/rendering/MaterialBinding.js.map +1 -1
- package/dist/rendering/PlanarReflection.d.ts +2 -2
- package/dist/rendering/PlanarReflection.js +3 -3
- package/dist/rendering/PlanarReflection.js.map +1 -1
- package/dist/rendering/PostProcessPass.d.ts +19 -0
- package/dist/rendering/PostProcessPass.d.ts.map +1 -1
- package/dist/rendering/PostProcessPass.js +64 -32
- package/dist/rendering/PostProcessPass.js.map +1 -1
- package/dist/rendering/ProjectionMath.d.ts +3 -0
- package/dist/rendering/ProjectionMath.d.ts.map +1 -0
- package/dist/rendering/ProjectionMath.js +26 -0
- package/dist/rendering/ProjectionMath.js.map +1 -0
- package/dist/rendering/ReflectionSurfaces.d.ts +4 -1
- package/dist/rendering/ReflectionSurfaces.d.ts.map +1 -1
- package/dist/rendering/ReflectionSurfaces.js +10 -1
- package/dist/rendering/ReflectionSurfaces.js.map +1 -1
- package/dist/rendering/RenderDevice.d.ts +5 -0
- package/dist/rendering/RenderDevice.d.ts.map +1 -1
- package/dist/rendering/RenderDevice.js.map +1 -1
- package/dist/rendering/Renderer.d.ts +9 -0
- package/dist/rendering/Renderer.d.ts.map +1 -1
- package/dist/rendering/Renderer.js +94 -8
- package/dist/rendering/Renderer.js.map +1 -1
- package/dist/rendering/RendererPostprocessPlan.d.ts +16 -3
- package/dist/rendering/RendererPostprocessPlan.d.ts.map +1 -1
- package/dist/rendering/RendererPostprocessPlan.js +16 -2
- package/dist/rendering/RendererPostprocessPlan.js.map +1 -1
- package/dist/rendering/ScreenSpaceReflectionPass.d.ts +43 -0
- package/dist/rendering/ScreenSpaceReflectionPass.d.ts.map +1 -0
- package/dist/rendering/ScreenSpaceReflectionPass.js +58 -0
- package/dist/rendering/ScreenSpaceReflectionPass.js.map +1 -0
- package/dist/rendering/ShaderLibrary.d.ts.map +1 -1
- package/dist/rendering/ShaderLibrary.js +168 -197
- package/dist/rendering/ShaderLibrary.js.map +1 -1
- package/dist/rendering/ShaderLibraryCore.d.ts +3 -0
- package/dist/rendering/ShaderLibraryCore.d.ts.map +1 -1
- package/dist/rendering/ShaderLibraryCore.js +3 -0
- package/dist/rendering/ShaderLibraryCore.js.map +1 -1
- package/dist/rendering/TemporalHistory.d.ts +37 -0
- package/dist/rendering/TemporalHistory.d.ts.map +1 -0
- package/dist/rendering/TemporalHistory.js +135 -0
- package/dist/rendering/TemporalHistory.js.map +1 -0
- package/dist/rendering/TemporalMath.d.ts +3 -0
- package/dist/rendering/TemporalMath.d.ts.map +1 -0
- package/dist/rendering/TemporalMath.js +9 -0
- package/dist/rendering/TemporalMath.js.map +1 -0
- package/dist/rendering/TexturedPBRMaterial.d.ts +3 -0
- package/dist/rendering/TexturedPBRMaterial.d.ts.map +1 -1
- package/dist/rendering/TexturedPBRMaterial.js +65 -3
- package/dist/rendering/TexturedPBRMaterial.js.map +1 -1
- package/dist/rendering/WebGL2Device.d.ts +15 -0
- package/dist/rendering/WebGL2Device.d.ts.map +1 -1
- package/dist/rendering/WebGL2Device.js +328 -90
- package/dist/rendering/WebGL2Device.js.map +1 -1
- package/dist/rendering/WebGPUDevice.d.ts +16 -5
- package/dist/rendering/WebGPUDevice.d.ts.map +1 -1
- package/dist/rendering/WebGPUDevice.js +357 -58
- package/dist/rendering/WebGPUDevice.js.map +1 -1
- package/dist/rendering/WebGPUExtensionAtlas.d.ts +6 -0
- package/dist/rendering/WebGPUExtensionAtlas.d.ts.map +1 -0
- package/dist/rendering/WebGPUExtensionAtlas.js +225 -0
- package/dist/rendering/WebGPUExtensionAtlas.js.map +1 -0
- package/dist/rendering/effects/GPUParticleBackend.d.ts +4 -2
- package/dist/rendering/effects/GPUParticleBackend.d.ts.map +1 -1
- package/dist/rendering/effects/GPUParticleBackend.js +20 -2
- package/dist/rendering/effects/GPUParticleBackend.js.map +1 -1
- package/dist/rendering/effects/ResidentGPUParticleRenderer.d.ts +158 -0
- package/dist/rendering/effects/ResidentGPUParticleRenderer.d.ts.map +1 -0
- package/dist/rendering/effects/ResidentGPUParticleRenderer.js +576 -0
- package/dist/rendering/effects/ResidentGPUParticleRenderer.js.map +1 -0
- package/dist/rendering/extension-scalar-atlas.d.ts +3 -0
- package/dist/rendering/extension-scalar-atlas.d.ts.map +1 -0
- package/dist/rendering/extension-scalar-atlas.js +2 -0
- package/dist/rendering/extension-scalar-atlas.js.map +1 -0
- package/dist/rendering/index.d.ts +1 -0
- package/dist/rendering/index.d.ts.map +1 -1
- package/dist/rendering/index.js +1 -0
- package/dist/rendering/index.js.map +1 -1
- package/dist/rendering/lean/LeanProductionRenderer.d.ts.map +1 -1
- package/dist/rendering/lean/LeanProductionRenderer.js +2 -2
- package/dist/rendering/lean/LeanProductionRenderer.js.map +1 -1
- package/dist/rendering/lean-core-runtime.d.ts +13 -0
- package/dist/rendering/lean-core-runtime.d.ts.map +1 -0
- package/dist/rendering/lean-core-runtime.js +10 -0
- package/dist/rendering/lean-core-runtime.js.map +1 -0
- package/dist/rendering/postprocess/NativeBloomPyramid.d.ts +17 -1
- package/dist/rendering/postprocess/NativeBloomPyramid.d.ts.map +1 -1
- package/dist/rendering/postprocess/NativeBloomPyramid.js +31 -1
- package/dist/rendering/postprocess/NativeBloomPyramid.js.map +1 -1
- package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts +1 -0
- package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts.map +1 -1
- package/dist/rendering/production-runtime/ProductionRendererTypes.js.map +1 -1
- package/dist/rendering/production-runtime/ProductionRuntimeRenderer.d.ts +3 -0
- package/dist/rendering/production-runtime/ProductionRuntimeRenderer.d.ts.map +1 -1
- package/dist/rendering/production-runtime/ProductionRuntimeRenderer.js +8 -1
- package/dist/rendering/production-runtime/ProductionRuntimeRenderer.js.map +1 -1
- package/dist/rendering/production-runtime/ProductionWebGL2Renderer.d.ts +4 -0
- package/dist/rendering/production-runtime/ProductionWebGL2Renderer.d.ts.map +1 -1
- package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js +15 -0
- package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js.map +1 -1
- package/dist/rendering/production-runtime/ProductionWebGPURenderer.d.ts +7 -1
- package/dist/rendering/production-runtime/ProductionWebGPURenderer.d.ts.map +1 -1
- package/dist/rendering/production-runtime/ProductionWebGPURenderer.js +28 -2
- package/dist/rendering/production-runtime/ProductionWebGPURenderer.js.map +1 -1
- package/dist/rendering/production-runtime/framegraph/FrameGraph.d.ts +4 -2
- package/dist/rendering/production-runtime/framegraph/FrameGraph.d.ts.map +1 -1
- package/dist/rendering/production-runtime/framegraph/FrameGraph.js +62 -4
- package/dist/rendering/production-runtime/framegraph/FrameGraph.js.map +1 -1
- package/dist/rendering/production-runtime/framegraph/NativeFrameGraphBindings.d.ts +32 -0
- package/dist/rendering/production-runtime/framegraph/NativeFrameGraphBindings.d.ts.map +1 -0
- package/dist/rendering/production-runtime/framegraph/NativeFrameGraphBindings.js +111 -0
- package/dist/rendering/production-runtime/framegraph/NativeFrameGraphBindings.js.map +1 -0
- package/dist/rendering/production-runtime/framegraph/RenderPass.d.ts +23 -0
- package/dist/rendering/production-runtime/framegraph/RenderPass.d.ts.map +1 -1
- package/dist/rendering/production-runtime/framegraph/RenderPass.js +87 -1
- package/dist/rendering/production-runtime/framegraph/RenderPass.js.map +1 -1
- package/dist/rendering/production-runtime/index.d.ts +2 -0
- package/dist/rendering/production-runtime/index.d.ts.map +1 -1
- package/dist/rendering/production-runtime/index.js +1 -0
- package/dist/rendering/production-runtime/index.js.map +1 -1
- package/dist/rendering/production-runtime/passes/DepthPrepass.d.ts +4 -12
- package/dist/rendering/production-runtime/passes/DepthPrepass.d.ts.map +1 -1
- package/dist/rendering/production-runtime/passes/DepthPrepass.js +3 -11
- package/dist/rendering/production-runtime/passes/DepthPrepass.js.map +1 -1
- package/dist/rendering/production-runtime/passes/FramegraphTopology.js +1 -1
- package/dist/rendering/production-runtime/passes/FramegraphTopology.js.map +1 -1
- package/dist/rendering/production-runtime/passes/OpaquePass.d.ts +3 -8
- package/dist/rendering/production-runtime/passes/OpaquePass.d.ts.map +1 -1
- package/dist/rendering/production-runtime/passes/OpaquePass.js +3 -1
- package/dist/rendering/production-runtime/passes/OpaquePass.js.map +1 -1
- package/dist/rendering/production-runtime/passes/ShadowPass.d.ts +3 -8
- package/dist/rendering/production-runtime/passes/ShadowPass.d.ts.map +1 -1
- package/dist/rendering/production-runtime/passes/ShadowPass.js +2 -0
- package/dist/rendering/production-runtime/passes/ShadowPass.js.map +1 -1
- package/dist/rendering/production-runtime/passes/SkyboxPass.d.ts +3 -7
- package/dist/rendering/production-runtime/passes/SkyboxPass.d.ts.map +1 -1
- package/dist/rendering/production-runtime/passes/SkyboxPass.js +2 -0
- package/dist/rendering/production-runtime/passes/SkyboxPass.js.map +1 -1
- package/dist/rendering/production-runtime/passes/ToneMappingPass.d.ts +7 -10
- package/dist/rendering/production-runtime/passes/ToneMappingPass.d.ts.map +1 -1
- package/dist/rendering/production-runtime/passes/ToneMappingPass.js +9 -0
- package/dist/rendering/production-runtime/passes/ToneMappingPass.js.map +1 -1
- package/dist/rendering/production-runtime/passes/TransparentPass.d.ts +4 -9
- package/dist/rendering/production-runtime/passes/TransparentPass.d.ts.map +1 -1
- package/dist/rendering/production-runtime/passes/TransparentPass.js +6 -1
- package/dist/rendering/production-runtime/passes/TransparentPass.js.map +1 -1
- package/dist/rendering/reflection-surfaces.d.ts +5 -0
- package/dist/rendering/reflection-surfaces.d.ts.map +1 -0
- package/dist/rendering/reflection-surfaces.js +3 -0
- package/dist/rendering/reflection-surfaces.js.map +1 -0
- package/dist/rendering/webgpu/WebGPUPostShaders.d.ts +2 -3
- package/dist/rendering/webgpu/WebGPUPostShaders.d.ts.map +1 -1
- package/dist/rendering/webgpu/WebGPUPostShaders.js +2 -3
- package/dist/rendering/webgpu/WebGPUPostShaders.js.map +1 -1
- package/dist/rendering/webgpu/WebGPUTemporal.d.ts +17 -0
- package/dist/rendering/webgpu/WebGPUTemporal.d.ts.map +1 -0
- package/dist/rendering/webgpu/WebGPUTemporal.js +64 -0
- package/dist/rendering/webgpu/WebGPUTemporal.js.map +1 -0
- package/dist/rendering/webgpu.d.ts +6 -0
- package/dist/rendering/webgpu.d.ts.map +1 -1
- package/dist/rendering/webgpu.js +4 -0
- package/dist/rendering/webgpu.js.map +1 -1
- package/package.json +37 -24
- package/templates/cinematic-scene/package.json +2 -2
- package/templates/cinematic-scene/src/main.ts +14 -2
- package/templates/mini-game/package.json +2 -2
- package/templates/product-viewer/package.json +2 -2
- package/templates/production-asset-inspector/package.json +1 -1
- package/templates/production-material-studio/package.json +1 -1
- package/templates/production-product-configurator/package.json +1 -1
- package/templates/production-product-viewer/package.json +1 -1
- package/templates/cinematic-scene/node_modules/.vite/deps/_metadata.json +0 -8
- package/templates/cinematic-scene/node_modules/.vite/deps/package.json +0 -3
- package/templates/cinematic-scene/test-results/.last-run.json +0 -6
- package/templates/cinematic-scene/test-results/route-health-Aura3D-cinematic-scene-reaches-ready-state/error-context.md +0 -64
- package/templates/product-viewer/node_modules/.vite/deps/_metadata.json +0 -8
- package/templates/product-viewer/node_modules/.vite/deps/package.json +0 -3
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { temporalAccumulationWeight } from "./TemporalMath.js";
|
|
2
|
+
import { invertSsrProjection } from "./ProjectionMath.js";
|
|
1
3
|
import { RenderDeviceError, resolveGpuTargetOwner, spreadGpuTargetInventory, } from "./RenderDevice.js";
|
|
2
4
|
import { Texture, isCompressedTextureFormat, isFloatColorTextureFormat } from "./Texture.js";
|
|
3
5
|
import { isTextureBinding, TextureBinding } from "./TextureBinding.js";
|
|
4
6
|
import {} from "./VertexFormat.js";
|
|
5
7
|
import { WebGL2StateCache } from "./WebGL2StateCache.js";
|
|
6
8
|
import { BLOOM_BRIGHT_LUT_HEIGHT, BLOOM_BRIGHT_LUT_WIDTH, BLOOM_COMPOSITE_LUT_SIZE, OUTLINE_BLEND_LUT_WIDTH, OUTLINE_LIMB_RADIX, createOutlineBlendLut, createOutlineGradientBound, createBloomBrightThresholdLut, createBloomCompositeLut } from "./postprocess/NativeLdrEffectLuts.js";
|
|
7
|
-
import { normalizeBloomQualityPreset, resolveBloomPyramidPlan, } from "./postprocess/NativeBloomPyramid.js";
|
|
9
|
+
import { normalizeBloomQualityPreset, resolveBloomPyramidBlurRadii, resolveBloomPyramidPlan, resolveBloomPyramidResponseGain, } from "./postprocess/NativeBloomPyramid.js";
|
|
8
10
|
const WEBGL_CUBE_FACES = ["px", "nx", "py", "ny", "pz", "nz"];
|
|
9
11
|
class WebGL2Buffer {
|
|
10
12
|
id;
|
|
@@ -112,6 +114,8 @@ export class WebGL2Device {
|
|
|
112
114
|
gl;
|
|
113
115
|
nextId = 1;
|
|
114
116
|
drawCalls = 0;
|
|
117
|
+
nativeTemporalPasses = 0;
|
|
118
|
+
nativeTemporalBindings = 0;
|
|
115
119
|
buffers = new Set();
|
|
116
120
|
shaders = new Set();
|
|
117
121
|
renderTargets = new Set();
|
|
@@ -137,6 +141,7 @@ export class WebGL2Device {
|
|
|
137
141
|
motionBlurVelocityTexture = null;
|
|
138
142
|
motionBlurVelocitySize = null;
|
|
139
143
|
taaProgram = null;
|
|
144
|
+
taaPresentationProgram = null;
|
|
140
145
|
taaHistoryTexture = null;
|
|
141
146
|
taaHistorySize = null;
|
|
142
147
|
bloomPingPongResources = null;
|
|
@@ -516,7 +521,9 @@ export class WebGL2Device {
|
|
|
516
521
|
this.renderTargets.add(target);
|
|
517
522
|
// Shadow passes label their depth target after the shadow map texture, so the
|
|
518
523
|
// label is the device-side signal that a shadow depth target was allocated.
|
|
519
|
-
|
|
524
|
+
// Cascaded maps use the established renderer-csm-cascade-* labels.
|
|
525
|
+
// Count their actual allocation too, including the first shadow frame.
|
|
526
|
+
if (/shadow|(?:^|-)csm(?:-|$)/i.test(descriptor.label ?? ""))
|
|
520
527
|
this.shadowRenderTargetsAllocated += 1;
|
|
521
528
|
this.textures.set(target.colorTexture, colorHandle);
|
|
522
529
|
this.textureUploadModes.set(target.colorTexture, "rgba8");
|
|
@@ -618,6 +625,29 @@ export class WebGL2Device {
|
|
|
618
625
|
});
|
|
619
626
|
}
|
|
620
627
|
}
|
|
628
|
+
/** Executes the same native SSR kernel used by postprocessing into an owned target. */
|
|
629
|
+
executeReflectionSurfaceSsr(source, normalMask, output, options) {
|
|
630
|
+
this.assertAlive();
|
|
631
|
+
for (const target of [source, normalMask, output]) {
|
|
632
|
+
if (!(target instanceof WebGL2RenderTarget) || !this.renderTargets.has(target) || target.disposed) {
|
|
633
|
+
throw new RenderDeviceError("SSR inputs must be live targets owned by this device", "INVALID_RESOURCE");
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
const color = source, normals = normalMask, destination = output;
|
|
637
|
+
if (!color.depthTextureHandle || color === destination || normals === destination
|
|
638
|
+
|| color.width !== normals.width || color.height !== normals.height) {
|
|
639
|
+
throw new RenderDeviceError("SSR requires sampleable scene depth, matching normal-mask input, and a separate output", "INVALID_RESOURCE");
|
|
640
|
+
}
|
|
641
|
+
this.resolveMultisampleTarget(color);
|
|
642
|
+
this.resolveMultisampleTarget(normals);
|
|
643
|
+
const state = this.prepareFullscreenPresentation(destination.framebuffer, destination.width, destination.height);
|
|
644
|
+
try {
|
|
645
|
+
this.drawSsrKernel(color.colorHandle, color.depthTextureHandle, destination.width, destination.height, { ...options, normalMask: normals.colorHandle }, this.ensurePresentationVertexArray(), { near: 0.1, far: 1000 });
|
|
646
|
+
}
|
|
647
|
+
finally {
|
|
648
|
+
this.restoreFullscreenPresentationState(state, destination.width, destination.height);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
621
651
|
presentLdrPostprocess(source, options) {
|
|
622
652
|
this.assertAlive();
|
|
623
653
|
if (!(source instanceof WebGL2RenderTarget) || !this.renderTargets.has(source) || source.disposed) {
|
|
@@ -701,10 +731,10 @@ export class WebGL2Device {
|
|
|
701
731
|
if (outlineOptions) {
|
|
702
732
|
this.ensureOutlineBlendLutTexture(outlineOptions);
|
|
703
733
|
}
|
|
704
|
-
if (motionBlurOptions) {
|
|
734
|
+
if (motionBlurOptions?.velocity) {
|
|
705
735
|
this.ensureMotionBlurVelocityTexture(source.width, source.height, motionBlurOptions.velocity);
|
|
706
736
|
}
|
|
707
|
-
if (taaOptions) {
|
|
737
|
+
if (taaOptions?.history) {
|
|
708
738
|
this.ensureTaaHistoryTexture(source.width, source.height, taaOptions.history);
|
|
709
739
|
}
|
|
710
740
|
const outputWidth = webglOutputTarget?.width ?? (this.viewportWidth || this.gl.drawingBufferWidth);
|
|
@@ -743,7 +773,7 @@ export class WebGL2Device {
|
|
|
743
773
|
this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_blurred"), 1);
|
|
744
774
|
this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_compositeLut"), 2);
|
|
745
775
|
this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_hdr"), sourceIsHdr ? 1 : 0);
|
|
746
|
-
this.gl.uniform1f(this.gl.getUniformLocation(pyramidComposite, "u_intensity"), bloomOptions.intensity);
|
|
776
|
+
this.gl.uniform1f(this.gl.getUniformLocation(pyramidComposite, "u_intensity"), bloomOptions.intensity * resolveBloomPyramidResponseGain(plan));
|
|
747
777
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
748
778
|
ldrSourceHandle = bloomResources.textures[1];
|
|
749
779
|
// The composited result lives in texture B, so subsequent passes
|
|
@@ -1041,6 +1071,8 @@ export class WebGL2Device {
|
|
|
1041
1071
|
["actualViewportHeight", viewport[3] ?? 0],
|
|
1042
1072
|
["renderTarget", this.activeRenderTarget?.label ?? null],
|
|
1043
1073
|
["drawCalls", this.drawCalls],
|
|
1074
|
+
["nativeTemporalPasses", this.nativeTemporalPasses],
|
|
1075
|
+
["nativeTemporalBindings", this.nativeTemporalBindings],
|
|
1044
1076
|
["shaderProgramCreates", this.shaderProgramCreateCount],
|
|
1045
1077
|
["uniformLocationLookups", this.uniformLocationLookupCount],
|
|
1046
1078
|
["bufferUpdates", this.bufferUpdateCount],
|
|
@@ -1090,6 +1122,8 @@ export class WebGL2Device {
|
|
|
1090
1122
|
shadowRenderTargetsAllocated: this.shadowRenderTargetsAllocated,
|
|
1091
1123
|
nativeInstancedSubmissions: this.nativeInstancedSubmissions,
|
|
1092
1124
|
bloom: this.lastBloomDiagnostics,
|
|
1125
|
+
nativeTemporalPasses: this.nativeTemporalPasses,
|
|
1126
|
+
nativeTemporalBindings: this.nativeTemporalBindings,
|
|
1093
1127
|
samplerAnisotropyUploads: this.samplerAnisotropyUploadCount,
|
|
1094
1128
|
maxTextureAnisotropy: this.maxTextureAnisotropy,
|
|
1095
1129
|
stateCacheIssued: stateCacheStats.issued,
|
|
@@ -1203,6 +1237,10 @@ export class WebGL2Device {
|
|
|
1203
1237
|
this.gl.deleteProgram(this.taaProgram);
|
|
1204
1238
|
this.taaProgram = null;
|
|
1205
1239
|
}
|
|
1240
|
+
if (this.taaPresentationProgram) {
|
|
1241
|
+
this.gl.deleteProgram(this.taaPresentationProgram);
|
|
1242
|
+
this.taaPresentationProgram = null;
|
|
1243
|
+
}
|
|
1206
1244
|
if (this.taaHistoryTexture) {
|
|
1207
1245
|
this.gl.deleteTexture(this.taaHistoryTexture);
|
|
1208
1246
|
this.taaHistoryTexture = null;
|
|
@@ -1594,6 +1632,7 @@ export class WebGL2Device {
|
|
|
1594
1632
|
executeNativeBloomPyramidPasses(sourceTexture, sourceWidth, sourceHeight, resources, fullResStaging, options, vertexArray, hdr) {
|
|
1595
1633
|
const plan = resources.plan;
|
|
1596
1634
|
const mipCount = plan.mips.length;
|
|
1635
|
+
const blurRadii = resolveBloomPyramidBlurRadii(plan, options.radius);
|
|
1597
1636
|
const downsampleProgram = this.ensureBloomDownsampleProgram();
|
|
1598
1637
|
const brightProgram = this.ensureBloomBrightExtractProgram();
|
|
1599
1638
|
const blurProgram = this.ensureBloomBlurProgram();
|
|
@@ -1602,8 +1641,8 @@ export class WebGL2Device {
|
|
|
1602
1641
|
const mipTexture = (level, slot) => resources.textures[level * 2 + slot];
|
|
1603
1642
|
const mipFramebuffer = (level, slot) => resources.framebuffers[level * 2 + slot];
|
|
1604
1643
|
const mipSize = (level) => plan.mips[level];
|
|
1605
|
-
//
|
|
1606
|
-
const blurredSlot = (
|
|
1644
|
+
// Every level settles in slot 0 after the vertical blur.
|
|
1645
|
+
const blurredSlot = (_level) => 0;
|
|
1607
1646
|
const drawDownsample = (fromTexture, fromWidth, fromHeight, toFramebuffer, toWidth, toHeight) => {
|
|
1608
1647
|
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, toFramebuffer);
|
|
1609
1648
|
this.gl.viewport(0, 0, toWidth, toHeight);
|
|
@@ -1612,6 +1651,7 @@ export class WebGL2Device {
|
|
|
1612
1651
|
this.bindFullscreenTexture(0, fromTexture);
|
|
1613
1652
|
this.gl.uniform1i(this.gl.getUniformLocation(downsampleProgram, "u_source"), 0);
|
|
1614
1653
|
this.gl.uniform2f(this.gl.getUniformLocation(downsampleProgram, "u_texelSize"), 1 / fromWidth, 1 / fromHeight);
|
|
1654
|
+
this.gl.uniform2f(this.gl.getUniformLocation(downsampleProgram, "u_targetSize"), toWidth, toHeight);
|
|
1615
1655
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1616
1656
|
};
|
|
1617
1657
|
const drawBrightExtract = (fromTexture, toFramebuffer, size) => {
|
|
@@ -1629,7 +1669,7 @@ export class WebGL2Device {
|
|
|
1629
1669
|
this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_softKnee"), options.softKnee);
|
|
1630
1670
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1631
1671
|
};
|
|
1632
|
-
const drawSeparableBlur = (readTexture, tmpTexture, tmpFramebuffer, outFramebuffer, size) => {
|
|
1672
|
+
const drawSeparableBlur = (readTexture, tmpTexture, tmpFramebuffer, outFramebuffer, size, radius) => {
|
|
1633
1673
|
// Horizontal into the temp target, vertical back into the output target.
|
|
1634
1674
|
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, tmpFramebuffer);
|
|
1635
1675
|
this.gl.viewport(0, 0, size.width, size.height);
|
|
@@ -1638,7 +1678,7 @@ export class WebGL2Device {
|
|
|
1638
1678
|
this.bindFullscreenTexture(0, readTexture);
|
|
1639
1679
|
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_source"), 0);
|
|
1640
1680
|
this.gl.uniform2i(this.gl.getUniformLocation(blurProgram, "u_size"), size.width, size.height);
|
|
1641
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_radius"),
|
|
1681
|
+
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_radius"), radius);
|
|
1642
1682
|
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_horizontal"), 1);
|
|
1643
1683
|
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1644
1684
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
@@ -1647,18 +1687,34 @@ export class WebGL2Device {
|
|
|
1647
1687
|
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_horizontal"), 0);
|
|
1648
1688
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1649
1689
|
};
|
|
1650
|
-
//
|
|
1651
|
-
//
|
|
1690
|
+
// Extract highlights at the source resolution before the first downsample.
|
|
1691
|
+
// Downsampling the complete scene first averaged narrow emissive sources
|
|
1692
|
+
// below the authored threshold, so balanced/cinematic bloom could execute
|
|
1693
|
+
// all native passes yet remain pixel-identical to disabled output.
|
|
1694
|
+
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, fullResStaging.framebufferA);
|
|
1695
|
+
this.gl.viewport(0, 0, sourceWidth, sourceHeight);
|
|
1696
|
+
this.gl.useProgram(brightProgram);
|
|
1697
|
+
this.gl.bindVertexArray(vertexArray);
|
|
1698
|
+
this.bindFullscreenTexture(0, sourceTexture);
|
|
1699
|
+
if (brightLut)
|
|
1700
|
+
this.bindFullscreenTexture(1, brightLut);
|
|
1701
|
+
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_source"), 0);
|
|
1702
|
+
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_brightLut"), 1);
|
|
1703
|
+
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1704
|
+
this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_threshold"), options.threshold);
|
|
1705
|
+
this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_softKnee"), options.softKnee);
|
|
1706
|
+
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1707
|
+
// Level 0 downsamples the extracted highlight field, then blurs H into
|
|
1708
|
+
// slot 1 and V back into slot 0. The result therefore settles in slot 0.
|
|
1652
1709
|
const level0 = mipSize(0);
|
|
1653
|
-
drawDownsample(
|
|
1654
|
-
|
|
1655
|
-
drawSeparableBlur(mipTexture(0, 1), mipTexture(0, 0), mipFramebuffer(0, 0), mipFramebuffer(0, 1), level0);
|
|
1710
|
+
drawDownsample(fullResStaging.textureA, sourceWidth, sourceHeight, mipFramebuffer(0, 0), level0.width, level0.height);
|
|
1711
|
+
drawSeparableBlur(mipTexture(0, 0), mipTexture(0, 1), mipFramebuffer(0, 1), mipFramebuffer(0, 0), level0, blurRadii[0]);
|
|
1656
1712
|
for (let level = 1; level < mipCount; level += 1) {
|
|
1657
1713
|
const size = mipSize(level);
|
|
1658
1714
|
const previous = mipSize(level - 1);
|
|
1659
1715
|
drawDownsample(mipTexture(level - 1, blurredSlot(level - 1)), previous.width, previous.height, mipFramebuffer(level, 0), size.width, size.height);
|
|
1660
1716
|
// H into slot 1, V back into slot 0: blurred result settles in slot 0.
|
|
1661
|
-
drawSeparableBlur(mipTexture(level, 0), mipTexture(level, 1), mipFramebuffer(level, 1), mipFramebuffer(level, 0), size);
|
|
1717
|
+
drawSeparableBlur(mipTexture(level, 0), mipTexture(level, 1), mipFramebuffer(level, 1), mipFramebuffer(level, 0), size, blurRadii[level]);
|
|
1662
1718
|
}
|
|
1663
1719
|
// Accumulate smallest-to-largest, ping-ponging between the two
|
|
1664
1720
|
// accumulators (a pass must never sample its own bound target).
|
|
@@ -1762,23 +1818,35 @@ export class WebGL2Device {
|
|
|
1762
1818
|
return targetTexture;
|
|
1763
1819
|
}
|
|
1764
1820
|
executeNativeSsrPass(sourceTexture, depthTexture, resources, options, vertexArray, targetIndex, depthRange) {
|
|
1765
|
-
const program = this.ensureSsrProgram();
|
|
1766
1821
|
const targetTexture = resources.textures[targetIndex];
|
|
1767
1822
|
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
|
|
1768
|
-
this.
|
|
1823
|
+
this.drawSsrKernel(sourceTexture, depthTexture, resources.width, resources.height, options, vertexArray, depthRange);
|
|
1824
|
+
return targetTexture;
|
|
1825
|
+
}
|
|
1826
|
+
drawSsrKernel(sourceTexture, depthTexture, width, height, options, vertexArray, depthRange) {
|
|
1827
|
+
const program = this.ensureSsrProgram();
|
|
1828
|
+
this.gl.viewport(0, 0, width, height);
|
|
1769
1829
|
this.gl.useProgram(program);
|
|
1770
1830
|
this.gl.bindVertexArray(vertexArray);
|
|
1771
1831
|
this.bindFullscreenTexture(0, sourceTexture);
|
|
1772
1832
|
this.bindFullscreenTexture(1, depthTexture);
|
|
1833
|
+
this.bindFullscreenTexture(2, options.normalMask ?? sourceTexture);
|
|
1773
1834
|
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
|
|
1774
1835
|
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_depth"), 1);
|
|
1775
|
-
this.gl.
|
|
1836
|
+
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_normalMask"), 2);
|
|
1837
|
+
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_hasNormalMask"), options.normalMask ? 1 : 0);
|
|
1838
|
+
this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), width, height);
|
|
1776
1839
|
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_intensity"), options.intensity);
|
|
1777
|
-
this.gl.
|
|
1840
|
+
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_maxDistance"), options.maxDistance);
|
|
1841
|
+
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_maxSteps"), options.maxSteps ?? 32);
|
|
1842
|
+
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_thickness"), options.thickness ?? 0.2);
|
|
1843
|
+
if (options.projection && options.inverseProjection) {
|
|
1844
|
+
this.gl.uniformMatrix4fv(this.gl.getUniformLocation(program, "u_projection"), false, options.projection);
|
|
1845
|
+
this.gl.uniformMatrix4fv(this.gl.getUniformLocation(program, "u_inverseProjection"), false, options.inverseProjection);
|
|
1846
|
+
}
|
|
1778
1847
|
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_depthNear"), depthRange.near);
|
|
1779
1848
|
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_depthFar"), depthRange.far);
|
|
1780
1849
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1781
|
-
return targetTexture;
|
|
1782
1850
|
}
|
|
1783
1851
|
executeNativeDepthOfFieldPass(sourceTexture, depthTexture, resources, options, vertexArray, targetIndex, depthRange) {
|
|
1784
1852
|
const program = this.ensureDepthOfFieldProgram();
|
|
@@ -1801,7 +1869,7 @@ export class WebGL2Device {
|
|
|
1801
1869
|
return targetTexture;
|
|
1802
1870
|
}
|
|
1803
1871
|
executeNativeMotionBlurPass(sourceTexture, resources, options, vertexArray, targetIndex) {
|
|
1804
|
-
const velocityTexture = this.motionBlurVelocityTexture;
|
|
1872
|
+
const velocityTexture = options.temporal ? this.requireTemporalTarget(options.temporal.velocity, resources.width, resources.height).colorHandle : this.motionBlurVelocityTexture;
|
|
1805
1873
|
if (!velocityTexture) {
|
|
1806
1874
|
throw new RenderDeviceError("WebGL2 motion-blur velocity texture was not initialized", "WEBGL_ALLOCATION_FAILED");
|
|
1807
1875
|
}
|
|
@@ -1818,28 +1886,66 @@ export class WebGL2Device {
|
|
|
1818
1886
|
this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), resources.width, resources.height);
|
|
1819
1887
|
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_samples"), options.samples);
|
|
1820
1888
|
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_scale"), options.scale);
|
|
1889
|
+
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_velocityUv"), options.temporal ? 1 : 0);
|
|
1890
|
+
if (options.temporal) {
|
|
1891
|
+
this.nativeTemporalPasses++;
|
|
1892
|
+
this.nativeTemporalBindings++;
|
|
1893
|
+
}
|
|
1821
1894
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1822
1895
|
return targetTexture;
|
|
1823
1896
|
}
|
|
1824
1897
|
executeNativeTaaPass(sourceTexture, resources, options, vertexArray, targetIndex) {
|
|
1825
|
-
const
|
|
1898
|
+
const temporal = options.temporal;
|
|
1899
|
+
const historyTarget = temporal ? this.requireTemporalTarget(temporal.history, resources.width, resources.height) : undefined;
|
|
1900
|
+
const historyTexture = historyTarget?.colorHandle ?? this.taaHistoryTexture;
|
|
1826
1901
|
if (!historyTexture) {
|
|
1827
1902
|
throw new RenderDeviceError("WebGL2 TAA history texture was not initialized", "WEBGL_ALLOCATION_FAILED");
|
|
1828
1903
|
}
|
|
1829
|
-
const
|
|
1904
|
+
const accumulationProgram = this.ensureTaaProgram();
|
|
1830
1905
|
const targetTexture = resources.textures[targetIndex];
|
|
1831
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
|
|
1832
1906
|
this.gl.viewport(0, 0, resources.width, resources.height);
|
|
1833
|
-
this.gl.useProgram(
|
|
1907
|
+
this.gl.useProgram(accumulationProgram);
|
|
1834
1908
|
this.gl.bindVertexArray(vertexArray);
|
|
1835
1909
|
this.bindFullscreenTexture(0, sourceTexture);
|
|
1836
1910
|
this.bindFullscreenTexture(1, historyTexture);
|
|
1837
|
-
this.gl.uniform1i(this.gl.getUniformLocation(
|
|
1838
|
-
this.gl.uniform1i(this.gl.getUniformLocation(
|
|
1839
|
-
this.gl.uniform1f(this.gl.getUniformLocation(
|
|
1840
|
-
this.gl.
|
|
1911
|
+
this.gl.uniform1i(this.gl.getUniformLocation(accumulationProgram, "u_source"), 0);
|
|
1912
|
+
this.gl.uniform1i(this.gl.getUniformLocation(accumulationProgram, "u_history"), 1);
|
|
1913
|
+
this.gl.uniform1f(this.gl.getUniformLocation(accumulationProgram, "u_blend"), temporal && !temporal.historyValid ? 0 : temporalAccumulationWeight(options.blend, temporal?.historyFrames));
|
|
1914
|
+
this.gl.uniform1i(this.gl.getUniformLocation(accumulationProgram, "u_temporal"), temporal ? 1 : 0);
|
|
1915
|
+
if (temporal) {
|
|
1916
|
+
const velocity = this.requireTemporalTarget(temporal.velocity, resources.width, resources.height);
|
|
1917
|
+
const destination = this.requireTemporalTarget(temporal.historyOutput, resources.width, resources.height);
|
|
1918
|
+
if (destination === historyTarget || destination === velocity || historyTarget === velocity)
|
|
1919
|
+
throw new RenderDeviceError("Temporal targets must not alias", "TEMPORAL_TARGET_ALIAS");
|
|
1920
|
+
this.bindFullscreenTexture(2, velocity.colorHandle);
|
|
1921
|
+
this.gl.uniform1i(this.gl.getUniformLocation(accumulationProgram, "u_velocity"), 2);
|
|
1922
|
+
// Resolve exactly once into the next history target. Presentation reads
|
|
1923
|
+
// this immutable result through a separate program, so display tuning
|
|
1924
|
+
// cannot alter the accumulated history shader or its stored bytes.
|
|
1925
|
+
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, destination.framebuffer);
|
|
1926
|
+
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1927
|
+
const presentationProgram = this.ensureTaaPresentationProgram();
|
|
1928
|
+
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
|
|
1929
|
+
this.gl.useProgram(presentationProgram);
|
|
1930
|
+
this.bindFullscreenTexture(0, sourceTexture);
|
|
1931
|
+
this.bindFullscreenTexture(1, destination.colorHandle);
|
|
1932
|
+
this.gl.uniform1i(this.gl.getUniformLocation(presentationProgram, "u_source"), 0);
|
|
1933
|
+
this.gl.uniform1i(this.gl.getUniformLocation(presentationProgram, "u_accumulated"), 1);
|
|
1934
|
+
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1935
|
+
this.nativeTemporalPasses++;
|
|
1936
|
+
this.nativeTemporalBindings += 3;
|
|
1937
|
+
}
|
|
1938
|
+
else {
|
|
1939
|
+
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
|
|
1940
|
+
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1941
|
+
}
|
|
1841
1942
|
return targetTexture;
|
|
1842
1943
|
}
|
|
1944
|
+
requireTemporalTarget(target, width, height) {
|
|
1945
|
+
if (!(target instanceof WebGL2RenderTarget) || !this.renderTargets.has(target) || target.disposed || target.width !== width || target.height !== height || target.colorTexture.format !== "rgba16f")
|
|
1946
|
+
throw new RenderDeviceError("Temporal input must be a live same-device same-size RGBA16F target", "TEMPORAL_TARGET_INVALID");
|
|
1947
|
+
return target;
|
|
1948
|
+
}
|
|
1843
1949
|
bindFullscreenTexture(unit, texture) {
|
|
1844
1950
|
this.gl.activeTexture(this.gl.TEXTURE0 + unit);
|
|
1845
1951
|
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
|
|
@@ -1872,7 +1978,7 @@ export class WebGL2Device {
|
|
|
1872
1978
|
mipCount,
|
|
1873
1979
|
targetCount: options.quality === "performance" ? 2 : plan.mips.length * 2 + 1,
|
|
1874
1980
|
targetBytes: (options.quality === "performance" ? pingPongBytes : plan.targetBytes + accumulatorBytes + pingPongBytes),
|
|
1875
|
-
compositeGain: options.intensity,
|
|
1981
|
+
compositeGain: options.intensity * resolveBloomPyramidResponseGain(plan),
|
|
1876
1982
|
threshold: options.threshold,
|
|
1877
1983
|
intensity: options.intensity,
|
|
1878
1984
|
softKnee: options.softKnee,
|
|
@@ -2336,38 +2442,25 @@ uniform int u_horizontal;
|
|
|
2336
2442
|
uniform int u_hdr;
|
|
2337
2443
|
out vec4 outColor;
|
|
2338
2444
|
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
return uvec4(texelFetch(u_source, bounded, 0) * 255.0 + 0.5);
|
|
2445
|
+
vec4 sourcePixel(ivec2 coordinate) {
|
|
2446
|
+
return texelFetch(u_source, clamp(coordinate, ivec2(0), u_size - ivec2(1)), 0);
|
|
2342
2447
|
}
|
|
2343
2448
|
|
|
2344
2449
|
void main() {
|
|
2345
2450
|
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2451
|
+
float sigma = max(float(u_radius) / 3.0, 0.5);
|
|
2452
|
+
float coefficient = 0.39894 / sigma;
|
|
2453
|
+
vec4 sum = sourcePixel(pixel) * coefficient;
|
|
2454
|
+
float weightSum = coefficient;
|
|
2455
|
+
for (int offset = 1; offset <= 16; offset += 1) {
|
|
2456
|
+
if (offset > u_radius) continue;
|
|
2457
|
+
float distance = float(offset);
|
|
2458
|
+
float weight = coefficient * exp(-0.5 * distance * distance / (sigma * sigma));
|
|
2459
|
+
ivec2 delta = u_horizontal == 1 ? ivec2(offset, 0) : ivec2(0, offset);
|
|
2460
|
+
sum += (sourcePixel(pixel + delta) + sourcePixel(pixel - delta)) * weight;
|
|
2461
|
+
weightSum += 2.0 * weight;
|
|
2355
2462
|
}
|
|
2356
|
-
|
|
2357
|
-
for (int offset = -16; offset <= 16; offset += 1) {
|
|
2358
|
-
if (abs(offset) > u_radius) {
|
|
2359
|
-
continue;
|
|
2360
|
-
}
|
|
2361
|
-
ivec2 sampleCoordinate = pixel + (
|
|
2362
|
-
u_horizontal == 1
|
|
2363
|
-
? ivec2(offset, 0)
|
|
2364
|
-
: ivec2(0, offset)
|
|
2365
|
-
);
|
|
2366
|
-
sum += sourceByte(sampleCoordinate);
|
|
2367
|
-
}
|
|
2368
|
-
uint kernelSize = uint(u_radius * 2 + 1);
|
|
2369
|
-
uvec4 rounded = (sum * 2u + uvec4(kernelSize)) / uvec4(kernelSize * 2u);
|
|
2370
|
-
outColor = vec4(rounded) / 255.0;
|
|
2463
|
+
outColor = sum / max(weightSum, 0.000001);
|
|
2371
2464
|
}
|
|
2372
2465
|
`, "webgl2-bloom-blur");
|
|
2373
2466
|
return this.bloomBlurProgram;
|
|
@@ -2421,9 +2514,14 @@ void main() {
|
|
|
2421
2514
|
precision highp float;
|
|
2422
2515
|
uniform sampler2D u_source;
|
|
2423
2516
|
uniform vec2 u_texelSize;
|
|
2517
|
+
uniform vec2 u_targetSize;
|
|
2424
2518
|
out vec4 outColor;
|
|
2425
2519
|
void main() {
|
|
2426
|
-
|
|
2520
|
+
// gl_FragCoord is expressed in destination pixels. Normalize by the
|
|
2521
|
+
// destination size so every downsample covers the complete source image;
|
|
2522
|
+
// multiplying by source texel size cropped a half-size target to the
|
|
2523
|
+
// lower-left quarter of the preceding level.
|
|
2524
|
+
vec2 uv = gl_FragCoord.xy / u_targetSize;
|
|
2427
2525
|
vec2 e = u_texelSize * 0.5;
|
|
2428
2526
|
vec4 sum = texture(u_source, uv - e) + texture(u_source, uv + vec2(e.x, -e.y))
|
|
2429
2527
|
+ texture(u_source, uv + vec2(-e.x, e.y)) + texture(u_source, uv + e);
|
|
@@ -2590,40 +2688,73 @@ precision highp float;
|
|
|
2590
2688
|
precision highp int;
|
|
2591
2689
|
uniform sampler2D u_source;
|
|
2592
2690
|
uniform sampler2D u_depth;
|
|
2691
|
+
uniform sampler2D u_normalMask;
|
|
2593
2692
|
uniform ivec2 u_size;
|
|
2594
2693
|
uniform float u_intensity;
|
|
2595
|
-
uniform
|
|
2596
|
-
uniform
|
|
2597
|
-
uniform float
|
|
2694
|
+
uniform float u_maxDistance;
|
|
2695
|
+
uniform int u_maxSteps;
|
|
2696
|
+
uniform float u_thickness;
|
|
2697
|
+
uniform int u_hasNormalMask;
|
|
2698
|
+
uniform mat4 u_projection;
|
|
2699
|
+
uniform mat4 u_inverseProjection;
|
|
2598
2700
|
out vec4 outColor;
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2701
|
+
vec3 positionAtDepth(vec2 uv, float depth) {
|
|
2702
|
+
vec4 p = u_inverseProjection * vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
|
|
2703
|
+
return p.xyz / p.w;
|
|
2704
|
+
}
|
|
2705
|
+
vec3 positionAt(vec2 uv) {
|
|
2706
|
+
return positionAtDepth(uv, texture(u_depth, uv).r);
|
|
2707
|
+
}
|
|
2708
|
+
vec3 viewDirection(vec2 uv) {
|
|
2709
|
+
return normalize(positionAtDepth(uv, 0.999) - positionAtDepth(uv, 0.0));
|
|
2710
|
+
}
|
|
2711
|
+
vec2 projectPosition(vec3 p) {
|
|
2712
|
+
vec4 clip = u_projection * vec4(p, 1.0);
|
|
2713
|
+
return clip.xy / clip.w * 0.5 + 0.5;
|
|
2714
|
+
}
|
|
2715
|
+
float depthDifference(vec3 p, vec2 uv) {
|
|
2716
|
+
return dot(p - positionAt(uv), viewDirection(uv));
|
|
2607
2717
|
}
|
|
2608
|
-
|
|
2609
2718
|
void main() {
|
|
2610
|
-
|
|
2611
|
-
vec4
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
);
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2719
|
+
vec2 uv = gl_FragCoord.xy / vec2(u_size);
|
|
2720
|
+
vec4 base = texture(u_source, uv);
|
|
2721
|
+
outColor = base;
|
|
2722
|
+
vec3 origin = positionAt(uv);
|
|
2723
|
+
vec4 normalMask = texture(u_normalMask, uv);
|
|
2724
|
+
vec3 normal = u_hasNormalMask == 1 ? normalize(normalMask.xyz * 2.0 - 1.0) : normalize(cross(dFdx(origin), dFdy(origin)));
|
|
2725
|
+
float roughness = u_hasNormalMask == 1 ? normalMask.a : 0.25;
|
|
2726
|
+
if (texture(u_depth, uv).r >= 0.999999 || (u_hasNormalMask == 1 && normalMask.a == 0.0) || roughness >= 1.0) return;
|
|
2727
|
+
vec3 ray = normalize(reflect(viewDirection(uv), normal));
|
|
2728
|
+
float stepSize = u_maxDistance / float(u_maxSteps);
|
|
2729
|
+
vec3 start = origin + normal * u_thickness;
|
|
2730
|
+
float previous = 0.0;
|
|
2731
|
+
for (int i = 1; i <= 64; ++i) {
|
|
2732
|
+
if (i > u_maxSteps) break;
|
|
2733
|
+
float distanceAlong = float(i) * stepSize;
|
|
2734
|
+
vec3 candidate = start + ray * distanceAlong;
|
|
2735
|
+
vec4 candidateClip = u_projection * vec4(candidate, 1.0);
|
|
2736
|
+
if (candidateClip.w <= 0.0 || abs(candidateClip.z) >= candidateClip.w) break;
|
|
2737
|
+
vec2 hitUV = projectPosition(candidate);
|
|
2738
|
+
if (any(lessThanEqual(hitUV, vec2(0.0))) || any(greaterThanEqual(hitUV, vec2(1.0)))) break;
|
|
2739
|
+
float difference = depthDifference(candidate, hitUV);
|
|
2740
|
+
if (difference >= 0.0 && previous < 0.0) {
|
|
2741
|
+
float lo = distanceAlong - stepSize, hi = distanceAlong;
|
|
2742
|
+
for (int j = 0; j < 5; ++j) {
|
|
2743
|
+
float mid = (lo + hi) * 0.5;
|
|
2744
|
+
vec3 point = start + ray * mid;
|
|
2745
|
+
if (depthDifference(point, projectPosition(point)) >= 0.0) hi = mid; else lo = mid;
|
|
2746
|
+
}
|
|
2747
|
+
candidate = start + ray * hi;
|
|
2748
|
+
hitUV = projectPosition(candidate);
|
|
2749
|
+
difference = depthDifference(candidate, hitUV);
|
|
2750
|
+
if (difference > u_thickness || texture(u_depth, hitUV).r >= 0.999999) break;
|
|
2751
|
+
float edge = smoothstep(0.0, 0.08, min(min(hitUV.x, hitUV.y), min(1.0 - hitUV.x, 1.0 - hitUV.y)));
|
|
2752
|
+
float response = clamp(u_intensity * edge * (1.0 - roughness) * (1.0 - hi / u_maxDistance), 0.0, 1.0);
|
|
2753
|
+
outColor = vec4(mix(base.rgb, texture(u_source, hitUV).rgb, response), base.a);
|
|
2754
|
+
break;
|
|
2755
|
+
}
|
|
2756
|
+
previous = difference;
|
|
2624
2757
|
}
|
|
2625
|
-
float boost = sourceLuma * u_intensity * (1.0 - linearDepth);
|
|
2626
|
-
outColor = vec4(clamp(target.rgb + reflected * boost, 0.0, 1.0), target.a);
|
|
2627
2758
|
}
|
|
2628
2759
|
`, "webgl2-ssr");
|
|
2629
2760
|
return this.ssrProgram;
|
|
@@ -2690,6 +2821,7 @@ precision highp float;
|
|
|
2690
2821
|
precision highp int;
|
|
2691
2822
|
uniform sampler2D u_source;
|
|
2692
2823
|
uniform sampler2D u_velocity;
|
|
2824
|
+
uniform bool u_velocityUv;
|
|
2693
2825
|
uniform ivec2 u_size;
|
|
2694
2826
|
uniform int u_samples;
|
|
2695
2827
|
uniform float u_scale;
|
|
@@ -2699,6 +2831,8 @@ void main() {
|
|
|
2699
2831
|
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2700
2832
|
vec4 source = texelFetch(u_source, pixel, 0);
|
|
2701
2833
|
vec2 velocity = texelFetch(u_velocity, pixel, 0).rg * u_scale;
|
|
2834
|
+
if (u_velocityUv) velocity *= vec2(u_size);
|
|
2835
|
+
velocity = clamp(velocity, vec2(-64.0), vec2(64.0));
|
|
2702
2836
|
if (length(velocity) < 0.01) {
|
|
2703
2837
|
outColor = source;
|
|
2704
2838
|
return;
|
|
@@ -2723,18 +2857,108 @@ void main() {
|
|
|
2723
2857
|
precision highp float;
|
|
2724
2858
|
uniform sampler2D u_source;
|
|
2725
2859
|
uniform sampler2D u_history;
|
|
2860
|
+
uniform sampler2D u_velocity;
|
|
2726
2861
|
uniform float u_blend;
|
|
2862
|
+
uniform bool u_temporal;
|
|
2727
2863
|
out vec4 outColor;
|
|
2864
|
+
vec4 cubicWeights(float f) {
|
|
2865
|
+
float f2=f*f, f3=f2*f;
|
|
2866
|
+
return vec4(-0.5*f+f2-0.5*f3,1.0-2.5*f2+1.5*f3,0.5*f+2.0*f2-1.5*f3,-0.5*f2+0.5*f3);
|
|
2867
|
+
}
|
|
2868
|
+
vec4 historyAt(vec2 uv) {
|
|
2869
|
+
ivec2 size=textureSize(u_history,0);
|
|
2870
|
+
vec2 position=uv*vec2(size)-0.5;
|
|
2871
|
+
ivec2 base=ivec2(floor(position));
|
|
2872
|
+
vec4 wx=cubicWeights(fract(position.x)), wy=cubicWeights(fract(position.y));
|
|
2873
|
+
vec4 result=vec4(0.0);
|
|
2874
|
+
// Repeated bilinear history reconstruction diffuses a moving edge every
|
|
2875
|
+
// frame. Cubic reconstruction preserves it; the resolve's current-neighbor
|
|
2876
|
+
// clipping below bounds ringing before accumulation.
|
|
2877
|
+
for(int y=0;y<4;y++) for(int x=0;x<4;x++) {
|
|
2878
|
+
result+=texelFetch(u_history,clamp(base+ivec2(x-1,y-1),ivec2(0),size-1),0)*wx[x]*wy[y];
|
|
2879
|
+
}
|
|
2880
|
+
return result;
|
|
2881
|
+
}
|
|
2728
2882
|
|
|
2729
2883
|
void main() {
|
|
2730
2884
|
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2885
|
+
ivec2 size = textureSize(u_source, 0);
|
|
2886
|
+
vec2 outputUV=(vec2(pixel)+0.5)/vec2(size);
|
|
2887
|
+
// Raster jitter supplies quadrature samples inside the output pixel.
|
|
2888
|
+
// Keep that sample on its pixel's accumulation grid; undoing the jitter
|
|
2889
|
+
// spatially filters it and defeats temporal coverage integration.
|
|
2890
|
+
vec2 sourceUV=outputUV;
|
|
2891
|
+
ivec2 sourcePixel=clamp(ivec2(floor(sourceUV*vec2(size))),ivec2(0),size-1);
|
|
2892
|
+
// Reconstruct current color on the stable output grid before accumulation.
|
|
2731
2893
|
vec4 source = texelFetch(u_source, pixel, 0);
|
|
2732
|
-
|
|
2733
|
-
|
|
2894
|
+
vec4 motion = u_temporal ? texelFetch(u_velocity, sourcePixel, 0) : vec4(0.0);
|
|
2895
|
+
// A currently uncovered sample may still carry integrated foreground
|
|
2896
|
+
// coverage in history. Track nearby foreground motion for that coverage,
|
|
2897
|
+
// but retain this pixel's own current/previous depth tags: copying RGBA
|
|
2898
|
+
// wholesale falsely labels background color as a foreground surface.
|
|
2899
|
+
if (u_temporal) {
|
|
2900
|
+
float nearestDepth=motion.b;
|
|
2901
|
+
for(int y=-1;y<=1;y++) for(int x=-1;x<=1;x++) {
|
|
2902
|
+
vec4 candidate=texelFetch(u_velocity,clamp(pixel+ivec2(x,y),ivec2(0),size-1),0);
|
|
2903
|
+
if(candidate.b<nearestDepth) {nearestDepth=candidate.b;motion.xy=candidate.xy;}
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
vec2 previousUV = outputUV-motion.xy;
|
|
2907
|
+
vec4 history = u_temporal ? historyAt(previousUV) : texture(u_history, previousUV);
|
|
2908
|
+
float weight = u_blend;
|
|
2909
|
+
if (u_temporal) {
|
|
2910
|
+
// Reprojected history incurs reconstruction error as the footprint moves
|
|
2911
|
+
// across the pixel grid. Reduce its confidence with displacement instead
|
|
2912
|
+
// of repeatedly giving a softened moving edge the stationary .9 weight.
|
|
2913
|
+
// Physical motion itself remains fully represented in previousUV.
|
|
2914
|
+
weight /= 1.0 + length(motion.xy * vec2(size));
|
|
2915
|
+
// Depth is categorical at a silhouette: bilinear alpha interpolation creates
|
|
2916
|
+
// nonexistent surfaces and rejects valid history on every jittered edge.
|
|
2917
|
+
// Test surface presence in the central history footprint. RGB remains
|
|
2918
|
+
// an integrated coverage value reconstructed from the wider cubic kernel.
|
|
2919
|
+
ivec2 previousBase=ivec2(floor(previousUV*vec2(size)-vec2(0.5)));
|
|
2920
|
+
float depthError=1.0;
|
|
2921
|
+
for(int y=0;y<2;y++) for(int x=0;x<2;x++) {
|
|
2922
|
+
float previousDepth=texelFetch(u_history,clamp(previousBase+ivec2(x,y),ivec2(0),size-1),0).a;
|
|
2923
|
+
depthError=min(depthError,abs(previousDepth-motion.a));
|
|
2924
|
+
}
|
|
2925
|
+
if (any(lessThan(previousUV,vec2(0.0))) || any(greaterThanEqual(previousUV,vec2(1.0))) || depthError>0.002) weight=0.0;
|
|
2926
|
+
vec3 lo=source.rgb, hi=source.rgb;
|
|
2927
|
+
for(int y=-1;y<=1;y++) for(int x=-1;x<=1;x++) { vec3 tap=texelFetch(u_source,clamp(pixel+ivec2(x,y),ivec2(0),size-1),0).rgb; lo=min(lo,tap); hi=max(hi,tap); }
|
|
2928
|
+
history.rgb=clamp(history.rgb,lo,hi);
|
|
2929
|
+
}
|
|
2930
|
+
vec3 resolved=mix(source.rgb,history.rgb,weight);
|
|
2931
|
+
outColor=vec4(resolved,u_temporal?motion.b:source.a);
|
|
2734
2932
|
}
|
|
2735
|
-
`, "webgl2-taa");
|
|
2933
|
+
`, "webgl2-taa-accumulation");
|
|
2736
2934
|
return this.taaProgram;
|
|
2737
2935
|
}
|
|
2936
|
+
ensureTaaPresentationProgram() {
|
|
2937
|
+
if (this.taaPresentationProgram)
|
|
2938
|
+
return this.taaPresentationProgram;
|
|
2939
|
+
this.taaPresentationProgram = this.createFullscreenProgram(`#version 300 es
|
|
2940
|
+
precision highp float;
|
|
2941
|
+
uniform sampler2D u_source;
|
|
2942
|
+
uniform sampler2D u_accumulated;
|
|
2943
|
+
out vec4 outColor;
|
|
2944
|
+
void main() {
|
|
2945
|
+
ivec2 pixel=ivec2(gl_FragCoord.xy);
|
|
2946
|
+
ivec2 size=textureSize(u_source,0);
|
|
2947
|
+
vec4 source=texelFetch(u_source,pixel,0);
|
|
2948
|
+
vec3 accumulated=texelFetch(u_accumulated,pixel,0).rgb;
|
|
2949
|
+
// Retained native pixels isolate the remaining spatial excess to the
|
|
2950
|
+
// horizontally moving silhouette. Apply a bounded three-tap unsharp resolve
|
|
2951
|
+
// to presentation only; accumulated history remains immutable.
|
|
2952
|
+
vec3 center=mix(source.rgb,accumulated,0.90);
|
|
2953
|
+
ivec2 leftPixel=clamp(pixel+ivec2(-1,0),ivec2(0),size-1);
|
|
2954
|
+
ivec2 rightPixel=clamp(pixel+ivec2(1,0),ivec2(0),size-1);
|
|
2955
|
+
vec3 left=mix(texelFetch(u_source,leftPixel,0).rgb,texelFetch(u_accumulated,leftPixel,0).rgb,0.90);
|
|
2956
|
+
vec3 right=mix(texelFetch(u_source,rightPixel,0).rgb,texelFetch(u_accumulated,rightPixel,0).rgb,0.90);
|
|
2957
|
+
outColor=vec4(clamp(center*1.04-(left+right)*0.02,0.0,1.0),source.a);
|
|
2958
|
+
}
|
|
2959
|
+
`, "webgl2-taa-presentation");
|
|
2960
|
+
return this.taaPresentationProgram;
|
|
2961
|
+
}
|
|
2738
2962
|
createFullscreenProgram(fragmentSource, label) {
|
|
2739
2963
|
const vertex = this.compileShader(this.gl.VERTEX_SHADER, `#version 300 es
|
|
2740
2964
|
precision highp float;
|
|
@@ -3821,7 +4045,11 @@ function normalizeNativeSsrOptions(options) {
|
|
|
3821
4045
|
if (!Number.isInteger(maxDistance) || maxDistance < 1 || maxDistance > 64) {
|
|
3822
4046
|
throw new RenderDeviceError("SSR maxDistance must be an integer in [1, 64].", "INVALID_POSTPROCESS_OPTIONS", { maxDistance });
|
|
3823
4047
|
}
|
|
3824
|
-
|
|
4048
|
+
const projection = options["projection"];
|
|
4049
|
+
if (!(projection instanceof Float32Array))
|
|
4050
|
+
throw new RenderDeviceError("Native SSR requires the actual frame projection or view-projection matrix.", "INVALID_POSTPROCESS_OPTIONS");
|
|
4051
|
+
const inverseProjection = invertSsrProjection(projection);
|
|
4052
|
+
return { intensity, maxDistance, projection, inverseProjection };
|
|
3825
4053
|
}
|
|
3826
4054
|
function normalizeNativeDepthOfFieldOptions(options) {
|
|
3827
4055
|
const focusDepth = depthOfFieldNumberOption(options, "focusDepth", 0.5);
|
|
@@ -3841,6 +4069,11 @@ function normalizeNativeDepthOfFieldOptions(options) {
|
|
|
3841
4069
|
function normalizeNativeMotionBlurOptions(options, width, height) {
|
|
3842
4070
|
const samples = motionBlurNumberOption(options, "samples", 5);
|
|
3843
4071
|
const scale = motionBlurNumberOption(options, "scale", 1);
|
|
4072
|
+
if (options.temporal) {
|
|
4073
|
+
if (!Number.isInteger(samples) || samples < 2 || samples > 16 || scale < 0 || scale > 8)
|
|
4074
|
+
throw new RenderDeviceError("Invalid motion blur samples/scale", "INVALID_POSTPROCESS_OPTIONS");
|
|
4075
|
+
return { samples, scale, temporal: options.temporal };
|
|
4076
|
+
}
|
|
3844
4077
|
const value = options.velocity;
|
|
3845
4078
|
if (!(value instanceof Float32Array) && !Array.isArray(value)) {
|
|
3846
4079
|
throw new RenderDeviceError("Motion blur requires a velocity Float32Array or number array.", "WEBGL_LDR_POSTPROCESS_VELOCITY_REQUIRED");
|
|
@@ -3862,6 +4095,11 @@ function normalizeNativeMotionBlurOptions(options, width, height) {
|
|
|
3862
4095
|
}
|
|
3863
4096
|
function normalizeNativeTaaOptions(options, width, height) {
|
|
3864
4097
|
const blend = taaNumberOption(options, "blend", 0.18);
|
|
4098
|
+
if (options.temporal) {
|
|
4099
|
+
if (blend < 0 || blend > .95)
|
|
4100
|
+
throw new RenderDeviceError("Invalid TAA blend", "INVALID_POSTPROCESS_OPTIONS");
|
|
4101
|
+
return { blend, temporal: options.temporal };
|
|
4102
|
+
}
|
|
3865
4103
|
const history = options.history;
|
|
3866
4104
|
if (!(history instanceof Uint8Array)) {
|
|
3867
4105
|
throw new RenderDeviceError("TAA requires a Uint8Array history buffer.", "WEBGL_LDR_POSTPROCESS_HISTORY_REQUIRED");
|