@aura3d/rendering 3.0.0 → 4.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/dist/BlendModes.d.ts +34 -0
- package/dist/BlendModes.d.ts.map +1 -0
- package/dist/BlendModes.js +42 -0
- package/dist/BlendModes.js.map +1 -0
- package/dist/CascadedShadowMaps.d.ts.map +1 -1
- package/dist/CascadedShadowMaps.js +3 -1
- package/dist/CascadedShadowMaps.js.map +1 -1
- package/dist/DepthPass.d.ts +18 -0
- package/dist/DepthPass.d.ts.map +1 -1
- package/dist/DepthPass.js +103 -20
- package/dist/DepthPass.js.map +1 -1
- package/dist/EnvironmentBackgroundPass.d.ts +7 -0
- package/dist/EnvironmentBackgroundPass.d.ts.map +1 -1
- package/dist/EnvironmentBackgroundPass.js +39 -14
- package/dist/EnvironmentBackgroundPass.js.map +1 -1
- package/dist/EnvironmentMapResources.d.ts +1 -1
- package/dist/EnvironmentMapResources.d.ts.map +1 -1
- package/dist/EnvironmentMapResources.js +19 -8
- package/dist/EnvironmentMapResources.js.map +1 -1
- package/dist/EnvironmentPlatform.d.ts +6 -0
- package/dist/EnvironmentPlatform.d.ts.map +1 -1
- package/dist/EnvironmentPlatform.js +3 -1
- package/dist/EnvironmentPlatform.js.map +1 -1
- package/dist/EnvironmentPreset.d.ts +7 -0
- package/dist/EnvironmentPreset.d.ts.map +1 -1
- package/dist/EnvironmentPreset.js +11 -11
- package/dist/EnvironmentPreset.js.map +1 -1
- package/dist/EnvironmentPresetPack.d.ts +16 -0
- package/dist/EnvironmentPresetPack.d.ts.map +1 -1
- package/dist/EnvironmentPresetPack.js +28 -0
- package/dist/EnvironmentPresetPack.js.map +1 -1
- package/dist/ExtensionScalarAtlas.d.ts +18 -0
- package/dist/ExtensionScalarAtlas.d.ts.map +1 -0
- package/dist/ExtensionScalarAtlas.js +107 -0
- package/dist/ExtensionScalarAtlas.js.map +1 -0
- package/dist/ExternalParityRenderPreset.d.ts +15 -1
- package/dist/ExternalParityRenderPreset.d.ts.map +1 -1
- package/dist/ExternalParityRenderPreset.js +52 -7
- package/dist/ExternalParityRenderPreset.js.map +1 -1
- package/dist/ForwardPass.d.ts +240 -50
- package/dist/ForwardPass.d.ts.map +1 -1
- package/dist/ForwardPass.js +845 -866
- package/dist/ForwardPass.js.map +1 -1
- package/dist/Geometry.d.ts +44 -1
- package/dist/Geometry.d.ts.map +1 -1
- package/dist/Geometry.js +174 -24
- package/dist/Geometry.js.map +1 -1
- package/dist/InstancedPBRMaterial.d.ts +5 -0
- package/dist/InstancedPBRMaterial.d.ts.map +1 -1
- package/dist/InstancedPBRMaterial.js +7 -0
- package/dist/InstancedPBRMaterial.js.map +1 -1
- package/dist/LeanWebGL2Device.d.ts +265 -0
- package/dist/LeanWebGL2Device.d.ts.map +1 -0
- package/dist/LeanWebGL2Device.js +4001 -0
- package/dist/LeanWebGL2Device.js.map +1 -0
- package/dist/LightCollector.d.ts +8 -0
- package/dist/LightCollector.d.ts.map +1 -1
- package/dist/LightCollector.js +1 -1
- package/dist/LightCollector.js.map +1 -1
- package/dist/LightUniforms.d.ts +78 -0
- package/dist/LightUniforms.d.ts.map +1 -1
- package/dist/LightUniforms.js +100 -0
- package/dist/LightUniforms.js.map +1 -1
- package/dist/Material.d.ts +15 -0
- package/dist/Material.d.ts.map +1 -1
- package/dist/Material.js +19 -2
- package/dist/Material.js.map +1 -1
- package/dist/MaterialBinding.d.ts +10 -0
- package/dist/MaterialBinding.d.ts.map +1 -1
- package/dist/MaterialBinding.js +92 -2
- package/dist/MaterialBinding.js.map +1 -1
- package/dist/MaterialPresets.d.ts +60 -0
- package/dist/MaterialPresets.d.ts.map +1 -1
- package/dist/MaterialPresets.js +212 -0
- package/dist/MaterialPresets.js.map +1 -1
- package/dist/NormalMappedPBRMaterial.d.ts +5 -0
- package/dist/NormalMappedPBRMaterial.d.ts.map +1 -1
- package/dist/NormalMappedPBRMaterial.js +7 -0
- package/dist/NormalMappedPBRMaterial.js.map +1 -1
- package/dist/OceanSurface.d.ts +8 -0
- package/dist/OceanSurface.d.ts.map +1 -1
- package/dist/OceanSurface.js +10 -79
- package/dist/OceanSurface.js.map +1 -1
- package/dist/PBRLightingDefaults.d.ts +8 -0
- package/dist/PBRLightingDefaults.d.ts.map +1 -1
- package/dist/PBRLightingDefaults.js +8 -0
- package/dist/PBRLightingDefaults.js.map +1 -1
- package/dist/PBRMaterial.d.ts +5 -0
- package/dist/PBRMaterial.d.ts.map +1 -1
- package/dist/PBRMaterial.js +7 -0
- package/dist/PBRMaterial.js.map +1 -1
- package/dist/PlanarReflection.d.ts +2 -2
- package/dist/PlanarReflection.js +3 -3
- package/dist/PlanarReflection.js.map +1 -1
- package/dist/PostProcessPass.d.ts +8 -473
- package/dist/PostProcessPass.d.ts.map +1 -1
- package/dist/PostProcessPass.js +6 -1984
- package/dist/PostProcessPass.js.map +1 -1
- package/dist/ProceduralMaterialTextures.d.ts +28 -0
- package/dist/ProceduralMaterialTextures.d.ts.map +1 -0
- package/dist/ProceduralMaterialTextures.js +217 -0
- package/dist/ProceduralMaterialTextures.js.map +1 -0
- package/dist/ProjectionMath.d.ts +3 -0
- package/dist/ProjectionMath.d.ts.map +1 -0
- package/dist/ProjectionMath.js +26 -0
- package/dist/ProjectionMath.js.map +1 -0
- package/dist/ReflectionProbe.d.ts.map +1 -1
- package/dist/ReflectionProbe.js +4 -1
- package/dist/ReflectionProbe.js.map +1 -1
- package/dist/ReflectionSurfaces.d.ts +4 -1
- package/dist/ReflectionSurfaces.d.ts.map +1 -1
- package/dist/ReflectionSurfaces.js +10 -1
- package/dist/ReflectionSurfaces.js.map +1 -1
- package/dist/RenderBackend.d.ts +2 -0
- package/dist/RenderBackend.d.ts.map +1 -1
- package/dist/RenderBackend.js +3 -0
- package/dist/RenderBackend.js.map +1 -1
- package/dist/RenderDevice.d.ts +97 -5
- package/dist/RenderDevice.d.ts.map +1 -1
- package/dist/RenderDevice.js +166 -9
- package/dist/RenderDevice.js.map +1 -1
- package/dist/RenderGraph.d.ts.map +1 -1
- package/dist/RenderGraph.js +17 -0
- package/dist/RenderGraph.js.map +1 -1
- package/dist/RenderPass.d.ts +7 -0
- package/dist/RenderPass.d.ts.map +1 -1
- package/dist/RenderPass.js.map +1 -1
- package/dist/RenderPipeline.d.ts +5 -0
- package/dist/RenderPipeline.d.ts.map +1 -1
- package/dist/RenderPipeline.js +6 -0
- package/dist/RenderPipeline.js.map +1 -1
- package/dist/Renderer.d.ts +270 -66
- package/dist/Renderer.d.ts.map +1 -1
- package/dist/Renderer.js +970 -1249
- package/dist/Renderer.js.map +1 -1
- package/dist/RendererPostprocessPlan.d.ts +20 -3
- package/dist/RendererPostprocessPlan.d.ts.map +1 -1
- package/dist/RendererPostprocessPlan.js +32 -4
- package/dist/RendererPostprocessPlan.js.map +1 -1
- package/dist/RendererTiming.d.ts +27 -0
- package/dist/RendererTiming.d.ts.map +1 -1
- package/dist/RendererTiming.js +179 -12
- package/dist/RendererTiming.js.map +1 -1
- package/dist/ResolutionGovernor.d.ts +56 -0
- package/dist/ResolutionGovernor.d.ts.map +1 -0
- package/dist/ResolutionGovernor.js +87 -0
- package/dist/ResolutionGovernor.js.map +1 -0
- package/dist/Sampler.d.ts +34 -1
- package/dist/Sampler.d.ts.map +1 -1
- package/dist/Sampler.js +55 -2
- package/dist/Sampler.js.map +1 -1
- package/dist/ScreenSpaceReflectionPass.d.ts +43 -0
- package/dist/ScreenSpaceReflectionPass.d.ts.map +1 -0
- package/dist/ScreenSpaceReflectionPass.js +58 -0
- package/dist/ScreenSpaceReflectionPass.js.map +1 -0
- package/dist/ShaderLibrary.d.ts.map +1 -1
- package/dist/ShaderLibrary.js +183 -207
- package/dist/ShaderLibrary.js.map +1 -1
- package/dist/ShaderLibraryCore.d.ts +3 -0
- package/dist/ShaderLibraryCore.d.ts.map +1 -1
- package/dist/ShaderLibraryCore.js +6 -2
- package/dist/ShaderLibraryCore.js.map +1 -1
- package/dist/ShaderModule.d.ts +7 -1
- package/dist/ShaderModule.d.ts.map +1 -1
- package/dist/ShaderModule.js +20 -5
- package/dist/ShaderModule.js.map +1 -1
- package/dist/ShadowPass.d.ts.map +1 -1
- package/dist/ShadowPass.js +14 -7
- package/dist/ShadowPass.js.map +1 -1
- package/dist/SkinnedLitMaterial.d.ts +5 -0
- package/dist/SkinnedLitMaterial.d.ts.map +1 -1
- package/dist/SkinnedLitMaterial.js +13 -0
- package/dist/SkinnedLitMaterial.js.map +1 -1
- package/dist/SkinningBounds.d.ts +18 -0
- package/dist/SkinningBounds.d.ts.map +1 -1
- package/dist/SkinningBounds.js +78 -0
- package/dist/SkinningBounds.js.map +1 -1
- package/dist/SkinningPaletteTextureCache.d.ts +117 -0
- package/dist/SkinningPaletteTextureCache.d.ts.map +1 -0
- package/dist/SkinningPaletteTextureCache.js +205 -0
- package/dist/SkinningPaletteTextureCache.js.map +1 -0
- package/dist/SkinningUniforms.d.ts +56 -0
- package/dist/SkinningUniforms.d.ts.map +1 -0
- package/dist/SkinningUniforms.js +262 -0
- package/dist/SkinningUniforms.js.map +1 -0
- package/dist/TemporalHistory.d.ts +70 -0
- package/dist/TemporalHistory.d.ts.map +1 -0
- package/dist/TemporalHistory.js +218 -0
- package/dist/TemporalHistory.js.map +1 -0
- package/dist/TemporalMath.d.ts +3 -0
- package/dist/TemporalMath.d.ts.map +1 -0
- package/dist/TemporalMath.js +9 -0
- package/dist/TemporalMath.js.map +1 -0
- package/dist/TerrainHeightfield.d.ts +12 -0
- package/dist/TerrainHeightfield.d.ts.map +1 -1
- package/dist/TerrainHeightfield.js +29 -6
- package/dist/TerrainHeightfield.js.map +1 -1
- package/dist/TerrainTiles.d.ts +40 -10
- package/dist/TerrainTiles.d.ts.map +1 -1
- package/dist/TerrainTiles.js +18 -57
- package/dist/TerrainTiles.js.map +1 -1
- package/dist/Texture.d.ts +47 -2
- package/dist/Texture.d.ts.map +1 -1
- package/dist/Texture.js +119 -3
- package/dist/Texture.js.map +1 -1
- package/dist/TexturedPBRMaterial.d.ts +27 -0
- package/dist/TexturedPBRMaterial.d.ts.map +1 -1
- package/dist/TexturedPBRMaterial.js +137 -23
- package/dist/TexturedPBRMaterial.js.map +1 -1
- package/dist/TransmissionRenderTarget.d.ts +33 -0
- package/dist/TransmissionRenderTarget.d.ts.map +1 -0
- package/dist/TransmissionRenderTarget.js +61 -0
- package/dist/TransmissionRenderTarget.js.map +1 -0
- package/dist/VegetationScatter.js +1 -1
- package/dist/VegetationScatter.js.map +1 -1
- package/dist/VolumetricFog.d.ts +42 -0
- package/dist/VolumetricFog.d.ts.map +1 -1
- package/dist/VolumetricFog.js +52 -1
- package/dist/VolumetricFog.js.map +1 -1
- package/dist/WaterSurface.d.ts +5 -0
- package/dist/WaterSurface.d.ts.map +1 -1
- package/dist/WaterSurface.js +5 -0
- package/dist/WaterSurface.js.map +1 -1
- package/dist/WebGL2Device.d.ts +159 -198
- package/dist/WebGL2Device.d.ts.map +1 -1
- package/dist/WebGL2Device.js +797 -3443
- package/dist/WebGL2Device.js.map +1 -1
- package/dist/WebGL2StateCache.d.ts +15 -1
- package/dist/WebGL2StateCache.d.ts.map +1 -1
- package/dist/WebGL2StateCache.js +31 -2
- package/dist/WebGL2StateCache.js.map +1 -1
- package/dist/WebGPUDevice.d.ts +16 -9
- package/dist/WebGPUDevice.d.ts.map +1 -1
- package/dist/WebGPUDevice.js +343 -618
- package/dist/WebGPUDevice.js.map +1 -1
- package/dist/WebGPUExtensionAtlas.d.ts +6 -0
- package/dist/WebGPUExtensionAtlas.d.ts.map +1 -0
- package/dist/WebGPUExtensionAtlas.js +225 -0
- package/dist/WebGPUExtensionAtlas.js.map +1 -0
- package/dist/WebGPUSkinningLimits.d.ts +10 -1
- package/dist/WebGPUSkinningLimits.d.ts.map +1 -1
- package/dist/WebGPUSkinningLimits.js +15 -1
- package/dist/WebGPUSkinningLimits.js.map +1 -1
- package/dist/advanced-runtime/index.d.ts +6 -2
- package/dist/advanced-runtime/index.d.ts.map +1 -1
- package/dist/advanced-runtime/index.js +0 -1
- package/dist/advanced-runtime/index.js.map +1 -1
- package/dist/animation/AnimationRenderPreset.d.ts +1 -1
- package/dist/animation/AnimationRenderPreset.d.ts.map +1 -1
- package/dist/animation/AnimationRenderPreset.js +1 -1
- package/dist/animation/AnimationRenderPreset.js.map +1 -1
- package/dist/animation/applyAnimationRenderPreset.d.ts +1 -1
- package/dist/animation/applyAnimationRenderPreset.d.ts.map +1 -1
- package/dist/animation/index.d.ts +2 -1
- package/dist/animation/index.d.ts.map +1 -1
- package/dist/animation/index.js +1 -1
- package/dist/animation/index.js.map +1 -1
- package/dist/atmosphere/CloudLayer.d.ts +24 -0
- package/dist/atmosphere/CloudLayer.d.ts.map +1 -0
- package/dist/atmosphere/CloudLayer.js +30 -0
- package/dist/atmosphere/CloudLayer.js.map +1 -0
- package/dist/atmosphere/FogVolumes.d.ts +30 -0
- package/dist/atmosphere/FogVolumes.d.ts.map +1 -0
- package/dist/atmosphere/FogVolumes.js +96 -0
- package/dist/atmosphere/FogVolumes.js.map +1 -0
- package/dist/atmosphere/GradientSky.d.ts +40 -0
- package/dist/atmosphere/GradientSky.d.ts.map +1 -0
- package/dist/atmosphere/GradientSky.js +75 -0
- package/dist/atmosphere/GradientSky.js.map +1 -0
- package/dist/atmosphere/HeightFog.d.ts +154 -0
- package/dist/atmosphere/HeightFog.d.ts.map +1 -0
- package/dist/atmosphere/HeightFog.js +379 -0
- package/dist/atmosphere/HeightFog.js.map +1 -0
- package/dist/atmosphere/PreethamSky.d.ts +38 -0
- package/dist/atmosphere/PreethamSky.d.ts.map +1 -0
- package/dist/atmosphere/PreethamSky.js +150 -0
- package/dist/atmosphere/PreethamSky.js.map +1 -0
- package/dist/atmosphere/SkyBackgroundPass.d.ts +63 -0
- package/dist/atmosphere/SkyBackgroundPass.d.ts.map +1 -0
- package/dist/atmosphere/SkyBackgroundPass.js +233 -0
- package/dist/atmosphere/SkyBackgroundPass.js.map +1 -0
- package/dist/atmosphere/SkyCaptureAdapter.d.ts +45 -0
- package/dist/atmosphere/SkyCaptureAdapter.d.ts.map +1 -0
- package/dist/atmosphere/SkyCaptureAdapter.js +65 -0
- package/dist/atmosphere/SkyCaptureAdapter.js.map +1 -0
- package/dist/atmosphere/SkyEval.d.ts +56 -0
- package/dist/atmosphere/SkyEval.d.ts.map +1 -0
- package/dist/atmosphere/SkyEval.js +99 -0
- package/dist/atmosphere/SkyEval.js.map +1 -0
- package/dist/atmosphere/StarField.d.ts +26 -0
- package/dist/atmosphere/StarField.d.ts.map +1 -0
- package/dist/atmosphere/StarField.js +31 -0
- package/dist/atmosphere/StarField.js.map +1 -0
- package/dist/atmosphere/VolumetricFogPass.d.ts +69 -0
- package/dist/atmosphere/VolumetricFogPass.d.ts.map +1 -0
- package/dist/atmosphere/VolumetricFogPass.js +265 -0
- package/dist/atmosphere/VolumetricFogPass.js.map +1 -0
- package/dist/atmosphere/fogChunks.d.ts +8 -0
- package/dist/atmosphere/fogChunks.d.ts.map +1 -0
- package/dist/atmosphere/fogChunks.js +39 -0
- package/dist/atmosphere/fogChunks.js.map +1 -0
- package/dist/atmosphere/fogUniformStore.d.ts +20 -0
- package/dist/atmosphere/fogUniformStore.d.ts.map +1 -0
- package/dist/atmosphere/fogUniformStore.js +45 -0
- package/dist/atmosphere/fogUniformStore.js.map +1 -0
- package/dist/atmosphere/shaders/fog.glsl.d.ts +10 -0
- package/dist/atmosphere/shaders/fog.glsl.d.ts.map +1 -0
- package/dist/atmosphere/shaders/fog.glsl.js +161 -0
- package/dist/atmosphere/shaders/fog.glsl.js.map +1 -0
- package/dist/atmosphere/shaders/volumetric-apply.glsl.d.ts +3 -0
- package/dist/atmosphere/shaders/volumetric-apply.glsl.d.ts.map +1 -0
- package/dist/atmosphere/shaders/volumetric-apply.glsl.js +61 -0
- package/dist/atmosphere/shaders/volumetric-apply.glsl.js.map +1 -0
- package/dist/atmosphere/shaders/volumetric-inject.glsl.d.ts +4 -0
- package/dist/atmosphere/shaders/volumetric-inject.glsl.d.ts.map +1 -0
- package/dist/atmosphere/shaders/volumetric-inject.glsl.js +129 -0
- package/dist/atmosphere/shaders/volumetric-inject.glsl.js.map +1 -0
- package/dist/atmosphere/shaders/volumetric-integrate.glsl.d.ts +3 -0
- package/dist/atmosphere/shaders/volumetric-integrate.glsl.d.ts.map +1 -0
- package/dist/atmosphere/shaders/volumetric-integrate.glsl.js +55 -0
- package/dist/atmosphere/shaders/volumetric-integrate.glsl.js.map +1 -0
- package/dist/atmosphere/shaders/wetness.glsl.d.ts +34 -0
- package/dist/atmosphere/shaders/wetness.glsl.d.ts.map +1 -0
- package/dist/atmosphere/shaders/wetness.glsl.js +101 -0
- package/dist/atmosphere/shaders/wetness.glsl.js.map +1 -0
- package/dist/atmosphere/sky.glsl.d.ts +8 -0
- package/dist/atmosphere/sky.glsl.d.ts.map +1 -0
- package/dist/atmosphere/sky.glsl.js +249 -0
- package/dist/atmosphere/sky.glsl.js.map +1 -0
- package/dist/batching/BatchedGeometryPool.d.ts +72 -0
- package/dist/batching/BatchedGeometryPool.d.ts.map +1 -0
- package/dist/batching/BatchedGeometryPool.js +138 -0
- package/dist/batching/BatchedGeometryPool.js.map +1 -0
- package/dist/batching/ContentKeys.d.ts +29 -0
- package/dist/batching/ContentKeys.d.ts.map +1 -0
- package/dist/batching/ContentKeys.js +220 -0
- package/dist/batching/ContentKeys.js.map +1 -0
- package/dist/batching/DrawDataTexture.d.ts +51 -0
- package/dist/batching/DrawDataTexture.d.ts.map +1 -0
- package/dist/batching/DrawDataTexture.js +99 -0
- package/dist/batching/DrawDataTexture.js.map +1 -0
- package/dist/batching/MultiDrawBatch.d.ts +64 -0
- package/dist/batching/MultiDrawBatch.d.ts.map +1 -0
- package/dist/batching/MultiDrawBatch.js +103 -0
- package/dist/batching/MultiDrawBatch.js.map +1 -0
- package/dist/batching/StaticMergePlanner.d.ts +80 -0
- package/dist/batching/StaticMergePlanner.d.ts.map +1 -0
- package/dist/batching/StaticMergePlanner.js +323 -0
- package/dist/batching/StaticMergePlanner.js.map +1 -0
- package/dist/batching/index.d.ts +8 -0
- package/dist/batching/index.d.ts.map +1 -0
- package/dist/batching/index.js +8 -0
- package/dist/batching/index.js.map +1 -0
- package/dist/batching/shaders/drawId.glsl.d.ts +29 -0
- package/dist/batching/shaders/drawId.glsl.d.ts.map +1 -0
- package/dist/batching/shaders/drawId.glsl.js +93 -0
- package/dist/batching/shaders/drawId.glsl.js.map +1 -0
- package/dist/batching/shaders/instanceEmissive.glsl.d.ts +16 -0
- package/dist/batching/shaders/instanceEmissive.glsl.d.ts.map +1 -0
- package/dist/batching/shaders/instanceEmissive.glsl.js +63 -0
- package/dist/batching/shaders/instanceEmissive.glsl.js.map +1 -0
- package/dist/cinematic/BloomPass.d.ts +5 -9
- package/dist/cinematic/BloomPass.d.ts.map +1 -1
- package/dist/cinematic/BloomPass.js +5 -17
- package/dist/cinematic/BloomPass.js.map +1 -1
- package/dist/cinematic/DepthHazePass.d.ts +5 -11
- package/dist/cinematic/DepthHazePass.d.ts.map +1 -1
- package/dist/cinematic/DepthHazePass.js +5 -19
- package/dist/cinematic/DepthHazePass.js.map +1 -1
- package/dist/cinematic/FilmGrainPass.d.ts +5 -8
- package/dist/cinematic/FilmGrainPass.d.ts.map +1 -1
- package/dist/cinematic/FilmGrainPass.js +5 -16
- package/dist/cinematic/FilmGrainPass.js.map +1 -1
- package/dist/cinematic/VignettePass.d.ts +5 -9
- package/dist/cinematic/VignettePass.d.ts.map +1 -1
- package/dist/cinematic/VignettePass.js +5 -16
- package/dist/cinematic/VignettePass.js.map +1 -1
- package/dist/cinematic/index.d.ts +2 -1
- package/dist/cinematic/index.d.ts.map +1 -1
- package/dist/cinematic/index.js +1 -1
- package/dist/cinematic/index.js.map +1 -1
- package/dist/contracts/atmosphere.d.ts +30 -0
- package/dist/contracts/atmosphere.d.ts.map +1 -0
- package/dist/contracts/atmosphere.js +42 -0
- package/dist/contracts/atmosphere.js.map +1 -0
- package/dist/contracts/blend.d.ts +28 -0
- package/dist/contracts/blend.d.ts.map +1 -0
- package/dist/contracts/blend.js +73 -0
- package/dist/contracts/blend.js.map +1 -0
- package/dist/contracts/core.d.ts +47 -0
- package/dist/contracts/core.d.ts.map +1 -0
- package/dist/contracts/core.js +70 -0
- package/dist/contracts/core.js.map +1 -0
- package/dist/contracts/deform.d.ts +38 -0
- package/dist/contracts/deform.d.ts.map +1 -0
- package/dist/contracts/deform.js +14 -0
- package/dist/contracts/deform.js.map +1 -0
- package/dist/contracts/device.d.ts +71 -0
- package/dist/contracts/device.d.ts.map +1 -0
- package/dist/contracts/device.js +97 -0
- package/dist/contracts/device.js.map +1 -0
- package/dist/contracts/environment.d.ts +55 -0
- package/dist/contracts/environment.d.ts.map +1 -0
- package/dist/contracts/environment.js +115 -0
- package/dist/contracts/environment.js.map +1 -0
- package/dist/contracts/flags.state.d.ts +15 -0
- package/dist/contracts/flags.state.d.ts.map +1 -0
- package/dist/contracts/flags.state.js +45 -0
- package/dist/contracts/flags.state.js.map +1 -0
- package/dist/contracts/frameGraph.d.ts +78 -0
- package/dist/contracts/frameGraph.d.ts.map +1 -0
- package/dist/contracts/frameGraph.js +32 -0
- package/dist/contracts/frameGraph.js.map +1 -0
- package/dist/contracts/frameUniforms.d.ts +43 -0
- package/dist/contracts/frameUniforms.d.ts.map +1 -0
- package/dist/contracts/frameUniforms.js +35 -0
- package/dist/contracts/frameUniforms.js.map +1 -0
- package/dist/contracts/geometry.d.ts +33 -0
- package/dist/contracts/geometry.d.ts.map +1 -0
- package/dist/contracts/geometry.js +59 -0
- package/dist/contracts/geometry.js.map +1 -0
- package/dist/contracts/index.d.ts +27 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +27 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/materialLobes.d.ts +41 -0
- package/dist/contracts/materialLobes.d.ts.map +1 -0
- package/dist/contracts/materialLobes.js +14 -0
- package/dist/contracts/materialLobes.js.map +1 -0
- package/dist/contracts/output.d.ts +35 -0
- package/dist/contracts/output.d.ts.map +1 -0
- package/dist/contracts/output.js +18 -0
- package/dist/contracts/output.js.map +1 -0
- package/dist/contracts/particles.d.ts +41 -0
- package/dist/contracts/particles.d.ts.map +1 -0
- package/dist/contracts/particles.js +15 -0
- package/dist/contracts/particles.js.map +1 -0
- package/dist/contracts/post.d.ts +71 -0
- package/dist/contracts/post.d.ts.map +1 -0
- package/dist/contracts/post.js +28 -0
- package/dist/contracts/post.js.map +1 -0
- package/dist/contracts/program.d.ts +158 -0
- package/dist/contracts/program.d.ts.map +1 -0
- package/dist/contracts/program.js +128 -0
- package/dist/contracts/program.js.map +1 -0
- package/dist/contracts/quality.d.ts +93 -0
- package/dist/contracts/quality.d.ts.map +1 -0
- package/dist/contracts/quality.js +149 -0
- package/dist/contracts/quality.js.map +1 -0
- package/dist/contracts/renderItem.d.ts +58 -0
- package/dist/contracts/renderItem.d.ts.map +1 -0
- package/dist/contracts/renderItem.js +8 -0
- package/dist/contracts/renderItem.js.map +1 -0
- package/dist/contracts/renderSource.d.ts +63 -0
- package/dist/contracts/renderSource.d.ts.map +1 -0
- package/dist/contracts/renderSource.js +7 -0
- package/dist/contracts/renderSource.js.map +1 -0
- package/dist/contracts/rendererFactory.d.ts +42 -0
- package/dist/contracts/rendererFactory.d.ts.map +1 -0
- package/dist/contracts/rendererFactory.js +32 -0
- package/dist/contracts/rendererFactory.js.map +1 -0
- package/dist/contracts/sampling.d.ts +23 -0
- package/dist/contracts/sampling.d.ts.map +1 -0
- package/dist/contracts/sampling.js +17 -0
- package/dist/contracts/sampling.js.map +1 -0
- package/dist/contracts/shadows.d.ts +53 -0
- package/dist/contracts/shadows.d.ts.map +1 -0
- package/dist/contracts/shadows.js +66 -0
- package/dist/contracts/shadows.js.map +1 -0
- package/dist/contracts/testing/ChunkHarness.d.ts +18 -0
- package/dist/contracts/testing/ChunkHarness.d.ts.map +1 -0
- package/dist/contracts/testing/ChunkHarness.js +68 -0
- package/dist/contracts/testing/ChunkHarness.js.map +1 -0
- package/dist/contracts/textureFormats.d.ts +18 -0
- package/dist/contracts/textureFormats.d.ts.map +1 -0
- package/dist/contracts/textureFormats.js +13 -0
- package/dist/contracts/textureFormats.js.map +1 -0
- package/dist/contracts/velocity.d.ts +37 -0
- package/dist/contracts/velocity.d.ts.map +1 -0
- package/dist/contracts/velocity.js +22 -0
- package/dist/contracts/velocity.js.map +1 -0
- package/dist/effects/GPUParticleBackend.d.ts +4 -2
- package/dist/effects/GPUParticleBackend.d.ts.map +1 -1
- package/dist/effects/GPUParticleBackend.js +20 -2
- package/dist/effects/GPUParticleBackend.js.map +1 -1
- package/dist/effects/ResidentGPUParticleRenderer.d.ts +158 -0
- package/dist/effects/ResidentGPUParticleRenderer.d.ts.map +1 -0
- package/dist/effects/ResidentGPUParticleRenderer.js +576 -0
- package/dist/effects/ResidentGPUParticleRenderer.js.map +1 -0
- package/dist/environment/EnvUniforms.d.ts +42 -0
- package/dist/environment/EnvUniforms.d.ts.map +1 -0
- package/dist/environment/EnvUniforms.js +54 -0
- package/dist/environment/EnvUniforms.js.map +1 -0
- package/dist/environment/EnvironmentCache.d.ts +83 -0
- package/dist/environment/EnvironmentCache.d.ts.map +1 -0
- package/dist/environment/EnvironmentCache.js +205 -0
- package/dist/environment/EnvironmentCache.js.map +1 -0
- package/dist/environment/EnvironmentProbeFactory.d.ts +41 -0
- package/dist/environment/EnvironmentProbeFactory.d.ts.map +1 -0
- package/dist/environment/EnvironmentProbeFactory.js +52 -0
- package/dist/environment/EnvironmentProbeFactory.js.map +1 -0
- package/dist/environment/GPUPMREMGenerator.d.ts +44 -0
- package/dist/environment/GPUPMREMGenerator.d.ts.map +1 -0
- package/dist/environment/GPUPMREMGenerator.js +98 -0
- package/dist/environment/GPUPMREMGenerator.js.map +1 -0
- package/dist/environment/HdrEquirect.d.ts +28 -0
- package/dist/environment/HdrEquirect.d.ts.map +1 -0
- package/dist/environment/HdrEquirect.js +205 -0
- package/dist/environment/HdrEquirect.js.map +1 -0
- package/dist/environment/LightingSamplerBudget.d.ts +20 -0
- package/dist/environment/LightingSamplerBudget.d.ts.map +1 -0
- package/dist/environment/LightingSamplerBudget.js +94 -0
- package/dist/environment/LightingSamplerBudget.js.map +1 -0
- package/dist/environment/Prd02BackgroundShaderLibrary.d.ts +10 -0
- package/dist/environment/Prd02BackgroundShaderLibrary.d.ts.map +1 -0
- package/dist/environment/Prd02BackgroundShaderLibrary.js +100 -0
- package/dist/environment/Prd02BackgroundShaderLibrary.js.map +1 -0
- package/dist/environment/Rgb9e5Cube.d.ts +25 -0
- package/dist/environment/Rgb9e5Cube.d.ts.map +1 -0
- package/dist/environment/Rgb9e5Cube.js +103 -0
- package/dist/environment/Rgb9e5Cube.js.map +1 -0
- package/dist/environment/RoomEnvironmentScene.d.ts +57 -0
- package/dist/environment/RoomEnvironmentScene.d.ts.map +1 -0
- package/dist/environment/RoomEnvironmentScene.js +165 -0
- package/dist/environment/RoomEnvironmentScene.js.map +1 -0
- package/dist/environment/SphericalHarmonics.d.ts +32 -0
- package/dist/environment/SphericalHarmonics.d.ts.map +1 -0
- package/dist/environment/SphericalHarmonics.js +155 -0
- package/dist/environment/SphericalHarmonics.js.map +1 -0
- package/dist/environment/probeBuild.d.ts +97 -0
- package/dist/environment/probeBuild.d.ts.map +1 -0
- package/dist/environment/probeBuild.js +406 -0
- package/dist/environment/probeBuild.js.map +1 -0
- package/dist/environment/workers/cpuPrefilter.d.ts +58 -0
- package/dist/environment/workers/cpuPrefilter.d.ts.map +1 -0
- package/dist/environment/workers/cpuPrefilter.js +288 -0
- package/dist/environment/workers/cpuPrefilter.js.map +1 -0
- package/dist/extension-scalar-atlas.d.ts +3 -0
- package/dist/extension-scalar-atlas.d.ts.map +1 -0
- package/dist/extension-scalar-atlas.js +2 -0
- package/dist/extension-scalar-atlas.js.map +1 -0
- package/dist/forward/Deform.d.ts +56 -0
- package/dist/forward/Deform.d.ts.map +1 -0
- package/dist/forward/Deform.js +517 -0
- package/dist/forward/Deform.js.map +1 -0
- package/dist/forward/DrawSubmit.d.ts +32 -0
- package/dist/forward/DrawSubmit.d.ts.map +1 -0
- package/dist/forward/DrawSubmit.js +75 -0
- package/dist/forward/DrawSubmit.js.map +1 -0
- package/dist/forward/Lighting.d.ts +35 -0
- package/dist/forward/Lighting.d.ts.map +1 -0
- package/dist/forward/Lighting.js +477 -0
- package/dist/forward/Lighting.js.map +1 -0
- package/dist/forward/Transmission.d.ts +62 -0
- package/dist/forward/Transmission.d.ts.map +1 -0
- package/dist/forward/Transmission.js +299 -0
- package/dist/forward/Transmission.js.map +1 -0
- package/dist/forward/Velocity.d.ts +47 -0
- package/dist/forward/Velocity.d.ts.map +1 -0
- package/dist/forward/Velocity.js +153 -0
- package/dist/forward/Velocity.js.map +1 -0
- package/dist/forward/transmissionTargetStore.d.ts +21 -0
- package/dist/forward/transmissionTargetStore.d.ts.map +1 -0
- package/dist/forward/transmissionTargetStore.js +8 -0
- package/dist/forward/transmissionTargetStore.js.map +1 -0
- package/dist/geometry/Primitives.d.ts +28 -0
- package/dist/geometry/Primitives.d.ts.map +1 -0
- package/dist/geometry/Primitives.js +110 -0
- package/dist/geometry/Primitives.js.map +1 -0
- package/dist/index.d.ts +140 -57
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +102 -51
- package/dist/index.js.map +1 -1
- package/dist/lanes/index.d.ts +17 -0
- package/dist/lanes/index.d.ts.map +1 -0
- package/dist/lanes/index.js +17 -0
- package/dist/lanes/index.js.map +1 -0
- package/dist/lanes/prd01.d.ts +6 -0
- package/dist/lanes/prd01.d.ts.map +1 -0
- package/dist/lanes/prd01.js +19 -0
- package/dist/lanes/prd01.js.map +1 -0
- package/dist/lanes/prd02.d.ts +62 -0
- package/dist/lanes/prd02.d.ts.map +1 -0
- package/dist/lanes/prd02.js +117 -0
- package/dist/lanes/prd02.js.map +1 -0
- package/dist/lanes/prd03.d.ts +19 -0
- package/dist/lanes/prd03.d.ts.map +1 -0
- package/dist/lanes/prd03.js +55 -0
- package/dist/lanes/prd03.js.map +1 -0
- package/dist/lanes/prd04.d.ts +22 -0
- package/dist/lanes/prd04.d.ts.map +1 -0
- package/dist/lanes/prd04.js +35 -0
- package/dist/lanes/prd04.js.map +1 -0
- package/dist/lanes/prd05.d.ts +4 -0
- package/dist/lanes/prd05.d.ts.map +1 -0
- package/dist/lanes/prd05.js +31 -0
- package/dist/lanes/prd05.js.map +1 -0
- package/dist/lanes/prd06.d.ts +33 -0
- package/dist/lanes/prd06.d.ts.map +1 -0
- package/dist/lanes/prd06.js +217 -0
- package/dist/lanes/prd06.js.map +1 -0
- package/dist/lanes/prd07.d.ts +49 -0
- package/dist/lanes/prd07.d.ts.map +1 -0
- package/dist/lanes/prd07.js +112 -0
- package/dist/lanes/prd07.js.map +1 -0
- package/dist/lanes/prd08.d.ts +2 -0
- package/dist/lanes/prd08.d.ts.map +1 -0
- package/dist/lanes/prd08.js +17 -0
- package/dist/lanes/prd08.js.map +1 -0
- package/dist/lanes/prd09.d.ts +6 -0
- package/dist/lanes/prd09.d.ts.map +1 -0
- package/dist/lanes/prd09.js +6 -0
- package/dist/lanes/prd09.js.map +1 -0
- package/dist/lanes/prd10.d.ts +2 -0
- package/dist/lanes/prd10.d.ts.map +1 -0
- package/dist/lanes/prd10.js +10 -0
- package/dist/lanes/prd10.js.map +1 -0
- package/dist/lanes/prd11.d.ts +61 -0
- package/dist/lanes/prd11.d.ts.map +1 -0
- package/dist/lanes/prd11.js +244 -0
- package/dist/lanes/prd11.js.map +1 -0
- package/dist/lanes/prd12.d.ts +6 -0
- package/dist/lanes/prd12.d.ts.map +1 -0
- package/dist/lanes/prd12.js +6 -0
- package/dist/lanes/prd12.js.map +1 -0
- package/dist/lanes/prd13.d.ts +6 -0
- package/dist/lanes/prd13.d.ts.map +1 -0
- package/dist/lanes/prd13.js +6 -0
- package/dist/lanes/prd13.js.map +1 -0
- package/dist/lanes/prd14.d.ts +6 -0
- package/dist/lanes/prd14.d.ts.map +1 -0
- package/dist/lanes/prd14.js +6 -0
- package/dist/lanes/prd14.js.map +1 -0
- package/dist/lanes/prd15.d.ts +6 -0
- package/dist/lanes/prd15.d.ts.map +1 -0
- package/dist/lanes/prd15.js +6 -0
- package/dist/lanes/prd15.js.map +1 -0
- package/dist/lean/LeanProductionRenderer.d.ts.map +1 -1
- package/dist/lean/LeanProductionRenderer.js +2 -2
- package/dist/lean/LeanProductionRenderer.js.map +1 -1
- package/dist/lean-core-runtime.d.ts +13 -0
- package/dist/lean-core-runtime.d.ts.map +1 -0
- package/dist/lean-core-runtime.js +10 -0
- package/dist/lean-core-runtime.js.map +1 -0
- package/dist/materials/PhysicalFeatures.d.ts +71 -0
- package/dist/materials/PhysicalFeatures.d.ts.map +1 -0
- package/dist/materials/PhysicalFeatures.js +255 -0
- package/dist/materials/PhysicalFeatures.js.map +1 -0
- package/dist/materials/PhysicalMaterial.d.ts +85 -0
- package/dist/materials/PhysicalMaterial.d.ts.map +1 -1
- package/dist/materials/PhysicalMaterial.js +21 -0
- package/dist/materials/PhysicalMaterial.js.map +1 -1
- package/dist/materials/features.d.ts +47 -0
- package/dist/materials/features.d.ts.map +1 -0
- package/dist/materials/features.js +282 -0
- package/dist/materials/features.js.map +1 -0
- package/dist/materials/lobes.d.ts +3 -0
- package/dist/materials/lobes.d.ts.map +1 -0
- package/dist/materials/lobes.js +225 -0
- package/dist/materials/lobes.js.map +1 -0
- package/dist/output/HdrTarget.d.ts +27 -0
- package/dist/output/HdrTarget.d.ts.map +1 -0
- package/dist/output/HdrTarget.js +48 -0
- package/dist/output/HdrTarget.js.map +1 -0
- package/dist/output/OutputPass.d.ts +28 -0
- package/dist/output/OutputPass.d.ts.map +1 -0
- package/dist/output/OutputPass.js +142 -0
- package/dist/output/OutputPass.js.map +1 -0
- package/dist/output/ToneMappingOperators.glsl.d.ts +22 -0
- package/dist/output/ToneMappingOperators.glsl.d.ts.map +1 -0
- package/dist/output/ToneMappingOperators.glsl.js +217 -0
- package/dist/output/ToneMappingOperators.glsl.js.map +1 -0
- package/dist/passes/ContactShadowPass.d.ts +57 -0
- package/dist/passes/ContactShadowPass.d.ts.map +1 -0
- package/dist/passes/ContactShadowPass.js +151 -0
- package/dist/passes/ContactShadowPass.js.map +1 -0
- package/dist/passes/Prd02ContactShadowsContributor.d.ts +16 -0
- package/dist/passes/Prd02ContactShadowsContributor.d.ts.map +1 -0
- package/dist/passes/Prd02ContactShadowsContributor.js +133 -0
- package/dist/passes/Prd02ContactShadowsContributor.js.map +1 -0
- package/dist/passes/Prd02SubFlags.d.ts +22 -0
- package/dist/passes/Prd02SubFlags.d.ts.map +1 -0
- package/dist/passes/Prd02SubFlags.js +32 -0
- package/dist/passes/Prd02SubFlags.js.map +1 -0
- package/dist/performance/BVH.d.ts +46 -0
- package/dist/performance/BVH.d.ts.map +1 -1
- package/dist/performance/BVH.js +212 -0
- package/dist/performance/BVH.js.map +1 -1
- package/dist/performance/Batcher.d.ts +11 -0
- package/dist/performance/Batcher.d.ts.map +1 -1
- package/dist/performance/Batcher.js +10 -0
- package/dist/performance/Batcher.js.map +1 -1
- package/dist/performance/FrustumCuller.d.ts +29 -0
- package/dist/performance/FrustumCuller.d.ts.map +1 -1
- package/dist/performance/FrustumCuller.js +78 -1
- package/dist/performance/FrustumCuller.js.map +1 -1
- package/dist/performance/LOD.d.ts +6 -0
- package/dist/performance/LOD.d.ts.map +1 -1
- package/dist/performance/LOD.js +12 -0
- package/dist/performance/LOD.js.map +1 -1
- package/dist/performance/RenderItemSorting.d.ts +2 -0
- package/dist/performance/RenderItemSorting.d.ts.map +1 -1
- package/dist/performance/RenderItemSorting.js +5 -1
- package/dist/performance/RenderItemSorting.js.map +1 -1
- package/dist/post/CubeLut.d.ts +15 -0
- package/dist/post/CubeLut.d.ts.map +1 -0
- package/dist/post/CubeLut.js +86 -0
- package/dist/post/CubeLut.js.map +1 -0
- package/dist/post/DisplayLutCache.d.ts +31 -0
- package/dist/post/DisplayLutCache.d.ts.map +1 -0
- package/dist/post/DisplayLutCache.js +44 -0
- package/dist/post/DisplayLutCache.js.map +1 -0
- package/dist/post/PostAntiAlias.d.ts +49 -0
- package/dist/post/PostAntiAlias.d.ts.map +1 -0
- package/dist/post/PostAntiAlias.js +75 -0
- package/dist/post/PostAntiAlias.js.map +1 -0
- package/dist/post/PostGraph.d.ts +206 -0
- package/dist/post/PostGraph.d.ts.map +1 -0
- package/dist/post/PostGraph.js +234 -0
- package/dist/post/PostGraph.js.map +1 -0
- package/dist/post/PostQualityTiers.d.ts +95 -0
- package/dist/post/PostQualityTiers.d.ts.map +1 -0
- package/dist/post/PostQualityTiers.js +62 -0
- package/dist/post/PostQualityTiers.js.map +1 -0
- package/dist/post/PostResources.d.ts +49 -0
- package/dist/post/PostResources.d.ts.map +1 -0
- package/dist/post/PostResources.js +119 -0
- package/dist/post/PostResources.js.map +1 -0
- package/dist/post/PostTimer.d.ts +37 -0
- package/dist/post/PostTimer.d.ts.map +1 -0
- package/dist/post/PostTimer.js +88 -0
- package/dist/post/PostTimer.js.map +1 -0
- package/dist/post/ScreenFeelPass.d.ts +83 -0
- package/dist/post/ScreenFeelPass.d.ts.map +1 -0
- package/dist/post/ScreenFeelPass.js +197 -0
- package/dist/post/ScreenFeelPass.js.map +1 -0
- package/dist/post/ToneOperators.d.ts +42 -0
- package/dist/post/ToneOperators.d.ts.map +1 -0
- package/dist/post/ToneOperators.js +179 -0
- package/dist/post/ToneOperators.js.map +1 -0
- package/dist/post/chunks/indirectFraction.glsl.d.ts +50 -0
- package/dist/post/chunks/indirectFraction.glsl.d.ts.map +1 -0
- package/dist/post/chunks/indirectFraction.glsl.js +82 -0
- package/dist/post/chunks/indirectFraction.glsl.js.map +1 -0
- package/dist/post/chunks/velocity.glsl.d.ts +35 -0
- package/dist/post/chunks/velocity.glsl.d.ts.map +1 -0
- package/dist/post/chunks/velocity.glsl.js +86 -0
- package/dist/post/chunks/velocity.glsl.js.map +1 -0
- package/dist/post/shaders/bloom.glsl.d.ts +21 -0
- package/dist/post/shaders/bloom.glsl.d.ts.map +1 -0
- package/dist/post/shaders/bloom.glsl.js +120 -0
- package/dist/post/shaders/bloom.glsl.js.map +1 -0
- package/dist/post/shaders/bloom.wgsl.d.ts +10 -0
- package/dist/post/shaders/bloom.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/bloom.wgsl.js +121 -0
- package/dist/post/shaders/bloom.wgsl.js.map +1 -0
- package/dist/post/shaders/common.glsl.d.ts +11 -0
- package/dist/post/shaders/common.glsl.d.ts.map +1 -0
- package/dist/post/shaders/common.glsl.js +34 -0
- package/dist/post/shaders/common.glsl.js.map +1 -0
- package/dist/post/shaders/common.wgsl.d.ts +25 -0
- package/dist/post/shaders/common.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/common.wgsl.js +48 -0
- package/dist/post/shaders/common.wgsl.js.map +1 -0
- package/dist/post/shaders/composite.glsl.d.ts +25 -0
- package/dist/post/shaders/composite.glsl.d.ts.map +1 -0
- package/dist/post/shaders/composite.glsl.js +96 -0
- package/dist/post/shaders/composite.glsl.js.map +1 -0
- package/dist/post/shaders/composite.wgsl.d.ts +10 -0
- package/dist/post/shaders/composite.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/composite.wgsl.js +92 -0
- package/dist/post/shaders/composite.wgsl.js.map +1 -0
- package/dist/post/shaders/depthDownsample.glsl.d.ts +20 -0
- package/dist/post/shaders/depthDownsample.glsl.d.ts.map +1 -0
- package/dist/post/shaders/depthDownsample.glsl.js +78 -0
- package/dist/post/shaders/depthDownsample.glsl.js.map +1 -0
- package/dist/post/shaders/depthDownsample.wgsl.d.ts +17 -0
- package/dist/post/shaders/depthDownsample.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/depthDownsample.wgsl.js +87 -0
- package/dist/post/shaders/depthDownsample.wgsl.js.map +1 -0
- package/dist/post/shaders/displayGrade.glsl.d.ts +18 -0
- package/dist/post/shaders/displayGrade.glsl.d.ts.map +1 -0
- package/dist/post/shaders/displayGrade.glsl.js +80 -0
- package/dist/post/shaders/displayGrade.glsl.js.map +1 -0
- package/dist/post/shaders/displayGrade.wgsl.d.ts +9 -0
- package/dist/post/shaders/displayGrade.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/displayGrade.wgsl.js +75 -0
- package/dist/post/shaders/displayGrade.wgsl.js.map +1 -0
- package/dist/post/shaders/dof.glsl.d.ts +25 -0
- package/dist/post/shaders/dof.glsl.d.ts.map +1 -0
- package/dist/post/shaders/dof.glsl.js +129 -0
- package/dist/post/shaders/dof.glsl.js.map +1 -0
- package/dist/post/shaders/dof.wgsl.d.ts +11 -0
- package/dist/post/shaders/dof.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/dof.wgsl.js +119 -0
- package/dist/post/shaders/dof.wgsl.js.map +1 -0
- package/dist/post/shaders/exposure.glsl.d.ts +43 -0
- package/dist/post/shaders/exposure.glsl.d.ts.map +1 -0
- package/dist/post/shaders/exposure.glsl.js +115 -0
- package/dist/post/shaders/exposure.glsl.js.map +1 -0
- package/dist/post/shaders/exposure.wgsl.d.ts +16 -0
- package/dist/post/shaders/exposure.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/exposure.wgsl.js +97 -0
- package/dist/post/shaders/exposure.wgsl.js.map +1 -0
- package/dist/post/shaders/finalize.glsl.d.ts +17 -0
- package/dist/post/shaders/finalize.glsl.d.ts.map +1 -0
- package/dist/post/shaders/finalize.glsl.js +120 -0
- package/dist/post/shaders/finalize.glsl.js.map +1 -0
- package/dist/post/shaders/finalize.wgsl.d.ts +13 -0
- package/dist/post/shaders/finalize.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/finalize.wgsl.js +124 -0
- package/dist/post/shaders/finalize.wgsl.js.map +1 -0
- package/dist/post/shaders/fxaa.glsl.d.ts +26 -0
- package/dist/post/shaders/fxaa.glsl.d.ts.map +1 -0
- package/dist/post/shaders/fxaa.glsl.js +246 -0
- package/dist/post/shaders/fxaa.glsl.js.map +1 -0
- package/dist/post/shaders/fxaa.wgsl.d.ts +17 -0
- package/dist/post/shaders/fxaa.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/fxaa.wgsl.js +268 -0
- package/dist/post/shaders/fxaa.wgsl.js.map +1 -0
- package/dist/post/shaders/godrays.glsl.d.ts +16 -0
- package/dist/post/shaders/godrays.glsl.d.ts.map +1 -0
- package/dist/post/shaders/godrays.glsl.js +70 -0
- package/dist/post/shaders/godrays.glsl.js.map +1 -0
- package/dist/post/shaders/godrays.wgsl.d.ts +8 -0
- package/dist/post/shaders/godrays.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/godrays.wgsl.js +60 -0
- package/dist/post/shaders/godrays.wgsl.js.map +1 -0
- package/dist/post/shaders/gtao.glsl.d.ts +29 -0
- package/dist/post/shaders/gtao.glsl.d.ts.map +1 -0
- package/dist/post/shaders/gtao.glsl.js +190 -0
- package/dist/post/shaders/gtao.glsl.js.map +1 -0
- package/dist/post/shaders/gtao.wgsl.d.ts +13 -0
- package/dist/post/shaders/gtao.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/gtao.wgsl.js +163 -0
- package/dist/post/shaders/gtao.wgsl.js.map +1 -0
- package/dist/post/shaders/gtaoDenoise.glsl.d.ts +22 -0
- package/dist/post/shaders/gtaoDenoise.glsl.d.ts.map +1 -0
- package/dist/post/shaders/gtaoDenoise.glsl.js +121 -0
- package/dist/post/shaders/gtaoDenoise.glsl.js.map +1 -0
- package/dist/post/shaders/gtaoDenoise.wgsl.d.ts +11 -0
- package/dist/post/shaders/gtaoDenoise.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/gtaoDenoise.wgsl.js +117 -0
- package/dist/post/shaders/gtaoDenoise.wgsl.js.map +1 -0
- package/dist/post/shaders/motionBlur.glsl.d.ts +21 -0
- package/dist/post/shaders/motionBlur.glsl.d.ts.map +1 -0
- package/dist/post/shaders/motionBlur.glsl.js +110 -0
- package/dist/post/shaders/motionBlur.glsl.js.map +1 -0
- package/dist/post/shaders/motionBlur.wgsl.d.ts +10 -0
- package/dist/post/shaders/motionBlur.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/motionBlur.wgsl.js +102 -0
- package/dist/post/shaders/motionBlur.wgsl.js.map +1 -0
- package/dist/post/shaders/smaa.glsl.d.ts +28 -0
- package/dist/post/shaders/smaa.glsl.d.ts.map +1 -0
- package/dist/post/shaders/smaa.glsl.js +354 -0
- package/dist/post/shaders/smaa.glsl.js.map +1 -0
- package/dist/post/shaders/smaa.wgsl.d.ts +20 -0
- package/dist/post/shaders/smaa.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/smaa.wgsl.js +375 -0
- package/dist/post/shaders/smaa.wgsl.js.map +1 -0
- package/dist/post/shaders/taa.glsl.d.ts +23 -0
- package/dist/post/shaders/taa.glsl.d.ts.map +1 -0
- package/dist/post/shaders/taa.glsl.js +169 -0
- package/dist/post/shaders/taa.glsl.js.map +1 -0
- package/dist/post/shaders/taa.wgsl.d.ts +10 -0
- package/dist/post/shaders/taa.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/taa.wgsl.js +185 -0
- package/dist/post/shaders/taa.wgsl.js.map +1 -0
- package/dist/post/shaders/velocityDilate.glsl.d.ts +16 -0
- package/dist/post/shaders/velocityDilate.glsl.d.ts.map +1 -0
- package/dist/post/shaders/velocityDilate.glsl.js +45 -0
- package/dist/post/shaders/velocityDilate.glsl.js.map +1 -0
- package/dist/post/shaders/velocityDilate.wgsl.d.ts +8 -0
- package/dist/post/shaders/velocityDilate.wgsl.d.ts.map +1 -0
- package/dist/post/shaders/velocityDilate.wgsl.js +30 -0
- package/dist/post/shaders/velocityDilate.wgsl.js.map +1 -0
- package/dist/post/smaa/textures.d.ts +17 -0
- package/dist/post/smaa/textures.d.ts.map +1 -0
- package/dist/post/smaa/textures.js +17 -0
- package/dist/post/smaa/textures.js.map +1 -0
- package/dist/post/v2Entry.d.ts +25 -0
- package/dist/post/v2Entry.d.ts.map +1 -0
- package/dist/post/v2Entry.js +28 -0
- package/dist/post/v2Entry.js.map +1 -0
- package/dist/post/v2Stages.d.ts +156 -0
- package/dist/post/v2Stages.d.ts.map +1 -0
- package/dist/post/v2Stages.js +1189 -0
- package/dist/post/v2Stages.js.map +1 -0
- package/dist/postprocess/EffectComposer.d.ts +6 -109
- package/dist/postprocess/EffectComposer.d.ts.map +1 -1
- package/dist/postprocess/EffectComposer.js +6 -246
- package/dist/postprocess/EffectComposer.js.map +1 -1
- package/dist/postprocess/NativeBloomPyramid.d.ts +51 -1
- package/dist/postprocess/NativeBloomPyramid.d.ts.map +1 -1
- package/dist/postprocess/NativeBloomPyramid.js +88 -1
- package/dist/postprocess/NativeBloomPyramid.js.map +1 -1
- package/dist/postprocess/SSAOPass.d.ts +5 -5
- package/dist/postprocess/SSAOPass.d.ts.map +1 -1
- package/dist/postprocess/SSAOPass.js +5 -17
- package/dist/postprocess/SSAOPass.js.map +1 -1
- package/dist/probes/IrradianceVolume.d.ts +45 -0
- package/dist/probes/IrradianceVolume.d.ts.map +1 -0
- package/dist/probes/IrradianceVolume.js +230 -0
- package/dist/probes/IrradianceVolume.js.map +1 -0
- package/dist/probes/LtcLuts.d.ts +30 -0
- package/dist/probes/LtcLuts.d.ts.map +1 -0
- package/dist/probes/LtcLuts.js +120 -0
- package/dist/probes/LtcLuts.js.map +1 -0
- package/dist/probes/Prd02ProbesContributor.d.ts +53 -0
- package/dist/probes/Prd02ProbesContributor.d.ts.map +1 -0
- package/dist/probes/Prd02ProbesContributor.js +241 -0
- package/dist/probes/Prd02ProbesContributor.js.map +1 -0
- package/dist/probes/ProbeBoxProjection.d.ts +53 -0
- package/dist/probes/ProbeBoxProjection.d.ts.map +1 -0
- package/dist/probes/ProbeBoxProjection.js +99 -0
- package/dist/probes/ProbeBoxProjection.js.map +1 -0
- package/dist/probes/ReflectionProbeSystem.d.ts +64 -0
- package/dist/probes/ReflectionProbeSystem.d.ts.map +1 -0
- package/dist/probes/ReflectionProbeSystem.js +157 -0
- package/dist/probes/ReflectionProbeSystem.js.map +1 -0
- package/dist/production-runtime/PBRHDRPipeline.d.ts.map +1 -1
- package/dist/production-runtime/PBRHDRPipeline.js +23 -9
- package/dist/production-runtime/PBRHDRPipeline.js.map +1 -1
- package/dist/production-runtime/ProductionRendererTypes.d.ts +17 -6
- package/dist/production-runtime/ProductionRendererTypes.d.ts.map +1 -1
- package/dist/production-runtime/ProductionRendererTypes.js.map +1 -1
- package/dist/production-runtime/ProductionRuntimeRenderer.d.ts +3 -0
- package/dist/production-runtime/ProductionRuntimeRenderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionRuntimeRenderer.js +8 -1
- package/dist/production-runtime/ProductionRuntimeRenderer.js.map +1 -1
- package/dist/production-runtime/ProductionWebGL2Renderer.d.ts +4 -0
- package/dist/production-runtime/ProductionWebGL2Renderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionWebGL2Renderer.js +15 -0
- package/dist/production-runtime/ProductionWebGL2Renderer.js.map +1 -1
- package/dist/production-runtime/ProductionWebGPURenderer.d.ts +11 -5
- package/dist/production-runtime/ProductionWebGPURenderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionWebGPURenderer.js +38 -47
- package/dist/production-runtime/ProductionWebGPURenderer.js.map +1 -1
- package/dist/production-runtime/backendSelection.d.ts +26 -0
- package/dist/production-runtime/backendSelection.d.ts.map +1 -0
- package/dist/production-runtime/backendSelection.js +46 -0
- package/dist/production-runtime/backendSelection.js.map +1 -0
- package/dist/production-runtime/backends/WebGL2RendererBackend.d.ts +1 -1
- package/dist/production-runtime/backends/WebGL2RendererBackend.d.ts.map +1 -1
- package/dist/production-runtime/backends/WebGL2RendererBackend.js +8 -4
- package/dist/production-runtime/backends/WebGL2RendererBackend.js.map +1 -1
- package/dist/production-runtime/backends/WebGPURendererBackend.d.ts +2 -19
- package/dist/production-runtime/backends/WebGPURendererBackend.d.ts.map +1 -1
- package/dist/production-runtime/backends/WebGPURendererBackend.js +2 -18
- package/dist/production-runtime/backends/WebGPURendererBackend.js.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2Buffer.d.ts +2 -10
- package/dist/production-runtime/backends/webgl2/WebGL2Buffer.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2Buffer.js +2 -7
- package/dist/production-runtime/backends/webgl2/WebGL2Buffer.js.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2Capabilities.d.ts +2 -10
- package/dist/production-runtime/backends/webgl2/WebGL2Capabilities.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2Capabilities.js +2 -7
- package/dist/production-runtime/backends/webgl2/WebGL2Capabilities.js.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2RenderTarget.d.ts +2 -10
- package/dist/production-runtime/backends/webgl2/WebGL2RenderTarget.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2RenderTarget.js +2 -7
- package/dist/production-runtime/backends/webgl2/WebGL2RenderTarget.js.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2Shader.d.ts +2 -10
- package/dist/production-runtime/backends/webgl2/WebGL2Shader.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2Shader.js +2 -7
- package/dist/production-runtime/backends/webgl2/WebGL2Shader.js.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2StateCache.d.ts +1 -0
- package/dist/production-runtime/backends/webgl2/WebGL2StateCache.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2StateCache.js +1 -0
- package/dist/production-runtime/backends/webgl2/WebGL2StateCache.js.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2Texture.d.ts +2 -10
- package/dist/production-runtime/backends/webgl2/WebGL2Texture.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgl2/WebGL2Texture.js +2 -7
- package/dist/production-runtime/backends/webgl2/WebGL2Texture.js.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPUBuffer.d.ts +2 -10
- package/dist/production-runtime/backends/webgpu/WebGPUBuffer.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPUBuffer.js +2 -7
- package/dist/production-runtime/backends/webgpu/WebGPUBuffer.js.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPUCapabilities.d.ts +2 -10
- package/dist/production-runtime/backends/webgpu/WebGPUCapabilities.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPUCapabilities.js +2 -7
- package/dist/production-runtime/backends/webgpu/WebGPUCapabilities.js.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPURenderTarget.d.ts +2 -10
- package/dist/production-runtime/backends/webgpu/WebGPURenderTarget.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPURenderTarget.js +2 -7
- package/dist/production-runtime/backends/webgpu/WebGPURenderTarget.js.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPUShader.d.ts +2 -10
- package/dist/production-runtime/backends/webgpu/WebGPUShader.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPUShader.js +2 -7
- package/dist/production-runtime/backends/webgpu/WebGPUShader.js.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPUTexture.d.ts +2 -10
- package/dist/production-runtime/backends/webgpu/WebGPUTexture.d.ts.map +1 -1
- package/dist/production-runtime/backends/webgpu/WebGPUTexture.js +2 -7
- package/dist/production-runtime/backends/webgpu/WebGPUTexture.js.map +1 -1
- package/dist/production-runtime/framegraph/FrameGraph.d.ts +4 -2
- package/dist/production-runtime/framegraph/FrameGraph.d.ts.map +1 -1
- package/dist/production-runtime/framegraph/FrameGraph.js +62 -4
- package/dist/production-runtime/framegraph/FrameGraph.js.map +1 -1
- package/dist/production-runtime/framegraph/NativeFrameGraphBindings.d.ts +32 -0
- package/dist/production-runtime/framegraph/NativeFrameGraphBindings.d.ts.map +1 -0
- package/dist/production-runtime/framegraph/NativeFrameGraphBindings.js +111 -0
- package/dist/production-runtime/framegraph/NativeFrameGraphBindings.js.map +1 -0
- package/dist/production-runtime/framegraph/RenderPass.d.ts +23 -0
- package/dist/production-runtime/framegraph/RenderPass.d.ts.map +1 -1
- package/dist/production-runtime/framegraph/RenderPass.js +87 -1
- package/dist/production-runtime/framegraph/RenderPass.js.map +1 -1
- package/dist/production-runtime/index.d.ts +8 -6
- package/dist/production-runtime/index.d.ts.map +1 -1
- package/dist/production-runtime/index.js +10 -3
- package/dist/production-runtime/index.js.map +1 -1
- package/dist/production-runtime/materials/GLTFMaterialAdapter.d.ts +12 -13
- package/dist/production-runtime/materials/GLTFMaterialAdapter.d.ts.map +1 -1
- package/dist/production-runtime/materials/GLTFMaterialAdapter.js +10 -4
- package/dist/production-runtime/materials/GLTFMaterialAdapter.js.map +1 -1
- package/dist/production-runtime/materials/GLTFPBRMaterialAdapter.d.ts +9 -2
- package/dist/production-runtime/materials/GLTFPBRMaterialAdapter.d.ts.map +1 -1
- package/dist/production-runtime/materials/GLTFPBRMaterialAdapter.js +7 -1
- package/dist/production-runtime/materials/GLTFPBRMaterialAdapter.js.map +1 -1
- package/dist/production-runtime/materials/MaterialCompiler.d.ts +10 -8
- package/dist/production-runtime/materials/MaterialCompiler.d.ts.map +1 -1
- package/dist/production-runtime/materials/MaterialCompiler.js +9 -4
- package/dist/production-runtime/materials/MaterialCompiler.js.map +1 -1
- package/dist/production-runtime/materials/PBRShaderFeatures.d.ts.map +1 -1
- package/dist/production-runtime/materials/PBRShaderFeatures.js +30 -1
- package/dist/production-runtime/materials/PBRShaderFeatures.js.map +1 -1
- package/dist/production-runtime/passes/DepthPrepass.d.ts +4 -12
- package/dist/production-runtime/passes/DepthPrepass.d.ts.map +1 -1
- package/dist/production-runtime/passes/DepthPrepass.js +3 -11
- package/dist/production-runtime/passes/DepthPrepass.js.map +1 -1
- package/dist/production-runtime/passes/FramegraphTopology.js +1 -1
- package/dist/production-runtime/passes/FramegraphTopology.js.map +1 -1
- package/dist/production-runtime/passes/OpaquePass.d.ts +3 -8
- package/dist/production-runtime/passes/OpaquePass.d.ts.map +1 -1
- package/dist/production-runtime/passes/OpaquePass.js +3 -1
- package/dist/production-runtime/passes/OpaquePass.js.map +1 -1
- package/dist/production-runtime/passes/ShadowPass.d.ts +3 -8
- package/dist/production-runtime/passes/ShadowPass.d.ts.map +1 -1
- package/dist/production-runtime/passes/ShadowPass.js +2 -0
- package/dist/production-runtime/passes/ShadowPass.js.map +1 -1
- package/dist/production-runtime/passes/SkyboxPass.d.ts +3 -7
- package/dist/production-runtime/passes/SkyboxPass.d.ts.map +1 -1
- package/dist/production-runtime/passes/SkyboxPass.js +2 -0
- package/dist/production-runtime/passes/SkyboxPass.js.map +1 -1
- package/dist/production-runtime/passes/ToneMappingPass.d.ts +7 -10
- package/dist/production-runtime/passes/ToneMappingPass.d.ts.map +1 -1
- package/dist/production-runtime/passes/ToneMappingPass.js +9 -0
- package/dist/production-runtime/passes/ToneMappingPass.js.map +1 -1
- package/dist/production-runtime/passes/TransparentPass.d.ts +4 -9
- package/dist/production-runtime/passes/TransparentPass.d.ts.map +1 -1
- package/dist/production-runtime/passes/TransparentPass.js +6 -1
- package/dist/production-runtime/passes/TransparentPass.js.map +1 -1
- package/dist/production-runtime/renderProofs.d.ts +54 -0
- package/dist/production-runtime/renderProofs.d.ts.map +1 -0
- package/dist/production-runtime/renderProofs.js +245 -0
- package/dist/production-runtime/renderProofs.js.map +1 -0
- package/dist/program/DFGLut.d.ts +23 -0
- package/dist/program/DFGLut.d.ts.map +1 -0
- package/dist/program/DFGLut.js +58 -0
- package/dist/program/DFGLut.js.map +1 -0
- package/dist/program/DFGLutData.d.ts +35 -0
- package/dist/program/DFGLutData.d.ts.map +1 -0
- package/dist/program/DFGLutData.js +52 -0
- package/dist/program/DFGLutData.js.map +1 -0
- package/dist/program/FeatureSelect.d.ts +35 -0
- package/dist/program/FeatureSelect.d.ts.map +1 -0
- package/dist/program/FeatureSelect.js +88 -0
- package/dist/program/FeatureSelect.js.map +1 -0
- package/dist/program/MaterialFeatures.d.ts +66 -0
- package/dist/program/MaterialFeatures.d.ts.map +1 -0
- package/dist/program/MaterialFeatures.js +242 -0
- package/dist/program/MaterialFeatures.js.map +1 -0
- package/dist/program/ProgramCache.d.ts +83 -0
- package/dist/program/ProgramCache.d.ts.map +1 -0
- package/dist/program/ProgramCache.js +194 -0
- package/dist/program/ProgramCache.js.map +1 -0
- package/dist/program/ProgramFeatures.d.ts +21 -0
- package/dist/program/ProgramFeatures.d.ts.map +1 -0
- package/dist/program/ProgramFeatures.js +95 -0
- package/dist/program/ProgramFeatures.js.map +1 -0
- package/dist/program/ProgramGenerator.d.ts +60 -0
- package/dist/program/ProgramGenerator.d.ts.map +1 -0
- package/dist/program/ProgramGenerator.js +760 -0
- package/dist/program/ProgramGenerator.js.map +1 -0
- package/dist/program/ProgramKey.d.ts +10 -0
- package/dist/program/ProgramKey.d.ts.map +1 -0
- package/dist/program/ProgramKey.js +13 -0
- package/dist/program/ProgramKey.js.map +1 -0
- package/dist/program/ProgramWarmup.d.ts +37 -0
- package/dist/program/ProgramWarmup.d.ts.map +1 -0
- package/dist/program/ProgramWarmup.js +68 -0
- package/dist/program/ProgramWarmup.js.map +1 -0
- package/dist/program/UniformLayout.d.ts +40 -0
- package/dist/program/UniformLayout.d.ts.map +1 -0
- package/dist/program/UniformLayout.js +105 -0
- package/dist/program/UniformLayout.js.map +1 -0
- package/dist/program/chunks/alpha.glsl.d.ts +7 -0
- package/dist/program/chunks/alpha.glsl.d.ts.map +1 -0
- package/dist/program/chunks/alpha.glsl.js +17 -0
- package/dist/program/chunks/alpha.glsl.js.map +1 -0
- package/dist/program/chunks/brdf.glsl.d.ts +12 -0
- package/dist/program/chunks/brdf.glsl.d.ts.map +1 -0
- package/dist/program/chunks/brdf.glsl.js +144 -0
- package/dist/program/chunks/brdf.glsl.js.map +1 -0
- package/dist/program/chunks/colorspace.glsl.d.ts +8 -0
- package/dist/program/chunks/colorspace.glsl.d.ts.map +1 -0
- package/dist/program/chunks/colorspace.glsl.js +16 -0
- package/dist/program/chunks/colorspace.glsl.js.map +1 -0
- package/dist/program/chunks/common.glsl.d.ts +7 -0
- package/dist/program/chunks/common.glsl.d.ts.map +1 -0
- package/dist/program/chunks/common.glsl.js +25 -0
- package/dist/program/chunks/common.glsl.js.map +1 -0
- package/dist/program/chunks/depth.glsl.d.ts +9 -0
- package/dist/program/chunks/depth.glsl.d.ts.map +1 -0
- package/dist/program/chunks/depth.glsl.js +18 -0
- package/dist/program/chunks/depth.glsl.js.map +1 -0
- package/dist/program/chunks/drawId.wgsl.d.ts +9 -0
- package/dist/program/chunks/drawId.wgsl.d.ts.map +1 -0
- package/dist/program/chunks/drawId.wgsl.js +29 -0
- package/dist/program/chunks/drawId.wgsl.js.map +1 -0
- package/dist/program/chunks/fog_default.glsl.d.ts +8 -0
- package/dist/program/chunks/fog_default.glsl.d.ts.map +1 -0
- package/dist/program/chunks/fog_default.glsl.js +31 -0
- package/dist/program/chunks/fog_default.glsl.js.map +1 -0
- package/dist/program/chunks/indirect_default.glsl.d.ts +29 -0
- package/dist/program/chunks/indirect_default.glsl.d.ts.map +1 -0
- package/dist/program/chunks/indirect_default.glsl.js +113 -0
- package/dist/program/chunks/indirect_default.glsl.js.map +1 -0
- package/dist/program/chunks/instanceEmissive.wgsl.d.ts +10 -0
- package/dist/program/chunks/instanceEmissive.wgsl.d.ts.map +1 -0
- package/dist/program/chunks/instanceEmissive.wgsl.js +21 -0
- package/dist/program/chunks/instanceEmissive.wgsl.js.map +1 -0
- package/dist/program/chunks/instancing.glsl.d.ts +8 -0
- package/dist/program/chunks/instancing.glsl.d.ts.map +1 -0
- package/dist/program/chunks/instancing.glsl.js +25 -0
- package/dist/program/chunks/instancing.glsl.js.map +1 -0
- package/dist/program/chunks/lights_legacy.glsl.d.ts +15 -0
- package/dist/program/chunks/lights_legacy.glsl.d.ts.map +1 -0
- package/dist/program/chunks/lights_legacy.glsl.js +95 -0
- package/dist/program/chunks/lights_legacy.glsl.js.map +1 -0
- package/dist/program/chunks/manifest.d.ts +42 -0
- package/dist/program/chunks/manifest.d.ts.map +1 -0
- package/dist/program/chunks/manifest.js +48 -0
- package/dist/program/chunks/manifest.js.map +1 -0
- package/dist/program/chunks/normal.glsl.d.ts +8 -0
- package/dist/program/chunks/normal.glsl.d.ts.map +1 -0
- package/dist/program/chunks/normal.glsl.js +34 -0
- package/dist/program/chunks/normal.glsl.js.map +1 -0
- package/dist/program/chunks/shadow_forward.glsl.d.ts +23 -0
- package/dist/program/chunks/shadow_forward.glsl.d.ts.map +1 -0
- package/dist/program/chunks/shadow_forward.glsl.js +73 -0
- package/dist/program/chunks/shadow_forward.glsl.js.map +1 -0
- package/dist/quality/DeviceClasses.d.ts +31 -0
- package/dist/quality/DeviceClasses.d.ts.map +1 -0
- package/dist/quality/DeviceClasses.js +83 -0
- package/dist/quality/DeviceClasses.js.map +1 -0
- package/dist/quality/DeviceProbe.d.ts +42 -0
- package/dist/quality/DeviceProbe.d.ts.map +1 -0
- package/dist/quality/DeviceProbe.js +83 -0
- package/dist/quality/DeviceProbe.js.map +1 -0
- package/dist/quality/FrameStats.d.ts +62 -0
- package/dist/quality/FrameStats.d.ts.map +1 -0
- package/dist/quality/FrameStats.js +220 -0
- package/dist/quality/FrameStats.js.map +1 -0
- package/dist/quality/PostprocessGuard.d.ts +49 -0
- package/dist/quality/PostprocessGuard.d.ts.map +1 -0
- package/dist/quality/PostprocessGuard.js +92 -0
- package/dist/quality/PostprocessGuard.js.map +1 -0
- package/dist/quality/QualityController.d.ts +93 -0
- package/dist/quality/QualityController.d.ts.map +1 -0
- package/dist/quality/QualityController.js +248 -0
- package/dist/quality/QualityController.js.map +1 -0
- package/dist/quality/QualityGovernor.d.ts +78 -0
- package/dist/quality/QualityGovernor.d.ts.map +1 -0
- package/dist/quality/QualityGovernor.js +170 -0
- package/dist/quality/QualityGovernor.js.map +1 -0
- package/dist/quality/QualityTier.d.ts +17 -0
- package/dist/quality/QualityTier.d.ts.map +1 -0
- package/dist/quality/QualityTier.js +23 -0
- package/dist/quality/QualityTier.js.map +1 -0
- package/dist/quality/RenderScaleController.d.ts +35 -0
- package/dist/quality/RenderScaleController.d.ts.map +1 -0
- package/dist/quality/RenderScaleController.js +57 -0
- package/dist/quality/RenderScaleController.js.map +1 -0
- package/dist/quality/RetentionPolicy.d.ts +11 -0
- package/dist/quality/RetentionPolicy.d.ts.map +1 -0
- package/dist/quality/RetentionPolicy.js +12 -0
- package/dist/quality/RetentionPolicy.js.map +1 -0
- package/dist/quality/TierResolver.d.ts +52 -0
- package/dist/quality/TierResolver.d.ts.map +1 -0
- package/dist/quality/TierResolver.js +155 -0
- package/dist/quality/TierResolver.js.map +1 -0
- package/dist/quality/liveTier.d.ts +23 -0
- package/dist/quality/liveTier.d.ts.map +1 -0
- package/dist/quality/liveTier.js +16 -0
- package/dist/quality/liveTier.js.map +1 -0
- package/dist/reference/BloomPass.d.ts +10 -0
- package/dist/reference/BloomPass.d.ts.map +1 -0
- package/dist/reference/BloomPass.js +18 -0
- package/dist/reference/BloomPass.js.map +1 -0
- package/dist/reference/DepthHazePass.d.ts +12 -0
- package/dist/reference/DepthHazePass.d.ts.map +1 -0
- package/dist/reference/DepthHazePass.js +20 -0
- package/dist/reference/DepthHazePass.js.map +1 -0
- package/dist/reference/EffectComposer.d.ts +110 -0
- package/dist/reference/EffectComposer.d.ts.map +1 -0
- package/dist/reference/EffectComposer.js +247 -0
- package/dist/reference/EffectComposer.js.map +1 -0
- package/dist/reference/FilmGrainPass.d.ts +9 -0
- package/dist/reference/FilmGrainPass.d.ts.map +1 -0
- package/dist/reference/FilmGrainPass.js +17 -0
- package/dist/reference/FilmGrainPass.js.map +1 -0
- package/dist/reference/PostProcessPass.d.ts +511 -0
- package/dist/reference/PostProcessPass.d.ts.map +1 -0
- package/dist/reference/PostProcessPass.js +2020 -0
- package/dist/reference/PostProcessPass.js.map +1 -0
- package/dist/reference/SSAOPass.d.ts +6 -0
- package/dist/reference/SSAOPass.d.ts.map +1 -0
- package/dist/reference/SSAOPass.js +18 -0
- package/dist/reference/SSAOPass.js.map +1 -0
- package/dist/reference/VignettePass.d.ts +10 -0
- package/dist/reference/VignettePass.d.ts.map +1 -0
- package/dist/reference/VignettePass.js +17 -0
- package/dist/reference/VignettePass.js.map +1 -0
- package/dist/reference/index.d.ts +15 -0
- package/dist/reference/index.d.ts.map +1 -0
- package/dist/reference/index.js +15 -0
- package/dist/reference/index.js.map +1 -0
- package/dist/reflection-surfaces.d.ts +5 -0
- package/dist/reflection-surfaces.d.ts.map +1 -0
- package/dist/reflection-surfaces.js +3 -0
- package/dist/reflection-surfaces.js.map +1 -0
- package/dist/renderer/Background.d.ts +49 -0
- package/dist/renderer/Background.d.ts.map +1 -0
- package/dist/renderer/Background.js +259 -0
- package/dist/renderer/Background.js.map +1 -0
- package/dist/renderer/CullingBatching.d.ts +55 -0
- package/dist/renderer/CullingBatching.d.ts.map +1 -0
- package/dist/renderer/CullingBatching.js +362 -0
- package/dist/renderer/CullingBatching.js.map +1 -0
- package/dist/renderer/DeviceLifecycle.d.ts +29 -0
- package/dist/renderer/DeviceLifecycle.d.ts.map +1 -0
- package/dist/renderer/DeviceLifecycle.js +48 -0
- package/dist/renderer/DeviceLifecycle.js.map +1 -0
- package/dist/renderer/FrameGraph.d.ts +96 -0
- package/dist/renderer/FrameGraph.d.ts.map +1 -0
- package/dist/renderer/FrameGraph.js +301 -0
- package/dist/renderer/FrameGraph.js.map +1 -0
- package/dist/renderer/InterleavedTransparentPass.d.ts +31 -0
- package/dist/renderer/InterleavedTransparentPass.d.ts.map +1 -0
- package/dist/renderer/InterleavedTransparentPass.js +65 -0
- package/dist/renderer/InterleavedTransparentPass.js.map +1 -0
- package/dist/renderer/PixelRatio.d.ts +64 -0
- package/dist/renderer/PixelRatio.d.ts.map +1 -0
- package/dist/renderer/PixelRatio.js +81 -0
- package/dist/renderer/PixelRatio.js.map +1 -0
- package/dist/renderer/PostprocessExecution.d.ts +82 -0
- package/dist/renderer/PostprocessExecution.d.ts.map +1 -0
- package/dist/renderer/PostprocessExecution.js +741 -0
- package/dist/renderer/PostprocessExecution.js.map +1 -0
- package/dist/renderer/Prd06ShaderWarmup.d.ts +32 -0
- package/dist/renderer/Prd06ShaderWarmup.d.ts.map +1 -0
- package/dist/renderer/Prd06ShaderWarmup.js +45 -0
- package/dist/renderer/Prd06ShaderWarmup.js.map +1 -0
- package/dist/renderer/RenderShared.d.ts +11 -0
- package/dist/renderer/RenderShared.d.ts.map +1 -0
- package/dist/renderer/RenderShared.js +47 -0
- package/dist/renderer/RenderShared.js.map +1 -0
- package/dist/renderer/RendererFactory.d.ts +3 -0
- package/dist/renderer/RendererFactory.d.ts.map +1 -0
- package/dist/renderer/RendererFactory.js +19 -0
- package/dist/renderer/RendererFactory.js.map +1 -0
- package/dist/renderer/RendererHost.d.ts +25 -0
- package/dist/renderer/RendererHost.d.ts.map +1 -0
- package/dist/renderer/RendererHost.js +4 -0
- package/dist/renderer/RendererHost.js.map +1 -0
- package/dist/renderer/SceneDepthCopyPass.d.ts +50 -0
- package/dist/renderer/SceneDepthCopyPass.d.ts.map +1 -0
- package/dist/renderer/SceneDepthCopyPass.js +124 -0
- package/dist/renderer/SceneDepthCopyPass.js.map +1 -0
- package/dist/renderer/ShadowOrchestration.d.ts +32 -0
- package/dist/renderer/ShadowOrchestration.d.ts.map +1 -0
- package/dist/renderer/ShadowOrchestration.js +491 -0
- package/dist/renderer/ShadowOrchestration.js.map +1 -0
- package/dist/renderer/SkinnedBounds.d.ts +6 -0
- package/dist/renderer/SkinnedBounds.d.ts.map +1 -0
- package/dist/renderer/SkinnedBounds.js +74 -0
- package/dist/renderer/SkinnedBounds.js.map +1 -0
- package/dist/renderer/coreOutputPostRoute.d.ts +40 -0
- package/dist/renderer/coreOutputPostRoute.d.ts.map +1 -0
- package/dist/renderer/coreOutputPostRoute.js +46 -0
- package/dist/renderer/coreOutputPostRoute.js.map +1 -0
- package/dist/renderer/postSkipped.d.ts +12 -0
- package/dist/renderer/postSkipped.d.ts.map +1 -0
- package/dist/renderer/postSkipped.js +54 -0
- package/dist/renderer/postSkipped.js.map +1 -0
- package/dist/renderer/qrSubFlags.d.ts +45 -0
- package/dist/renderer/qrSubFlags.d.ts.map +1 -0
- package/dist/renderer/qrSubFlags.js +130 -0
- package/dist/renderer/qrSubFlags.js.map +1 -0
- package/dist/resources/InstanceBuffer.d.ts +34 -0
- package/dist/resources/InstanceBuffer.d.ts.map +1 -0
- package/dist/resources/InstanceBuffer.js +96 -0
- package/dist/resources/InstanceBuffer.js.map +1 -0
- package/dist/resources/MorphTargetTexture.d.ts +53 -0
- package/dist/resources/MorphTargetTexture.d.ts.map +1 -0
- package/dist/resources/MorphTargetTexture.js +135 -0
- package/dist/resources/MorphTargetTexture.js.map +1 -0
- package/dist/resources/RenderTargetPool.d.ts +47 -0
- package/dist/resources/RenderTargetPool.d.ts.map +1 -0
- package/dist/resources/RenderTargetPool.js +113 -0
- package/dist/resources/RenderTargetPool.js.map +1 -0
- package/dist/resources/ResourceRegistry.d.ts +48 -0
- package/dist/resources/ResourceRegistry.d.ts.map +1 -0
- package/dist/resources/ResourceRegistry.js +95 -0
- package/dist/resources/ResourceRegistry.js.map +1 -0
- package/dist/resources/UniformBlock.d.ts +90 -0
- package/dist/resources/UniformBlock.d.ts.map +1 -0
- package/dist/resources/UniformBlock.js +184 -0
- package/dist/resources/UniformBlock.js.map +1 -0
- package/dist/shaders/camera-fade.glsl.d.ts +26 -0
- package/dist/shaders/camera-fade.glsl.d.ts.map +1 -0
- package/dist/shaders/camera-fade.glsl.js +109 -0
- package/dist/shaders/camera-fade.glsl.js.map +1 -0
- package/dist/shaders/chunks/contact_shadow.glsl.d.ts +12 -0
- package/dist/shaders/chunks/contact_shadow.glsl.d.ts.map +1 -0
- package/dist/shaders/chunks/contact_shadow.glsl.js +53 -0
- package/dist/shaders/chunks/contact_shadow.glsl.js.map +1 -0
- package/dist/shaders/chunks/lighting_ibl.glsl.d.ts +29 -0
- package/dist/shaders/chunks/lighting_ibl.glsl.d.ts.map +1 -0
- package/dist/shaders/chunks/lighting_ibl.glsl.js +122 -0
- package/dist/shaders/chunks/lighting_ibl.glsl.js.map +1 -0
- package/dist/shaders/chunks/lighting_mirrors.d.ts +18 -0
- package/dist/shaders/chunks/lighting_mirrors.d.ts.map +1 -0
- package/dist/shaders/chunks/lighting_mirrors.js +35 -0
- package/dist/shaders/chunks/lighting_mirrors.js.map +1 -0
- package/dist/shaders/chunks/lighting_punctual.glsl.d.ts +17 -0
- package/dist/shaders/chunks/lighting_punctual.glsl.d.ts.map +1 -0
- package/dist/shaders/chunks/lighting_punctual.glsl.js +197 -0
- package/dist/shaders/chunks/lighting_punctual.glsl.js.map +1 -0
- package/dist/shaders/chunks/sh9.glsl.d.ts +9 -0
- package/dist/shaders/chunks/sh9.glsl.d.ts.map +1 -0
- package/dist/shaders/chunks/sh9.glsl.js +41 -0
- package/dist/shaders/chunks/sh9.glsl.js.map +1 -0
- package/dist/shaders/chunks/shadow_caster.glsl.d.ts +10 -0
- package/dist/shaders/chunks/shadow_caster.glsl.d.ts.map +1 -0
- package/dist/shaders/chunks/shadow_caster.glsl.js +32 -0
- package/dist/shaders/chunks/shadow_caster.glsl.js.map +1 -0
- package/dist/shaders/chunks/shadow_receive.glsl.d.ts +13 -0
- package/dist/shaders/chunks/shadow_receive.glsl.d.ts.map +1 -0
- package/dist/shaders/chunks/shadow_receive.glsl.js +136 -0
- package/dist/shaders/chunks/shadow_receive.glsl.js.map +1 -0
- package/dist/shaders/debug-view.glsl.d.ts +18 -0
- package/dist/shaders/debug-view.glsl.d.ts.map +1 -0
- package/dist/shaders/debug-view.glsl.js +153 -0
- package/dist/shaders/debug-view.glsl.js.map +1 -0
- package/dist/shaders/deform/deform.glsl.d.ts +17 -0
- package/dist/shaders/deform/deform.glsl.d.ts.map +1 -0
- package/dist/shaders/deform/deform.glsl.js +99 -0
- package/dist/shaders/deform/deform.glsl.js.map +1 -0
- package/dist/shaders/deform/deform.wgsl.d.ts +15 -0
- package/dist/shaders/deform/deform.wgsl.d.ts.map +1 -0
- package/dist/shaders/deform/deform.wgsl.js +89 -0
- package/dist/shaders/deform/deform.wgsl.js.map +1 -0
- package/dist/shaders/deform/depthFeature.d.ts +22 -0
- package/dist/shaders/deform/depthFeature.d.ts.map +1 -0
- package/dist/shaders/deform/depthFeature.js +44 -0
- package/dist/shaders/deform/depthFeature.js.map +1 -0
- package/dist/shaders/deform/forwardFeature.d.ts +114 -0
- package/dist/shaders/deform/forwardFeature.d.ts.map +1 -0
- package/dist/shaders/deform/forwardFeature.js +300 -0
- package/dist/shaders/deform/forwardFeature.js.map +1 -0
- package/dist/shaders/deform/morph.glsl.d.ts +14 -0
- package/dist/shaders/deform/morph.glsl.d.ts.map +1 -0
- package/dist/shaders/deform/morph.glsl.js +45 -0
- package/dist/shaders/deform/morph.glsl.js.map +1 -0
- package/dist/shaders/deform/morph.wgsl.d.ts +21 -0
- package/dist/shaders/deform/morph.wgsl.d.ts.map +1 -0
- package/dist/shaders/deform/morph.wgsl.js +73 -0
- package/dist/shaders/deform/morph.wgsl.js.map +1 -0
- package/dist/shaders/deform/skinning.glsl.d.ts +8 -0
- package/dist/shaders/deform/skinning.glsl.d.ts.map +1 -0
- package/dist/shaders/deform/skinning.glsl.js +37 -0
- package/dist/shaders/deform/skinning.glsl.js.map +1 -0
- package/dist/shaders/deform/skinning.wgsl.d.ts +26 -0
- package/dist/shaders/deform/skinning.wgsl.d.ts.map +1 -0
- package/dist/shaders/deform/skinning.wgsl.js +58 -0
- package/dist/shaders/deform/skinning.wgsl.js.map +1 -0
- package/dist/shaders/deform/twins.d.ts +8 -0
- package/dist/shaders/deform/twins.d.ts.map +1 -0
- package/dist/shaders/deform/twins.js +20 -0
- package/dist/shaders/deform/twins.js.map +1 -0
- package/dist/shaders/lod-dither.glsl.d.ts +12 -0
- package/dist/shaders/lod-dither.glsl.d.ts.map +1 -0
- package/dist/shaders/lod-dither.glsl.js +101 -0
- package/dist/shaders/lod-dither.glsl.js.map +1 -0
- package/dist/shaders/physical/alpha_a2c.glsl.d.ts +19 -0
- package/dist/shaders/physical/alpha_a2c.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/alpha_a2c.glsl.js +29 -0
- package/dist/shaders/physical/alpha_a2c.glsl.js.map +1 -0
- package/dist/shaders/physical/anisotropy.glsl.d.ts +23 -0
- package/dist/shaders/physical/anisotropy.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/anisotropy.glsl.js +116 -0
- package/dist/shaders/physical/anisotropy.glsl.js.map +1 -0
- package/dist/shaders/physical/bsdf_lobes_common.glsl.d.ts +25 -0
- package/dist/shaders/physical/bsdf_lobes_common.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/bsdf_lobes_common.glsl.js +95 -0
- package/dist/shaders/physical/bsdf_lobes_common.glsl.js.map +1 -0
- package/dist/shaders/physical/clearcoat.glsl.d.ts +23 -0
- package/dist/shaders/physical/clearcoat.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/clearcoat.glsl.js +70 -0
- package/dist/shaders/physical/clearcoat.glsl.js.map +1 -0
- package/dist/shaders/physical/debug_view.glsl.d.ts +19 -0
- package/dist/shaders/physical/debug_view.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/debug_view.glsl.js +76 -0
- package/dist/shaders/physical/debug_view.glsl.js.map +1 -0
- package/dist/shaders/physical/dispersion.glsl.d.ts +18 -0
- package/dist/shaders/physical/dispersion.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/dispersion.glsl.js +67 -0
- package/dist/shaders/physical/dispersion.glsl.js.map +1 -0
- package/dist/shaders/physical/emissive_strength.glsl.d.ts +18 -0
- package/dist/shaders/physical/emissive_strength.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/emissive_strength.glsl.js +20 -0
- package/dist/shaders/physical/emissive_strength.glsl.js.map +1 -0
- package/dist/shaders/physical/index.d.ts +27 -0
- package/dist/shaders/physical/index.d.ts.map +1 -0
- package/dist/shaders/physical/index.js +69 -0
- package/dist/shaders/physical/index.js.map +1 -0
- package/dist/shaders/physical/iridescence.glsl.d.ts +25 -0
- package/dist/shaders/physical/iridescence.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/iridescence.glsl.js +186 -0
- package/dist/shaders/physical/iridescence.glsl.js.map +1 -0
- package/dist/shaders/physical/lobe_calls.glsl.d.ts +83 -0
- package/dist/shaders/physical/lobe_calls.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/lobe_calls.glsl.js +397 -0
- package/dist/shaders/physical/lobe_calls.glsl.js.map +1 -0
- package/dist/shaders/physical/sheen.glsl.d.ts +24 -0
- package/dist/shaders/physical/sheen.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/sheen.glsl.js +108 -0
- package/dist/shaders/physical/sheen.glsl.js.map +1 -0
- package/dist/shaders/physical/specular_ior.glsl.d.ts +20 -0
- package/dist/shaders/physical/specular_ior.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/specular_ior.glsl.js +64 -0
- package/dist/shaders/physical/specular_ior.glsl.js.map +1 -0
- package/dist/shaders/physical/tangent_frame.glsl.d.ts +27 -0
- package/dist/shaders/physical/tangent_frame.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/tangent_frame.glsl.js +71 -0
- package/dist/shaders/physical/tangent_frame.glsl.js.map +1 -0
- package/dist/shaders/physical/transmission.glsl.d.ts +25 -0
- package/dist/shaders/physical/transmission.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/transmission.glsl.js +204 -0
- package/dist/shaders/physical/transmission.glsl.js.map +1 -0
- package/dist/shaders/physical/transmission_copy.glsl.d.ts +15 -0
- package/dist/shaders/physical/transmission_copy.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/transmission_copy.glsl.js +33 -0
- package/dist/shaders/physical/transmission_copy.glsl.js.map +1 -0
- package/dist/shaders/physical/unlit.glsl.d.ts +17 -0
- package/dist/shaders/physical/unlit.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/unlit.glsl.js +19 -0
- package/dist/shaders/physical/unlit.glsl.js.map +1 -0
- package/dist/shaders/physical/uv_transform.glsl.d.ts +18 -0
- package/dist/shaders/physical/uv_transform.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/uv_transform.glsl.js +30 -0
- package/dist/shaders/physical/uv_transform.glsl.js.map +1 -0
- package/dist/shaders/physical/volume.glsl.d.ts +19 -0
- package/dist/shaders/physical/volume.glsl.d.ts.map +1 -0
- package/dist/shaders/physical/volume.glsl.js +47 -0
- package/dist/shaders/physical/volume.glsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/alpha_a2c.wgsl.d.ts +8 -0
- package/dist/shaders/physical-wgsl/alpha_a2c.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/alpha_a2c.wgsl.js +26 -0
- package/dist/shaders/physical-wgsl/alpha_a2c.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/anisotropy.wgsl.d.ts +10 -0
- package/dist/shaders/physical-wgsl/anisotropy.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/anisotropy.wgsl.js +97 -0
- package/dist/shaders/physical-wgsl/anisotropy.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/bsdf_lobes_common.wgsl.d.ts +11 -0
- package/dist/shaders/physical-wgsl/bsdf_lobes_common.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/bsdf_lobes_common.wgsl.js +76 -0
- package/dist/shaders/physical-wgsl/bsdf_lobes_common.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/clearcoat.wgsl.d.ts +9 -0
- package/dist/shaders/physical-wgsl/clearcoat.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/clearcoat.wgsl.js +56 -0
- package/dist/shaders/physical-wgsl/clearcoat.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/debug_view.wgsl.d.ts +10 -0
- package/dist/shaders/physical-wgsl/debug_view.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/debug_view.wgsl.js +71 -0
- package/dist/shaders/physical-wgsl/debug_view.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/dispersion.wgsl.d.ts +10 -0
- package/dist/shaders/physical-wgsl/dispersion.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/dispersion.wgsl.js +51 -0
- package/dist/shaders/physical-wgsl/dispersion.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/emissive_strength.wgsl.d.ts +9 -0
- package/dist/shaders/physical-wgsl/emissive_strength.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/emissive_strength.wgsl.js +15 -0
- package/dist/shaders/physical-wgsl/emissive_strength.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/index.d.ts +35 -0
- package/dist/shaders/physical-wgsl/index.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/index.js +51 -0
- package/dist/shaders/physical-wgsl/index.js.map +1 -0
- package/dist/shaders/physical-wgsl/iridescence.wgsl.d.ts +9 -0
- package/dist/shaders/physical-wgsl/iridescence.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/iridescence.wgsl.js +162 -0
- package/dist/shaders/physical-wgsl/iridescence.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/sheen.wgsl.d.ts +9 -0
- package/dist/shaders/physical-wgsl/sheen.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/sheen.wgsl.js +85 -0
- package/dist/shaders/physical-wgsl/sheen.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/specular_ior.wgsl.d.ts +10 -0
- package/dist/shaders/physical-wgsl/specular_ior.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/specular_ior.wgsl.js +47 -0
- package/dist/shaders/physical-wgsl/specular_ior.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/tangent_frame.wgsl.d.ts +11 -0
- package/dist/shaders/physical-wgsl/tangent_frame.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/tangent_frame.wgsl.js +57 -0
- package/dist/shaders/physical-wgsl/tangent_frame.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/transmission.wgsl.d.ts +14 -0
- package/dist/shaders/physical-wgsl/transmission.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/transmission.wgsl.js +159 -0
- package/dist/shaders/physical-wgsl/transmission.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/unlit.wgsl.d.ts +8 -0
- package/dist/shaders/physical-wgsl/unlit.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/unlit.wgsl.js +13 -0
- package/dist/shaders/physical-wgsl/unlit.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/uv_transform.wgsl.d.ts +10 -0
- package/dist/shaders/physical-wgsl/uv_transform.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/uv_transform.wgsl.js +24 -0
- package/dist/shaders/physical-wgsl/uv_transform.wgsl.js.map +1 -0
- package/dist/shaders/physical-wgsl/volume.wgsl.d.ts +10 -0
- package/dist/shaders/physical-wgsl/volume.wgsl.d.ts.map +1 -0
- package/dist/shaders/physical-wgsl/volume.wgsl.js +35 -0
- package/dist/shaders/physical-wgsl/volume.wgsl.js.map +1 -0
- package/dist/shadows/DirectionalCascadeFitter.d.ts +97 -0
- package/dist/shadows/DirectionalCascadeFitter.d.ts.map +1 -0
- package/dist/shadows/DirectionalCascadeFitter.js +372 -0
- package/dist/shadows/DirectionalCascadeFitter.js.map +1 -0
- package/dist/shadows/Prd02DepthShaderLibrary.d.ts +77 -0
- package/dist/shadows/Prd02DepthShaderLibrary.d.ts.map +1 -0
- package/dist/shadows/Prd02DepthShaderLibrary.js +381 -0
- package/dist/shadows/Prd02DepthShaderLibrary.js.map +1 -0
- package/dist/shadows/Prd02ReceiveShadowContributor.d.ts +20 -0
- package/dist/shadows/Prd02ReceiveShadowContributor.d.ts.map +1 -0
- package/dist/shadows/Prd02ReceiveShadowContributor.js +20 -0
- package/dist/shadows/Prd02ReceiveShadowContributor.js.map +1 -0
- package/dist/shadows/Prd02ShadowBridge.d.ts +111 -0
- package/dist/shadows/Prd02ShadowBridge.d.ts.map +1 -0
- package/dist/shadows/Prd02ShadowBridge.js +267 -0
- package/dist/shadows/Prd02ShadowBridge.js.map +1 -0
- package/dist/shadows/Prd02ShadowFilter.d.ts +29 -0
- package/dist/shadows/Prd02ShadowFilter.d.ts.map +1 -0
- package/dist/shadows/Prd02ShadowFilter.js +35 -0
- package/dist/shadows/Prd02ShadowFilter.js.map +1 -0
- package/dist/shadows/Prd02ShadowsContributor.d.ts +44 -0
- package/dist/shadows/Prd02ShadowsContributor.d.ts.map +1 -0
- package/dist/shadows/Prd02ShadowsContributor.js +197 -0
- package/dist/shadows/Prd02ShadowsContributor.js.map +1 -0
- package/dist/shadows/ShadowAtlas.d.ts +59 -0
- package/dist/shadows/ShadowAtlas.d.ts.map +1 -0
- package/dist/shadows/ShadowAtlas.js +137 -0
- package/dist/shadows/ShadowAtlas.js.map +1 -0
- package/dist/shadows/ShadowDebugViews.d.ts +5 -0
- package/dist/shadows/ShadowDebugViews.d.ts.map +1 -1
- package/dist/shadows/ShadowDebugViews.js +15 -10
- package/dist/shadows/ShadowDebugViews.js.map +1 -1
- package/dist/shadows/ShadowFrameBinding.d.ts +18 -0
- package/dist/shadows/ShadowFrameBinding.d.ts.map +1 -0
- package/dist/shadows/ShadowFrameBinding.js +52 -0
- package/dist/shadows/ShadowFrameBinding.js.map +1 -0
- package/dist/shadows/ShadowSystem.d.ts +125 -0
- package/dist/shadows/ShadowSystem.d.ts.map +1 -0
- package/dist/shadows/ShadowSystem.js +293 -0
- package/dist/shadows/ShadowSystem.js.map +1 -0
- package/dist/textures/TextureBudget.d.ts +42 -0
- package/dist/textures/TextureBudget.d.ts.map +1 -0
- package/dist/textures/TextureBudget.js +180 -0
- package/dist/textures/TextureBudget.js.map +1 -0
- package/dist/vfx/BeamPass.d.ts +42 -0
- package/dist/vfx/BeamPass.d.ts.map +1 -0
- package/dist/vfx/BeamPass.js +249 -0
- package/dist/vfx/BeamPass.js.map +1 -0
- package/dist/vfx/BlendFallback.d.ts +19 -0
- package/dist/vfx/BlendFallback.d.ts.map +1 -0
- package/dist/vfx/BlendFallback.js +73 -0
- package/dist/vfx/BlendFallback.js.map +1 -0
- package/dist/vfx/DecalBatch.d.ts +120 -0
- package/dist/vfx/DecalBatch.d.ts.map +1 -0
- package/dist/vfx/DecalBatch.js +234 -0
- package/dist/vfx/DecalBatch.js.map +1 -0
- package/dist/vfx/DecalPass.d.ts +63 -0
- package/dist/vfx/DecalPass.d.ts.map +1 -0
- package/dist/vfx/DecalPass.js +159 -0
- package/dist/vfx/DecalPass.js.map +1 -0
- package/dist/vfx/LowResParticles.d.ts +31 -0
- package/dist/vfx/LowResParticles.d.ts.map +1 -0
- package/dist/vfx/LowResParticles.js +151 -0
- package/dist/vfx/LowResParticles.js.map +1 -0
- package/dist/vfx/MeshParticleBatch.d.ts +49 -0
- package/dist/vfx/MeshParticleBatch.d.ts.map +1 -0
- package/dist/vfx/MeshParticleBatch.js +184 -0
- package/dist/vfx/MeshParticleBatch.js.map +1 -0
- package/dist/vfx/MeshParticlePass.d.ts +28 -0
- package/dist/vfx/MeshParticlePass.d.ts.map +1 -0
- package/dist/vfx/MeshParticlePass.js +150 -0
- package/dist/vfx/MeshParticlePass.js.map +1 -0
- package/dist/vfx/ParticleBatchPass.d.ts +61 -0
- package/dist/vfx/ParticleBatchPass.d.ts.map +1 -0
- package/dist/vfx/ParticleBatchPass.js +320 -0
- package/dist/vfx/ParticleBatchPass.js.map +1 -0
- package/dist/vfx/ParticleGpuSim.d.ts +85 -0
- package/dist/vfx/ParticleGpuSim.d.ts.map +1 -0
- package/dist/vfx/ParticleGpuSim.js +301 -0
- package/dist/vfx/ParticleGpuSim.js.map +1 -0
- package/dist/vfx/ParticleInstanceLayout.d.ts +38 -0
- package/dist/vfx/ParticleInstanceLayout.d.ts.map +1 -0
- package/dist/vfx/ParticleInstanceLayout.js +105 -0
- package/dist/vfx/ParticleInstanceLayout.js.map +1 -0
- package/dist/vfx/ParticleSort.d.ts +21 -0
- package/dist/vfx/ParticleSort.d.ts.map +1 -0
- package/dist/vfx/ParticleSort.js +80 -0
- package/dist/vfx/ParticleSort.js.map +1 -0
- package/dist/vfx/ProceduralVolumeEmitter.d.ts +90 -0
- package/dist/vfx/ProceduralVolumeEmitter.d.ts.map +1 -0
- package/dist/vfx/ProceduralVolumeEmitter.js +155 -0
- package/dist/vfx/ProceduralVolumeEmitter.js.map +1 -0
- package/dist/vfx/RibbonBatch.d.ts +71 -0
- package/dist/vfx/RibbonBatch.d.ts.map +1 -0
- package/dist/vfx/RibbonBatch.js +234 -0
- package/dist/vfx/RibbonBatch.js.map +1 -0
- package/dist/vfx/RibbonPass.d.ts +21 -0
- package/dist/vfx/RibbonPass.d.ts.map +1 -0
- package/dist/vfx/RibbonPass.js +108 -0
- package/dist/vfx/RibbonPass.js.map +1 -0
- package/dist/vfx/SceneDepthAdapter.d.ts +28 -0
- package/dist/vfx/SceneDepthAdapter.d.ts.map +1 -0
- package/dist/vfx/SceneDepthAdapter.js +70 -0
- package/dist/vfx/SceneDepthAdapter.js.map +1 -0
- package/dist/vfx/VfxAtlas.d.ts +68 -0
- package/dist/vfx/VfxAtlas.d.ts.map +1 -0
- package/dist/vfx/VfxAtlas.js +106 -0
- package/dist/vfx/VfxAtlas.js.map +1 -0
- package/dist/vfx/contributors.d.ts +73 -0
- package/dist/vfx/contributors.d.ts.map +1 -0
- package/dist/vfx/contributors.js +615 -0
- package/dist/vfx/contributors.js.map +1 -0
- package/dist/vfx/decalLighting.d.ts +8 -0
- package/dist/vfx/decalLighting.d.ts.map +1 -0
- package/dist/vfx/decalLighting.js +53 -0
- package/dist/vfx/decalLighting.js.map +1 -0
- package/dist/vfx/depthSampler.d.ts +3 -0
- package/dist/vfx/depthSampler.d.ts.map +1 -0
- package/dist/vfx/depthSampler.js +10 -0
- package/dist/vfx/depthSampler.js.map +1 -0
- package/dist/vfx/prd07FeaturePars.d.ts +12 -0
- package/dist/vfx/prd07FeaturePars.d.ts.map +1 -0
- package/dist/vfx/prd07FeaturePars.js +54 -0
- package/dist/vfx/prd07FeaturePars.js.map +1 -0
- package/dist/vfx/shaders/beam.glsl.d.ts +11 -0
- package/dist/vfx/shaders/beam.glsl.d.ts.map +1 -0
- package/dist/vfx/shaders/beam.glsl.js +89 -0
- package/dist/vfx/shaders/beam.glsl.js.map +1 -0
- package/dist/vfx/shaders/decal.glsl.d.ts +14 -0
- package/dist/vfx/shaders/decal.glsl.d.ts.map +1 -0
- package/dist/vfx/shaders/decal.glsl.js +157 -0
- package/dist/vfx/shaders/decal.glsl.js.map +1 -0
- package/dist/vfx/shaders/gpu-sim.glsl.d.ts +5 -0
- package/dist/vfx/shaders/gpu-sim.glsl.d.ts.map +1 -0
- package/dist/vfx/shaders/gpu-sim.glsl.js +177 -0
- package/dist/vfx/shaders/gpu-sim.glsl.js.map +1 -0
- package/dist/vfx/shaders/lowresComposite.glsl.d.ts +9 -0
- package/dist/vfx/shaders/lowresComposite.glsl.d.ts.map +1 -0
- package/dist/vfx/shaders/lowresComposite.glsl.js +64 -0
- package/dist/vfx/shaders/lowresComposite.glsl.js.map +1 -0
- package/dist/vfx/shaders/mesh-particle.glsl.d.ts +4 -0
- package/dist/vfx/shaders/mesh-particle.glsl.d.ts.map +1 -0
- package/dist/vfx/shaders/mesh-particle.glsl.js +55 -0
- package/dist/vfx/shaders/mesh-particle.glsl.js.map +1 -0
- package/dist/vfx/shaders/particle.glsl.d.ts +24 -0
- package/dist/vfx/shaders/particle.glsl.d.ts.map +1 -0
- package/dist/vfx/shaders/particle.glsl.js +215 -0
- package/dist/vfx/shaders/particle.glsl.js.map +1 -0
- package/dist/vfx/shaders/ribbon.glsl.d.ts +9 -0
- package/dist/vfx/shaders/ribbon.glsl.d.ts.map +1 -0
- package/dist/vfx/shaders/ribbon.glsl.js +60 -0
- package/dist/vfx/shaders/ribbon.glsl.js.map +1 -0
- package/dist/vfx/shaders/volume.glsl.d.ts +5 -0
- package/dist/vfx/shaders/volume.glsl.d.ts.map +1 -0
- package/dist/vfx/shaders/volume.glsl.js +52 -0
- package/dist/vfx/shaders/volume.glsl.js.map +1 -0
- package/dist/webgl2/ContextLifecycle.d.ts +43 -0
- package/dist/webgl2/ContextLifecycle.d.ts.map +1 -0
- package/dist/webgl2/ContextLifecycle.js +189 -0
- package/dist/webgl2/ContextLifecycle.js.map +1 -0
- package/dist/webgl2/Counters.d.ts +58 -0
- package/dist/webgl2/Counters.d.ts.map +1 -0
- package/dist/webgl2/Counters.js +207 -0
- package/dist/webgl2/Counters.js.map +1 -0
- package/dist/webgl2/DeviceHost.d.ts +41 -0
- package/dist/webgl2/DeviceHost.d.ts.map +1 -0
- package/dist/webgl2/DeviceHost.js +3 -0
- package/dist/webgl2/DeviceHost.js.map +1 -0
- package/dist/webgl2/LegacyPost.d.ts +279 -0
- package/dist/webgl2/LegacyPost.d.ts.map +1 -0
- package/dist/webgl2/LegacyPost.js +2477 -0
- package/dist/webgl2/LegacyPost.js.map +1 -0
- package/dist/webgl2/MultiDraw.d.ts +96 -0
- package/dist/webgl2/MultiDraw.d.ts.map +1 -0
- package/dist/webgl2/MultiDraw.js +716 -0
- package/dist/webgl2/MultiDraw.js.map +1 -0
- package/dist/webgl2/Probe.d.ts +27 -0
- package/dist/webgl2/Probe.d.ts.map +1 -0
- package/dist/webgl2/Probe.js +303 -0
- package/dist/webgl2/Probe.js.map +1 -0
- package/dist/webgl2/Samplers.d.ts +20 -0
- package/dist/webgl2/Samplers.d.ts.map +1 -0
- package/dist/webgl2/Samplers.js +179 -0
- package/dist/webgl2/Samplers.js.map +1 -0
- package/dist/webgl2/TextureFormats.d.ts +48 -0
- package/dist/webgl2/TextureFormats.d.ts.map +1 -0
- package/dist/webgl2/TextureFormats.js +185 -0
- package/dist/webgl2/TextureFormats.js.map +1 -0
- package/dist/webgl2/TextureUpload.d.ts +38 -0
- package/dist/webgl2/TextureUpload.d.ts.map +1 -0
- package/dist/webgl2/TextureUpload.js +346 -0
- package/dist/webgl2/TextureUpload.js.map +1 -0
- package/dist/webgpu/WebGPUBuffer.d.ts +1 -0
- package/dist/webgpu/WebGPUBuffer.d.ts.map +1 -1
- package/dist/webgpu/WebGPUCompute.d.ts +1 -0
- package/dist/webgpu/WebGPUCompute.d.ts.map +1 -1
- package/dist/webgpu/WebGPUCompute.js +1 -0
- package/dist/webgpu/WebGPUCompute.js.map +1 -1
- package/dist/webgpu/WebGPUPipelineCache.d.ts +4 -0
- package/dist/webgpu/WebGPUPipelineCache.d.ts.map +1 -1
- package/dist/webgpu/WebGPUPipelineCache.js +4 -0
- package/dist/webgpu/WebGPUPipelineCache.js.map +1 -1
- package/dist/webgpu/WebGPUPostShaders.d.ts +2 -3
- package/dist/webgpu/WebGPUPostShaders.d.ts.map +1 -1
- package/dist/webgpu/WebGPUPostShaders.js +35 -5
- package/dist/webgpu/WebGPUPostShaders.js.map +1 -1
- package/dist/webgpu/WebGPUTemporal.d.ts +17 -0
- package/dist/webgpu/WebGPUTemporal.d.ts.map +1 -0
- package/dist/webgpu/WebGPUTemporal.js +64 -0
- package/dist/webgpu/WebGPUTemporal.js.map +1 -0
- package/dist/webgpu/WebGPUTexture.d.ts +1 -0
- package/dist/webgpu/WebGPUTexture.d.ts.map +1 -1
- package/dist/webgpu/WebGPUTexture.js.map +1 -1
- package/dist/webgpu.d.ts +6 -0
- package/dist/webgpu.d.ts.map +1 -1
- package/dist/webgpu.js +4 -0
- package/dist/webgpu.js.map +1 -1
- package/dist/world/chunks.d.ts +15 -0
- package/dist/world/chunks.d.ts.map +1 -0
- package/dist/world/chunks.js +56 -0
- package/dist/world/chunks.js.map +1 -0
- package/dist/world/index.d.ts +38 -0
- package/dist/world/index.d.ts.map +1 -0
- package/dist/world/index.js +39 -0
- package/dist/world/index.js.map +1 -0
- package/dist/world/shared/shaders/worldLightFallback.d.ts +12 -0
- package/dist/world/shared/shaders/worldLightFallback.d.ts.map +1 -0
- package/dist/world/shared/shaders/worldLightFallback.js +82 -0
- package/dist/world/shared/shaders/worldLightFallback.js.map +1 -0
- package/dist/world/space/PlanetMaterial.d.ts +24 -0
- package/dist/world/space/PlanetMaterial.d.ts.map +1 -0
- package/dist/world/space/PlanetMaterial.js +82 -0
- package/dist/world/space/PlanetMaterial.js.map +1 -0
- package/dist/world/space/SpaceSkyBake.d.ts +46 -0
- package/dist/world/space/SpaceSkyBake.d.ts.map +1 -0
- package/dist/world/space/SpaceSkyBake.js +145 -0
- package/dist/world/space/SpaceSkyBake.js.map +1 -0
- package/dist/world/space/shaders/planet.d.ts +8 -0
- package/dist/world/space/shaders/planet.d.ts.map +1 -0
- package/dist/world/space/shaders/planet.js +55 -0
- package/dist/world/space/shaders/planet.js.map +1 -0
- package/dist/world/space/shaders/spaceBake.d.ts +9 -0
- package/dist/world/space/shaders/spaceBake.d.ts.map +1 -0
- package/dist/world/space/shaders/spaceBake.js +102 -0
- package/dist/world/space/shaders/spaceBake.js.map +1 -0
- package/dist/world/terrain/SplatBake.d.ts +76 -0
- package/dist/world/terrain/SplatBake.d.ts.map +1 -0
- package/dist/world/terrain/SplatBake.js +308 -0
- package/dist/world/terrain/SplatBake.js.map +1 -0
- package/dist/world/terrain/TerrainCdlod.d.ts +67 -0
- package/dist/world/terrain/TerrainCdlod.d.ts.map +1 -0
- package/dist/world/terrain/TerrainCdlod.js +115 -0
- package/dist/world/terrain/TerrainCdlod.js.map +1 -0
- package/dist/world/terrain/TerrainHeightTexture.d.ts +44 -0
- package/dist/world/terrain/TerrainHeightTexture.d.ts.map +1 -0
- package/dist/world/terrain/TerrainHeightTexture.js +173 -0
- package/dist/world/terrain/TerrainHeightTexture.js.map +1 -0
- package/dist/world/terrain/TerrainPatchGeometry.d.ts +18 -0
- package/dist/world/terrain/TerrainPatchGeometry.d.ts.map +1 -0
- package/dist/world/terrain/TerrainPatchGeometry.js +40 -0
- package/dist/world/terrain/TerrainPatchGeometry.js.map +1 -0
- package/dist/world/terrain/shaders/terrain.vert.glsl.d.ts +19 -0
- package/dist/world/terrain/shaders/terrain.vert.glsl.d.ts.map +1 -0
- package/dist/world/terrain/shaders/terrain.vert.glsl.js +162 -0
- package/dist/world/terrain/shaders/terrain.vert.glsl.js.map +1 -0
- package/dist/world/terrain/shaders/terrainCdlod.d.ts +23 -0
- package/dist/world/terrain/shaders/terrainCdlod.d.ts.map +1 -0
- package/dist/world/terrain/shaders/terrainCdlod.js +110 -0
- package/dist/world/terrain/shaders/terrainCdlod.js.map +1 -0
- package/dist/world/terrain/shaders/terrainSplat.d.ts +26 -0
- package/dist/world/terrain/shaders/terrainSplat.d.ts.map +1 -0
- package/dist/world/terrain/shaders/terrainSplat.js +181 -0
- package/dist/world/terrain/shaders/terrainSplat.js.map +1 -0
- package/dist/world/vegetation/FoliageMaterial.d.ts +14 -0
- package/dist/world/vegetation/FoliageMaterial.d.ts.map +1 -0
- package/dist/world/vegetation/FoliageMaterial.js +107 -0
- package/dist/world/vegetation/FoliageMaterial.js.map +1 -0
- package/dist/world/vegetation/GrassField.d.ts +43 -0
- package/dist/world/vegetation/GrassField.d.ts.map +1 -0
- package/dist/world/vegetation/GrassField.js +68 -0
- package/dist/world/vegetation/GrassField.js.map +1 -0
- package/dist/world/vegetation/ImpostorMaterial.d.ts +20 -0
- package/dist/world/vegetation/ImpostorMaterial.d.ts.map +1 -0
- package/dist/world/vegetation/ImpostorMaterial.js +80 -0
- package/dist/world/vegetation/ImpostorMaterial.js.map +1 -0
- package/dist/world/vegetation/InstanceChunkGrid.d.ts +67 -0
- package/dist/world/vegetation/InstanceChunkGrid.d.ts.map +1 -0
- package/dist/world/vegetation/InstanceChunkGrid.js +150 -0
- package/dist/world/vegetation/InstanceChunkGrid.js.map +1 -0
- package/dist/world/vegetation/WindCpu.d.ts +19 -0
- package/dist/world/vegetation/WindCpu.d.ts.map +1 -0
- package/dist/world/vegetation/WindCpu.js +43 -0
- package/dist/world/vegetation/WindCpu.js.map +1 -0
- package/dist/world/vegetation/WindField.d.ts +42 -0
- package/dist/world/vegetation/WindField.d.ts.map +1 -0
- package/dist/world/vegetation/WindField.js +154 -0
- package/dist/world/vegetation/WindField.js.map +1 -0
- package/dist/world/vegetation/shaders/foliage.d.ts +8 -0
- package/dist/world/vegetation/shaders/foliage.d.ts.map +1 -0
- package/dist/world/vegetation/shaders/foliage.js +104 -0
- package/dist/world/vegetation/shaders/foliage.js.map +1 -0
- package/dist/world/vegetation/shaders/grass.d.ts +10 -0
- package/dist/world/vegetation/shaders/grass.d.ts.map +1 -0
- package/dist/world/vegetation/shaders/grass.js +79 -0
- package/dist/world/vegetation/shaders/grass.js.map +1 -0
- package/dist/world/vegetation/shaders/impostor.d.ts +9 -0
- package/dist/world/vegetation/shaders/impostor.d.ts.map +1 -0
- package/dist/world/vegetation/shaders/impostor.js +97 -0
- package/dist/world/vegetation/shaders/impostor.js.map +1 -0
- package/dist/world/vegetation/shaders/wind.d.ts +9 -0
- package/dist/world/vegetation/shaders/wind.d.ts.map +1 -0
- package/dist/world/vegetation/shaders/wind.js +103 -0
- package/dist/world/vegetation/shaders/wind.js.map +1 -0
- package/dist/world/water/GerstnerWaves.d.ts +65 -0
- package/dist/world/water/GerstnerWaves.d.ts.map +1 -0
- package/dist/world/water/GerstnerWaves.js +182 -0
- package/dist/world/water/GerstnerWaves.js.map +1 -0
- package/dist/world/water/ReflectionViewPass.d.ts +46 -0
- package/dist/world/water/ReflectionViewPass.d.ts.map +1 -0
- package/dist/world/water/ReflectionViewPass.js +85 -0
- package/dist/world/water/ReflectionViewPass.js.map +1 -0
- package/dist/world/water/SceneCopyFallback.d.ts +21 -0
- package/dist/world/water/SceneCopyFallback.d.ts.map +1 -0
- package/dist/world/water/SceneCopyFallback.js +150 -0
- package/dist/world/water/SceneCopyFallback.js.map +1 -0
- package/dist/world/water/UnderwaterState.d.ts +25 -0
- package/dist/world/water/UnderwaterState.d.ts.map +1 -0
- package/dist/world/water/UnderwaterState.js +134 -0
- package/dist/world/water/UnderwaterState.js.map +1 -0
- package/dist/world/water/WaterMaterial.d.ts +23 -0
- package/dist/world/water/WaterMaterial.d.ts.map +1 -0
- package/dist/world/water/WaterMaterial.js +129 -0
- package/dist/world/water/WaterMaterial.js.map +1 -0
- package/dist/world/water/shaders/caustics.d.ts +13 -0
- package/dist/world/water/shaders/caustics.d.ts.map +1 -0
- package/dist/world/water/shaders/caustics.js +103 -0
- package/dist/world/water/shaders/caustics.js.map +1 -0
- package/dist/world/water/shaders/gerstner.d.ts +9 -0
- package/dist/world/water/shaders/gerstner.d.ts.map +1 -0
- package/dist/world/water/shaders/gerstner.js +100 -0
- package/dist/world/water/shaders/gerstner.js.map +1 -0
- package/dist/world/water/shaders/water.d.ts +12 -0
- package/dist/world/water/shaders/water.d.ts.map +1 -0
- package/dist/world/water/shaders/water.js +112 -0
- package/dist/world/water/shaders/water.js.map +1 -0
- package/package.json +40 -7
package/dist/WebGL2Device.js
CHANGED
|
@@ -1,12 +1,56 @@
|
|
|
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";
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
import { normalizeBloomQualityPreset, resolveBloomPyramidBlurRadii, resolveBloomPyramidPlan, resolveBloomPyramidResponseGain, } from "./postprocess/NativeBloomPyramid.js";
|
|
10
|
+
import { WebGL2Counters } from "./webgl2/Counters.js";
|
|
11
|
+
import { createWebGL2DeviceProbe } from "./webgl2/Probe.js";
|
|
12
|
+
import { WebGL2ContextLifecycle } from "./webgl2/ContextLifecycle.js";
|
|
13
|
+
import { WebGL2TextureRegistry } from "./webgl2/TextureUpload.js";
|
|
14
|
+
import { WebGL2SamplerRegistry } from "./webgl2/Samplers.js";
|
|
15
|
+
import { WebGL2DrawCallBinder } from "./webgl2/MultiDraw.js";
|
|
16
|
+
import { AURA_FRAME_BINDING, AURA_LIGHTS_BINDING } from "./resources/UniformBlock.js";
|
|
17
|
+
import { WebGL2ReadbackProbe } from "./webgl2/Probe.js";
|
|
18
|
+
import { WebGL2LegacyPostPipeline } from "./webgl2/LegacyPost.js";
|
|
19
|
+
import { cubeFaceTarget, rgba8TextureInternalFormat, textureUploadFormat, resolveRenderTargetFormat, resolveCompressedTextureFormat, magFilter, minFilter, addressMode } from "./webgl2/TextureFormats.js";
|
|
20
|
+
export const WEBGL_CUBE_FACES = ["px", "nx", "py", "ny", "pz", "nz"];
|
|
21
|
+
/**
|
|
22
|
+
* #621 (01-RTARRAY): immutable storage (`texStorage2D/3D`) only accepts SIZED
|
|
23
|
+
* internal formats. `resolveRenderTargetFormat("rgba8")` returns unsized
|
|
24
|
+
* `gl.RGBA`, which is valid for the `texImage2D` 2d path but makes
|
|
25
|
+
* texStorage raise INVALID_ENUM and allocate nothing, so cube/array colour
|
|
26
|
+
* framebuffers come out incomplete (GPU run 38143556299: "array: WebGL render
|
|
27
|
+
* target framebuffer status is invalid"). Float formats are already sized.
|
|
28
|
+
*/
|
|
29
|
+
export function renderTargetStorageFormat(gl, internalFormat) {
|
|
30
|
+
return internalFormat === gl.RGBA ? gl.RGBA8 : internalFormat;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Attachment-0 color format of a single-attachment 2d target: an explicit
|
|
34
|
+
* `colorAttachments[0].format` wins over the legacy `format` field.
|
|
35
|
+
*/
|
|
36
|
+
export function renderTargetColorFormat(descriptor) {
|
|
37
|
+
return descriptor.colorAttachments?.[0]?.format ?? descriptor.format ?? "rgba8";
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* MAX_TEXTURE_SIZE of the canvas's WebGL2 context (4096 when unavailable).
|
|
41
|
+
* Lives in the device owner file so callers never touch getContext
|
|
42
|
+
* themselves (single-renderer gate). Moved from the engine's deleted
|
|
43
|
+
* safe-basic webglRuntime in Live Fix E6.
|
|
44
|
+
*/
|
|
45
|
+
export function webGL2MaxTextureSize(canvas) {
|
|
46
|
+
return Number(canvas.getContext("webgl2")?.getParameter(WebGL2RenderingContext.MAX_TEXTURE_SIZE) ?? 4096);
|
|
47
|
+
}
|
|
48
|
+
/** C-08 named uniform-block → binding-point assignment applied post-link (T0-02). */
|
|
49
|
+
const NAMED_UNIFORM_BLOCK_BINDINGS = [
|
|
50
|
+
["AuraFrame", AURA_FRAME_BINDING],
|
|
51
|
+
["AuraLights", AURA_LIGHTS_BINDING]
|
|
52
|
+
];
|
|
53
|
+
export class WebGL2Buffer {
|
|
10
54
|
id;
|
|
11
55
|
usage;
|
|
12
56
|
byteLength;
|
|
@@ -14,6 +58,8 @@ class WebGL2Buffer {
|
|
|
14
58
|
handle;
|
|
15
59
|
gl;
|
|
16
60
|
disposed = false;
|
|
61
|
+
/** PRD-01 Phase 6 (CONTRACTS §6.1): device-side cleanup hook — VAO eviction. */
|
|
62
|
+
onDispose;
|
|
17
63
|
constructor(id, usage, byteLength, target, handle, gl) {
|
|
18
64
|
this.id = id;
|
|
19
65
|
this.usage = usage;
|
|
@@ -24,12 +70,14 @@ class WebGL2Buffer {
|
|
|
24
70
|
}
|
|
25
71
|
dispose() {
|
|
26
72
|
if (!this.disposed) {
|
|
27
|
-
this.gl.deleteBuffer(this.handle);
|
|
28
73
|
this.disposed = true;
|
|
74
|
+
// Evict VAOs referencing this buffer before the GL object goes away.
|
|
75
|
+
this.onDispose?.();
|
|
76
|
+
this.gl.deleteBuffer(this.handle);
|
|
29
77
|
}
|
|
30
78
|
}
|
|
31
79
|
}
|
|
32
|
-
class WebGL2ShaderProgram {
|
|
80
|
+
export class WebGL2ShaderProgram {
|
|
33
81
|
id;
|
|
34
82
|
label;
|
|
35
83
|
marker;
|
|
@@ -52,7 +100,7 @@ class WebGL2ShaderProgram {
|
|
|
52
100
|
}
|
|
53
101
|
}
|
|
54
102
|
}
|
|
55
|
-
class WebGL2RenderTarget {
|
|
103
|
+
export class WebGL2RenderTarget {
|
|
56
104
|
id;
|
|
57
105
|
width;
|
|
58
106
|
height;
|
|
@@ -69,7 +117,14 @@ class WebGL2RenderTarget {
|
|
|
69
117
|
gl;
|
|
70
118
|
disposed = false;
|
|
71
119
|
needsResolve = false;
|
|
72
|
-
|
|
120
|
+
dimension;
|
|
121
|
+
layers;
|
|
122
|
+
colorTextures;
|
|
123
|
+
layerTargets;
|
|
124
|
+
extraColorHandles;
|
|
125
|
+
layerFramebuffers;
|
|
126
|
+
layerChild;
|
|
127
|
+
constructor(id, width, height, label, colorTexture, depthTexture, framebuffer, colorHandle, depthHandle, depthTextureHandle, sampleCount, drawFramebuffer, multisampleColorHandle, gl, options = {}) {
|
|
73
128
|
this.id = id;
|
|
74
129
|
this.width = width;
|
|
75
130
|
this.height = height;
|
|
@@ -84,13 +139,31 @@ class WebGL2RenderTarget {
|
|
|
84
139
|
this.drawFramebuffer = drawFramebuffer;
|
|
85
140
|
this.multisampleColorHandle = multisampleColorHandle;
|
|
86
141
|
this.gl = gl;
|
|
142
|
+
this.dimension = options.dimension ?? "2d";
|
|
143
|
+
this.layers = options.layers;
|
|
144
|
+
this.colorTextures = options.colorTextures;
|
|
145
|
+
this.layerTargets = options.layerTargets;
|
|
146
|
+
this.extraColorHandles = options.extraColorHandles ?? [];
|
|
147
|
+
this.layerFramebuffers = options.layerFramebuffers ?? [];
|
|
148
|
+
this.layerChild = options.layerChild === true;
|
|
87
149
|
}
|
|
88
150
|
dispose() {
|
|
89
151
|
if (!this.disposed) {
|
|
152
|
+
if (this.layerChild) {
|
|
153
|
+
this.disposed = true;
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
for (const framebuffer of this.layerFramebuffers) {
|
|
157
|
+
if (framebuffer !== this.framebuffer)
|
|
158
|
+
this.gl.deleteFramebuffer(framebuffer);
|
|
159
|
+
}
|
|
90
160
|
this.gl.deleteFramebuffer(this.framebuffer);
|
|
91
161
|
if (this.drawFramebuffer !== this.framebuffer)
|
|
92
162
|
this.gl.deleteFramebuffer(this.drawFramebuffer);
|
|
93
163
|
this.gl.deleteTexture(this.colorHandle);
|
|
164
|
+
for (const handle of this.extraColorHandles) {
|
|
165
|
+
this.gl.deleteTexture(handle);
|
|
166
|
+
}
|
|
94
167
|
if (this.depthHandle)
|
|
95
168
|
this.gl.deleteRenderbuffer(this.depthHandle);
|
|
96
169
|
if (this.multisampleColorHandle)
|
|
@@ -98,7 +171,14 @@ class WebGL2RenderTarget {
|
|
|
98
171
|
if (this.depthTextureHandle)
|
|
99
172
|
this.gl.deleteTexture(this.depthTextureHandle);
|
|
100
173
|
this.colorTexture.dispose();
|
|
174
|
+
for (const texture of this.colorTextures ?? []) {
|
|
175
|
+
if (texture !== this.colorTexture)
|
|
176
|
+
texture.dispose();
|
|
177
|
+
}
|
|
101
178
|
this.depthTexture?.dispose();
|
|
179
|
+
for (const child of this.layerTargets ?? []) {
|
|
180
|
+
child.disposed = true;
|
|
181
|
+
}
|
|
102
182
|
this.disposed = true;
|
|
103
183
|
}
|
|
104
184
|
}
|
|
@@ -107,73 +187,13 @@ export class WebGL2Device {
|
|
|
107
187
|
errorCheckMode;
|
|
108
188
|
kind = "webgl2";
|
|
109
189
|
info;
|
|
110
|
-
disposed = false;
|
|
111
|
-
contextLost = false;
|
|
112
190
|
gl;
|
|
113
191
|
nextId = 1;
|
|
114
|
-
drawCalls = 0;
|
|
115
192
|
buffers = new Set();
|
|
193
|
+
disposedBufferCount = 0;
|
|
116
194
|
shaders = new Set();
|
|
117
195
|
renderTargets = new Set();
|
|
118
|
-
activeRenderTarget = null;
|
|
119
|
-
textures = new Map();
|
|
120
|
-
textureUploadModes = new Map();
|
|
121
|
-
fallbackTexture = null;
|
|
122
|
-
fallbackCubeTexture = null;
|
|
123
|
-
samplerObjectCache = new Map();
|
|
124
|
-
presentationProgram = null;
|
|
125
|
-
ldrPostprocessProgram = null;
|
|
126
|
-
bloomBrightExtractProgram = null;
|
|
127
|
-
bloomBlurProgram = null;
|
|
128
|
-
bloomCompositeProgram = null;
|
|
129
|
-
bloomDownsampleProgram = null;
|
|
130
|
-
bloomAccumulateProgram = null;
|
|
131
|
-
bloomPyramidResources = null;
|
|
132
|
-
outlineProgram = null;
|
|
133
|
-
ssaoProgram = null;
|
|
134
|
-
ssrProgram = null;
|
|
135
|
-
depthOfFieldProgram = null;
|
|
136
|
-
motionBlurProgram = null;
|
|
137
|
-
motionBlurVelocityTexture = null;
|
|
138
|
-
motionBlurVelocitySize = null;
|
|
139
|
-
taaProgram = null;
|
|
140
|
-
taaHistoryTexture = null;
|
|
141
|
-
taaHistorySize = null;
|
|
142
|
-
bloomPingPongResources = null;
|
|
143
|
-
bloomBrightLutTexture = null;
|
|
144
|
-
bloomBrightLutThreshold = null;
|
|
145
|
-
bloomCompositeLutTexture = null;
|
|
146
|
-
bloomCompositeLutIntensity = null;
|
|
147
|
-
bloomCompositeLutShoulder = null;
|
|
148
|
-
lastBloomDiagnostics = null;
|
|
149
|
-
outlineBlendLutTexture = null;
|
|
150
|
-
outlineBlendLutKey = null;
|
|
151
|
-
depthReadbackProgram = null;
|
|
152
|
-
uniformLocationCache = new WeakMap();
|
|
153
|
-
textureSamplerParameterCache = new WeakMap();
|
|
154
196
|
stateCache = new WebGL2StateCache({ label: "webgl2-device-state-cache" });
|
|
155
|
-
textureUnitBindings = new Map();
|
|
156
|
-
vertexArrayCache = new Map();
|
|
157
|
-
vertexFormatIds = new WeakMap();
|
|
158
|
-
presentationVertexArray = null;
|
|
159
|
-
activeTextureUnitIndex = -1;
|
|
160
|
-
shaderProgramCreateCount = 0;
|
|
161
|
-
uniformLocationLookupCount = 0;
|
|
162
|
-
bufferUpdateCount = 0;
|
|
163
|
-
textureBindCount = 0;
|
|
164
|
-
samplerParameterUploadCount = 0;
|
|
165
|
-
samplerAnisotropyUploadCount = 0;
|
|
166
|
-
vertexArrayCreateCount = 0;
|
|
167
|
-
nativeInstancedSubmissions = 0;
|
|
168
|
-
nextVertexFormatId = 1;
|
|
169
|
-
releasedTextureHandles = 0;
|
|
170
|
-
nativeEnvironmentBindings = 0;
|
|
171
|
-
nativeShadowMapBindings = 0;
|
|
172
|
-
shadowRenderTargetsAllocated = 0;
|
|
173
|
-
lastError = null;
|
|
174
|
-
frameActive = false;
|
|
175
|
-
viewportWidth = 0;
|
|
176
|
-
viewportHeight = 0;
|
|
177
197
|
maxVertexAttributes;
|
|
178
198
|
anisotropicFilteringExtension;
|
|
179
199
|
maxTextureAnisotropy;
|
|
@@ -185,16 +205,15 @@ export class WebGL2Device {
|
|
|
185
205
|
* why the parity table listed context-loss recovery as a gap while the listeners existed — the
|
|
186
206
|
* device layer was never the gap, the absence of a public signal was.
|
|
187
207
|
*/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
contextRestoredListener;
|
|
192
|
-
canvas;
|
|
208
|
+
host;
|
|
209
|
+
/** C-28: device capability probe, filled from extension detection in the ctor. */
|
|
210
|
+
probe;
|
|
193
211
|
static create(options) {
|
|
194
212
|
const gl = options.canvas.getContext("webgl2", {
|
|
195
213
|
antialias: options.antialias ?? true,
|
|
196
214
|
alpha: options.alpha ?? false,
|
|
197
|
-
preserveDrawingBuffer: options.preserveDrawingBuffer ?? false
|
|
215
|
+
preserveDrawingBuffer: options.preserveDrawingBuffer ?? false,
|
|
216
|
+
...(options.powerPreference !== undefined ? { powerPreference: options.powerPreference } : {})
|
|
198
217
|
});
|
|
199
218
|
if (!gl) {
|
|
200
219
|
throw new RenderDeviceError("WebGL2 is not available for the provided canvas", "WEBGL2_UNAVAILABLE");
|
|
@@ -251,39 +270,34 @@ export class WebGL2Device {
|
|
|
251
270
|
...(gl.getExtension("EXT_color_buffer_float") ? ["hdr-render-targets", "float-readback"] : [])
|
|
252
271
|
]
|
|
253
272
|
};
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
this.
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
canvas.addEventListener("webglcontextlost", this.contextLostListener);
|
|
285
|
-
canvas.addEventListener("webglcontextrestored", this.contextRestoredListener);
|
|
286
|
-
}
|
|
273
|
+
const host = {
|
|
274
|
+
gl,
|
|
275
|
+
stateCache: this.stateCache,
|
|
276
|
+
counters: new WebGL2Counters(),
|
|
277
|
+
buffers: this.buffers,
|
|
278
|
+
shaders: this.shaders,
|
|
279
|
+
renderTargets: this.renderTargets,
|
|
280
|
+
activeRenderTarget: null,
|
|
281
|
+
disposed: false,
|
|
282
|
+
contextLost: false,
|
|
283
|
+
errorCheckMode: this.errorCheckMode,
|
|
284
|
+
anisotropicFilteringExtension: this.anisotropicFilteringExtension,
|
|
285
|
+
maxTextureAnisotropy: this.maxTextureAnisotropy,
|
|
286
|
+
maxVertexAttributes: this.maxVertexAttributes,
|
|
287
|
+
resolveMultisampleTarget: (target) => this.resolveMultisampleTarget(target),
|
|
288
|
+
device: this
|
|
289
|
+
};
|
|
290
|
+
host.lifecycle = new WebGL2ContextLifecycle(host, canvas);
|
|
291
|
+
host.textureRegistry = new WebGL2TextureRegistry(host);
|
|
292
|
+
host.samplers = new WebGL2SamplerRegistry(host);
|
|
293
|
+
host.drawBinder = new WebGL2DrawCallBinder(host);
|
|
294
|
+
// #94 (Q-01-1): the C-29 restore hook (`renderer/DeviceLifecycle.ts`)
|
|
295
|
+
// calls `host.invalidateGpuObjects?.()` before the registry rebuild.
|
|
296
|
+
host.invalidateGpuObjects = () => this.invalidateGpuObjects();
|
|
297
|
+
host.probe = new WebGL2ReadbackProbe(host);
|
|
298
|
+
host.post = new WebGL2LegacyPostPipeline(host);
|
|
299
|
+
this.host = host;
|
|
300
|
+
this.probe = createWebGL2DeviceProbe(gl);
|
|
287
301
|
}
|
|
288
302
|
/**
|
|
289
303
|
* Subscribe to WebGL context loss. Returns an unsubscribe function.
|
|
@@ -292,21 +306,190 @@ export class WebGL2Device {
|
|
|
292
306
|
* memory pressure, on driver reset, or when a tab is backgrounded too long. What a caller can do is
|
|
293
307
|
* be told, so it can recreate resources rather than render nothing.
|
|
294
308
|
*/
|
|
309
|
+
get disposed() {
|
|
310
|
+
return this.host.disposed;
|
|
311
|
+
}
|
|
312
|
+
set disposed(value) {
|
|
313
|
+
this.host.disposed = value;
|
|
314
|
+
}
|
|
315
|
+
get contextLost() {
|
|
316
|
+
return this.host.contextLost;
|
|
317
|
+
}
|
|
318
|
+
set contextLost(value) {
|
|
319
|
+
this.host.contextLost = value;
|
|
320
|
+
}
|
|
295
321
|
onDeviceLost(listener) {
|
|
296
|
-
this.
|
|
297
|
-
return () => this.deviceLostListeners.delete(listener);
|
|
322
|
+
return this.host.lifecycle.onDeviceLost(listener);
|
|
298
323
|
}
|
|
299
|
-
/** Subscribe to context restoration. Returns an unsubscribe function. */
|
|
300
324
|
onDeviceRestored(listener) {
|
|
301
|
-
this.
|
|
302
|
-
return () => this.deviceRestoredListeners.delete(listener);
|
|
325
|
+
return this.host.lifecycle.onDeviceRestored(listener);
|
|
303
326
|
}
|
|
304
|
-
/** True while the WebGL context is lost. Polling alternative to {@link onDeviceLost}. */
|
|
305
327
|
isDeviceLost() {
|
|
306
|
-
return this.
|
|
328
|
+
return this.host.lifecycle.isDeviceLost();
|
|
329
|
+
}
|
|
330
|
+
beginFrame(width, height) {
|
|
331
|
+
this.host.lifecycle.beginFrame(width, height);
|
|
332
|
+
}
|
|
333
|
+
clear(color) {
|
|
334
|
+
this.host.lifecycle.clear(color);
|
|
335
|
+
}
|
|
336
|
+
clearRenderTarget(color, attachment) {
|
|
337
|
+
this.host.lifecycle.clearRenderTarget(color, attachment);
|
|
338
|
+
}
|
|
339
|
+
endFrame() {
|
|
340
|
+
this.host.lifecycle.endFrame();
|
|
341
|
+
}
|
|
342
|
+
draw(command) {
|
|
343
|
+
this.host.drawBinder.draw(command);
|
|
344
|
+
}
|
|
345
|
+
readPixels(x, y, width, height, attachment) {
|
|
346
|
+
return this.host.probe.readPixels(x, y, width, height, attachment);
|
|
347
|
+
}
|
|
348
|
+
readFloatPixels(x, y, width, height) {
|
|
349
|
+
return this.host.probe.readFloatPixels(x, y, width, height);
|
|
350
|
+
}
|
|
351
|
+
readDepthPixels(x, y, width, height) {
|
|
352
|
+
return this.host.probe.readDepthPixels(x, y, width, height);
|
|
353
|
+
}
|
|
354
|
+
writeRenderTargetPixels(target, pixels) {
|
|
355
|
+
this.host.probe.writeRenderTargetPixels(target, pixels);
|
|
356
|
+
}
|
|
357
|
+
presentRenderTarget(source) {
|
|
358
|
+
this.host.post.presentRenderTarget(source);
|
|
359
|
+
}
|
|
360
|
+
presentLdrPostprocess(source, options) {
|
|
361
|
+
this.host.post.presentLdrPostprocess(source, options);
|
|
362
|
+
}
|
|
363
|
+
executeReflectionSurfaceSsr(source, normalMask, output, options) {
|
|
364
|
+
this.host.post.executeReflectionSurfaceSsr(source, normalMask, output, options);
|
|
365
|
+
}
|
|
366
|
+
getBloomDiagnostics() {
|
|
367
|
+
return this.host.post.getBloomDiagnostics();
|
|
368
|
+
}
|
|
369
|
+
/** C-28: partial counters from existing diagnostics and the wrapped counter fields. */
|
|
370
|
+
counters() {
|
|
371
|
+
const diagnostics = this.getDiagnostics();
|
|
372
|
+
return {
|
|
373
|
+
drawCalls: this.host.counters.drawCalls,
|
|
374
|
+
bufferCreates: diagnostics.buffers,
|
|
375
|
+
textureUploads: diagnostics.textures ?? 0,
|
|
376
|
+
readbacks: this.host.counters.readbacks,
|
|
377
|
+
renderTargetsCreated: diagnostics.renderTargets ?? 0,
|
|
378
|
+
programCompiles: this.host.counters.programCompiles,
|
|
379
|
+
liveBuffers: diagnostics.buffers,
|
|
380
|
+
liveVertexArrays: this.host.drawBinder.vertexArrayCache.size,
|
|
381
|
+
textureBytes: diagnostics.textureBytes ?? 0,
|
|
382
|
+
renderTargetBytes: 0
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
resetFrameCounters() {
|
|
386
|
+
this.host.counters.drawCalls = 0;
|
|
387
|
+
this.host.counters.readbacks = 0;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* PRD-01 §6.4 / 01-S7: with `KHR_parallel_shader_compile`, compile and
|
|
391
|
+
* link are issued without querying status, and the promise resolves once
|
|
392
|
+
* `COMPLETION_STATUS_KHR` reports done (polled per animation frame), so
|
|
393
|
+
* the caller's frame is not blocked. Without the extension this is the
|
|
394
|
+
* synchronous `createShaderProgram` wrapped in a resolved promise.
|
|
395
|
+
*/
|
|
396
|
+
compileAsync(sources) {
|
|
397
|
+
const ext = this.parallelShaderCompileExtension();
|
|
398
|
+
if (!ext)
|
|
399
|
+
return Promise.resolve(this.createShaderProgram(sources));
|
|
400
|
+
this.host.lifecycle.assertAlive();
|
|
401
|
+
this.assertShaderMarker(sources);
|
|
402
|
+
const vertexShader = this.issueShaderCompile(this.gl.VERTEX_SHADER, sources.vertex, sources.label);
|
|
403
|
+
const fragmentShader = this.issueShaderCompile(this.gl.FRAGMENT_SHADER, sources.fragment, sources.label);
|
|
404
|
+
const program = this.gl.createProgram();
|
|
405
|
+
if (!program) {
|
|
406
|
+
throw new RenderDeviceError("Failed to allocate WebGL shader program", "WEBGL_ALLOCATION_FAILED");
|
|
407
|
+
}
|
|
408
|
+
this.host.counters.shaderProgramCreateCount += 1;
|
|
409
|
+
this.gl.attachShader(program, vertexShader);
|
|
410
|
+
this.gl.attachShader(program, fragmentShader);
|
|
411
|
+
this.gl.linkProgram(program);
|
|
412
|
+
this.host.counters.programCompiles += 1;
|
|
413
|
+
this.parallelCompilesPending += 1;
|
|
414
|
+
return new Promise((resolve, reject) => {
|
|
415
|
+
const poll = () => {
|
|
416
|
+
if (this.host.disposed || this.host.contextLost) {
|
|
417
|
+
this.parallelCompilesPending -= 1;
|
|
418
|
+
reject(new RenderDeviceError("Device lost during parallel shader compile", "DEVICE_LOST", { label: sources.label }));
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
if (this.gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR) !== true) {
|
|
422
|
+
scheduleParallelCompilePoll(poll);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
this.parallelCompilesPending -= 1;
|
|
426
|
+
try {
|
|
427
|
+
for (const [shader, type] of [[vertexShader, "vertex"], [fragmentShader, "fragment"]]) {
|
|
428
|
+
if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
|
|
429
|
+
const log = this.gl.getShaderInfoLog(shader) ?? "Unknown shader compile error";
|
|
430
|
+
this.gl.deleteShader(vertexShader);
|
|
431
|
+
this.gl.deleteShader(fragmentShader);
|
|
432
|
+
this.gl.deleteProgram(program);
|
|
433
|
+
throw new RenderDeviceError("WebGL shader compile failed", "SHADER_COMPILE_FAILED", { label: sources.label, log, stage: type });
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
this.gl.deleteShader(vertexShader);
|
|
437
|
+
this.gl.deleteShader(fragmentShader);
|
|
438
|
+
resolve(this.finalizeLinkedProgram(program, sources));
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
reject(error);
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
scheduleParallelCompilePoll(poll);
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
/** Programs issued through `compileAsync`'s parallel path that have not completed yet. */
|
|
448
|
+
parallelCompilesPending = 0;
|
|
449
|
+
parallelCompileExt;
|
|
450
|
+
parallelShaderCompileExtension() {
|
|
451
|
+
if (this.parallelCompileExt === undefined) {
|
|
452
|
+
this.parallelCompileExt = this.gl.getExtension("KHR_parallel_shader_compile") ?? null;
|
|
453
|
+
}
|
|
454
|
+
return this.parallelCompileExt;
|
|
455
|
+
}
|
|
456
|
+
issueShaderCompile(type, source, label) {
|
|
457
|
+
const shader = this.gl.createShader(type);
|
|
458
|
+
if (!shader) {
|
|
459
|
+
throw new RenderDeviceError("Failed to allocate WebGL shader", "WEBGL_ALLOCATION_FAILED", { label });
|
|
460
|
+
}
|
|
461
|
+
this.gl.shaderSource(shader, source);
|
|
462
|
+
this.gl.compileShader(shader);
|
|
463
|
+
return shader;
|
|
464
|
+
}
|
|
465
|
+
assertShaderMarker(sources) {
|
|
466
|
+
if (!sources.vertex.includes(sources.marker) || !sources.fragment.includes(sources.marker)) {
|
|
467
|
+
throw new RenderDeviceError("Shader source marker is missing from compiled sources", "SHADER_MARKER_MISSING", {
|
|
468
|
+
label: sources.label,
|
|
469
|
+
marker: sources.marker
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
multiDrawElementsInstanced(draws) {
|
|
474
|
+
this.host.drawBinder.multiDrawElementsInstanced(draws);
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* #94 (Q-01-1, C-28/C-29): forget every GL object name and uploaded value
|
|
478
|
+
* cached against the lost context — VAOs, uniform locations, last-value
|
|
479
|
+
* uniform snapshots, the GL state shadow and texture-unit bindings — so
|
|
480
|
+
* they recreate lazily on the next draw after `webglcontextrestored`.
|
|
481
|
+
* `counters().liveVertexArrays` reads 0 afterwards. Buffers, textures and
|
|
482
|
+
* programs are recreated by the C-29 ResourceRegistry rebuild that runs
|
|
483
|
+
* right after this in the restore hook.
|
|
484
|
+
*/
|
|
485
|
+
invalidateGpuObjects() {
|
|
486
|
+
this.host.drawBinder.invalidateGpuObjects();
|
|
487
|
+
this.host.stateCache.invalidate();
|
|
488
|
+
this.host.samplers.activeTextureUnitIndex = -1;
|
|
489
|
+
this.host.samplers.textureUnitBindings.clear();
|
|
307
490
|
}
|
|
308
491
|
createBuffer(usage, byteLength, initialData) {
|
|
309
|
-
this.assertAlive();
|
|
492
|
+
this.host.lifecycle.assertAlive();
|
|
310
493
|
if (byteLength <= 0 || !Number.isInteger(byteLength)) {
|
|
311
494
|
throw new RenderDeviceError("Buffer byteLength must be a positive integer", "INVALID_BUFFER_SIZE", { byteLength });
|
|
312
495
|
}
|
|
@@ -314,8 +497,12 @@ export class WebGL2Device {
|
|
|
314
497
|
if (!handle) {
|
|
315
498
|
throw new RenderDeviceError("Failed to allocate WebGL buffer", "WEBGL_ALLOCATION_FAILED");
|
|
316
499
|
}
|
|
317
|
-
const target = usage === "index"
|
|
318
|
-
|
|
500
|
+
const target = usage === "index"
|
|
501
|
+
? this.gl.ELEMENT_ARRAY_BUFFER
|
|
502
|
+
: usage === "uniform"
|
|
503
|
+
? this.gl.UNIFORM_BUFFER
|
|
504
|
+
: this.gl.ARRAY_BUFFER;
|
|
505
|
+
this.host.drawBinder.bindNoVertexArray();
|
|
319
506
|
this.stateCache.bindBuffer(target, handle, () => this.gl.bindBuffer(target, handle));
|
|
320
507
|
this.gl.bufferData(target, byteLength, this.gl.DYNAMIC_DRAW);
|
|
321
508
|
if (initialData) {
|
|
@@ -328,12 +515,20 @@ export class WebGL2Device {
|
|
|
328
515
|
this.gl.bufferSubData(target, 0, initialData);
|
|
329
516
|
}
|
|
330
517
|
const buffer = new WebGL2Buffer(this.nextId++, usage, byteLength, target, handle, this.gl);
|
|
518
|
+
buffer.onDispose = () => {
|
|
519
|
+
// §6.1 declared leak fix: cached VAOs key on buffer ids; a dead buffer's
|
|
520
|
+
// entries must die with it, and the live-buffer set drops the corpse
|
|
521
|
+
// (`disposedBuffers` stays meaningful via the monotonic counter).
|
|
522
|
+
this.host.drawBinder.evictVertexArraysForBuffer(buffer.id);
|
|
523
|
+
this.buffers.delete(buffer);
|
|
524
|
+
this.disposedBufferCount += 1;
|
|
525
|
+
};
|
|
331
526
|
this.buffers.add(buffer);
|
|
332
527
|
return buffer;
|
|
333
528
|
}
|
|
334
529
|
updateBuffer(buffer, byteOffset, data) {
|
|
335
|
-
this.assertAlive();
|
|
336
|
-
const webglBuffer = this.requireBuffer(buffer);
|
|
530
|
+
this.host.lifecycle.assertAlive();
|
|
531
|
+
const webglBuffer = this.host.drawBinder.requireBuffer(buffer);
|
|
337
532
|
if (byteOffset < 0 || byteOffset + data.byteLength > webglBuffer.byteLength) {
|
|
338
533
|
throw new RenderDeviceError("Buffer update range is out of bounds", "BUFFER_RANGE_OUT_OF_BOUNDS", {
|
|
339
534
|
byteOffset,
|
|
@@ -341,14 +536,22 @@ export class WebGL2Device {
|
|
|
341
536
|
byteLength: webglBuffer.byteLength
|
|
342
537
|
});
|
|
343
538
|
}
|
|
344
|
-
this.bindNoVertexArray();
|
|
539
|
+
this.host.drawBinder.bindNoVertexArray();
|
|
345
540
|
this.stateCache.bindBuffer(webglBuffer.target, webglBuffer.handle, () => this.gl.bindBuffer(webglBuffer.target, webglBuffer.handle));
|
|
346
541
|
this.gl.bufferSubData(webglBuffer.target, byteOffset, data);
|
|
347
|
-
this.bufferUpdateCount += 1;
|
|
542
|
+
this.host.counters.bufferUpdateCount += 1;
|
|
543
|
+
}
|
|
544
|
+
bindUniformBuffer(buffer, binding) {
|
|
545
|
+
this.host.lifecycle.assertAlive();
|
|
546
|
+
const webglBuffer = this.host.drawBinder.requireBuffer(buffer);
|
|
547
|
+
if (webglBuffer.target !== this.gl.UNIFORM_BUFFER) {
|
|
548
|
+
throw new RenderDeviceError("Buffer was not created with usage 'uniform'", "INVALID_BUFFER_USAGE", { bufferId: buffer.id });
|
|
549
|
+
}
|
|
550
|
+
this.gl.bindBufferBase(this.gl.UNIFORM_BUFFER, binding, webglBuffer.handle);
|
|
348
551
|
}
|
|
349
552
|
readBuffer(buffer, byteOffset = 0, byteLength = buffer.byteLength - byteOffset) {
|
|
350
|
-
this.assertAlive();
|
|
351
|
-
const webglBuffer = this.requireBuffer(buffer);
|
|
553
|
+
this.host.lifecycle.assertAlive();
|
|
554
|
+
const webglBuffer = this.host.drawBinder.requireBuffer(buffer);
|
|
352
555
|
if (byteOffset < 0 || byteLength < 0 || byteOffset + byteLength > webglBuffer.byteLength) {
|
|
353
556
|
throw new RenderDeviceError("Buffer read range is out of bounds", "BUFFER_RANGE_OUT_OF_BOUNDS", {
|
|
354
557
|
byteOffset,
|
|
@@ -357,42 +560,59 @@ export class WebGL2Device {
|
|
|
357
560
|
});
|
|
358
561
|
}
|
|
359
562
|
const output = new Uint8Array(byteLength);
|
|
360
|
-
this.bindNoVertexArray();
|
|
563
|
+
this.host.drawBinder.bindNoVertexArray();
|
|
361
564
|
this.stateCache.bindBuffer(webglBuffer.target, webglBuffer.handle, () => this.gl.bindBuffer(webglBuffer.target, webglBuffer.handle));
|
|
362
565
|
this.gl.getBufferSubData(webglBuffer.target, byteOffset, output);
|
|
363
566
|
return output;
|
|
364
567
|
}
|
|
365
568
|
createShaderProgram(sources) {
|
|
366
|
-
this.assertAlive();
|
|
367
|
-
|
|
368
|
-
throw new RenderDeviceError("Shader source marker is missing from compiled sources", "SHADER_MARKER_MISSING", {
|
|
369
|
-
label: sources.label,
|
|
370
|
-
marker: sources.marker
|
|
371
|
-
});
|
|
372
|
-
}
|
|
569
|
+
this.host.lifecycle.assertAlive();
|
|
570
|
+
this.assertShaderMarker(sources);
|
|
373
571
|
const vertexShader = this.compileShader(this.gl.VERTEX_SHADER, sources.vertex, sources.label);
|
|
374
572
|
const fragmentShader = this.compileShader(this.gl.FRAGMENT_SHADER, sources.fragment, sources.label);
|
|
375
573
|
const program = this.gl.createProgram();
|
|
376
574
|
if (!program) {
|
|
377
575
|
throw new RenderDeviceError("Failed to allocate WebGL shader program", "WEBGL_ALLOCATION_FAILED");
|
|
378
576
|
}
|
|
379
|
-
this.shaderProgramCreateCount += 1;
|
|
577
|
+
this.host.counters.shaderProgramCreateCount += 1;
|
|
380
578
|
this.gl.attachShader(program, vertexShader);
|
|
381
579
|
this.gl.attachShader(program, fragmentShader);
|
|
382
580
|
this.gl.linkProgram(program);
|
|
581
|
+
this.host.counters.programCompiles += 1;
|
|
383
582
|
this.gl.deleteShader(vertexShader);
|
|
384
583
|
this.gl.deleteShader(fragmentShader);
|
|
584
|
+
return this.finalizeLinkedProgram(program, sources);
|
|
585
|
+
}
|
|
586
|
+
/** LINK_STATUS check, named-block bindings and reflection for a linked program. */
|
|
587
|
+
finalizeLinkedProgram(program, sources) {
|
|
385
588
|
if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
|
|
386
589
|
const log = this.gl.getProgramInfoLog(program) ?? "Unknown shader link error";
|
|
387
590
|
this.gl.deleteProgram(program);
|
|
388
591
|
throw new RenderDeviceError("WebGL shader link failed", "SHADER_LINK_FAILED", { label: sources.label, log });
|
|
389
592
|
}
|
|
593
|
+
// T0-02/C-08: generated blocks declare `layout(std140)` with no baked
|
|
594
|
+
// `binding=`; the named-block → binding-point assignment is fixed here so
|
|
595
|
+
// every linked program gets AuraFrame→0 and AuraLights→1 regardless of
|
|
596
|
+
// declaration order. Programs that do not declare a block are skipped.
|
|
597
|
+
for (const [blockName, binding] of NAMED_UNIFORM_BLOCK_BINDINGS) {
|
|
598
|
+
const index = this.gl.getUniformBlockIndex(program, blockName);
|
|
599
|
+
if (index !== this.gl.INVALID_INDEX) {
|
|
600
|
+
this.gl.uniformBlockBinding(program, index, binding);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
390
603
|
const shader = new WebGL2ShaderProgram(this.nextId++, sources.label, sources.marker, this.reflectProgram(program), program, this.gl);
|
|
391
604
|
this.shaders.add(shader);
|
|
392
605
|
return shader;
|
|
393
606
|
}
|
|
394
607
|
createRenderTarget(descriptor) {
|
|
395
|
-
this.assertAlive();
|
|
608
|
+
this.host.lifecycle.assertAlive();
|
|
609
|
+
if ((descriptor.dimension !== undefined && descriptor.dimension !== "2d") ||
|
|
610
|
+
descriptor.layers !== undefined ||
|
|
611
|
+
descriptor.depthOnly === true ||
|
|
612
|
+
descriptor.depthCompare === true ||
|
|
613
|
+
(descriptor.colorAttachments?.length ?? 0) > 1) {
|
|
614
|
+
return this.createFeatureRenderTarget(descriptor);
|
|
615
|
+
}
|
|
396
616
|
if (!Number.isInteger(descriptor.width) ||
|
|
397
617
|
descriptor.width <= 0 ||
|
|
398
618
|
!Number.isInteger(descriptor.height) ||
|
|
@@ -457,8 +677,15 @@ export class WebGL2Device {
|
|
|
457
677
|
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
|
|
458
678
|
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
459
679
|
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
460
|
-
|
|
461
|
-
|
|
680
|
+
// A single `colorAttachments` entry is the attachment-0 format (CONTRACTS
|
|
681
|
+
// §3.4) and wins over the legacy `format` field. Before this, the 2d path
|
|
682
|
+
// ignored it, so `createHdrTarget` ({ format: "rgba8", colorAttachments:
|
|
683
|
+
// [{ format: "rgba16f" }] }) without coverage allocated an RGBA8 "HDR"
|
|
684
|
+
// scene target: linear radiance clamped at 1.0 and 8-bit dark banding
|
|
685
|
+
// before tone mapping (GPU run 38190015020: device ACES of 4.0 = 226 vs
|
|
686
|
+
// three 250; tonemap-ramp dark swatches ΔE2000 13-30).
|
|
687
|
+
const format = renderTargetColorFormat(descriptor);
|
|
688
|
+
const textureFormat = resolveRenderTargetFormat(this.gl, format);
|
|
462
689
|
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, textureFormat.internalFormat, descriptor.width, descriptor.height, 0, this.gl.RGBA, textureFormat.type, null);
|
|
463
690
|
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
|
|
464
691
|
this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, colorHandle, 0);
|
|
@@ -516,563 +743,376 @@ export class WebGL2Device {
|
|
|
516
743
|
this.renderTargets.add(target);
|
|
517
744
|
// Shadow passes label their depth target after the shadow map texture, so the
|
|
518
745
|
// label is the device-side signal that a shadow depth target was allocated.
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
746
|
+
// Cascaded maps use the established renderer-csm-cascade-* labels.
|
|
747
|
+
// Count their actual allocation too, including the first shadow frame.
|
|
748
|
+
if (/shadow|(?:^|-)csm(?:-|$)/i.test(descriptor.label ?? ""))
|
|
749
|
+
this.host.counters.shadowRenderTargetsAllocated += 1;
|
|
750
|
+
this.host.textureRegistry.textures.set(target.colorTexture, colorHandle);
|
|
751
|
+
this.host.textureRegistry.textureUploadModes.set(target.colorTexture, "rgba8");
|
|
523
752
|
if (depthTexture && depthTextureHandle) {
|
|
524
|
-
this.textures.set(depthTexture, depthTextureHandle);
|
|
525
|
-
this.textureUploadModes.set(depthTexture, "depth-render-target");
|
|
753
|
+
this.host.textureRegistry.textures.set(depthTexture, depthTextureHandle);
|
|
754
|
+
this.host.textureRegistry.textureUploadModes.set(depthTexture, "depth-render-target");
|
|
526
755
|
}
|
|
527
756
|
return target;
|
|
528
757
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
throw new RenderDeviceError("Render target
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
this.activeRenderTarget = target;
|
|
546
|
-
this.stateCache.bindFramebuffer(this.gl.FRAMEBUFFER, target.drawFramebuffer, () => this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, target.drawFramebuffer));
|
|
547
|
-
this.stateCache.viewport(0, 0, target.width, target.height, () => this.gl.viewport(0, 0, target.width, target.height));
|
|
548
|
-
}
|
|
549
|
-
resolveMultisampleTarget(target) {
|
|
550
|
-
if (target.sampleCount <= 1 || !target.needsResolve)
|
|
551
|
-
return;
|
|
552
|
-
const previousFramebuffer = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
|
|
553
|
-
this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER, target.drawFramebuffer);
|
|
554
|
-
this.gl.bindFramebuffer(this.gl.DRAW_FRAMEBUFFER, target.framebuffer);
|
|
555
|
-
let mask = this.gl.COLOR_BUFFER_BIT;
|
|
556
|
-
if (target.depthTextureHandle)
|
|
557
|
-
mask |= this.gl.DEPTH_BUFFER_BIT;
|
|
558
|
-
this.gl.blitFramebuffer(0, 0, target.width, target.height, 0, 0, target.width, target.height, mask, this.gl.NEAREST);
|
|
559
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, previousFramebuffer);
|
|
560
|
-
target.needsResolve = false;
|
|
561
|
-
this.stateCache.invalidate();
|
|
562
|
-
}
|
|
563
|
-
writeRenderTargetPixels(target, pixels) {
|
|
564
|
-
this.assertAlive();
|
|
565
|
-
if (!(target instanceof WebGL2RenderTarget) || !this.renderTargets.has(target) || target.disposed) {
|
|
566
|
-
throw new RenderDeviceError("Render target is not a live WebGL2 resource owned by this device", "INVALID_RESOURCE", {
|
|
567
|
-
targetId: target.id
|
|
568
|
-
});
|
|
569
|
-
}
|
|
570
|
-
if (target.colorTexture.format !== "rgba8") {
|
|
571
|
-
throw new RenderDeviceError("Byte pixel uploads are only supported for rgba8 WebGL2 render targets", "INVALID_PIXEL_UPLOAD_FORMAT", {
|
|
572
|
-
targetId: target.id,
|
|
573
|
-
format: target.colorTexture.format
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
if (pixels.length !== target.width * target.height * 4) {
|
|
577
|
-
throw new RenderDeviceError("Render-target pixel upload must contain width * height * 4 bytes", "INVALID_PIXEL_UPLOAD_SIZE", {
|
|
578
|
-
targetId: target.id,
|
|
579
|
-
byteLength: pixels.length,
|
|
580
|
-
expectedByteLength: target.width * target.height * 4
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
const textureUnit0 = this.captureTextureUnit0();
|
|
584
|
-
try {
|
|
585
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, target.colorHandle);
|
|
586
|
-
this.gl.texSubImage2D(this.gl.TEXTURE_2D, 0, 0, 0, target.width, target.height, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels);
|
|
587
|
-
target.needsResolve = false;
|
|
588
|
-
}
|
|
589
|
-
finally {
|
|
590
|
-
this.restoreTextureUnit0(textureUnit0);
|
|
591
|
-
}
|
|
592
|
-
this.lastError = this.readError();
|
|
593
|
-
if (this.lastError) {
|
|
594
|
-
throw new RenderDeviceError("WebGL2 render-target pixel upload failed", "WEBGL_PIXEL_UPLOAD_FAILED", {
|
|
595
|
-
targetId: target.id,
|
|
596
|
-
error: this.lastError
|
|
597
|
-
});
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
presentRenderTarget(source) {
|
|
601
|
-
this.assertAlive();
|
|
602
|
-
if (!(source instanceof WebGL2RenderTarget) || !this.renderTargets.has(source) || source.disposed) {
|
|
603
|
-
throw new RenderDeviceError("Render target is not a live WebGL2 resource owned by this device", "INVALID_RESOURCE", {
|
|
604
|
-
targetId: source.id
|
|
758
|
+
/**
|
|
759
|
+
* PR 0a render-target fields (CONTRACTS §3.4): `dimension`/`layers` (cube +
|
|
760
|
+
* 2d-array layered targets rendered through `layerTargets`), `depthOnly`
|
|
761
|
+
* (no color attachment), `depthCompare` (comparison-sampler depth texture)
|
|
762
|
+
* and `colorAttachments` (MRT, per-layer `drawBuffers` state).
|
|
763
|
+
*/
|
|
764
|
+
createFeatureRenderTarget(descriptor) {
|
|
765
|
+
const gl = this.gl;
|
|
766
|
+
if (!Number.isInteger(descriptor.width) ||
|
|
767
|
+
descriptor.width <= 0 ||
|
|
768
|
+
!Number.isInteger(descriptor.height) ||
|
|
769
|
+
descriptor.height <= 0) {
|
|
770
|
+
throw new RenderDeviceError("Render target dimensions must be positive integers", "INVALID_RENDER_TARGET_SIZE", {
|
|
771
|
+
width: descriptor.width,
|
|
772
|
+
height: descriptor.height,
|
|
773
|
+
label: descriptor.label
|
|
605
774
|
});
|
|
606
775
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
|
|
613
|
-
this.lastError = this.readError();
|
|
614
|
-
if (this.lastError) {
|
|
615
|
-
throw new RenderDeviceError(`WebGL2 render-target presentation failed: ${this.lastError}`, "WEBGL_PRESENT_FAILED", {
|
|
616
|
-
targetId: source.id,
|
|
617
|
-
error: this.lastError
|
|
776
|
+
const dimension = descriptor.dimension ?? "2d";
|
|
777
|
+
if (descriptor.layers !== undefined && (!Number.isInteger(descriptor.layers) || descriptor.layers < 1)) {
|
|
778
|
+
throw new RenderDeviceError("Render target layer count must be a positive integer", "INVALID_RENDER_TARGET_SIZE", {
|
|
779
|
+
layers: descriptor.layers,
|
|
780
|
+
label: descriptor.label
|
|
618
781
|
});
|
|
619
782
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
targetId: source.id
|
|
783
|
+
if (descriptor.layers !== undefined && dimension !== "2d-array") {
|
|
784
|
+
throw new RenderDeviceError("Render target `layers` only applies to dimension \"2d-array\"", "INVALID_RENDER_TARGET_SIZE", {
|
|
785
|
+
dimension,
|
|
786
|
+
layers: descriptor.layers,
|
|
787
|
+
label: descriptor.label
|
|
626
788
|
});
|
|
627
789
|
}
|
|
628
|
-
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
const ssaoPass = options.passes.find((pass) => pass.name === "ssao");
|
|
634
|
-
const ssrPass = options.passes.find((pass) => pass.name === "ssr");
|
|
635
|
-
const taaPass = options.passes.find((pass) => pass.name === "taa");
|
|
636
|
-
const outlinePass = options.passes.find((pass) => pass.name === "outline");
|
|
637
|
-
if (source.colorTexture.format !== "rgba8" && !tonePass) {
|
|
638
|
-
throw new RenderDeviceError("WebGL2 HDR postprocess presentation requires a tone-mapping pass before LDR output.", "WEBGL_LDR_POSTPROCESS_FORMAT_UNSUPPORTED", {
|
|
639
|
-
targetId: source.id,
|
|
640
|
-
format: source.colorTexture.format
|
|
790
|
+
const layerCount = dimension === "cube" ? 6 : dimension === "2d-array" ? descriptor.layers ?? 1 : 1;
|
|
791
|
+
const depthOnly = descriptor.depthOnly === true;
|
|
792
|
+
if (depthOnly && (descriptor.colorAttachments?.length ?? 0) > 0) {
|
|
793
|
+
throw new RenderDeviceError("Render target cannot combine `depthOnly` with `colorAttachments`", "INVALID_RENDER_TARGET_SIZE", {
|
|
794
|
+
label: descriptor.label
|
|
641
795
|
});
|
|
642
796
|
}
|
|
643
|
-
if (
|
|
644
|
-
throw new RenderDeviceError("
|
|
645
|
-
|
|
646
|
-
format: source.colorTexture.format,
|
|
647
|
-
pass: depthOfFieldPass ? "depth-of-field" : motionBlurPass ? "motion-blur" : ssaoPass ? "ssao" : ssrPass ? "ssr" : taaPass ? "taa" : "outline"
|
|
797
|
+
if (depthOnly && descriptor.depth === false) {
|
|
798
|
+
throw new RenderDeviceError("Render target cannot combine `depthOnly` with `depth: false`", "INVALID_RENDER_TARGET_SIZE", {
|
|
799
|
+
label: descriptor.label
|
|
648
800
|
});
|
|
649
801
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
802
|
+
const sampleCount = descriptor.sampleCount ?? 1;
|
|
803
|
+
const colorAttachmentCount = depthOnly ? 0 : Math.max(1, descriptor.colorAttachments?.length ?? 1);
|
|
804
|
+
if (sampleCount > 1 && (depthOnly || descriptor.depthCompare === true || (descriptor.colorAttachments?.length ?? 0) > 1 || layerCount > 1)) {
|
|
805
|
+
throw new RenderDeviceError("Multisample render targets do not support layered, depth-only, compare or MRT descriptors", "INVALID_RENDER_TARGET_SAMPLE_COUNT", {
|
|
806
|
+
sampleCount,
|
|
807
|
+
label: descriptor.label
|
|
654
808
|
});
|
|
655
809
|
}
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
throw new RenderDeviceError("Output render target is not a live WebGL2 resource owned by this device", "INVALID_RESOURCE", {
|
|
663
|
-
targetId: outputTarget.id
|
|
810
|
+
const maxSamples = Number(gl.getParameter(gl.MAX_SAMPLES) ?? 1);
|
|
811
|
+
if (!Number.isInteger(sampleCount) || sampleCount < 1 || sampleCount > maxSamples) {
|
|
812
|
+
throw new RenderDeviceError("WebGL2 render-target sampleCount must be an integer supported by MAX_SAMPLES.", "INVALID_RENDER_TARGET_SAMPLE_COUNT", {
|
|
813
|
+
sampleCount,
|
|
814
|
+
maxSamples,
|
|
815
|
+
label: descriptor.label
|
|
664
816
|
});
|
|
665
817
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
818
|
+
const label = descriptor.label ?? "render-target";
|
|
819
|
+
const textureTarget = dimension === "cube" ? gl.TEXTURE_CUBE_MAP : dimension === "2d-array" ? gl.TEXTURE_2D_ARRAY : gl.TEXTURE_2D;
|
|
820
|
+
const depthMode = depthOnly || descriptor.depth === "texture" || (layerCount > 1 && descriptor.depth !== false) ? "texture" : descriptor.depth === false ? "none" : "renderbuffer";
|
|
821
|
+
const depthCompare = descriptor.depthCompare === true;
|
|
822
|
+
const colorFormats = depthOnly
|
|
823
|
+
? []
|
|
824
|
+
: colorAttachmentCount === 1 && !descriptor.colorAttachments
|
|
825
|
+
? [descriptor.format ?? "rgba8"]
|
|
826
|
+
: (descriptor.colorAttachments ?? [{ format: descriptor.format ?? "rgba8" }]).map((attachment) => attachment.format);
|
|
827
|
+
const colorHandles = [];
|
|
828
|
+
const colorTextures = [];
|
|
829
|
+
let depthTextureHandle = null;
|
|
830
|
+
const layerFramebuffers = [];
|
|
831
|
+
const cleanup = () => {
|
|
832
|
+
for (const handle of colorHandles)
|
|
833
|
+
gl.deleteTexture(handle);
|
|
834
|
+
if (depthTextureHandle)
|
|
835
|
+
gl.deleteTexture(depthTextureHandle);
|
|
836
|
+
for (const framebuffer of layerFramebuffers)
|
|
837
|
+
gl.deleteFramebuffer(framebuffer);
|
|
838
|
+
};
|
|
839
|
+
const previousActiveTexture = gl.getParameter(gl.ACTIVE_TEXTURE);
|
|
840
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
841
|
+
const previousTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);
|
|
842
|
+
const previousCubeTexture = gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP);
|
|
843
|
+
const previousArrayTexture = gl.getParameter(gl.TEXTURE_BINDING_2D_ARRAY);
|
|
844
|
+
const previousFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
|
|
845
|
+
for (let attachment = 0; attachment < colorFormats.length; attachment += 1) {
|
|
846
|
+
const format = colorFormats[attachment];
|
|
847
|
+
const textureFormat = resolveRenderTargetFormat(gl, format);
|
|
848
|
+
const handle = gl.createTexture();
|
|
849
|
+
if (!handle) {
|
|
850
|
+
cleanup();
|
|
851
|
+
throw new RenderDeviceError("Failed to allocate WebGL render target", "WEBGL_ALLOCATION_FAILED", { label });
|
|
852
|
+
}
|
|
853
|
+
colorHandles.push(handle);
|
|
854
|
+
colorTextures.push(new Texture({ width: descriptor.width, height: descriptor.height, format, label: colorAttachmentCount > 1 ? `${label}-color-${attachment}` : descriptor.label ?? "render-target-color", dimension, layers: dimension === "2d" ? undefined : layerCount, renderAttachment: true }));
|
|
855
|
+
gl.bindTexture(textureTarget, handle);
|
|
856
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
857
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
858
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
859
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
860
|
+
if (dimension === "2d") {
|
|
861
|
+
gl.texImage2D(textureTarget, 0, textureFormat.internalFormat, descriptor.width, descriptor.height, 0, gl.RGBA, textureFormat.type, null);
|
|
862
|
+
}
|
|
863
|
+
else if (dimension === "cube") {
|
|
864
|
+
gl.texStorage2D(textureTarget, 1, renderTargetStorageFormat(gl, textureFormat.internalFormat), descriptor.width, descriptor.height);
|
|
865
|
+
}
|
|
866
|
+
else {
|
|
867
|
+
gl.texStorage3D(textureTarget, 1, renderTargetStorageFormat(gl, textureFormat.internalFormat), descriptor.width, descriptor.height, layerCount);
|
|
868
|
+
}
|
|
671
869
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
870
|
+
let depthTexture;
|
|
871
|
+
if (depthMode === "texture") {
|
|
872
|
+
depthTextureHandle = gl.createTexture();
|
|
873
|
+
if (!depthTextureHandle) {
|
|
874
|
+
cleanup();
|
|
875
|
+
throw new RenderDeviceError("Failed to allocate WebGL render target", "WEBGL_ALLOCATION_FAILED", { label });
|
|
876
|
+
}
|
|
877
|
+
depthTexture = new Texture({
|
|
878
|
+
width: descriptor.width,
|
|
879
|
+
height: descriptor.height,
|
|
880
|
+
format: "depth24",
|
|
881
|
+
label: `${label}-depth`,
|
|
882
|
+
dimension,
|
|
883
|
+
layers: dimension === "2d" ? undefined : layerCount,
|
|
884
|
+
renderAttachment: true
|
|
678
885
|
});
|
|
886
|
+
gl.bindTexture(textureTarget, depthTextureHandle);
|
|
887
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
888
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
889
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
890
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
891
|
+
if (depthCompare) {
|
|
892
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
|
|
893
|
+
gl.texParameteri(textureTarget, gl.TEXTURE_COMPARE_FUNC, gl.LEQUAL);
|
|
894
|
+
}
|
|
895
|
+
if (dimension === "2d-array") {
|
|
896
|
+
gl.texImage3D(textureTarget, 0, gl.DEPTH_COMPONENT24, descriptor.width, descriptor.height, layerCount, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
|
|
897
|
+
}
|
|
898
|
+
else if (dimension === "cube") {
|
|
899
|
+
gl.texStorage2D(textureTarget, 1, gl.DEPTH_COMPONENT24, descriptor.width, descriptor.height);
|
|
900
|
+
}
|
|
901
|
+
else {
|
|
902
|
+
gl.texImage2D(textureTarget, 0, gl.DEPTH_COMPONENT24, descriptor.width, descriptor.height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
|
|
903
|
+
}
|
|
679
904
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
const
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
const
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
}
|
|
704
|
-
if (motionBlurOptions) {
|
|
705
|
-
this.ensureMotionBlurVelocityTexture(source.width, source.height, motionBlurOptions.velocity);
|
|
706
|
-
}
|
|
707
|
-
if (taaOptions) {
|
|
708
|
-
this.ensureTaaHistoryTexture(source.width, source.height, taaOptions.history);
|
|
709
|
-
}
|
|
710
|
-
const outputWidth = webglOutputTarget?.width ?? (this.viewportWidth || this.gl.drawingBufferWidth);
|
|
711
|
-
const outputHeight = webglOutputTarget?.height ?? (this.viewportHeight || this.gl.drawingBufferHeight);
|
|
712
|
-
const previousState = this.prepareFullscreenPresentation(webglOutputTarget?.framebuffer ?? null, outputWidth, outputHeight);
|
|
713
|
-
try {
|
|
714
|
-
let ldrSourceHandle = source.colorHandle;
|
|
715
|
-
let temporarySourceIndex = -1;
|
|
716
|
-
if (bloomOptions && bloomResources) {
|
|
717
|
-
if (bloomOptions.quality === "performance") {
|
|
718
|
-
ldrSourceHandle = this.executeNativeBloomPasses(ldrSourceHandle, bloomResources, bloomOptions, vertexArray, sourceIsHdr);
|
|
719
|
-
temporarySourceIndex = 1;
|
|
720
|
-
this.recordBloomDiagnostics(bloomOptions, source.width, source.height, sourceIsHdr, 1);
|
|
721
|
-
}
|
|
722
|
-
else {
|
|
723
|
-
const plan = resolveBloomPyramidPlan(source.width, source.height, bloomOptions.quality, sourceIsHdr);
|
|
724
|
-
const pyramid = this.ensureBloomPyramidResources(plan, sourceIsHdr);
|
|
725
|
-
const pyramidResult = this.executeNativeBloomPyramidPasses(ldrSourceHandle, source.width, source.height, pyramid, {
|
|
726
|
-
textureA: bloomResources.textures[0],
|
|
727
|
-
framebufferA: bloomResources.framebuffers[0],
|
|
728
|
-
textureB: bloomResources.textures[1],
|
|
729
|
-
framebufferB: bloomResources.framebuffers[1]
|
|
730
|
-
}, bloomOptions, vertexArray, sourceIsHdr);
|
|
731
|
-
// The pyramid sum lands in ping-pong texture A; composite it with the
|
|
732
|
-
// source through the proven single-scale composite program.
|
|
733
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, bloomResources.framebuffers[1]);
|
|
734
|
-
this.gl.viewport(0, 0, source.width, source.height);
|
|
735
|
-
const pyramidComposite = this.ensureBloomCompositeProgram();
|
|
736
|
-
this.gl.useProgram(pyramidComposite);
|
|
737
|
-
this.gl.bindVertexArray(vertexArray);
|
|
738
|
-
this.bindFullscreenTexture(0, ldrSourceHandle);
|
|
739
|
-
this.bindFullscreenTexture(1, pyramidResult);
|
|
740
|
-
if (this.bloomCompositeLutTexture)
|
|
741
|
-
this.bindFullscreenTexture(2, this.bloomCompositeLutTexture);
|
|
742
|
-
this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_source"), 0);
|
|
743
|
-
this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_blurred"), 1);
|
|
744
|
-
this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_compositeLut"), 2);
|
|
745
|
-
this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_hdr"), sourceIsHdr ? 1 : 0);
|
|
746
|
-
this.gl.uniform1f(this.gl.getUniformLocation(pyramidComposite, "u_intensity"), bloomOptions.intensity);
|
|
747
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
748
|
-
ldrSourceHandle = bloomResources.textures[1];
|
|
749
|
-
// The composited result lives in texture B, so subsequent passes
|
|
750
|
-
// must write texture A (index 0) to avoid sampling a bound target.
|
|
751
|
-
temporarySourceIndex = 0;
|
|
752
|
-
this.recordBloomDiagnostics(bloomOptions, source.width, source.height, sourceIsHdr, plan.mipCount);
|
|
753
|
-
}
|
|
905
|
+
let depthRenderbufferHandle = null;
|
|
906
|
+
if (depthMode === "renderbuffer") {
|
|
907
|
+
depthRenderbufferHandle = gl.createRenderbuffer();
|
|
908
|
+
if (!depthRenderbufferHandle) {
|
|
909
|
+
cleanup();
|
|
910
|
+
throw new RenderDeviceError("Failed to allocate WebGL render target", "WEBGL_ALLOCATION_FAILED", { label });
|
|
911
|
+
}
|
|
912
|
+
const previousRenderbuffer = gl.getParameter(gl.RENDERBUFFER_BINDING);
|
|
913
|
+
gl.bindRenderbuffer(gl.RENDERBUFFER, depthRenderbufferHandle);
|
|
914
|
+
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, descriptor.width, descriptor.height);
|
|
915
|
+
gl.bindRenderbuffer(gl.RENDERBUFFER, previousRenderbuffer);
|
|
916
|
+
}
|
|
917
|
+
const drawBuffers = depthOnly
|
|
918
|
+
? [gl.NONE]
|
|
919
|
+
: colorFormats.map((_, attachment) => gl.COLOR_ATTACHMENT0 + attachment);
|
|
920
|
+
const attachLayer = (framebuffer, layer) => {
|
|
921
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
|
922
|
+
if (depthOnly) {
|
|
923
|
+
gl.drawBuffers([gl.NONE]);
|
|
924
|
+
gl.readBuffer(gl.NONE);
|
|
925
|
+
}
|
|
926
|
+
else if (drawBuffers.length > 1) {
|
|
927
|
+
gl.drawBuffers(drawBuffers);
|
|
754
928
|
}
|
|
755
|
-
|
|
756
|
-
if (
|
|
757
|
-
|
|
758
|
-
this.drawNativeLdrStage(ldrSourceHandle, bloomResources.framebuffers[baseTargetIndex], source.width, source.height, program, vertexArray, tonePass, colorPass, undefined, options.toneMappingDefaults);
|
|
759
|
-
ldrSourceHandle = bloomResources.textures[baseTargetIndex];
|
|
760
|
-
temporarySourceIndex = baseTargetIndex;
|
|
929
|
+
for (let attachment = 0; attachment < colorHandles.length; attachment += 1) {
|
|
930
|
+
if (dimension === "cube") {
|
|
931
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + attachment, gl.TEXTURE_CUBE_MAP_POSITIVE_X + layer, colorHandles[attachment], 0);
|
|
761
932
|
}
|
|
762
|
-
if (
|
|
763
|
-
|
|
764
|
-
ldrSourceHandle = this.executeNativeDepthOfFieldPass(ldrSourceHandle, source.depthTextureHandle, bloomResources, depthOfFieldOptions, vertexArray, depthOfFieldTargetIndex, depthRange);
|
|
765
|
-
temporarySourceIndex = depthOfFieldTargetIndex;
|
|
933
|
+
else if (dimension === "2d-array") {
|
|
934
|
+
gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + attachment, colorHandles[attachment], 0, layer);
|
|
766
935
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
ldrSourceHandle = this.executeNativeMotionBlurPass(ldrSourceHandle, bloomResources, motionBlurOptions, vertexArray, motionBlurTargetIndex);
|
|
770
|
-
temporarySourceIndex = motionBlurTargetIndex;
|
|
936
|
+
else {
|
|
937
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + attachment, gl.TEXTURE_2D, colorHandles[attachment], 0);
|
|
771
938
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
939
|
+
}
|
|
940
|
+
if (depthTextureHandle) {
|
|
941
|
+
if (dimension === "cube") {
|
|
942
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X + layer, depthTextureHandle, 0);
|
|
776
943
|
}
|
|
777
|
-
if (
|
|
778
|
-
|
|
779
|
-
ldrSourceHandle = this.executeNativeSsrPass(ldrSourceHandle, source.depthTextureHandle, bloomResources, ssrOptions, vertexArray, ssrTargetIndex, depthRange);
|
|
780
|
-
temporarySourceIndex = ssrTargetIndex;
|
|
944
|
+
else if (dimension === "2d-array") {
|
|
945
|
+
gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, depthTextureHandle, 0, layer);
|
|
781
946
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
ldrSourceHandle = this.executeNativeTaaPass(ldrSourceHandle, bloomResources, taaOptions, vertexArray, taaTargetIndex);
|
|
785
|
-
temporarySourceIndex = taaTargetIndex;
|
|
947
|
+
else {
|
|
948
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTextureHandle, 0);
|
|
786
949
|
}
|
|
787
950
|
}
|
|
788
|
-
if (
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
951
|
+
if (depthRenderbufferHandle) {
|
|
952
|
+
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRenderbufferHandle);
|
|
953
|
+
}
|
|
954
|
+
return gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;
|
|
955
|
+
};
|
|
956
|
+
for (let layer = 0; layer < layerCount; layer += 1) {
|
|
957
|
+
const framebuffer = gl.createFramebuffer();
|
|
958
|
+
if (!framebuffer) {
|
|
959
|
+
cleanup();
|
|
960
|
+
throw new RenderDeviceError("Failed to allocate WebGL render target", "WEBGL_ALLOCATION_FAILED", { label });
|
|
961
|
+
}
|
|
962
|
+
layerFramebuffers.push(framebuffer);
|
|
963
|
+
if (!attachLayer(framebuffer, layer)) {
|
|
964
|
+
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
|
965
|
+
cleanup();
|
|
966
|
+
if (depthRenderbufferHandle)
|
|
967
|
+
gl.deleteRenderbuffer(depthRenderbufferHandle);
|
|
968
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, previousFramebuffer);
|
|
969
|
+
gl.bindTexture(gl.TEXTURE_2D, previousTexture);
|
|
970
|
+
if (previousCubeTexture !== null)
|
|
971
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, previousCubeTexture);
|
|
972
|
+
if (previousArrayTexture !== null)
|
|
973
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, previousArrayTexture);
|
|
974
|
+
gl.activeTexture(previousActiveTexture);
|
|
975
|
+
this.stateCache.invalidate();
|
|
976
|
+
throw new RenderDeviceError("WebGL render target framebuffer status is invalid", "FRAMEBUFFER_INVALID", { status, layer, label });
|
|
792
977
|
}
|
|
793
|
-
this.drawNativeLdrStage(ldrSourceHandle, webglOutputTarget?.framebuffer ?? null, outputWidth, outputHeight, program, vertexArray, depthOfFieldOptions || motionBlurOptions || ssaoOptions || ssrOptions || taaOptions || outlineOptions ? undefined : tonePass, depthOfFieldOptions || motionBlurOptions || ssaoOptions || ssrOptions || taaOptions || outlineOptions ? undefined : colorPass, fxaaPass, options.toneMappingDefaults);
|
|
794
|
-
this.gl.flush();
|
|
795
|
-
}
|
|
796
|
-
finally {
|
|
797
|
-
this.restoreFullscreenPresentationState(previousState, outputWidth, outputHeight);
|
|
798
978
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
979
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, previousFramebuffer);
|
|
980
|
+
gl.bindTexture(gl.TEXTURE_2D, previousTexture);
|
|
981
|
+
if (previousCubeTexture !== null)
|
|
982
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, previousCubeTexture);
|
|
983
|
+
if (previousArrayTexture !== null)
|
|
984
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, previousArrayTexture);
|
|
985
|
+
gl.activeTexture(previousActiveTexture);
|
|
986
|
+
this.stateCache.invalidate();
|
|
987
|
+
const colorTexture = colorTextures[0] ?? new Texture({ width: descriptor.width, height: descriptor.height, format: "rgba8", label: `${label}-colorless`, dimension, renderAttachment: true });
|
|
988
|
+
let parentColorHandle = colorHandles[0];
|
|
989
|
+
if (!parentColorHandle) {
|
|
990
|
+
// Depth-only targets keep a placeholder Texture in `colorTexture`; give it a
|
|
991
|
+
// real (never-attached, never-registered) GL handle so dispose stays sound.
|
|
992
|
+
parentColorHandle = gl.createTexture();
|
|
993
|
+
if (!parentColorHandle) {
|
|
994
|
+
cleanup();
|
|
995
|
+
if (depthRenderbufferHandle)
|
|
996
|
+
gl.deleteRenderbuffer(depthRenderbufferHandle);
|
|
997
|
+
throw new RenderDeviceError("Failed to allocate WebGL render target", "WEBGL_ALLOCATION_FAILED", { label });
|
|
998
|
+
}
|
|
805
999
|
}
|
|
806
|
-
this.
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
boundsWidth,
|
|
822
|
-
boundsHeight
|
|
823
|
-
});
|
|
1000
|
+
const target = new WebGL2RenderTarget(this.nextId++, descriptor.width, descriptor.height, label, colorTexture, depthTexture, layerFramebuffers[0], parentColorHandle, depthRenderbufferHandle, depthTextureHandle, 1, layerFramebuffers[0], null, gl, {
|
|
1001
|
+
dimension,
|
|
1002
|
+
layers: layerCount > 1 ? layerCount : undefined,
|
|
1003
|
+
colorTextures: colorTextures.length > 1 ? colorTextures : undefined,
|
|
1004
|
+
extraColorHandles: colorHandles.slice(1),
|
|
1005
|
+
layerFramebuffers,
|
|
1006
|
+
layerChild: false
|
|
1007
|
+
});
|
|
1008
|
+
if (layerCount > 1) {
|
|
1009
|
+
const children = layerFramebuffers.map((framebuffer, layer) => new WebGL2RenderTarget(this.nextId++, descriptor.width, descriptor.height, `${label}-layer-${layer}`, colorTexture, depthTexture, framebuffer, colorHandles[0], null, depthTextureHandle, 1, framebuffer, null, gl, { dimension, layers: 1, colorTextures: target.colorTextures, layerChild: true }));
|
|
1010
|
+
// layerTargets shares parent GL resources; children only mark dispose.
|
|
1011
|
+
target.layerTargets = children;
|
|
1012
|
+
for (const child of children) {
|
|
1013
|
+
this.renderTargets.add(child);
|
|
1014
|
+
}
|
|
824
1015
|
}
|
|
825
|
-
|
|
826
|
-
if (
|
|
827
|
-
this.
|
|
828
|
-
|
|
1016
|
+
this.renderTargets.add(target);
|
|
1017
|
+
if (/shadow|(?:^|-)csm(?:-|$)/i.test(label))
|
|
1018
|
+
this.host.counters.shadowRenderTargetsAllocated += 1;
|
|
1019
|
+
for (let attachment = 0; attachment < colorHandles.length; attachment += 1) {
|
|
1020
|
+
this.host.textureRegistry.textures.set(colorTextures[attachment], colorHandles[attachment]);
|
|
1021
|
+
this.host.textureRegistry.textureUploadModes.set(colorTextures[attachment], colorFormats[attachment]);
|
|
829
1022
|
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, readTarget.drawFramebuffer);
|
|
834
|
-
this.stateCache.invalidate();
|
|
1023
|
+
if (depthTexture && depthTextureHandle) {
|
|
1024
|
+
this.host.textureRegistry.textures.set(depthTexture, depthTextureHandle);
|
|
1025
|
+
this.host.textureRegistry.textureUploadModes.set(depthTexture, "depth-render-target");
|
|
835
1026
|
}
|
|
836
|
-
return
|
|
1027
|
+
return target;
|
|
837
1028
|
}
|
|
838
|
-
|
|
839
|
-
this.assertAlive();
|
|
840
|
-
if (
|
|
841
|
-
|
|
842
|
-
}
|
|
843
|
-
const boundsWidth = this.activeRenderTarget?.width ?? this.gl.drawingBufferWidth;
|
|
844
|
-
const boundsHeight = this.activeRenderTarget?.height ?? this.gl.drawingBufferHeight;
|
|
845
|
-
if (x + width > boundsWidth || y + height > boundsHeight) {
|
|
846
|
-
throw new RenderDeviceError("Float readback rectangle exceeds framebuffer bounds", "READBACK_OUT_OF_BOUNDS", {
|
|
847
|
-
x,
|
|
848
|
-
y,
|
|
849
|
-
width,
|
|
850
|
-
height,
|
|
851
|
-
boundsWidth,
|
|
852
|
-
boundsHeight
|
|
853
|
-
});
|
|
854
|
-
}
|
|
855
|
-
const readTarget = this.activeRenderTarget;
|
|
856
|
-
if (readTarget) {
|
|
857
|
-
this.resolveMultisampleTarget(readTarget);
|
|
858
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, readTarget.framebuffer);
|
|
859
|
-
}
|
|
860
|
-
const pixels = new Float32Array(width * height * 4);
|
|
861
|
-
this.gl.readPixels(x, y, width, height, this.gl.RGBA, this.gl.FLOAT, pixels);
|
|
862
|
-
if (readTarget && readTarget.sampleCount > 1) {
|
|
863
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, readTarget.drawFramebuffer);
|
|
864
|
-
this.stateCache.invalidate();
|
|
1029
|
+
setRenderTarget(target) {
|
|
1030
|
+
this.host.lifecycle.assertAlive();
|
|
1031
|
+
if (this.host.activeRenderTarget && this.host.activeRenderTarget !== target) {
|
|
1032
|
+
this.resolveMultisampleTarget(this.host.activeRenderTarget);
|
|
865
1033
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
throw new RenderDeviceError("Depth readback rectangle must be positive and in bounds", "INVALID_READBACK_RECT", { x, y, width, height });
|
|
872
|
-
}
|
|
873
|
-
const target = this.activeRenderTarget;
|
|
874
|
-
if (!target?.depthTextureHandle) {
|
|
875
|
-
throw new RenderDeviceError("Depth readback requires an active WebGL2 render target with a sampleable depth texture.", "DEPTH_READBACK_UNAVAILABLE", {
|
|
876
|
-
renderTarget: target?.label ?? null
|
|
877
|
-
});
|
|
1034
|
+
if (target === null) {
|
|
1035
|
+
this.host.activeRenderTarget = null;
|
|
1036
|
+
this.stateCache.bindFramebuffer(this.gl.FRAMEBUFFER, null, () => this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null));
|
|
1037
|
+
this.stateCache.viewport(0, 0, this.host.lifecycle.viewportWidth || this.gl.drawingBufferWidth, this.host.lifecycle.viewportHeight || this.gl.drawingBufferHeight, () => this.gl.viewport(0, 0, this.host.lifecycle.viewportWidth || this.gl.drawingBufferWidth, this.host.lifecycle.viewportHeight || this.gl.drawingBufferHeight));
|
|
1038
|
+
return;
|
|
878
1039
|
}
|
|
879
|
-
if (
|
|
880
|
-
throw new RenderDeviceError("
|
|
881
|
-
|
|
882
|
-
y,
|
|
883
|
-
width,
|
|
884
|
-
height,
|
|
885
|
-
boundsWidth: target.width,
|
|
886
|
-
boundsHeight: target.height
|
|
1040
|
+
if (!(target instanceof WebGL2RenderTarget) || !this.renderTargets.has(target) || target.disposed) {
|
|
1041
|
+
throw new RenderDeviceError("Render target is not a live WebGL2 resource owned by this device", "INVALID_RESOURCE", {
|
|
1042
|
+
targetId: target.id
|
|
887
1043
|
});
|
|
888
1044
|
}
|
|
889
|
-
this.
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
for (let index = 0; index < pixels.length; index += 1) {
|
|
893
|
-
const byteIndex = index * 4;
|
|
894
|
-
const r = encoded[byteIndex] ?? 255;
|
|
895
|
-
const g = encoded[byteIndex + 1] ?? 255;
|
|
896
|
-
const b = encoded[byteIndex + 2] ?? 255;
|
|
897
|
-
pixels[index] = Math.max(0, Math.min(1, r / 255 + g / 65025 + b / 16581375));
|
|
898
|
-
}
|
|
899
|
-
return pixels;
|
|
1045
|
+
this.host.activeRenderTarget = target;
|
|
1046
|
+
this.stateCache.bindFramebuffer(this.gl.FRAMEBUFFER, target.drawFramebuffer, () => this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, target.drawFramebuffer));
|
|
1047
|
+
this.stateCache.viewport(0, 0, target.width, target.height, () => this.gl.viewport(0, 0, target.width, target.height));
|
|
900
1048
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
this.
|
|
911
|
-
this.
|
|
912
|
-
|
|
913
|
-
this.activeTextureUnitIndex = -1;
|
|
914
|
-
this.textureUnitBindings.clear();
|
|
1049
|
+
resolveMultisampleTarget(target) {
|
|
1050
|
+
if (target.sampleCount <= 1 || !target.needsResolve)
|
|
1051
|
+
return;
|
|
1052
|
+
const previousFramebuffer = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
|
|
1053
|
+
this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER, target.drawFramebuffer);
|
|
1054
|
+
this.gl.bindFramebuffer(this.gl.DRAW_FRAMEBUFFER, target.framebuffer);
|
|
1055
|
+
let mask = this.gl.COLOR_BUFFER_BIT;
|
|
1056
|
+
if (target.depthTextureHandle)
|
|
1057
|
+
mask |= this.gl.DEPTH_BUFFER_BIT;
|
|
1058
|
+
this.gl.blitFramebuffer(0, 0, target.width, target.height, 0, 0, target.width, target.height, mask, this.gl.NEAREST);
|
|
1059
|
+
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, previousFramebuffer);
|
|
1060
|
+
target.needsResolve = false;
|
|
915
1061
|
this.stateCache.invalidate();
|
|
916
|
-
this.viewportWidth = width;
|
|
917
|
-
this.viewportHeight = height;
|
|
918
|
-
this.stateCache.bindFramebuffer(this.gl.FRAMEBUFFER, this.activeRenderTarget?.framebuffer ?? null, () => this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.activeRenderTarget?.framebuffer ?? null));
|
|
919
|
-
this.stateCache.viewport(0, 0, width, height, () => this.gl.viewport(0, 0, width, height));
|
|
920
|
-
this.stateCache.setEnabled(this.gl.DEPTH_TEST, true, () => this.gl.enable(this.gl.DEPTH_TEST));
|
|
921
|
-
this.stateCache.depthFunc(this.gl.LEQUAL, () => this.gl.depthFunc(this.gl.LEQUAL));
|
|
922
|
-
}
|
|
923
|
-
clear(color) {
|
|
924
|
-
this.assertFrame();
|
|
925
|
-
this.gl.clearColor(color[0], color[1], color[2], color[3]);
|
|
926
|
-
this.stateCache.depthMask(true, () => this.gl.depthMask(true));
|
|
927
|
-
this.gl.clearDepth(1);
|
|
928
|
-
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
|
|
929
|
-
if (this.activeRenderTarget?.sampleCount && this.activeRenderTarget.sampleCount > 1)
|
|
930
|
-
this.activeRenderTarget.needsResolve = true;
|
|
931
|
-
}
|
|
932
|
-
clearRenderTarget(color) {
|
|
933
|
-
this.assertFrame();
|
|
934
|
-
this.gl.clearColor(color[0], color[1], color[2], color[3]);
|
|
935
|
-
this.stateCache.depthMask(true, () => this.gl.depthMask(true));
|
|
936
|
-
this.gl.clearDepth(1);
|
|
937
|
-
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
|
|
938
|
-
if (this.activeRenderTarget?.sampleCount && this.activeRenderTarget.sampleCount > 1)
|
|
939
|
-
this.activeRenderTarget.needsResolve = true;
|
|
940
|
-
}
|
|
941
|
-
draw(command) {
|
|
942
|
-
this.assertFrame();
|
|
943
|
-
const vertexBuffer = this.requireBuffer(command.vertexBuffer);
|
|
944
|
-
this.applyRenderState(command.renderState);
|
|
945
|
-
let shader;
|
|
946
|
-
if (command.shader) {
|
|
947
|
-
const activeShader = this.requireShader(command.shader);
|
|
948
|
-
shader = activeShader;
|
|
949
|
-
this.stateCache.useProgram(activeShader.handle, () => this.gl.useProgram(activeShader.handle));
|
|
950
|
-
if (command.uniforms) {
|
|
951
|
-
this.uploadUniforms(activeShader, command.uniforms);
|
|
952
|
-
if (this.errorCheckMode === "strict") {
|
|
953
|
-
const uniformError = this.readError();
|
|
954
|
-
if (uniformError) {
|
|
955
|
-
throw new RenderDeviceError(`WebGL2 uniform upload failed for draw ${command.label ?? "unnamed"}: ${uniformError}`, "WEBGL_DRAW_FAILED", {
|
|
956
|
-
label: command.label,
|
|
957
|
-
stage: "uniforms",
|
|
958
|
-
error: uniformError
|
|
959
|
-
});
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
if (shader && command.vertexFormat) {
|
|
965
|
-
this.bindVertexArrayForCommand(command, shader, vertexBuffer);
|
|
966
|
-
if (this.errorCheckMode === "strict") {
|
|
967
|
-
const vertexFormatError = this.readError();
|
|
968
|
-
if (vertexFormatError) {
|
|
969
|
-
throw new RenderDeviceError(`WebGL2 vertex format binding failed for draw ${command.label ?? "unnamed"}: ${vertexFormatError}`, "WEBGL_DRAW_FAILED", {
|
|
970
|
-
label: command.label,
|
|
971
|
-
stage: "vertex-format",
|
|
972
|
-
error: vertexFormatError
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
else {
|
|
978
|
-
this.bindNoVertexArray();
|
|
979
|
-
this.stateCache.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer.handle, () => this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer.handle));
|
|
980
|
-
}
|
|
981
|
-
if (command.indexBuffer) {
|
|
982
|
-
const indexBuffer = this.requireBuffer(command.indexBuffer);
|
|
983
|
-
if (!shader || !command.vertexFormat) {
|
|
984
|
-
this.stateCache.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer.handle, () => this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer.handle));
|
|
985
|
-
}
|
|
986
|
-
const type = command.indexType === "uint32" ? this.gl.UNSIGNED_INT : this.gl.UNSIGNED_SHORT;
|
|
987
|
-
const indexByteSize = command.indexType === "uint32" ? 4 : 2;
|
|
988
|
-
const indexOffset = (command.firstIndex ?? 0) * indexByteSize;
|
|
989
|
-
if ((command.instanceCount ?? 1) > 1) {
|
|
990
|
-
this.gl.drawElementsInstanced(this.primitive(command.topology), command.indexCount ?? 0, type, indexOffset, command.instanceCount ?? 1);
|
|
991
|
-
this.nativeInstancedSubmissions += 1;
|
|
992
|
-
}
|
|
993
|
-
else {
|
|
994
|
-
this.gl.drawElements(this.primitive(command.topology), command.indexCount ?? 0, type, indexOffset);
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
else {
|
|
998
|
-
if ((command.instanceCount ?? 1) > 1) {
|
|
999
|
-
this.gl.drawArraysInstanced(this.primitive(command.topology), command.firstVertex ?? 0, command.vertexCount, command.instanceCount ?? 1);
|
|
1000
|
-
this.nativeInstancedSubmissions += 1;
|
|
1001
|
-
}
|
|
1002
|
-
else {
|
|
1003
|
-
this.gl.drawArrays(this.primitive(command.topology), command.firstVertex ?? 0, command.vertexCount);
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
this.drawCalls += 1;
|
|
1007
|
-
if (this.activeRenderTarget?.sampleCount && this.activeRenderTarget.sampleCount > 1)
|
|
1008
|
-
this.activeRenderTarget.needsResolve = true;
|
|
1009
|
-
if (this.errorCheckMode === "strict") {
|
|
1010
|
-
const drawError = this.readError();
|
|
1011
|
-
if (drawError) {
|
|
1012
|
-
throw new RenderDeviceError(`WebGL2 draw failed for ${command.label ?? "unnamed"}: ${drawError}`, "WEBGL_DRAW_FAILED", {
|
|
1013
|
-
label: command.label,
|
|
1014
|
-
stage: "draw",
|
|
1015
|
-
error: drawError
|
|
1016
|
-
});
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
endFrame() {
|
|
1021
|
-
this.assertFrame();
|
|
1022
|
-
this.frameActive = false;
|
|
1023
|
-
this.lastError = this.readError();
|
|
1024
1062
|
}
|
|
1025
1063
|
captureState() {
|
|
1026
1064
|
const viewport = this.gl.getParameter(this.gl.VIEWPORT);
|
|
1027
1065
|
return new Map([
|
|
1028
1066
|
["backend", this.kind],
|
|
1029
|
-
["disposed", this.disposed],
|
|
1030
|
-
["contextLost", this.contextLost],
|
|
1031
|
-
["frameActive", this.frameActive],
|
|
1067
|
+
["disposed", this.host.disposed],
|
|
1068
|
+
["contextLost", this.host.contextLost],
|
|
1069
|
+
["frameActive", this.host.lifecycle.frameActive],
|
|
1032
1070
|
["depthTest", this.gl.isEnabled(this.gl.DEPTH_TEST)],
|
|
1033
1071
|
["blend", this.gl.isEnabled(this.gl.BLEND)],
|
|
1034
1072
|
["cullFace", this.gl.isEnabled(this.gl.CULL_FACE)],
|
|
1035
1073
|
["program", this.gl.getParameter(this.gl.CURRENT_PROGRAM) ? "bound" : null],
|
|
1036
1074
|
["arrayBuffer", this.gl.getParameter(this.gl.ARRAY_BUFFER_BINDING) ? "bound" : null],
|
|
1037
1075
|
["elementArrayBuffer", this.gl.getParameter(this.gl.ELEMENT_ARRAY_BUFFER_BINDING) ? "bound" : null],
|
|
1038
|
-
["viewportWidth", this.viewportWidth],
|
|
1039
|
-
["viewportHeight", this.viewportHeight],
|
|
1076
|
+
["viewportWidth", this.host.lifecycle.viewportWidth],
|
|
1077
|
+
["viewportHeight", this.host.lifecycle.viewportHeight],
|
|
1040
1078
|
["actualViewportWidth", viewport[2] ?? 0],
|
|
1041
1079
|
["actualViewportHeight", viewport[3] ?? 0],
|
|
1042
|
-
["renderTarget", this.activeRenderTarget?.label ?? null],
|
|
1043
|
-
["drawCalls", this.drawCalls],
|
|
1044
|
-
["
|
|
1045
|
-
["
|
|
1046
|
-
["
|
|
1047
|
-
["
|
|
1048
|
-
["
|
|
1049
|
-
["
|
|
1050
|
-
["
|
|
1051
|
-
["
|
|
1080
|
+
["renderTarget", this.host.activeRenderTarget?.label ?? null],
|
|
1081
|
+
["drawCalls", this.host.counters.drawCalls],
|
|
1082
|
+
["nativeTemporalPasses", this.host.counters.nativeTemporalPasses],
|
|
1083
|
+
["nativeTemporalBindings", this.host.counters.nativeTemporalBindings],
|
|
1084
|
+
["shaderProgramCreates", this.host.counters.shaderProgramCreateCount],
|
|
1085
|
+
["uniformLocationLookups", this.host.counters.uniformLocationLookupCount],
|
|
1086
|
+
["bufferUpdates", this.host.counters.bufferUpdateCount],
|
|
1087
|
+
["textureBinds", this.host.counters.textureBindCount],
|
|
1088
|
+
["samplerParameterUploads", this.host.counters.samplerParameterUploadCount],
|
|
1089
|
+
["vertexArrayCreates", this.host.counters.vertexArrayCreateCount],
|
|
1090
|
+
["samplerObjects", this.host.samplers.samplerObjectCache.size],
|
|
1091
|
+
["samplerAnisotropyUploads", this.host.counters.samplerAnisotropyUploadCount],
|
|
1052
1092
|
["maxTextureAnisotropy", this.maxTextureAnisotropy],
|
|
1053
|
-
["nativeEnvironmentBindings", this.nativeEnvironmentBindings],
|
|
1054
|
-
["nativeShadowMapBindings", this.nativeShadowMapBindings],
|
|
1055
|
-
["nativeInstancedSubmissions", this.nativeInstancedSubmissions],
|
|
1093
|
+
["nativeEnvironmentBindings", this.host.counters.nativeEnvironmentBindings],
|
|
1094
|
+
["nativeShadowMapBindings", this.host.counters.nativeShadowMapBindings],
|
|
1095
|
+
["nativeInstancedSubmissions", this.host.counters.nativeInstancedSubmissions],
|
|
1056
1096
|
["stateCacheIssued", this.stateCache.stats().issued],
|
|
1057
1097
|
["stateCacheSkipped", this.stateCache.stats().skipped]
|
|
1058
1098
|
]);
|
|
1059
1099
|
}
|
|
1060
1100
|
getDiagnostics() {
|
|
1061
|
-
this.releaseDisposedTextureHandles();
|
|
1101
|
+
this.host.textureRegistry.releaseDisposedTextureHandles();
|
|
1062
1102
|
const liveRenderTargets = [...this.renderTargets].filter((target) => !target.disposed);
|
|
1063
1103
|
const liveTextures = new Set([
|
|
1064
1104
|
...liveRenderTargets.map((target) => target.colorTexture),
|
|
1065
|
-
...[...this.textures.keys()].filter((texture) => !texture.disposed)
|
|
1105
|
+
...[...this.host.textureRegistry.textures.keys()].filter((texture) => !texture.disposed)
|
|
1066
1106
|
]);
|
|
1067
1107
|
const liveTextureList = [...liveTextures];
|
|
1068
1108
|
const compressedTextures = liveTextureList.filter((texture) => isCompressedTextureFormat(texture.format));
|
|
1069
|
-
const fallbackTextures = liveTextureList.filter((texture) => this.textureUploadModes.get(texture) === "fallback");
|
|
1109
|
+
const fallbackTextures = liveTextureList.filter((texture) => this.host.textureRegistry.textureUploadModes.get(texture) === "fallback");
|
|
1070
1110
|
const stateCacheStats = this.stateCache.stats();
|
|
1071
1111
|
const bufferBytes = [...this.buffers].filter((buffer) => !buffer.disposed).reduce((total, buffer) => total + buffer.byteLength, 0);
|
|
1072
1112
|
const textureBytes = liveTextureList.reduce((total, texture) => total + texture.byteLength, 0);
|
|
1073
|
-
const gpuTargetEntries = this.describeGpuTargetInventory(liveRenderTargets);
|
|
1113
|
+
const gpuTargetEntries = this.host.post.describeGpuTargetInventory(liveRenderTargets);
|
|
1074
1114
|
return {
|
|
1075
|
-
drawCalls: this.drawCalls,
|
|
1115
|
+
drawCalls: this.host.counters.drawCalls,
|
|
1076
1116
|
buffers: [...this.buffers].filter((buffer) => !buffer.disposed).length,
|
|
1077
1117
|
shaders: [...this.shaders].filter((shader) => !shader.disposed).length,
|
|
1078
1118
|
renderTargets: liveRenderTargets.length,
|
|
@@ -1085,12 +1125,14 @@ export class WebGL2Device {
|
|
|
1085
1125
|
compressedTextureBytes: compressedTextures.reduce((total, texture) => total + texture.byteLength, 0),
|
|
1086
1126
|
textureFallbacks: fallbackTextures.length,
|
|
1087
1127
|
textureFallbackBytes: fallbackTextures.reduce((total, texture) => total + texture.fallbackByteLength, 0),
|
|
1088
|
-
nativeEnvironmentBindings: this.nativeEnvironmentBindings,
|
|
1089
|
-
nativeShadowMapBindings: this.nativeShadowMapBindings,
|
|
1090
|
-
shadowRenderTargetsAllocated: this.shadowRenderTargetsAllocated,
|
|
1091
|
-
nativeInstancedSubmissions: this.nativeInstancedSubmissions,
|
|
1092
|
-
bloom: this.lastBloomDiagnostics,
|
|
1093
|
-
|
|
1128
|
+
nativeEnvironmentBindings: this.host.counters.nativeEnvironmentBindings,
|
|
1129
|
+
nativeShadowMapBindings: this.host.counters.nativeShadowMapBindings,
|
|
1130
|
+
shadowRenderTargetsAllocated: this.host.counters.shadowRenderTargetsAllocated,
|
|
1131
|
+
nativeInstancedSubmissions: this.host.counters.nativeInstancedSubmissions,
|
|
1132
|
+
bloom: this.host.post.lastBloomDiagnostics,
|
|
1133
|
+
nativeTemporalPasses: this.host.counters.nativeTemporalPasses,
|
|
1134
|
+
nativeTemporalBindings: this.host.counters.nativeTemporalBindings,
|
|
1135
|
+
samplerAnisotropyUploads: this.host.counters.samplerAnisotropyUploadCount,
|
|
1094
1136
|
maxTextureAnisotropy: this.maxTextureAnisotropy,
|
|
1095
1137
|
stateCacheIssued: stateCacheStats.issued,
|
|
1096
1138
|
stateCacheSkipped: stateCacheStats.skipped,
|
|
@@ -1099,23 +1141,25 @@ export class WebGL2Device {
|
|
|
1099
1141
|
stateCacheBufferBinds: stateCacheStats.byOperation.bindBuffer?.issued ?? 0,
|
|
1100
1142
|
stateCacheVertexArrayBinds: stateCacheStats.byOperation.bindVertexArray?.issued ?? 0,
|
|
1101
1143
|
stateCacheSamplerBinds: stateCacheStats.byOperation.bindSampler?.issued ?? 0,
|
|
1102
|
-
disposedBuffers: [...this.buffers].filter((buffer) => buffer.disposed).length,
|
|
1144
|
+
disposedBuffers: this.disposedBufferCount + [...this.buffers].filter((buffer) => buffer.disposed).length,
|
|
1103
1145
|
disposedShaders: [...this.shaders].filter((shader) => shader.disposed).length,
|
|
1104
1146
|
disposedRenderTargets: [...this.renderTargets].filter((target) => target.disposed).length,
|
|
1105
|
-
disposedTextures: [...this.renderTargets].filter((target) => target.colorTexture.disposed).length + this.releasedTextureHandles,
|
|
1147
|
+
disposedTextures: [...this.renderTargets].filter((target) => target.colorTexture.disposed).length + this.host.counters.releasedTextureHandles,
|
|
1106
1148
|
...spreadGpuTargetInventory(gpuTargetEntries),
|
|
1107
|
-
|
|
1108
|
-
|
|
1149
|
+
programCompileCount: this.host.counters.programCompiles,
|
|
1150
|
+
readPixelsCalls: this.host.counters.readbacks,
|
|
1151
|
+
lastError: this.host.lifecycle.lastError,
|
|
1152
|
+
contextLost: this.host.contextLost
|
|
1109
1153
|
};
|
|
1110
1154
|
}
|
|
1111
1155
|
dispose() {
|
|
1112
|
-
if (this.canvas && "removeEventListener" in this.canvas) {
|
|
1113
|
-
this.deviceLostListeners.clear();
|
|
1114
|
-
this.deviceRestoredListeners.clear();
|
|
1115
|
-
if (this.contextLostListener)
|
|
1116
|
-
this.canvas.removeEventListener("webglcontextlost", this.contextLostListener);
|
|
1117
|
-
if (this.contextRestoredListener)
|
|
1118
|
-
this.canvas.removeEventListener("webglcontextrestored", this.contextRestoredListener);
|
|
1156
|
+
if (this.host.lifecycle.canvas && "removeEventListener" in this.host.lifecycle.canvas) {
|
|
1157
|
+
this.host.lifecycle.deviceLostListeners.clear();
|
|
1158
|
+
this.host.lifecycle.deviceRestoredListeners.clear();
|
|
1159
|
+
if (this.host.lifecycle.contextLostListener)
|
|
1160
|
+
this.host.lifecycle.canvas.removeEventListener("webglcontextlost", this.host.lifecycle.contextLostListener);
|
|
1161
|
+
if (this.host.lifecycle.contextRestoredListener)
|
|
1162
|
+
this.host.lifecycle.canvas.removeEventListener("webglcontextrestored", this.host.lifecycle.contextRestoredListener);
|
|
1119
1163
|
}
|
|
1120
1164
|
for (const buffer of this.buffers) {
|
|
1121
1165
|
buffer.dispose();
|
|
@@ -1126,1853 +1170,120 @@ export class WebGL2Device {
|
|
|
1126
1170
|
for (const target of this.renderTargets) {
|
|
1127
1171
|
target.dispose();
|
|
1128
1172
|
}
|
|
1129
|
-
for (const entry of this.vertexArrayCache.values()) {
|
|
1173
|
+
for (const entry of this.host.drawBinder.vertexArrayCache.values()) {
|
|
1130
1174
|
this.gl.deleteVertexArray(entry.handle);
|
|
1131
1175
|
}
|
|
1132
|
-
this.vertexArrayCache.clear();
|
|
1133
|
-
for (const sampler of this.samplerObjectCache.values()) {
|
|
1176
|
+
this.host.drawBinder.vertexArrayCache.clear();
|
|
1177
|
+
for (const sampler of this.host.samplers.samplerObjectCache.values()) {
|
|
1134
1178
|
this.gl.deleteSampler(sampler);
|
|
1135
1179
|
}
|
|
1136
|
-
this.samplerObjectCache.clear();
|
|
1137
|
-
for (const texture of this.textures.values()) {
|
|
1138
|
-
this.gl.deleteTexture(texture);
|
|
1139
|
-
}
|
|
1140
|
-
this.textureUploadModes.clear();
|
|
1141
|
-
if (this.fallbackTexture) {
|
|
1142
|
-
this.gl.deleteTexture(this.fallbackTexture);
|
|
1143
|
-
this.fallbackTexture = null;
|
|
1144
|
-
}
|
|
1145
|
-
if (this.fallbackCubeTexture) {
|
|
1146
|
-
this.gl.deleteTexture(this.fallbackCubeTexture);
|
|
1147
|
-
this.fallbackCubeTexture = null;
|
|
1148
|
-
}
|
|
1149
|
-
if (this.presentationProgram) {
|
|
1150
|
-
this.gl.deleteProgram(this.presentationProgram);
|
|
1151
|
-
this.presentationProgram = null;
|
|
1152
|
-
}
|
|
1153
|
-
if (this.ldrPostprocessProgram) {
|
|
1154
|
-
this.gl.deleteProgram(this.ldrPostprocessProgram);
|
|
1155
|
-
this.ldrPostprocessProgram = null;
|
|
1156
|
-
}
|
|
1157
|
-
if (this.bloomBrightExtractProgram) {
|
|
1158
|
-
this.gl.deleteProgram(this.bloomBrightExtractProgram);
|
|
1159
|
-
this.bloomBrightExtractProgram = null;
|
|
1160
|
-
}
|
|
1161
|
-
if (this.bloomBlurProgram) {
|
|
1162
|
-
this.gl.deleteProgram(this.bloomBlurProgram);
|
|
1163
|
-
this.bloomBlurProgram = null;
|
|
1164
|
-
}
|
|
1165
|
-
if (this.bloomCompositeProgram) {
|
|
1166
|
-
this.gl.deleteProgram(this.bloomCompositeProgram);
|
|
1167
|
-
this.bloomCompositeProgram = null;
|
|
1168
|
-
}
|
|
1169
|
-
if (this.bloomDownsampleProgram) {
|
|
1170
|
-
this.gl.deleteProgram(this.bloomDownsampleProgram);
|
|
1171
|
-
this.bloomDownsampleProgram = null;
|
|
1172
|
-
}
|
|
1173
|
-
if (this.bloomAccumulateProgram) {
|
|
1174
|
-
this.gl.deleteProgram(this.bloomAccumulateProgram);
|
|
1175
|
-
this.bloomAccumulateProgram = null;
|
|
1176
|
-
}
|
|
1177
|
-
if (this.outlineProgram) {
|
|
1178
|
-
this.gl.deleteProgram(this.outlineProgram);
|
|
1179
|
-
this.outlineProgram = null;
|
|
1180
|
-
}
|
|
1181
|
-
if (this.ssaoProgram) {
|
|
1182
|
-
this.gl.deleteProgram(this.ssaoProgram);
|
|
1183
|
-
this.ssaoProgram = null;
|
|
1184
|
-
}
|
|
1185
|
-
if (this.ssrProgram) {
|
|
1186
|
-
this.gl.deleteProgram(this.ssrProgram);
|
|
1187
|
-
this.ssrProgram = null;
|
|
1188
|
-
}
|
|
1189
|
-
if (this.depthOfFieldProgram) {
|
|
1190
|
-
this.gl.deleteProgram(this.depthOfFieldProgram);
|
|
1191
|
-
this.depthOfFieldProgram = null;
|
|
1192
|
-
}
|
|
1193
|
-
if (this.motionBlurProgram) {
|
|
1194
|
-
this.gl.deleteProgram(this.motionBlurProgram);
|
|
1195
|
-
this.motionBlurProgram = null;
|
|
1196
|
-
}
|
|
1197
|
-
if (this.motionBlurVelocityTexture) {
|
|
1198
|
-
this.gl.deleteTexture(this.motionBlurVelocityTexture);
|
|
1199
|
-
this.motionBlurVelocityTexture = null;
|
|
1200
|
-
this.motionBlurVelocitySize = null;
|
|
1201
|
-
}
|
|
1202
|
-
if (this.taaProgram) {
|
|
1203
|
-
this.gl.deleteProgram(this.taaProgram);
|
|
1204
|
-
this.taaProgram = null;
|
|
1205
|
-
}
|
|
1206
|
-
if (this.taaHistoryTexture) {
|
|
1207
|
-
this.gl.deleteTexture(this.taaHistoryTexture);
|
|
1208
|
-
this.taaHistoryTexture = null;
|
|
1209
|
-
this.taaHistorySize = null;
|
|
1210
|
-
}
|
|
1211
|
-
this.disposeBloomPingPongResources();
|
|
1212
|
-
this.disposeBloomPyramidResources();
|
|
1213
|
-
if (this.bloomBrightLutTexture) {
|
|
1214
|
-
this.gl.deleteTexture(this.bloomBrightLutTexture);
|
|
1215
|
-
this.bloomBrightLutTexture = null;
|
|
1216
|
-
this.bloomBrightLutThreshold = null;
|
|
1217
|
-
}
|
|
1218
|
-
if (this.bloomCompositeLutTexture) {
|
|
1219
|
-
this.gl.deleteTexture(this.bloomCompositeLutTexture);
|
|
1220
|
-
this.bloomCompositeLutTexture = null;
|
|
1221
|
-
this.bloomCompositeLutIntensity = null;
|
|
1222
|
-
this.bloomCompositeLutShoulder = null;
|
|
1223
|
-
}
|
|
1224
|
-
if (this.outlineBlendLutTexture) {
|
|
1225
|
-
this.gl.deleteTexture(this.outlineBlendLutTexture);
|
|
1226
|
-
this.outlineBlendLutTexture = null;
|
|
1227
|
-
this.outlineBlendLutKey = null;
|
|
1228
|
-
}
|
|
1229
|
-
if (this.presentationVertexArray) {
|
|
1230
|
-
this.gl.deleteVertexArray(this.presentationVertexArray);
|
|
1231
|
-
this.presentationVertexArray = null;
|
|
1232
|
-
}
|
|
1233
|
-
if (this.depthReadbackProgram) {
|
|
1234
|
-
this.gl.deleteProgram(this.depthReadbackProgram);
|
|
1235
|
-
this.depthReadbackProgram = null;
|
|
1236
|
-
}
|
|
1237
|
-
this.textures.clear();
|
|
1238
|
-
this.disposed = true;
|
|
1239
|
-
}
|
|
1240
|
-
copyDepthTextureToBytes(source, x, y, width, height) {
|
|
1241
|
-
const colorHandle = this.gl.createTexture();
|
|
1242
|
-
const framebuffer = this.gl.createFramebuffer();
|
|
1243
|
-
if (!colorHandle || !framebuffer) {
|
|
1244
|
-
if (colorHandle)
|
|
1245
|
-
this.gl.deleteTexture(colorHandle);
|
|
1246
|
-
if (framebuffer)
|
|
1247
|
-
this.gl.deleteFramebuffer(framebuffer);
|
|
1248
|
-
throw new RenderDeviceError("Failed to allocate WebGL2 depth readback target", "WEBGL_ALLOCATION_FAILED", {
|
|
1249
|
-
renderTarget: source.label
|
|
1250
|
-
});
|
|
1251
|
-
}
|
|
1252
|
-
const previousFramebuffer = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
|
|
1253
|
-
const previousProgram = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
|
|
1254
|
-
const textureUnit0 = this.captureTextureUnit0();
|
|
1255
|
-
const viewport = this.gl.getParameter(this.gl.VIEWPORT);
|
|
1256
|
-
const depthTestEnabled = this.gl.isEnabled(this.gl.DEPTH_TEST);
|
|
1257
|
-
const depthMask = this.gl.getParameter(this.gl.DEPTH_WRITEMASK);
|
|
1258
|
-
const cullFaceEnabled = this.gl.isEnabled(this.gl.CULL_FACE);
|
|
1259
|
-
const blendEnabled = this.gl.isEnabled(this.gl.BLEND);
|
|
1260
|
-
const pixels = new Uint8Array(width * height * 4);
|
|
1261
|
-
try {
|
|
1262
|
-
this.gl.activeTexture(this.gl.TEXTURE0);
|
|
1263
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, colorHandle);
|
|
1264
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
|
|
1265
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
1266
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
1267
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
1268
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA8, width, height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, null);
|
|
1269
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
|
|
1270
|
-
this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, colorHandle, 0);
|
|
1271
|
-
const status = this.gl.checkFramebufferStatus(this.gl.FRAMEBUFFER);
|
|
1272
|
-
if (status !== this.gl.FRAMEBUFFER_COMPLETE) {
|
|
1273
|
-
throw new RenderDeviceError("WebGL2 depth readback framebuffer status is invalid", "FRAMEBUFFER_INVALID", {
|
|
1274
|
-
renderTarget: source.label,
|
|
1275
|
-
status
|
|
1276
|
-
});
|
|
1277
|
-
}
|
|
1278
|
-
this.gl.viewport(0, 0, width, height);
|
|
1279
|
-
this.gl.disable(this.gl.DEPTH_TEST);
|
|
1280
|
-
this.gl.disable(this.gl.CULL_FACE);
|
|
1281
|
-
this.gl.disable(this.gl.BLEND);
|
|
1282
|
-
this.gl.depthMask(false);
|
|
1283
|
-
this.gl.useProgram(this.ensureDepthReadbackProgram());
|
|
1284
|
-
this.gl.activeTexture(this.gl.TEXTURE0);
|
|
1285
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, source.depthTextureHandle);
|
|
1286
|
-
this.gl.bindSampler(0, null);
|
|
1287
|
-
this.gl.uniform1i(this.gl.getUniformLocation(this.ensureDepthReadbackProgram(), "u_depth"), 0);
|
|
1288
|
-
this.gl.uniform4f(this.gl.getUniformLocation(this.ensureDepthReadbackProgram(), "u_sourceRect"), x / source.width, y / source.height, width / source.width, height / source.height);
|
|
1289
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1290
|
-
this.gl.readPixels(0, 0, width, height, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels);
|
|
1291
|
-
const error = this.readError();
|
|
1292
|
-
if (error) {
|
|
1293
|
-
throw new RenderDeviceError("WebGL2 depth texture readback failed", "WEBGL_DEPTH_READBACK_FAILED", {
|
|
1294
|
-
renderTarget: source.label,
|
|
1295
|
-
error
|
|
1296
|
-
});
|
|
1297
|
-
}
|
|
1298
|
-
return pixels;
|
|
1299
|
-
}
|
|
1300
|
-
finally {
|
|
1301
|
-
this.restoreTextureUnit0(textureUnit0);
|
|
1302
|
-
this.gl.useProgram(previousProgram);
|
|
1303
|
-
if (depthTestEnabled)
|
|
1304
|
-
this.gl.enable(this.gl.DEPTH_TEST);
|
|
1305
|
-
else
|
|
1306
|
-
this.gl.disable(this.gl.DEPTH_TEST);
|
|
1307
|
-
if (cullFaceEnabled)
|
|
1308
|
-
this.gl.enable(this.gl.CULL_FACE);
|
|
1309
|
-
else
|
|
1310
|
-
this.gl.disable(this.gl.CULL_FACE);
|
|
1311
|
-
if (blendEnabled)
|
|
1312
|
-
this.gl.enable(this.gl.BLEND);
|
|
1313
|
-
else
|
|
1314
|
-
this.gl.disable(this.gl.BLEND);
|
|
1315
|
-
this.gl.depthMask(depthMask);
|
|
1316
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, previousFramebuffer);
|
|
1317
|
-
this.gl.viewport(viewport[0] ?? 0, viewport[1] ?? 0, viewport[2] ?? this.viewportWidth, viewport[3] ?? this.viewportHeight);
|
|
1318
|
-
this.gl.deleteTexture(colorHandle);
|
|
1319
|
-
this.gl.deleteFramebuffer(framebuffer);
|
|
1320
|
-
this.stateCache.invalidate();
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
1323
|
-
drawRenderTargetToBackbuffer(source, outputWidth, outputHeight) {
|
|
1324
|
-
const program = this.ensurePresentationProgram();
|
|
1325
|
-
const vertexArray = this.ensurePresentationVertexArray();
|
|
1326
|
-
const previousState = this.prepareFullscreenPresentation(null, outputWidth, outputHeight);
|
|
1327
|
-
this.gl.useProgram(program);
|
|
1328
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1329
|
-
this.gl.activeTexture(this.gl.TEXTURE0);
|
|
1330
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, source.colorHandle);
|
|
1331
|
-
this.gl.bindSampler(0, null);
|
|
1332
|
-
try {
|
|
1333
|
-
const uniformLocation = this.gl.getUniformLocation(program, "u_source");
|
|
1334
|
-
this.gl.uniform1i(uniformLocation, 0);
|
|
1335
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1336
|
-
this.gl.flush();
|
|
1337
|
-
}
|
|
1338
|
-
finally {
|
|
1339
|
-
this.restoreFullscreenPresentationState(previousState, outputWidth, outputHeight);
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
ensureBloomPingPongResources(width, height, hdr = false) {
|
|
1343
|
-
const current = this.bloomPingPongResources;
|
|
1344
|
-
if (current && current.width === width && current.height === height && current.hdr === hdr) {
|
|
1345
|
-
return current;
|
|
1346
|
-
}
|
|
1347
|
-
this.disposeBloomPingPongResources();
|
|
1348
|
-
this.disposeBloomPyramidResources();
|
|
1349
|
-
const textureUnit0 = this.captureTextureUnit0();
|
|
1350
|
-
const previousFramebuffer = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
|
|
1351
|
-
const textures = [];
|
|
1352
|
-
const framebuffers = [];
|
|
1353
|
-
try {
|
|
1354
|
-
for (let index = 0; index < 2; index += 1) {
|
|
1355
|
-
const texture = this.gl.createTexture();
|
|
1356
|
-
const framebuffer = this.gl.createFramebuffer();
|
|
1357
|
-
if (!texture || !framebuffer) {
|
|
1358
|
-
if (texture)
|
|
1359
|
-
this.gl.deleteTexture(texture);
|
|
1360
|
-
if (framebuffer)
|
|
1361
|
-
this.gl.deleteFramebuffer(framebuffer);
|
|
1362
|
-
throw new RenderDeviceError("Failed to allocate WebGL2 bloom ping-pong resources", "WEBGL_ALLOCATION_FAILED", {
|
|
1363
|
-
width,
|
|
1364
|
-
height,
|
|
1365
|
-
index
|
|
1366
|
-
});
|
|
1367
|
-
}
|
|
1368
|
-
textures.push(texture);
|
|
1369
|
-
framebuffers.push(framebuffer);
|
|
1370
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
|
|
1371
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
|
|
1372
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
1373
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
1374
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
1375
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, hdr ? this.gl.RGBA16F : this.gl.RGBA8, width, height, 0, this.gl.RGBA, hdr ? this.gl.HALF_FLOAT : this.gl.UNSIGNED_BYTE, null);
|
|
1376
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
|
|
1377
|
-
this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, texture, 0);
|
|
1378
|
-
const status = this.gl.checkFramebufferStatus(this.gl.FRAMEBUFFER);
|
|
1379
|
-
if (status !== this.gl.FRAMEBUFFER_COMPLETE) {
|
|
1380
|
-
throw new RenderDeviceError("WebGL2 bloom ping-pong framebuffer status is invalid", "FRAMEBUFFER_INVALID", {
|
|
1381
|
-
width,
|
|
1382
|
-
height,
|
|
1383
|
-
index,
|
|
1384
|
-
status
|
|
1385
|
-
});
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
const resources = {
|
|
1389
|
-
width,
|
|
1390
|
-
height,
|
|
1391
|
-
hdr,
|
|
1392
|
-
textures: [textures[0], textures[1]],
|
|
1393
|
-
framebuffers: [framebuffers[0], framebuffers[1]]
|
|
1394
|
-
};
|
|
1395
|
-
this.bloomPingPongResources = resources;
|
|
1396
|
-
return resources;
|
|
1397
|
-
}
|
|
1398
|
-
catch (error) {
|
|
1399
|
-
for (const texture of textures)
|
|
1400
|
-
this.gl.deleteTexture(texture);
|
|
1401
|
-
for (const framebuffer of framebuffers)
|
|
1402
|
-
this.gl.deleteFramebuffer(framebuffer);
|
|
1403
|
-
throw error;
|
|
1404
|
-
}
|
|
1405
|
-
finally {
|
|
1406
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, previousFramebuffer);
|
|
1407
|
-
this.restoreTextureUnit0(textureUnit0);
|
|
1408
|
-
this.stateCache.invalidate();
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
ensureBloomLutTextures(options) {
|
|
1412
|
-
const updateBright = this.bloomBrightLutThreshold !== options.threshold;
|
|
1413
|
-
const updateComposite = this.bloomCompositeLutIntensity !== options.intensity ||
|
|
1414
|
-
this.bloomCompositeLutShoulder !== options.shoulder;
|
|
1415
|
-
if (this.bloomBrightLutTexture && this.bloomCompositeLutTexture && !updateBright && !updateComposite) {
|
|
1416
|
-
return;
|
|
1417
|
-
}
|
|
1418
|
-
const textureUnit0 = this.captureTextureUnit0();
|
|
1419
|
-
try {
|
|
1420
|
-
if (!this.bloomBrightLutTexture) {
|
|
1421
|
-
this.bloomBrightLutTexture = this.createNativeBloomDataTexture();
|
|
1422
|
-
}
|
|
1423
|
-
if (updateBright) {
|
|
1424
|
-
const pixels = createBloomBrightThresholdLut(options.threshold);
|
|
1425
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, this.bloomBrightLutTexture);
|
|
1426
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA8, BLOOM_BRIGHT_LUT_WIDTH, BLOOM_BRIGHT_LUT_HEIGHT, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels);
|
|
1427
|
-
this.bloomBrightLutThreshold = options.threshold;
|
|
1428
|
-
}
|
|
1429
|
-
if (!this.bloomCompositeLutTexture) {
|
|
1430
|
-
this.bloomCompositeLutTexture = this.createNativeBloomDataTexture();
|
|
1431
|
-
}
|
|
1432
|
-
if (updateComposite) {
|
|
1433
|
-
const pixels = createBloomCompositeLut(options.intensity, { shoulder: options.shoulder });
|
|
1434
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, this.bloomCompositeLutTexture);
|
|
1435
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA8, BLOOM_COMPOSITE_LUT_SIZE, BLOOM_COMPOSITE_LUT_SIZE, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels);
|
|
1436
|
-
this.bloomCompositeLutIntensity = options.intensity;
|
|
1437
|
-
this.bloomCompositeLutShoulder = options.shoulder;
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
finally {
|
|
1441
|
-
this.restoreTextureUnit0(textureUnit0);
|
|
1442
|
-
this.stateCache.invalidate();
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
|
-
createNativeBloomDataTexture() {
|
|
1446
|
-
const texture = this.gl.createTexture();
|
|
1447
|
-
if (!texture) {
|
|
1448
|
-
throw new RenderDeviceError("Failed to allocate WebGL2 bloom lookup texture", "WEBGL_ALLOCATION_FAILED");
|
|
1449
|
-
}
|
|
1450
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
|
|
1451
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
|
|
1452
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
1453
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
1454
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
1455
|
-
return texture;
|
|
1456
|
-
}
|
|
1457
|
-
ensureOutlineBlendLutTexture(options) {
|
|
1458
|
-
const combinedAlpha = options.opacity * (options.color[3] / 255);
|
|
1459
|
-
const key = `${options.color.join(",")}|${combinedAlpha}`;
|
|
1460
|
-
if (this.outlineBlendLutTexture && this.outlineBlendLutKey === key)
|
|
1461
|
-
return;
|
|
1462
|
-
const textureUnit0 = this.captureTextureUnit0();
|
|
1463
|
-
try {
|
|
1464
|
-
if (!this.outlineBlendLutTexture) {
|
|
1465
|
-
this.outlineBlendLutTexture = this.createNativeBloomDataTexture();
|
|
1466
|
-
}
|
|
1467
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, this.outlineBlendLutTexture);
|
|
1468
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA8, OUTLINE_BLEND_LUT_WIDTH, 1, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, createOutlineBlendLut(options.color, combinedAlpha));
|
|
1469
|
-
this.outlineBlendLutKey = key;
|
|
1470
|
-
}
|
|
1471
|
-
finally {
|
|
1472
|
-
this.restoreTextureUnit0(textureUnit0);
|
|
1473
|
-
this.stateCache.invalidate();
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
ensureMotionBlurVelocityTexture(width, height, velocity) {
|
|
1477
|
-
const textureUnit0 = this.captureTextureUnit0();
|
|
1478
|
-
try {
|
|
1479
|
-
if (!this.motionBlurVelocityTexture) {
|
|
1480
|
-
this.motionBlurVelocityTexture = this.createNativeBloomDataTexture();
|
|
1481
|
-
}
|
|
1482
|
-
this.motionBlurVelocitySize = { width, height };
|
|
1483
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, this.motionBlurVelocityTexture);
|
|
1484
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RG32F, width, height, 0, this.gl.RG, this.gl.FLOAT, velocity);
|
|
1485
|
-
}
|
|
1486
|
-
finally {
|
|
1487
|
-
this.restoreTextureUnit0(textureUnit0);
|
|
1488
|
-
this.stateCache.invalidate();
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
ensureTaaHistoryTexture(width, height, history) {
|
|
1492
|
-
const textureUnit0 = this.captureTextureUnit0();
|
|
1493
|
-
try {
|
|
1494
|
-
if (!this.taaHistoryTexture) {
|
|
1495
|
-
this.taaHistoryTexture = this.createNativeBloomDataTexture();
|
|
1496
|
-
}
|
|
1497
|
-
this.taaHistorySize = { width, height };
|
|
1498
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, this.taaHistoryTexture);
|
|
1499
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA8, width, height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, history);
|
|
1500
|
-
}
|
|
1501
|
-
finally {
|
|
1502
|
-
this.restoreTextureUnit0(textureUnit0);
|
|
1503
|
-
this.stateCache.invalidate();
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
drawNativeLdrStage(sourceTexture, framebuffer, width, height, program, vertexArray, tonePass, colorPass, fxaaPass, toneMappingDefaults) {
|
|
1507
|
-
const toneOptions = { ...(toneMappingDefaults ?? {}), ...(tonePass?.options ?? {}) };
|
|
1508
|
-
const colorOptions = colorPass?.options ?? {};
|
|
1509
|
-
const fxaaOptions = fxaaPass?.options ?? {};
|
|
1510
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
|
|
1511
|
-
this.gl.viewport(0, 0, width, height);
|
|
1512
|
-
this.gl.useProgram(program);
|
|
1513
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1514
|
-
this.bindFullscreenTexture(0, sourceTexture);
|
|
1515
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
|
|
1516
|
-
this.gl.uniform2f(this.gl.getUniformLocation(program, "u_texelSize"), 1 / width, 1 / height);
|
|
1517
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_hasToneMapping"), tonePass ? 1 : 0);
|
|
1518
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_toneOperator"), toneMappingOperatorId(stringOption(toneOptions, "operator", "reinhard")));
|
|
1519
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_inputColorSpace"), colorSpaceId(stringOption(toneOptions, "inputColorSpace", "linear")));
|
|
1520
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_outputColorSpace"), colorSpaceId(stringOption(toneOptions, "outputColorSpace", "linear")));
|
|
1521
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_exposure"), numberOption(toneOptions, "exposure", 1));
|
|
1522
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_whitePoint"), Math.max(0.0001, numberOption(toneOptions, "whitePoint", 1)));
|
|
1523
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_gamma"), Math.max(0.0001, numberOption(toneOptions, "gamma", 2.2)));
|
|
1524
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_hasColorGrade"), colorPass ? 1 : 0);
|
|
1525
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_contrast"), numberOption(colorOptions, "contrast", 1));
|
|
1526
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_temperature"), numberOption(colorOptions, "temperature", 0));
|
|
1527
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_tint"), numberOption(colorOptions, "tint", 0));
|
|
1528
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_saturation"), numberOption(colorOptions, "saturation", 1));
|
|
1529
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_vibrance"), numberOption(colorOptions, "vibrance", 0));
|
|
1530
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_vignette"), numberOption(colorOptions, "vignette", 0));
|
|
1531
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_sharpening"), numberOption(colorOptions, "sharpening", 0));
|
|
1532
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_hasFxaa"), fxaaPass ? 1 : 0);
|
|
1533
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_edgeThreshold"), numberOption(fxaaOptions, "edgeThreshold", 0.125));
|
|
1534
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_subpixelBlend"), numberOption(fxaaOptions, "subpixelBlend", 0.75));
|
|
1535
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1536
|
-
}
|
|
1537
|
-
executeNativeBloomPasses(sourceTexture, resources, options, vertexArray, hdr) {
|
|
1538
|
-
const brightLut = this.bloomBrightLutTexture;
|
|
1539
|
-
const compositeLut = this.bloomCompositeLutTexture;
|
|
1540
|
-
if (!hdr && (!brightLut || !compositeLut)) {
|
|
1541
|
-
throw new RenderDeviceError("WebGL2 bloom lookup textures were not initialized", "WEBGL_ALLOCATION_FAILED");
|
|
1542
|
-
}
|
|
1543
|
-
const [textureA, textureB] = resources.textures;
|
|
1544
|
-
const [framebufferA, framebufferB] = resources.framebuffers;
|
|
1545
|
-
const brightProgram = this.ensureBloomBrightExtractProgram();
|
|
1546
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebufferA);
|
|
1547
|
-
this.gl.viewport(0, 0, resources.width, resources.height);
|
|
1548
|
-
this.gl.useProgram(brightProgram);
|
|
1549
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1550
|
-
this.bindFullscreenTexture(0, sourceTexture);
|
|
1551
|
-
if (brightLut)
|
|
1552
|
-
this.bindFullscreenTexture(1, brightLut);
|
|
1553
|
-
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_source"), 0);
|
|
1554
|
-
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_brightLut"), 1);
|
|
1555
|
-
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1556
|
-
this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_threshold"), options.threshold);
|
|
1557
|
-
this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_softKnee"), options.softKnee);
|
|
1558
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1559
|
-
const blurProgram = this.ensureBloomBlurProgram();
|
|
1560
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebufferB);
|
|
1561
|
-
this.gl.useProgram(blurProgram);
|
|
1562
|
-
this.bindFullscreenTexture(0, textureA);
|
|
1563
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_source"), 0);
|
|
1564
|
-
this.gl.uniform2i(this.gl.getUniformLocation(blurProgram, "u_size"), resources.width, resources.height);
|
|
1565
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_radius"), options.radius);
|
|
1566
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_horizontal"), 1);
|
|
1567
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1568
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1569
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebufferA);
|
|
1570
|
-
this.bindFullscreenTexture(0, textureB);
|
|
1571
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_horizontal"), 0);
|
|
1572
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1573
|
-
const compositeProgram = this.ensureBloomCompositeProgram();
|
|
1574
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebufferB);
|
|
1575
|
-
this.gl.useProgram(compositeProgram);
|
|
1576
|
-
this.bindFullscreenTexture(0, sourceTexture);
|
|
1577
|
-
this.bindFullscreenTexture(1, textureA);
|
|
1578
|
-
if (compositeLut)
|
|
1579
|
-
this.bindFullscreenTexture(2, compositeLut);
|
|
1580
|
-
this.gl.uniform1i(this.gl.getUniformLocation(compositeProgram, "u_source"), 0);
|
|
1581
|
-
this.gl.uniform1i(this.gl.getUniformLocation(compositeProgram, "u_blurred"), 1);
|
|
1582
|
-
this.gl.uniform1i(this.gl.getUniformLocation(compositeProgram, "u_compositeLut"), 2);
|
|
1583
|
-
this.gl.uniform1i(this.gl.getUniformLocation(compositeProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1584
|
-
this.gl.uniform1f(this.gl.getUniformLocation(compositeProgram, "u_intensity"), options.intensity);
|
|
1585
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1586
|
-
return textureB;
|
|
1587
|
-
}
|
|
1588
|
-
/**
|
|
1589
|
-
* Balanced/cinematic bloom: bright-extract once, then a half-resolution mip
|
|
1590
|
-
* chain where every level is downsampled, separably blurred, and accumulated
|
|
1591
|
-
* with its energy-preserving weight. Returns a full-resolution bloom texture
|
|
1592
|
-
* holding the weighted sum, ready for the existing composite program.
|
|
1593
|
-
*/
|
|
1594
|
-
executeNativeBloomPyramidPasses(sourceTexture, sourceWidth, sourceHeight, resources, fullResStaging, options, vertexArray, hdr) {
|
|
1595
|
-
const plan = resources.plan;
|
|
1596
|
-
const mipCount = plan.mips.length;
|
|
1597
|
-
const downsampleProgram = this.ensureBloomDownsampleProgram();
|
|
1598
|
-
const brightProgram = this.ensureBloomBrightExtractProgram();
|
|
1599
|
-
const blurProgram = this.ensureBloomBlurProgram();
|
|
1600
|
-
const accumulateProgram = this.ensureBloomAccumulateProgram();
|
|
1601
|
-
const brightLut = this.bloomBrightLutTexture;
|
|
1602
|
-
const mipTexture = (level, slot) => resources.textures[level * 2 + slot];
|
|
1603
|
-
const mipFramebuffer = (level, slot) => resources.framebuffers[level * 2 + slot];
|
|
1604
|
-
const mipSize = (level) => plan.mips[level];
|
|
1605
|
-
// Blurred result settles in slot 1 for level 0, slot 0 for levels >= 1.
|
|
1606
|
-
const blurredSlot = (level) => (level === 0 ? 1 : 0);
|
|
1607
|
-
const drawDownsample = (fromTexture, fromWidth, fromHeight, toFramebuffer, toWidth, toHeight) => {
|
|
1608
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, toFramebuffer);
|
|
1609
|
-
this.gl.viewport(0, 0, toWidth, toHeight);
|
|
1610
|
-
this.gl.useProgram(downsampleProgram);
|
|
1611
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1612
|
-
this.bindFullscreenTexture(0, fromTexture);
|
|
1613
|
-
this.gl.uniform1i(this.gl.getUniformLocation(downsampleProgram, "u_source"), 0);
|
|
1614
|
-
this.gl.uniform2f(this.gl.getUniformLocation(downsampleProgram, "u_texelSize"), 1 / fromWidth, 1 / fromHeight);
|
|
1615
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1616
|
-
};
|
|
1617
|
-
const drawBrightExtract = (fromTexture, toFramebuffer, size) => {
|
|
1618
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, toFramebuffer);
|
|
1619
|
-
this.gl.viewport(0, 0, size.width, size.height);
|
|
1620
|
-
this.gl.useProgram(brightProgram);
|
|
1621
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1622
|
-
this.bindFullscreenTexture(0, fromTexture);
|
|
1623
|
-
if (brightLut)
|
|
1624
|
-
this.bindFullscreenTexture(1, brightLut);
|
|
1625
|
-
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_source"), 0);
|
|
1626
|
-
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_brightLut"), 1);
|
|
1627
|
-
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1628
|
-
this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_threshold"), options.threshold);
|
|
1629
|
-
this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_softKnee"), options.softKnee);
|
|
1630
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1631
|
-
};
|
|
1632
|
-
const drawSeparableBlur = (readTexture, tmpTexture, tmpFramebuffer, outFramebuffer, size) => {
|
|
1633
|
-
// Horizontal into the temp target, vertical back into the output target.
|
|
1634
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, tmpFramebuffer);
|
|
1635
|
-
this.gl.viewport(0, 0, size.width, size.height);
|
|
1636
|
-
this.gl.useProgram(blurProgram);
|
|
1637
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1638
|
-
this.bindFullscreenTexture(0, readTexture);
|
|
1639
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_source"), 0);
|
|
1640
|
-
this.gl.uniform2i(this.gl.getUniformLocation(blurProgram, "u_size"), size.width, size.height);
|
|
1641
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_radius"), options.radius);
|
|
1642
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_horizontal"), 1);
|
|
1643
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1644
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1645
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, outFramebuffer);
|
|
1646
|
-
this.bindFullscreenTexture(0, tmpTexture);
|
|
1647
|
-
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_horizontal"), 0);
|
|
1648
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1649
|
-
};
|
|
1650
|
-
// Level 0: downsample, bright-extract into slot 1, blur H into slot 0 and
|
|
1651
|
-
// V back into slot 1. Blurred result settles in slot 1.
|
|
1652
|
-
const level0 = mipSize(0);
|
|
1653
|
-
drawDownsample(sourceTexture, sourceWidth, sourceHeight, mipFramebuffer(0, 0), level0.width, level0.height);
|
|
1654
|
-
drawBrightExtract(mipTexture(0, 0), mipFramebuffer(0, 1), level0);
|
|
1655
|
-
drawSeparableBlur(mipTexture(0, 1), mipTexture(0, 0), mipFramebuffer(0, 0), mipFramebuffer(0, 1), level0);
|
|
1656
|
-
for (let level = 1; level < mipCount; level += 1) {
|
|
1657
|
-
const size = mipSize(level);
|
|
1658
|
-
const previous = mipSize(level - 1);
|
|
1659
|
-
drawDownsample(mipTexture(level - 1, blurredSlot(level - 1)), previous.width, previous.height, mipFramebuffer(level, 0), size.width, size.height);
|
|
1660
|
-
// 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);
|
|
1662
|
-
}
|
|
1663
|
-
// Accumulate smallest-to-largest, ping-ponging between the two
|
|
1664
|
-
// accumulators (a pass must never sample its own bound target).
|
|
1665
|
-
const weights = plan.weights;
|
|
1666
|
-
let readAccumulator = { texture: resources.accumulatorTextureA, framebuffer: resources.accumulatorFramebufferA };
|
|
1667
|
-
let writeAccumulator = { texture: resources.accumulatorTextureB, framebuffer: resources.accumulatorFramebufferB };
|
|
1668
|
-
// Clear both accumulators; the seed reads the cleared sibling, never the
|
|
1669
|
-
// bound target (feedback loop).
|
|
1670
|
-
for (const acc of [readAccumulator, writeAccumulator]) {
|
|
1671
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, acc.framebuffer);
|
|
1672
|
-
this.gl.viewport(0, 0, level0.width, level0.height);
|
|
1673
|
-
this.gl.clearColor(0, 0, 0, 0);
|
|
1674
|
-
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
1675
|
-
}
|
|
1676
|
-
// Seed: smallest mip onto the cleared sibling accumulator.
|
|
1677
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, writeAccumulator.framebuffer);
|
|
1678
|
-
this.gl.viewport(0, 0, level0.width, level0.height);
|
|
1679
|
-
this.gl.useProgram(accumulateProgram);
|
|
1680
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1681
|
-
this.bindFullscreenTexture(0, readAccumulator.texture);
|
|
1682
|
-
this.bindFullscreenTexture(1, mipTexture(mipCount - 1, blurredSlot(mipCount - 1)));
|
|
1683
|
-
this.gl.uniform1i(this.gl.getUniformLocation(accumulateProgram, "u_base"), 0);
|
|
1684
|
-
this.gl.uniform1i(this.gl.getUniformLocation(accumulateProgram, "u_bloom"), 1);
|
|
1685
|
-
this.gl.uniform1f(this.gl.getUniformLocation(accumulateProgram, "u_weight"), weights[mipCount - 1]);
|
|
1686
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1687
|
-
for (let level = mipCount - 2; level >= 0; level -= 1) {
|
|
1688
|
-
const nextRead = writeAccumulator;
|
|
1689
|
-
const nextWrite = readAccumulator;
|
|
1690
|
-
readAccumulator = nextRead;
|
|
1691
|
-
writeAccumulator = nextWrite;
|
|
1692
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, writeAccumulator.framebuffer);
|
|
1693
|
-
this.gl.viewport(0, 0, level0.width, level0.height);
|
|
1694
|
-
this.gl.useProgram(accumulateProgram);
|
|
1695
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1696
|
-
this.bindFullscreenTexture(0, readAccumulator.texture);
|
|
1697
|
-
this.bindFullscreenTexture(1, mipTexture(level, blurredSlot(level)));
|
|
1698
|
-
this.gl.uniform1i(this.gl.getUniformLocation(accumulateProgram, "u_base"), 0);
|
|
1699
|
-
this.gl.uniform1i(this.gl.getUniformLocation(accumulateProgram, "u_bloom"), 1);
|
|
1700
|
-
this.gl.uniform1f(this.gl.getUniformLocation(accumulateProgram, "u_weight"), weights[level]);
|
|
1701
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1702
|
-
}
|
|
1703
|
-
// Upsample the weighted sum onto full-resolution staging target A, using
|
|
1704
|
-
// the cleared staging target B as the zero base (never sample A while
|
|
1705
|
-
// rendering into it).
|
|
1706
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, fullResStaging.framebufferB);
|
|
1707
|
-
this.gl.viewport(0, 0, sourceWidth, sourceHeight);
|
|
1708
|
-
this.gl.clearColor(0, 0, 0, 0);
|
|
1709
|
-
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
1710
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, fullResStaging.framebufferA);
|
|
1711
|
-
this.gl.viewport(0, 0, sourceWidth, sourceHeight);
|
|
1712
|
-
this.gl.useProgram(accumulateProgram);
|
|
1713
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1714
|
-
this.bindFullscreenTexture(0, fullResStaging.textureB);
|
|
1715
|
-
this.bindFullscreenTexture(1, writeAccumulator.texture);
|
|
1716
|
-
this.gl.uniform1i(this.gl.getUniformLocation(accumulateProgram, "u_base"), 0);
|
|
1717
|
-
this.gl.uniform1i(this.gl.getUniformLocation(accumulateProgram, "u_bloom"), 1);
|
|
1718
|
-
this.gl.uniform1f(this.gl.getUniformLocation(accumulateProgram, "u_weight"), 1);
|
|
1719
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1720
|
-
return fullResStaging.textureA;
|
|
1721
|
-
}
|
|
1722
|
-
executeNativeOutlinePasses(sourceTexture, resources, options, vertexArray, targetIndex) {
|
|
1723
|
-
const blendLut = this.outlineBlendLutTexture;
|
|
1724
|
-
if (!blendLut) {
|
|
1725
|
-
throw new RenderDeviceError("WebGL2 outline lookup texture was not initialized", "WEBGL_ALLOCATION_FAILED");
|
|
1726
|
-
}
|
|
1727
|
-
const program = this.ensureOutlineProgram();
|
|
1728
|
-
const targetTexture = resources.textures[targetIndex];
|
|
1729
|
-
const targetFramebuffer = resources.framebuffers[targetIndex];
|
|
1730
|
-
const bound = createOutlineGradientBound(options.threshold);
|
|
1731
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, targetFramebuffer);
|
|
1732
|
-
this.gl.viewport(0, 0, resources.width, resources.height);
|
|
1733
|
-
this.gl.useProgram(program);
|
|
1734
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1735
|
-
this.bindFullscreenTexture(0, sourceTexture);
|
|
1736
|
-
this.bindFullscreenTexture(1, blendLut);
|
|
1737
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
|
|
1738
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_blendLut"), 1);
|
|
1739
|
-
this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), resources.width, resources.height);
|
|
1740
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_width"), options.width);
|
|
1741
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_boundHigh"), bound.highWord);
|
|
1742
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_boundLow"), bound.lowWord);
|
|
1743
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1744
|
-
return targetTexture;
|
|
1745
|
-
}
|
|
1746
|
-
executeNativeSsaoPass(sourceTexture, depthTexture, resources, options, vertexArray, targetIndex) {
|
|
1747
|
-
const program = this.ensureSsaoProgram();
|
|
1748
|
-
const targetTexture = resources.textures[targetIndex];
|
|
1749
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
|
|
1750
|
-
this.gl.viewport(0, 0, resources.width, resources.height);
|
|
1751
|
-
this.gl.useProgram(program);
|
|
1752
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1753
|
-
this.bindFullscreenTexture(0, sourceTexture);
|
|
1754
|
-
this.bindFullscreenTexture(1, depthTexture);
|
|
1755
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
|
|
1756
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_depth"), 1);
|
|
1757
|
-
this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), resources.width, resources.height);
|
|
1758
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_radius"), options.radius);
|
|
1759
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_intensity"), options.intensity);
|
|
1760
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_bias"), options.bias);
|
|
1761
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1762
|
-
return targetTexture;
|
|
1763
|
-
}
|
|
1764
|
-
executeNativeSsrPass(sourceTexture, depthTexture, resources, options, vertexArray, targetIndex, depthRange) {
|
|
1765
|
-
const program = this.ensureSsrProgram();
|
|
1766
|
-
const targetTexture = resources.textures[targetIndex];
|
|
1767
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
|
|
1768
|
-
this.gl.viewport(0, 0, resources.width, resources.height);
|
|
1769
|
-
this.gl.useProgram(program);
|
|
1770
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1771
|
-
this.bindFullscreenTexture(0, sourceTexture);
|
|
1772
|
-
this.bindFullscreenTexture(1, depthTexture);
|
|
1773
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
|
|
1774
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_depth"), 1);
|
|
1775
|
-
this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), resources.width, resources.height);
|
|
1776
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_intensity"), options.intensity);
|
|
1777
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_maxDistance"), options.maxDistance);
|
|
1778
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_depthNear"), depthRange.near);
|
|
1779
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_depthFar"), depthRange.far);
|
|
1780
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1781
|
-
return targetTexture;
|
|
1782
|
-
}
|
|
1783
|
-
executeNativeDepthOfFieldPass(sourceTexture, depthTexture, resources, options, vertexArray, targetIndex, depthRange) {
|
|
1784
|
-
const program = this.ensureDepthOfFieldProgram();
|
|
1785
|
-
const targetTexture = resources.textures[targetIndex];
|
|
1786
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
|
|
1787
|
-
this.gl.viewport(0, 0, resources.width, resources.height);
|
|
1788
|
-
this.gl.useProgram(program);
|
|
1789
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1790
|
-
this.bindFullscreenTexture(0, sourceTexture);
|
|
1791
|
-
this.bindFullscreenTexture(1, depthTexture);
|
|
1792
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
|
|
1793
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_depth"), 1);
|
|
1794
|
-
this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), resources.width, resources.height);
|
|
1795
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_focusDepth"), options.focusDepth);
|
|
1796
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_focusRange"), options.focusRange);
|
|
1797
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_maxRadius"), options.maxRadius);
|
|
1798
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_depthNear"), depthRange.near);
|
|
1799
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_depthFar"), depthRange.far);
|
|
1800
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1801
|
-
return targetTexture;
|
|
1802
|
-
}
|
|
1803
|
-
executeNativeMotionBlurPass(sourceTexture, resources, options, vertexArray, targetIndex) {
|
|
1804
|
-
const velocityTexture = this.motionBlurVelocityTexture;
|
|
1805
|
-
if (!velocityTexture) {
|
|
1806
|
-
throw new RenderDeviceError("WebGL2 motion-blur velocity texture was not initialized", "WEBGL_ALLOCATION_FAILED");
|
|
1807
|
-
}
|
|
1808
|
-
const program = this.ensureMotionBlurProgram();
|
|
1809
|
-
const targetTexture = resources.textures[targetIndex];
|
|
1810
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
|
|
1811
|
-
this.gl.viewport(0, 0, resources.width, resources.height);
|
|
1812
|
-
this.gl.useProgram(program);
|
|
1813
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1814
|
-
this.bindFullscreenTexture(0, sourceTexture);
|
|
1815
|
-
this.bindFullscreenTexture(1, velocityTexture);
|
|
1816
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
|
|
1817
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_velocity"), 1);
|
|
1818
|
-
this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), resources.width, resources.height);
|
|
1819
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_samples"), options.samples);
|
|
1820
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_scale"), options.scale);
|
|
1821
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1822
|
-
return targetTexture;
|
|
1823
|
-
}
|
|
1824
|
-
executeNativeTaaPass(sourceTexture, resources, options, vertexArray, targetIndex) {
|
|
1825
|
-
const historyTexture = this.taaHistoryTexture;
|
|
1826
|
-
if (!historyTexture) {
|
|
1827
|
-
throw new RenderDeviceError("WebGL2 TAA history texture was not initialized", "WEBGL_ALLOCATION_FAILED");
|
|
1828
|
-
}
|
|
1829
|
-
const program = this.ensureTaaProgram();
|
|
1830
|
-
const targetTexture = resources.textures[targetIndex];
|
|
1831
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
|
|
1832
|
-
this.gl.viewport(0, 0, resources.width, resources.height);
|
|
1833
|
-
this.gl.useProgram(program);
|
|
1834
|
-
this.gl.bindVertexArray(vertexArray);
|
|
1835
|
-
this.bindFullscreenTexture(0, sourceTexture);
|
|
1836
|
-
this.bindFullscreenTexture(1, historyTexture);
|
|
1837
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
|
|
1838
|
-
this.gl.uniform1i(this.gl.getUniformLocation(program, "u_history"), 1);
|
|
1839
|
-
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_blend"), options.blend);
|
|
1840
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1841
|
-
return targetTexture;
|
|
1842
|
-
}
|
|
1843
|
-
bindFullscreenTexture(unit, texture) {
|
|
1844
|
-
this.gl.activeTexture(this.gl.TEXTURE0 + unit);
|
|
1845
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
|
|
1846
|
-
this.gl.bindSampler(unit, null);
|
|
1847
|
-
}
|
|
1848
|
-
disposeBloomPingPongResources() {
|
|
1849
|
-
if (!this.bloomPingPongResources)
|
|
1850
|
-
return;
|
|
1851
|
-
for (const texture of this.bloomPingPongResources.textures)
|
|
1852
|
-
this.gl.deleteTexture(texture);
|
|
1853
|
-
for (const framebuffer of this.bloomPingPongResources.framebuffers)
|
|
1854
|
-
this.gl.deleteFramebuffer(framebuffer);
|
|
1855
|
-
this.bloomPingPongResources = null;
|
|
1856
|
-
}
|
|
1857
|
-
/**
|
|
1858
|
-
* Diagnostics for the most recent native bloom execution (muse3jsparity-PRD
|
|
1859
|
-
* A1). Null when no native bloom pass has run yet on this device.
|
|
1860
|
-
*/
|
|
1861
|
-
getBloomDiagnostics() {
|
|
1862
|
-
return this.lastBloomDiagnostics;
|
|
1863
|
-
}
|
|
1864
|
-
recordBloomDiagnostics(options, sourceWidth, sourceHeight, hdr, mipCount) {
|
|
1865
|
-
const plan = resolveBloomPyramidPlan(sourceWidth, sourceHeight, options.quality, hdr);
|
|
1866
|
-
const pingPongBytes = sourceWidth * sourceHeight * 4 * (hdr ? 2 : 1) * 2;
|
|
1867
|
-
const bytesPerChannel = plan.halfFloat ? 2 : 1;
|
|
1868
|
-
const level0 = plan.mips[0];
|
|
1869
|
-
const accumulatorBytes = level0.width * level0.height * 4 * bytesPerChannel;
|
|
1870
|
-
this.lastBloomDiagnostics = {
|
|
1871
|
-
quality: options.quality,
|
|
1872
|
-
mipCount,
|
|
1873
|
-
targetCount: options.quality === "performance" ? 2 : plan.mips.length * 2 + 1,
|
|
1874
|
-
targetBytes: (options.quality === "performance" ? pingPongBytes : plan.targetBytes + accumulatorBytes + pingPongBytes),
|
|
1875
|
-
compositeGain: options.intensity,
|
|
1876
|
-
threshold: options.threshold,
|
|
1877
|
-
intensity: options.intensity,
|
|
1878
|
-
softKnee: options.softKnee,
|
|
1879
|
-
shoulder: options.shoulder,
|
|
1880
|
-
halfFloat: hdr || plan.halfFloat,
|
|
1881
|
-
};
|
|
1882
|
-
}
|
|
1883
|
-
/**
|
|
1884
|
-
* PART U: every live GPU allocation with bytes + lane owner — registry
|
|
1885
|
-
* render targets (B1 shadow maps arrive labeled, B4 captures arrive as
|
|
1886
|
-
* `-mirror-target`/`-scene-color-target`) plus the raw-handle residents the
|
|
1887
|
-
* registry set cannot see: the A1 bloom pyramid (two targets per mip plus
|
|
1888
|
-
* two level-0 accumulators), the legacy bloom ping-pong pair, the A1/A3
|
|
1889
|
-
* lookup textures, and the motion-blur/taa history textures. The
|
|
1890
|
-
* depth-readback scratch pair is intentionally absent: it is allocated and
|
|
1891
|
-
* deleted inside one synchronous call, so it is never live at a diagnostics
|
|
1892
|
-
* boundary. A5 volumetric light, C4 decals, and the G1 SDF atlas own no GPU
|
|
1893
|
-
* target (forward uniforms + CPU kernel, CPU geometry, CPU atlas data), so
|
|
1894
|
-
* no entry is emitted for them; a target appearing under their owner would
|
|
1895
|
-
* be the signal that the lane grew one.
|
|
1896
|
-
*/
|
|
1897
|
-
describeGpuTargetInventory(liveRenderTargets) {
|
|
1898
|
-
const entries = liveRenderTargets.map((target) => ({
|
|
1899
|
-
label: target.label,
|
|
1900
|
-
kind: "render-target",
|
|
1901
|
-
bytes: target.colorTexture.byteLength + (target.depthTexture?.byteLength ?? 0),
|
|
1902
|
-
owner: resolveGpuTargetOwner(target.label)
|
|
1903
|
-
}));
|
|
1904
|
-
const pyramid = this.bloomPyramidResources;
|
|
1905
|
-
if (pyramid) {
|
|
1906
|
-
const bytesPerPixel = pyramid.hdr ? 8 : 4;
|
|
1907
|
-
pyramid.plan.mips.forEach((mip, index) => {
|
|
1908
|
-
for (const side of ["a", "b"]) {
|
|
1909
|
-
entries.push({
|
|
1910
|
-
label: `bloom-pyramid-mip${index}${side}`,
|
|
1911
|
-
kind: "pyramid-mip",
|
|
1912
|
-
bytes: mip.width * mip.height * bytesPerPixel,
|
|
1913
|
-
owner: "a1-bloom"
|
|
1914
|
-
});
|
|
1915
|
-
}
|
|
1916
|
-
});
|
|
1917
|
-
const level0 = pyramid.plan.mips[0];
|
|
1918
|
-
if (level0) {
|
|
1919
|
-
for (const side of ["a", "b"]) {
|
|
1920
|
-
entries.push({
|
|
1921
|
-
label: `bloom-pyramid-accumulator-${side}`,
|
|
1922
|
-
kind: "pyramid-accumulator",
|
|
1923
|
-
bytes: level0.width * level0.height * bytesPerPixel,
|
|
1924
|
-
owner: "a1-bloom"
|
|
1925
|
-
});
|
|
1926
|
-
}
|
|
1927
|
-
}
|
|
1928
|
-
}
|
|
1929
|
-
const pingPong = this.bloomPingPongResources;
|
|
1930
|
-
if (pingPong) {
|
|
1931
|
-
const bytesPerPixel = pingPong.hdr ? 8 : 4;
|
|
1932
|
-
for (const side of ["a", "b"]) {
|
|
1933
|
-
entries.push({
|
|
1934
|
-
label: `bloom-ping-pong-${side}`,
|
|
1935
|
-
kind: "ping-pong",
|
|
1936
|
-
bytes: pingPong.width * pingPong.height * bytesPerPixel,
|
|
1937
|
-
owner: "a1-bloom"
|
|
1938
|
-
});
|
|
1939
|
-
}
|
|
1940
|
-
}
|
|
1941
|
-
if (this.bloomBrightLutTexture) {
|
|
1942
|
-
entries.push({
|
|
1943
|
-
label: "bloom-bright-lut",
|
|
1944
|
-
kind: "lut",
|
|
1945
|
-
bytes: BLOOM_BRIGHT_LUT_WIDTH * BLOOM_BRIGHT_LUT_HEIGHT * 4,
|
|
1946
|
-
owner: "a1-bloom"
|
|
1947
|
-
});
|
|
1948
|
-
}
|
|
1949
|
-
if (this.bloomCompositeLutTexture) {
|
|
1950
|
-
entries.push({
|
|
1951
|
-
label: "bloom-composite-lut",
|
|
1952
|
-
kind: "lut",
|
|
1953
|
-
bytes: BLOOM_COMPOSITE_LUT_SIZE * BLOOM_COMPOSITE_LUT_SIZE * 4,
|
|
1954
|
-
owner: "a1-bloom"
|
|
1955
|
-
});
|
|
1956
|
-
}
|
|
1957
|
-
if (this.outlineBlendLutTexture) {
|
|
1958
|
-
entries.push({ label: "outline-blend-lut", kind: "lut", bytes: OUTLINE_BLEND_LUT_WIDTH * 4, owner: "post" });
|
|
1959
|
-
}
|
|
1960
|
-
if (this.motionBlurVelocityTexture && this.motionBlurVelocitySize) {
|
|
1961
|
-
entries.push({
|
|
1962
|
-
label: "motion-blur-velocity",
|
|
1963
|
-
kind: "history",
|
|
1964
|
-
bytes: this.motionBlurVelocitySize.width * this.motionBlurVelocitySize.height * 8,
|
|
1965
|
-
owner: "post"
|
|
1966
|
-
});
|
|
1967
|
-
}
|
|
1968
|
-
if (this.taaHistoryTexture && this.taaHistorySize) {
|
|
1969
|
-
entries.push({
|
|
1970
|
-
label: "taa-history",
|
|
1971
|
-
kind: "history",
|
|
1972
|
-
bytes: this.taaHistorySize.width * this.taaHistorySize.height * 4,
|
|
1973
|
-
owner: "post"
|
|
1974
|
-
});
|
|
1975
|
-
}
|
|
1976
|
-
return entries;
|
|
1977
|
-
}
|
|
1978
|
-
disposeBloomPyramidResources() {
|
|
1979
|
-
if (!this.bloomPyramidResources)
|
|
1980
|
-
return;
|
|
1981
|
-
for (const texture of this.bloomPyramidResources.textures)
|
|
1180
|
+
this.host.samplers.samplerObjectCache.clear();
|
|
1181
|
+
for (const texture of this.host.textureRegistry.textures.values()) {
|
|
1982
1182
|
this.gl.deleteTexture(texture);
|
|
1983
|
-
for (const framebuffer of this.bloomPyramidResources.framebuffers)
|
|
1984
|
-
this.gl.deleteFramebuffer(framebuffer);
|
|
1985
|
-
this.gl.deleteTexture(this.bloomPyramidResources.accumulatorTextureA);
|
|
1986
|
-
this.gl.deleteFramebuffer(this.bloomPyramidResources.accumulatorFramebufferA);
|
|
1987
|
-
this.gl.deleteTexture(this.bloomPyramidResources.accumulatorTextureB);
|
|
1988
|
-
this.gl.deleteFramebuffer(this.bloomPyramidResources.accumulatorFramebufferB);
|
|
1989
|
-
this.bloomPyramidResources = null;
|
|
1990
|
-
}
|
|
1991
|
-
/**
|
|
1992
|
-
* Mip-chain targets for the balanced/cinematic bloom pyramid. Each level is a
|
|
1993
|
-
* single texture+framebuffer at the planned size with linear filtering so the
|
|
1994
|
-
* downsample and accumulate passes can sample across levels. Half-float backs
|
|
1995
|
-
* the chain when the source is HDR or the cinematic preset requests it.
|
|
1996
|
-
*/
|
|
1997
|
-
ensureBloomPyramidResources(plan, hdr) {
|
|
1998
|
-
const current = this.bloomPyramidResources;
|
|
1999
|
-
if (current && current.plan.quality === plan.quality && current.hdr === (hdr || plan.halfFloat) &&
|
|
2000
|
-
current.plan.mips.length === plan.mips.length &&
|
|
2001
|
-
current.plan.mips.every((mip, index) => mip.width === plan.mips[index].width && mip.height === plan.mips[index].height)) {
|
|
2002
|
-
return current;
|
|
2003
|
-
}
|
|
2004
|
-
this.disposeBloomPyramidResources();
|
|
2005
|
-
const textureUnit0 = this.captureTextureUnit0();
|
|
2006
|
-
const previousFramebuffer = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
|
|
2007
|
-
const textures = [];
|
|
2008
|
-
const framebuffers = [];
|
|
2009
|
-
const useHalfFloat = hdr || plan.halfFloat;
|
|
2010
|
-
const allocateTarget = (width, height, label) => {
|
|
2011
|
-
const texture = this.gl.createTexture();
|
|
2012
|
-
const framebuffer = this.gl.createFramebuffer();
|
|
2013
|
-
if (!texture || !framebuffer) {
|
|
2014
|
-
if (texture)
|
|
2015
|
-
this.gl.deleteTexture(texture);
|
|
2016
|
-
if (framebuffer)
|
|
2017
|
-
this.gl.deleteFramebuffer(framebuffer);
|
|
2018
|
-
throw new RenderDeviceError(`Failed to allocate WebGL2 bloom pyramid ${label}`, "WEBGL_ALLOCATION_FAILED", { width, height });
|
|
2019
|
-
}
|
|
2020
|
-
textures.push(texture);
|
|
2021
|
-
framebuffers.push(framebuffer);
|
|
2022
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
|
|
2023
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
|
|
2024
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
|
|
2025
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
2026
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
2027
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, useHalfFloat ? this.gl.RGBA16F : this.gl.RGBA8, width, height, 0, this.gl.RGBA, useHalfFloat ? this.gl.HALF_FLOAT : this.gl.UNSIGNED_BYTE, null);
|
|
2028
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
|
|
2029
|
-
this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, texture, 0);
|
|
2030
|
-
const status = this.gl.checkFramebufferStatus(this.gl.FRAMEBUFFER);
|
|
2031
|
-
if (status !== this.gl.FRAMEBUFFER_COMPLETE) {
|
|
2032
|
-
throw new RenderDeviceError("WebGL2 bloom pyramid framebuffer status is invalid", "FRAMEBUFFER_INVALID", { width, height, status });
|
|
2033
|
-
}
|
|
2034
|
-
return { texture, framebuffer };
|
|
2035
|
-
};
|
|
2036
|
-
try {
|
|
2037
|
-
// Two ping-pong targets per mip (separable blur needs distinct read/write
|
|
2038
|
-
// targets at the same size), plus two level-0-sized accumulators: the
|
|
2039
|
-
// weighted sum ping-pongs between them so no pass ever samples the
|
|
2040
|
-
// texture of its own bound framebuffer (feedback loop).
|
|
2041
|
-
for (const mip of plan.mips) {
|
|
2042
|
-
allocateTarget(mip.width, mip.height, "mip");
|
|
2043
|
-
allocateTarget(mip.width, mip.height, "mip");
|
|
2044
|
-
}
|
|
2045
|
-
const level0 = plan.mips[0];
|
|
2046
|
-
const accumulatorA = allocateTarget(level0.width, level0.height, "accumulator-a");
|
|
2047
|
-
const accumulatorB = allocateTarget(level0.width, level0.height, "accumulator-b");
|
|
2048
|
-
const finalResources = {
|
|
2049
|
-
plan,
|
|
2050
|
-
hdr: useHalfFloat,
|
|
2051
|
-
textures,
|
|
2052
|
-
framebuffers,
|
|
2053
|
-
accumulatorTextureA: accumulatorA.texture,
|
|
2054
|
-
accumulatorFramebufferA: accumulatorA.framebuffer,
|
|
2055
|
-
accumulatorTextureB: accumulatorB.texture,
|
|
2056
|
-
accumulatorFramebufferB: accumulatorB.framebuffer
|
|
2057
|
-
};
|
|
2058
|
-
this.bloomPyramidResources = finalResources;
|
|
2059
|
-
return finalResources;
|
|
2060
|
-
}
|
|
2061
|
-
catch (error) {
|
|
2062
|
-
for (const texture of textures)
|
|
2063
|
-
this.gl.deleteTexture(texture);
|
|
2064
|
-
for (const framebuffer of framebuffers)
|
|
2065
|
-
this.gl.deleteFramebuffer(framebuffer);
|
|
2066
|
-
throw error;
|
|
2067
|
-
}
|
|
2068
|
-
finally {
|
|
2069
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, previousFramebuffer);
|
|
2070
|
-
this.restoreTextureUnit0(textureUnit0);
|
|
2071
|
-
this.stateCache.invalidate();
|
|
2072
|
-
}
|
|
2073
|
-
}
|
|
2074
|
-
captureTextureUnit0() {
|
|
2075
|
-
const activeTexture = this.gl.getParameter(this.gl.ACTIVE_TEXTURE);
|
|
2076
|
-
this.gl.activeTexture(this.gl.TEXTURE0);
|
|
2077
|
-
return {
|
|
2078
|
-
activeTexture,
|
|
2079
|
-
texture2d: this.gl.getParameter(this.gl.TEXTURE_BINDING_2D),
|
|
2080
|
-
sampler: this.gl.getParameter(this.gl.SAMPLER_BINDING)
|
|
2081
|
-
};
|
|
2082
|
-
}
|
|
2083
|
-
restoreTextureUnit0(snapshot) {
|
|
2084
|
-
this.gl.activeTexture(this.gl.TEXTURE0);
|
|
2085
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, snapshot.texture2d);
|
|
2086
|
-
this.gl.bindSampler(0, snapshot.sampler);
|
|
2087
|
-
this.gl.activeTexture(snapshot.activeTexture);
|
|
2088
|
-
}
|
|
2089
|
-
captureTextureUnitBinding(unit) {
|
|
2090
|
-
this.gl.activeTexture(this.gl.TEXTURE0 + unit);
|
|
2091
|
-
return {
|
|
2092
|
-
texture2d: this.gl.getParameter(this.gl.TEXTURE_BINDING_2D),
|
|
2093
|
-
sampler: this.gl.getParameter(this.gl.SAMPLER_BINDING)
|
|
2094
|
-
};
|
|
2095
|
-
}
|
|
2096
|
-
restoreTextureUnitBinding(unit, snapshot) {
|
|
2097
|
-
this.gl.activeTexture(this.gl.TEXTURE0 + unit);
|
|
2098
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, snapshot.texture2d);
|
|
2099
|
-
this.gl.bindSampler(unit, snapshot.sampler);
|
|
2100
|
-
}
|
|
2101
|
-
prepareFullscreenPresentation(framebuffer, outputWidth, outputHeight) {
|
|
2102
|
-
const textureUnit0 = this.captureTextureUnit0();
|
|
2103
|
-
const textureUnit1 = this.captureTextureUnitBinding(1);
|
|
2104
|
-
const textureUnit2 = this.captureTextureUnitBinding(2);
|
|
2105
|
-
this.gl.activeTexture(textureUnit0.activeTexture);
|
|
2106
|
-
const snapshot = {
|
|
2107
|
-
framebuffer: this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING),
|
|
2108
|
-
program: this.gl.getParameter(this.gl.CURRENT_PROGRAM),
|
|
2109
|
-
textureUnit0,
|
|
2110
|
-
textureUnit1,
|
|
2111
|
-
textureUnit2,
|
|
2112
|
-
vertexArray: this.gl.getParameter(this.gl.VERTEX_ARRAY_BINDING),
|
|
2113
|
-
viewport: this.gl.getParameter(this.gl.VIEWPORT),
|
|
2114
|
-
colorMask: this.gl.getParameter(this.gl.COLOR_WRITEMASK),
|
|
2115
|
-
depthTestEnabled: this.gl.isEnabled(this.gl.DEPTH_TEST),
|
|
2116
|
-
cullFaceEnabled: this.gl.isEnabled(this.gl.CULL_FACE),
|
|
2117
|
-
blendEnabled: this.gl.isEnabled(this.gl.BLEND),
|
|
2118
|
-
scissorTestEnabled: this.gl.isEnabled(this.gl.SCISSOR_TEST),
|
|
2119
|
-
stencilTestEnabled: this.gl.isEnabled(this.gl.STENCIL_TEST),
|
|
2120
|
-
polygonOffsetFillEnabled: this.gl.isEnabled(this.gl.POLYGON_OFFSET_FILL),
|
|
2121
|
-
depthMask: this.gl.getParameter(this.gl.DEPTH_WRITEMASK)
|
|
2122
|
-
};
|
|
2123
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
|
|
2124
|
-
this.gl.viewport(0, 0, outputWidth, outputHeight);
|
|
2125
|
-
this.gl.colorMask(true, true, true, true);
|
|
2126
|
-
this.gl.disable(this.gl.SCISSOR_TEST);
|
|
2127
|
-
this.gl.disable(this.gl.STENCIL_TEST);
|
|
2128
|
-
this.gl.disable(this.gl.POLYGON_OFFSET_FILL);
|
|
2129
|
-
this.gl.disable(this.gl.DEPTH_TEST);
|
|
2130
|
-
this.gl.disable(this.gl.CULL_FACE);
|
|
2131
|
-
this.gl.disable(this.gl.BLEND);
|
|
2132
|
-
this.gl.depthMask(false);
|
|
2133
|
-
return snapshot;
|
|
2134
|
-
}
|
|
2135
|
-
restoreFullscreenPresentationState(snapshot, fallbackWidth, fallbackHeight) {
|
|
2136
|
-
this.gl.bindVertexArray(snapshot.vertexArray);
|
|
2137
|
-
this.restoreTextureUnitBinding(2, snapshot.textureUnit2);
|
|
2138
|
-
this.restoreTextureUnitBinding(1, snapshot.textureUnit1);
|
|
2139
|
-
this.restoreTextureUnit0(snapshot.textureUnit0);
|
|
2140
|
-
this.gl.useProgram(snapshot.program);
|
|
2141
|
-
if (snapshot.depthTestEnabled)
|
|
2142
|
-
this.gl.enable(this.gl.DEPTH_TEST);
|
|
2143
|
-
else
|
|
2144
|
-
this.gl.disable(this.gl.DEPTH_TEST);
|
|
2145
|
-
if (snapshot.cullFaceEnabled)
|
|
2146
|
-
this.gl.enable(this.gl.CULL_FACE);
|
|
2147
|
-
else
|
|
2148
|
-
this.gl.disable(this.gl.CULL_FACE);
|
|
2149
|
-
if (snapshot.blendEnabled)
|
|
2150
|
-
this.gl.enable(this.gl.BLEND);
|
|
2151
|
-
else
|
|
2152
|
-
this.gl.disable(this.gl.BLEND);
|
|
2153
|
-
if (snapshot.scissorTestEnabled)
|
|
2154
|
-
this.gl.enable(this.gl.SCISSOR_TEST);
|
|
2155
|
-
else
|
|
2156
|
-
this.gl.disable(this.gl.SCISSOR_TEST);
|
|
2157
|
-
if (snapshot.stencilTestEnabled)
|
|
2158
|
-
this.gl.enable(this.gl.STENCIL_TEST);
|
|
2159
|
-
else
|
|
2160
|
-
this.gl.disable(this.gl.STENCIL_TEST);
|
|
2161
|
-
if (snapshot.polygonOffsetFillEnabled)
|
|
2162
|
-
this.gl.enable(this.gl.POLYGON_OFFSET_FILL);
|
|
2163
|
-
else
|
|
2164
|
-
this.gl.disable(this.gl.POLYGON_OFFSET_FILL);
|
|
2165
|
-
this.gl.colorMask(snapshot.colorMask[0] ?? true, snapshot.colorMask[1] ?? true, snapshot.colorMask[2] ?? true, snapshot.colorMask[3] ?? true);
|
|
2166
|
-
this.gl.depthMask(snapshot.depthMask);
|
|
2167
|
-
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, snapshot.framebuffer);
|
|
2168
|
-
this.gl.viewport(snapshot.viewport[0] ?? 0, snapshot.viewport[1] ?? 0, snapshot.viewport[2] ?? fallbackWidth, snapshot.viewport[3] ?? fallbackHeight);
|
|
2169
|
-
this.stateCache.invalidate();
|
|
2170
|
-
}
|
|
2171
|
-
ensurePresentationVertexArray() {
|
|
2172
|
-
if (this.presentationVertexArray)
|
|
2173
|
-
return this.presentationVertexArray;
|
|
2174
|
-
const vertexArray = this.gl.createVertexArray();
|
|
2175
|
-
if (!vertexArray) {
|
|
2176
|
-
throw new RenderDeviceError("Failed to allocate WebGL presentation vertex array", "WEBGL_ALLOCATION_FAILED");
|
|
2177
|
-
}
|
|
2178
|
-
this.presentationVertexArray = vertexArray;
|
|
2179
|
-
return vertexArray;
|
|
2180
|
-
}
|
|
2181
|
-
ensureDepthReadbackProgram() {
|
|
2182
|
-
if (this.depthReadbackProgram) {
|
|
2183
|
-
return this.depthReadbackProgram;
|
|
2184
|
-
}
|
|
2185
|
-
const vertex = this.compileShader(this.gl.VERTEX_SHADER, `#version 300 es
|
|
2186
|
-
precision highp float;
|
|
2187
|
-
out vec2 v_uv;
|
|
2188
|
-
void main() {
|
|
2189
|
-
vec2 position = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));
|
|
2190
|
-
v_uv = position;
|
|
2191
|
-
gl_Position = vec4(position * 2.0 - 1.0, 0.0, 1.0);
|
|
2192
|
-
}
|
|
2193
|
-
`, "webgl2-depth-readback");
|
|
2194
|
-
const fragment = this.compileShader(this.gl.FRAGMENT_SHADER, `#version 300 es
|
|
2195
|
-
precision highp float;
|
|
2196
|
-
uniform sampler2D u_depth;
|
|
2197
|
-
uniform vec4 u_sourceRect;
|
|
2198
|
-
in vec2 v_uv;
|
|
2199
|
-
out vec4 outColor;
|
|
2200
|
-
vec3 packDepth24(float value) {
|
|
2201
|
-
value = clamp(value, 0.0, 1.0);
|
|
2202
|
-
vec3 encoded = fract(value * vec3(1.0, 255.0, 65025.0));
|
|
2203
|
-
encoded -= encoded.yzz * vec3(1.0 / 255.0, 1.0 / 255.0, 0.0);
|
|
2204
|
-
return encoded;
|
|
2205
|
-
}
|
|
2206
|
-
void main() {
|
|
2207
|
-
vec2 uv = u_sourceRect.xy + v_uv * u_sourceRect.zw;
|
|
2208
|
-
outColor = vec4(packDepth24(texture(u_depth, uv).r), 1.0);
|
|
2209
|
-
}
|
|
2210
|
-
`, "webgl2-depth-readback");
|
|
2211
|
-
const program = this.gl.createProgram();
|
|
2212
|
-
if (!program) {
|
|
2213
|
-
this.gl.deleteShader(vertex);
|
|
2214
|
-
this.gl.deleteShader(fragment);
|
|
2215
|
-
throw new RenderDeviceError("Failed to allocate WebGL2 depth readback shader", "WEBGL_ALLOCATION_FAILED");
|
|
2216
|
-
}
|
|
2217
|
-
this.gl.attachShader(program, vertex);
|
|
2218
|
-
this.gl.attachShader(program, fragment);
|
|
2219
|
-
this.gl.linkProgram(program);
|
|
2220
|
-
this.gl.deleteShader(vertex);
|
|
2221
|
-
this.gl.deleteShader(fragment);
|
|
2222
|
-
if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
|
|
2223
|
-
const log = this.gl.getProgramInfoLog(program) ?? "Unknown depth readback shader link error";
|
|
2224
|
-
this.gl.deleteProgram(program);
|
|
2225
|
-
throw new RenderDeviceError("WebGL2 depth readback shader link failed", "SHADER_LINK_FAILED", { log });
|
|
2226
|
-
}
|
|
2227
|
-
this.depthReadbackProgram = program;
|
|
2228
|
-
return program;
|
|
2229
|
-
}
|
|
2230
|
-
ensurePresentationProgram() {
|
|
2231
|
-
if (this.presentationProgram) {
|
|
2232
|
-
return this.presentationProgram;
|
|
2233
|
-
}
|
|
2234
|
-
const vertex = this.compileShader(this.gl.VERTEX_SHADER, `#version 300 es
|
|
2235
|
-
precision highp float;
|
|
2236
|
-
out vec2 v_uv;
|
|
2237
|
-
void main() {
|
|
2238
|
-
vec2 position = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));
|
|
2239
|
-
v_uv = position;
|
|
2240
|
-
gl_Position = vec4(position * 2.0 - 1.0, 0.0, 1.0);
|
|
2241
|
-
}
|
|
2242
|
-
`, "webgl2-present-render-target");
|
|
2243
|
-
const fragment = this.compileShader(this.gl.FRAGMENT_SHADER, `#version 300 es
|
|
2244
|
-
precision highp float;
|
|
2245
|
-
uniform sampler2D u_source;
|
|
2246
|
-
in vec2 v_uv;
|
|
2247
|
-
out vec4 outColor;
|
|
2248
|
-
void main() {
|
|
2249
|
-
outColor = texture(u_source, v_uv);
|
|
2250
|
-
}
|
|
2251
|
-
`, "webgl2-present-render-target");
|
|
2252
|
-
const program = this.gl.createProgram();
|
|
2253
|
-
if (!program) {
|
|
2254
|
-
this.gl.deleteShader(vertex);
|
|
2255
|
-
this.gl.deleteShader(fragment);
|
|
2256
|
-
throw new RenderDeviceError("Failed to allocate WebGL presentation shader", "WEBGL_ALLOCATION_FAILED");
|
|
2257
1183
|
}
|
|
2258
|
-
this.
|
|
2259
|
-
this.
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
if (
|
|
2264
|
-
|
|
2265
|
-
this.
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
}
|
|
2275
|
-
this.bloomBrightExtractProgram
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
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;
|
|
2371
|
-
}
|
|
2372
|
-
`, "webgl2-bloom-blur");
|
|
2373
|
-
return this.bloomBlurProgram;
|
|
2374
|
-
}
|
|
2375
|
-
ensureBloomCompositeProgram() {
|
|
2376
|
-
if (this.bloomCompositeProgram) {
|
|
2377
|
-
return this.bloomCompositeProgram;
|
|
2378
|
-
}
|
|
2379
|
-
this.bloomCompositeProgram = this.createFullscreenProgram(`#version 300 es
|
|
2380
|
-
precision highp float;
|
|
2381
|
-
precision highp int;
|
|
2382
|
-
uniform sampler2D u_source;
|
|
2383
|
-
uniform sampler2D u_blurred;
|
|
2384
|
-
uniform sampler2D u_compositeLut;
|
|
2385
|
-
uniform int u_hdr;
|
|
2386
|
-
uniform float u_intensity;
|
|
2387
|
-
out vec4 outColor;
|
|
2388
|
-
|
|
2389
|
-
uvec4 byteTexel(sampler2D source, ivec2 coordinate) {
|
|
2390
|
-
return uvec4(texelFetch(source, coordinate, 0) * 255.0 + 0.5);
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2393
|
-
float compositeChannel(uint source, uint blurred) {
|
|
2394
|
-
return texelFetch(u_compositeLut, ivec2(int(source), int(blurred)), 0).r;
|
|
2395
|
-
}
|
|
2396
|
-
|
|
2397
|
-
void main() {
|
|
2398
|
-
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2399
|
-
if (u_hdr == 1) {
|
|
2400
|
-
vec4 source = texelFetch(u_source, pixel, 0);
|
|
2401
|
-
vec3 blurred = texelFetch(u_blurred, pixel, 0).rgb;
|
|
2402
|
-
outColor = vec4(source.rgb + blurred * u_intensity, source.a);
|
|
2403
|
-
return;
|
|
2404
|
-
}
|
|
2405
|
-
uvec4 source = byteTexel(u_source, pixel);
|
|
2406
|
-
uvec4 blurred = byteTexel(u_blurred, pixel);
|
|
2407
|
-
outColor = vec4(
|
|
2408
|
-
compositeChannel(source.r, blurred.r),
|
|
2409
|
-
compositeChannel(source.g, blurred.g),
|
|
2410
|
-
compositeChannel(source.b, blurred.b),
|
|
2411
|
-
float(source.a) / 255.0
|
|
2412
|
-
);
|
|
2413
|
-
}
|
|
2414
|
-
`, "webgl2-bloom-composite");
|
|
2415
|
-
return this.bloomCompositeProgram;
|
|
2416
|
-
}
|
|
2417
|
-
ensureBloomDownsampleProgram() {
|
|
2418
|
-
if (this.bloomDownsampleProgram)
|
|
2419
|
-
return this.bloomDownsampleProgram;
|
|
2420
|
-
this.bloomDownsampleProgram = this.createFullscreenProgram(`#version 300 es
|
|
2421
|
-
precision highp float;
|
|
2422
|
-
uniform sampler2D u_source;
|
|
2423
|
-
uniform vec2 u_texelSize;
|
|
2424
|
-
out vec4 outColor;
|
|
2425
|
-
void main() {
|
|
2426
|
-
vec2 uv = (gl_FragCoord.xy - 0.5) * u_texelSize;
|
|
2427
|
-
vec2 e = u_texelSize * 0.5;
|
|
2428
|
-
vec4 sum = texture(u_source, uv - e) + texture(u_source, uv + vec2(e.x, -e.y))
|
|
2429
|
-
+ texture(u_source, uv + vec2(-e.x, e.y)) + texture(u_source, uv + e);
|
|
2430
|
-
outColor = sum * 0.25;
|
|
2431
|
-
}
|
|
2432
|
-
`, "webgl2-bloom-downsample");
|
|
2433
|
-
return this.bloomDownsampleProgram;
|
|
2434
|
-
}
|
|
2435
|
-
ensureBloomAccumulateProgram() {
|
|
2436
|
-
if (this.bloomAccumulateProgram)
|
|
2437
|
-
return this.bloomAccumulateProgram;
|
|
2438
|
-
this.bloomAccumulateProgram = this.createFullscreenProgram(`#version 300 es
|
|
2439
|
-
precision highp float;
|
|
2440
|
-
uniform sampler2D u_base;
|
|
2441
|
-
uniform sampler2D u_bloom;
|
|
2442
|
-
uniform float u_weight;
|
|
2443
|
-
out vec4 outColor;
|
|
2444
|
-
void main() {
|
|
2445
|
-
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2446
|
-
vec4 base = texelFetch(u_base, pixel, 0);
|
|
2447
|
-
vec2 uv = (vec2(pixel) + 0.5) / vec2(textureSize(u_base, 0));
|
|
2448
|
-
vec3 bloom = texture(u_bloom, uv).rgb;
|
|
2449
|
-
outColor = vec4(base.rgb + bloom * u_weight, base.a);
|
|
2450
|
-
}
|
|
2451
|
-
`, "webgl2-bloom-accumulate");
|
|
2452
|
-
return this.bloomAccumulateProgram;
|
|
2453
|
-
}
|
|
2454
|
-
ensureOutlineProgram() {
|
|
2455
|
-
if (this.outlineProgram)
|
|
2456
|
-
return this.outlineProgram;
|
|
2457
|
-
this.outlineProgram = this.createFullscreenProgram(`#version 300 es
|
|
2458
|
-
precision highp float;
|
|
2459
|
-
precision highp int;
|
|
2460
|
-
uniform sampler2D u_source;
|
|
2461
|
-
uniform sampler2D u_blendLut;
|
|
2462
|
-
uniform ivec2 u_size;
|
|
2463
|
-
uniform int u_width;
|
|
2464
|
-
uniform float u_boundHigh;
|
|
2465
|
-
uniform float u_boundLow;
|
|
2466
|
-
out vec4 outColor;
|
|
2467
|
-
|
|
2468
|
-
uvec4 sourceByte(ivec2 coordinate) {
|
|
2469
|
-
ivec2 bounded = clamp(coordinate, ivec2(0), u_size - ivec2(1));
|
|
2470
|
-
return uvec4(texelFetch(u_source, bounded, 0) * 255.0 + 0.5);
|
|
2471
|
-
}
|
|
2472
|
-
|
|
2473
|
-
uint lumaNumerator(ivec2 coordinate) {
|
|
2474
|
-
uvec3 source = sourceByte(coordinate).rgb;
|
|
2475
|
-
return 2126u * source.r + 7152u * source.g + 722u * source.b;
|
|
2476
|
-
}
|
|
2477
|
-
|
|
2478
|
-
uvec2 squareWords(int signedValue) {
|
|
2479
|
-
uint value = uint(abs(signedValue));
|
|
2480
|
-
uint high = value >> 12u;
|
|
2481
|
-
uint low = value & 4095u;
|
|
2482
|
-
uint middle = 2u * high * low;
|
|
2483
|
-
uint lowWord = low * low + (middle & 4095u) * 4096u;
|
|
2484
|
-
uint highWord = high * high + (middle >> 12u);
|
|
2485
|
-
highWord += lowWord / ${OUTLINE_LIMB_RADIX}u;
|
|
2486
|
-
lowWord %= ${OUTLINE_LIMB_RADIX}u;
|
|
2487
|
-
return uvec2(highWord, lowWord);
|
|
2488
|
-
}
|
|
2489
|
-
|
|
2490
|
-
bool edgeAt(ivec2 pixel) {
|
|
2491
|
-
int nw = int(lumaNumerator(pixel + ivec2(-1, -1)));
|
|
2492
|
-
int n = int(lumaNumerator(pixel + ivec2(0, -1)));
|
|
2493
|
-
int ne = int(lumaNumerator(pixel + ivec2(1, -1)));
|
|
2494
|
-
int w = int(lumaNumerator(pixel + ivec2(-1, 0)));
|
|
2495
|
-
int e = int(lumaNumerator(pixel + ivec2(1, 0)));
|
|
2496
|
-
int sw = int(lumaNumerator(pixel + ivec2(-1, 1)));
|
|
2497
|
-
int s = int(lumaNumerator(pixel + ivec2(0, 1)));
|
|
2498
|
-
int se = int(lumaNumerator(pixel + ivec2(1, 1)));
|
|
2499
|
-
int gx = -nw - 2 * w - sw + ne + 2 * e + se;
|
|
2500
|
-
int gy = -nw - 2 * n - ne + sw + 2 * s + se;
|
|
2501
|
-
uvec2 x = squareWords(gx);
|
|
2502
|
-
uvec2 y = squareWords(gy);
|
|
2503
|
-
uint low = x.y + y.y;
|
|
2504
|
-
uint high = x.x + y.x;
|
|
2505
|
-
if (low >= ${OUTLINE_LIMB_RADIX}u) {
|
|
2506
|
-
low -= ${OUTLINE_LIMB_RADIX}u;
|
|
2507
|
-
high += 1u;
|
|
2508
|
-
}
|
|
2509
|
-
uint boundHigh = uint(u_boundHigh);
|
|
2510
|
-
uint boundLow = uint(u_boundLow);
|
|
2511
|
-
return high != boundHigh ? high > boundHigh : low >= boundLow;
|
|
2512
|
-
}
|
|
2513
|
-
|
|
2514
|
-
void main() {
|
|
2515
|
-
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2516
|
-
bool outlined = false;
|
|
2517
|
-
for (int offsetY = -6; offsetY <= 6 && !outlined; offsetY += 1) {
|
|
2518
|
-
for (int offsetX = -6; offsetX <= 6; offsetX += 1) {
|
|
2519
|
-
if (abs(offsetX) > u_width || abs(offsetY) > u_width) continue;
|
|
2520
|
-
if (offsetX * offsetX + offsetY * offsetY > u_width * u_width) continue;
|
|
2521
|
-
ivec2 candidate = clamp(pixel + ivec2(offsetX, offsetY), ivec2(0), u_size - ivec2(1));
|
|
2522
|
-
if (edgeAt(candidate)) {
|
|
2523
|
-
outlined = true;
|
|
2524
|
-
break;
|
|
2525
|
-
}
|
|
2526
|
-
}
|
|
2527
|
-
}
|
|
2528
|
-
uvec4 source = sourceByte(pixel);
|
|
2529
|
-
if (!outlined) {
|
|
2530
|
-
outColor = vec4(source) / 255.0;
|
|
2531
|
-
return;
|
|
2532
|
-
}
|
|
2533
|
-
outColor = vec4(
|
|
2534
|
-
texelFetch(u_blendLut, ivec2(int(source.r), 0), 0).r,
|
|
2535
|
-
texelFetch(u_blendLut, ivec2(int(source.g), 0), 0).g,
|
|
2536
|
-
texelFetch(u_blendLut, ivec2(int(source.b), 0), 0).b,
|
|
2537
|
-
float(source.a) / 255.0
|
|
2538
|
-
);
|
|
2539
|
-
}
|
|
2540
|
-
`, "webgl2-outline");
|
|
2541
|
-
return this.outlineProgram;
|
|
2542
|
-
}
|
|
2543
|
-
ensureSsaoProgram() {
|
|
2544
|
-
if (this.ssaoProgram)
|
|
2545
|
-
return this.ssaoProgram;
|
|
2546
|
-
this.ssaoProgram = this.createFullscreenProgram(`#version 300 es
|
|
2547
|
-
precision highp float;
|
|
2548
|
-
precision highp int;
|
|
2549
|
-
uniform sampler2D u_source;
|
|
2550
|
-
uniform sampler2D u_depth;
|
|
2551
|
-
uniform ivec2 u_size;
|
|
2552
|
-
uniform int u_radius;
|
|
2553
|
-
uniform float u_intensity;
|
|
2554
|
-
uniform float u_bias;
|
|
2555
|
-
out vec4 outColor;
|
|
2556
|
-
|
|
2557
|
-
float depthAt(ivec2 coordinate) {
|
|
2558
|
-
return texelFetch(u_depth, clamp(coordinate, ivec2(0), u_size - ivec2(1)), 0).r;
|
|
2559
|
-
}
|
|
2560
|
-
|
|
2561
|
-
void main() {
|
|
2562
|
-
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2563
|
-
float centerDepth = depthAt(pixel);
|
|
2564
|
-
float occlusion = 0.0;
|
|
2565
|
-
float samples = 0.0;
|
|
2566
|
-
for (int stepY = -1; stepY <= 1; stepY += 1) {
|
|
2567
|
-
for (int stepX = -1; stepX <= 1; stepX += 1) {
|
|
2568
|
-
if (stepX == 0 && stepY == 0) continue;
|
|
2569
|
-
float sampleDepth = depthAt(pixel + ivec2(stepX * u_radius, stepY * u_radius));
|
|
2570
|
-
occlusion += clamp(
|
|
2571
|
-
(centerDepth - sampleDepth - u_bias) / (0.14 + float(u_radius) * 0.04),
|
|
2572
|
-
0.0,
|
|
2573
|
-
1.0
|
|
2574
|
-
);
|
|
2575
|
-
samples += 1.0;
|
|
2576
|
-
}
|
|
2577
|
-
}
|
|
2578
|
-
float factor = max(0.18, 1.0 - (occlusion / max(1.0, samples)) * u_intensity * 0.72);
|
|
2579
|
-
vec4 source = texelFetch(u_source, pixel, 0);
|
|
2580
|
-
outColor = vec4(source.rgb * factor, source.a);
|
|
2581
|
-
}
|
|
2582
|
-
`, "webgl2-ssao");
|
|
2583
|
-
return this.ssaoProgram;
|
|
2584
|
-
}
|
|
2585
|
-
ensureSsrProgram() {
|
|
2586
|
-
if (this.ssrProgram)
|
|
2587
|
-
return this.ssrProgram;
|
|
2588
|
-
this.ssrProgram = this.createFullscreenProgram(`#version 300 es
|
|
2589
|
-
precision highp float;
|
|
2590
|
-
precision highp int;
|
|
2591
|
-
uniform sampler2D u_source;
|
|
2592
|
-
uniform sampler2D u_depth;
|
|
2593
|
-
uniform ivec2 u_size;
|
|
2594
|
-
uniform float u_intensity;
|
|
2595
|
-
uniform int u_maxDistance;
|
|
2596
|
-
uniform float u_depthNear;
|
|
2597
|
-
uniform float u_depthFar;
|
|
2598
|
-
out vec4 outColor;
|
|
2599
|
-
|
|
2600
|
-
// Raw GL depth is nonlinear (0.1/1000 defaults park the play area past 0.97),
|
|
2601
|
-
// so every depth-gated comparison below runs on linearized depth. The CPU
|
|
2602
|
-
// byte kernel keeps fixture-unit semantics; the divergence is documented at
|
|
2603
|
-
// normalizeLdrDepthRange.
|
|
2604
|
-
float a3dSsrLinearDepth(float depth) {
|
|
2605
|
-
float viewZ = u_depthNear * u_depthFar / max(u_depthFar - depth * (u_depthFar - u_depthNear), 0.0001);
|
|
2606
|
-
return clamp((viewZ - u_depthNear) / max(u_depthFar - u_depthNear, 0.0001), 0.0, 1.0);
|
|
2607
|
-
}
|
|
2608
|
-
|
|
2609
|
-
void main() {
|
|
2610
|
-
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2611
|
-
vec4 target = texelFetch(u_source, pixel, 0);
|
|
2612
|
-
float linearDepth = a3dSsrLinearDepth(texelFetch(u_depth, pixel, 0).r);
|
|
2613
|
-
int rayDistance = max(1, int(round((1.0 - linearDepth) * float(u_maxDistance))));
|
|
2614
|
-
int direction = pixel.x < u_size.x / 2 ? 1 : -1;
|
|
2615
|
-
ivec2 samplePixel = ivec2(
|
|
2616
|
-
clamp(pixel.x + direction * rayDistance, 0, u_size.x - 1),
|
|
2617
|
-
clamp(u_size.y - 1 - pixel.y, 0, u_size.y - 1)
|
|
2618
|
-
);
|
|
2619
|
-
vec3 reflected = texelFetch(u_source, samplePixel, 0).rgb;
|
|
2620
|
-
float sourceLuma = (reflected.r + reflected.g + reflected.b) / 3.0;
|
|
2621
|
-
if (sourceLuma < 0.18 || linearDepth > 0.995) {
|
|
2622
|
-
outColor = target;
|
|
2623
|
-
return;
|
|
2624
|
-
}
|
|
2625
|
-
float boost = sourceLuma * u_intensity * (1.0 - linearDepth);
|
|
2626
|
-
outColor = vec4(clamp(target.rgb + reflected * boost, 0.0, 1.0), target.a);
|
|
2627
|
-
}
|
|
2628
|
-
`, "webgl2-ssr");
|
|
2629
|
-
return this.ssrProgram;
|
|
2630
|
-
}
|
|
2631
|
-
ensureDepthOfFieldProgram() {
|
|
2632
|
-
if (this.depthOfFieldProgram)
|
|
2633
|
-
return this.depthOfFieldProgram;
|
|
2634
|
-
this.depthOfFieldProgram = this.createFullscreenProgram(`#version 300 es
|
|
2635
|
-
precision highp float;
|
|
2636
|
-
precision highp int;
|
|
2637
|
-
uniform sampler2D u_source;
|
|
2638
|
-
uniform sampler2D u_depth;
|
|
2639
|
-
uniform ivec2 u_size;
|
|
2640
|
-
uniform float u_focusDepth;
|
|
2641
|
-
uniform float u_focusRange;
|
|
2642
|
-
uniform int u_maxRadius;
|
|
2643
|
-
uniform float u_depthNear;
|
|
2644
|
-
uniform float u_depthFar;
|
|
2645
|
-
out vec4 outColor;
|
|
2646
|
-
|
|
2647
|
-
// Same linearization contract as the SSR program, except focus is authored
|
|
2648
|
-
// directly as a linear-distance fraction (0 = near plane, 1 = far plane):
|
|
2649
|
-
// buffer-unit focus values are unusable once depth is linearized, because the
|
|
2650
|
-
// projection curve parks the whole play area inside a sliver of buffer units.
|
|
2651
|
-
// The CPU byte kernel keeps buffer-unit semantics; the divergence is
|
|
2652
|
-
// documented at normalizeLdrDepthRange.
|
|
2653
|
-
float a3dDofLinearDepth(float depth) {
|
|
2654
|
-
float viewZ = u_depthNear * u_depthFar / max(u_depthFar - depth * (u_depthFar - u_depthNear), 0.0001);
|
|
2655
|
-
return clamp((viewZ - u_depthNear) / max(u_depthFar - u_depthNear, 0.0001), 0.0, 1.0);
|
|
2656
|
-
}
|
|
2657
|
-
|
|
2658
|
-
void main() {
|
|
2659
|
-
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2660
|
-
vec4 source = texelFetch(u_source, pixel, 0);
|
|
2661
|
-
float linearDepth = a3dDofLinearDepth(texelFetch(u_depth, pixel, 0).r);
|
|
2662
|
-
float normalizedBlur = max(0.0, abs(linearDepth - u_focusDepth) - u_focusRange)
|
|
2663
|
-
/ max(u_focusRange, 0.001) * float(u_maxRadius);
|
|
2664
|
-
int radius = min(u_maxRadius, int(round(normalizedBlur)));
|
|
2665
|
-
if (radius == 0) {
|
|
2666
|
-
outColor = source;
|
|
2667
|
-
return;
|
|
2668
|
-
}
|
|
2669
|
-
vec3 sum = vec3(0.0);
|
|
2670
|
-
float samples = 0.0;
|
|
2671
|
-
for (int offsetY = -8; offsetY <= 8; offsetY += 1) {
|
|
2672
|
-
for (int offsetX = -8; offsetX <= 8; offsetX += 1) {
|
|
2673
|
-
if (abs(offsetX) > radius || abs(offsetY) > radius) continue;
|
|
2674
|
-
if (offsetX * offsetX + offsetY * offsetY > radius * radius) continue;
|
|
2675
|
-
ivec2 samplePixel = clamp(pixel + ivec2(offsetX, offsetY), ivec2(0), u_size - ivec2(1));
|
|
2676
|
-
sum += texelFetch(u_source, samplePixel, 0).rgb;
|
|
2677
|
-
samples += 1.0;
|
|
2678
|
-
}
|
|
2679
|
-
}
|
|
2680
|
-
outColor = vec4(sum / max(1.0, samples), source.a);
|
|
2681
|
-
}
|
|
2682
|
-
`, "webgl2-depth-of-field");
|
|
2683
|
-
return this.depthOfFieldProgram;
|
|
2684
|
-
}
|
|
2685
|
-
ensureMotionBlurProgram() {
|
|
2686
|
-
if (this.motionBlurProgram)
|
|
2687
|
-
return this.motionBlurProgram;
|
|
2688
|
-
this.motionBlurProgram = this.createFullscreenProgram(`#version 300 es
|
|
2689
|
-
precision highp float;
|
|
2690
|
-
precision highp int;
|
|
2691
|
-
uniform sampler2D u_source;
|
|
2692
|
-
uniform sampler2D u_velocity;
|
|
2693
|
-
uniform ivec2 u_size;
|
|
2694
|
-
uniform int u_samples;
|
|
2695
|
-
uniform float u_scale;
|
|
2696
|
-
out vec4 outColor;
|
|
2697
|
-
|
|
2698
|
-
void main() {
|
|
2699
|
-
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2700
|
-
vec4 source = texelFetch(u_source, pixel, 0);
|
|
2701
|
-
vec2 velocity = texelFetch(u_velocity, pixel, 0).rg * u_scale;
|
|
2702
|
-
if (length(velocity) < 0.01) {
|
|
2703
|
-
outColor = source;
|
|
2704
|
-
return;
|
|
2705
|
-
}
|
|
2706
|
-
vec3 sum = vec3(0.0);
|
|
2707
|
-
for (int sampleIndex = 0; sampleIndex < 16; sampleIndex += 1) {
|
|
2708
|
-
if (sampleIndex >= u_samples) continue;
|
|
2709
|
-
float t = float(sampleIndex) / float(u_samples - 1) - 0.5;
|
|
2710
|
-
ivec2 samplePixel = ivec2(floor(vec2(pixel) - velocity * t + vec2(0.5)));
|
|
2711
|
-
samplePixel = clamp(samplePixel, ivec2(0), u_size - ivec2(1));
|
|
2712
|
-
sum += texelFetch(u_source, samplePixel, 0).rgb;
|
|
2713
|
-
}
|
|
2714
|
-
outColor = vec4(sum / float(u_samples), source.a);
|
|
2715
|
-
}
|
|
2716
|
-
`, "webgl2-motion-blur");
|
|
2717
|
-
return this.motionBlurProgram;
|
|
2718
|
-
}
|
|
2719
|
-
ensureTaaProgram() {
|
|
2720
|
-
if (this.taaProgram)
|
|
2721
|
-
return this.taaProgram;
|
|
2722
|
-
this.taaProgram = this.createFullscreenProgram(`#version 300 es
|
|
2723
|
-
precision highp float;
|
|
2724
|
-
uniform sampler2D u_source;
|
|
2725
|
-
uniform sampler2D u_history;
|
|
2726
|
-
uniform float u_blend;
|
|
2727
|
-
out vec4 outColor;
|
|
2728
|
-
|
|
2729
|
-
void main() {
|
|
2730
|
-
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
2731
|
-
vec4 source = texelFetch(u_source, pixel, 0);
|
|
2732
|
-
vec3 history = texelFetch(u_history, pixel, 0).rgb;
|
|
2733
|
-
outColor = vec4(mix(source.rgb, history, u_blend), source.a);
|
|
2734
|
-
}
|
|
2735
|
-
`, "webgl2-taa");
|
|
2736
|
-
return this.taaProgram;
|
|
2737
|
-
}
|
|
2738
|
-
createFullscreenProgram(fragmentSource, label) {
|
|
2739
|
-
const vertex = this.compileShader(this.gl.VERTEX_SHADER, `#version 300 es
|
|
2740
|
-
precision highp float;
|
|
2741
|
-
void main() {
|
|
2742
|
-
vec2 position = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));
|
|
2743
|
-
gl_Position = vec4(position * 2.0 - 1.0, 0.0, 1.0);
|
|
2744
|
-
}
|
|
2745
|
-
`, label);
|
|
2746
|
-
const fragment = this.compileShader(this.gl.FRAGMENT_SHADER, fragmentSource, label);
|
|
2747
|
-
const program = this.gl.createProgram();
|
|
2748
|
-
if (!program) {
|
|
2749
|
-
this.gl.deleteShader(vertex);
|
|
2750
|
-
this.gl.deleteShader(fragment);
|
|
2751
|
-
throw new RenderDeviceError("Failed to allocate WebGL2 fullscreen shader program", "WEBGL_ALLOCATION_FAILED", { label });
|
|
2752
|
-
}
|
|
2753
|
-
this.gl.attachShader(program, vertex);
|
|
2754
|
-
this.gl.attachShader(program, fragment);
|
|
2755
|
-
this.gl.linkProgram(program);
|
|
2756
|
-
this.gl.deleteShader(vertex);
|
|
2757
|
-
this.gl.deleteShader(fragment);
|
|
2758
|
-
if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
|
|
2759
|
-
const log = this.gl.getProgramInfoLog(program) ?? "Unknown fullscreen shader link error";
|
|
2760
|
-
this.gl.deleteProgram(program);
|
|
2761
|
-
throw new RenderDeviceError("WebGL2 fullscreen shader link failed", "SHADER_LINK_FAILED", { label, log });
|
|
2762
|
-
}
|
|
2763
|
-
return program;
|
|
2764
|
-
}
|
|
2765
|
-
ensureLdrPostprocessProgram() {
|
|
2766
|
-
if (this.ldrPostprocessProgram) {
|
|
2767
|
-
return this.ldrPostprocessProgram;
|
|
2768
|
-
}
|
|
2769
|
-
const vertex = this.compileShader(this.gl.VERTEX_SHADER, `#version 300 es
|
|
2770
|
-
precision highp float;
|
|
2771
|
-
out vec2 v_uv;
|
|
2772
|
-
void main() {
|
|
2773
|
-
vec2 position = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));
|
|
2774
|
-
v_uv = position;
|
|
2775
|
-
gl_Position = vec4(position * 2.0 - 1.0, 0.0, 1.0);
|
|
2776
|
-
}
|
|
2777
|
-
`, "webgl2-ldr-postprocess");
|
|
2778
|
-
const fragment = this.compileShader(this.gl.FRAGMENT_SHADER, `#version 300 es
|
|
2779
|
-
precision highp float;
|
|
2780
|
-
uniform sampler2D u_source;
|
|
2781
|
-
uniform vec2 u_texelSize;
|
|
2782
|
-
uniform int u_hasToneMapping;
|
|
2783
|
-
uniform int u_toneOperator;
|
|
2784
|
-
uniform int u_inputColorSpace;
|
|
2785
|
-
uniform int u_outputColorSpace;
|
|
2786
|
-
uniform float u_exposure;
|
|
2787
|
-
uniform float u_whitePoint;
|
|
2788
|
-
uniform float u_gamma;
|
|
2789
|
-
uniform int u_hasColorGrade;
|
|
2790
|
-
uniform float u_contrast;
|
|
2791
|
-
uniform float u_temperature;
|
|
2792
|
-
uniform float u_tint;
|
|
2793
|
-
uniform float u_saturation;
|
|
2794
|
-
uniform float u_vibrance;
|
|
2795
|
-
uniform float u_vignette;
|
|
2796
|
-
uniform float u_sharpening;
|
|
2797
|
-
uniform int u_hasFxaa;
|
|
2798
|
-
uniform float u_edgeThreshold;
|
|
2799
|
-
uniform float u_subpixelBlend;
|
|
2800
|
-
in vec2 v_uv;
|
|
2801
|
-
out vec4 outColor;
|
|
2802
|
-
|
|
2803
|
-
float srgbToLinear(float value) {
|
|
2804
|
-
return value <= 0.04045 ? value / 12.92 : pow((value + 0.055) / 1.055, 2.4);
|
|
2805
|
-
}
|
|
2806
|
-
|
|
2807
|
-
float linearToSrgb(float value) {
|
|
2808
|
-
return value <= 0.0031308 ? value * 12.92 : 1.055 * pow(value, 1.0 / 2.4) - 0.055;
|
|
2809
|
-
}
|
|
2810
|
-
|
|
2811
|
-
vec3 decodeColor(vec3 color) {
|
|
2812
|
-
return u_inputColorSpace == 1 ? vec3(srgbToLinear(color.r), srgbToLinear(color.g), srgbToLinear(color.b)) : color;
|
|
2813
|
-
}
|
|
2814
|
-
|
|
2815
|
-
vec3 encodeColor(vec3 color) {
|
|
2816
|
-
vec3 linear = clamp(color, 0.0, 1.0);
|
|
2817
|
-
return u_outputColorSpace == 1 ? vec3(linearToSrgb(linear.r), linearToSrgb(linear.g), linearToSrgb(linear.b)) : linear;
|
|
2818
|
-
}
|
|
2819
|
-
|
|
2820
|
-
vec3 acesRrtAndOdtFit(vec3 value) {
|
|
2821
|
-
vec3 numerator = value * (value + 0.0245786) - 0.000090537;
|
|
2822
|
-
vec3 denominator = value * (0.983729 * value + 0.4329510) + 0.238081;
|
|
2823
|
-
return numerator / denominator;
|
|
2824
|
-
}
|
|
2825
|
-
|
|
2826
|
-
vec3 acesFilmic(vec3 color) {
|
|
2827
|
-
// Match current Three.js ACESFilmicToneMapping. ACES is a coupled RGB
|
|
2828
|
-
// transform; a scalar approximation shifts hue and washes saturated colors.
|
|
2829
|
-
const mat3 acesInput = mat3(
|
|
2830
|
-
vec3(0.59719, 0.07600, 0.02840),
|
|
2831
|
-
vec3(0.35458, 0.90834, 0.13383),
|
|
2832
|
-
vec3(0.04823, 0.01566, 0.83777)
|
|
2833
|
-
);
|
|
2834
|
-
const mat3 acesOutput = mat3(
|
|
2835
|
-
vec3(1.60475, -0.10208, -0.00327),
|
|
2836
|
-
vec3(-0.53108, 1.10813, -0.07276),
|
|
2837
|
-
vec3(-0.07367, -0.00605, 1.07602)
|
|
2838
|
-
);
|
|
2839
|
-
vec3 acesColor = acesInput * (color / 0.6);
|
|
2840
|
-
acesColor = acesRrtAndOdtFit(acesColor);
|
|
2841
|
-
return clamp(acesOutput * acesColor, 0.0, 1.0);
|
|
2842
|
-
}
|
|
2843
|
-
|
|
2844
|
-
float filmic(float value) {
|
|
2845
|
-
float x = max(0.0, value);
|
|
2846
|
-
float toe = max(0.0, x - 0.004);
|
|
2847
|
-
float curve = (toe * (6.2 * toe + 0.5)) / (toe * (6.2 * toe + 1.7) + 0.06);
|
|
2848
|
-
return min(curve, x * 1.08);
|
|
2849
|
-
}
|
|
2850
|
-
|
|
2851
|
-
float uncharted2(float value) {
|
|
2852
|
-
float a = 0.15;
|
|
2853
|
-
float b = 0.5;
|
|
2854
|
-
float c = 0.1;
|
|
2855
|
-
float d = 0.2;
|
|
2856
|
-
float e = 0.02;
|
|
2857
|
-
float f = 0.3;
|
|
2858
|
-
float w = 11.2;
|
|
2859
|
-
float x = value * 2.0;
|
|
2860
|
-
float curve = ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f;
|
|
2861
|
-
float wx = w;
|
|
2862
|
-
float white = ((wx * (a * wx + c * b) + d * e) / (wx * (a * wx + b) + d * f)) - e / f;
|
|
2863
|
-
return clamp(curve / white, 0.0, 1.0);
|
|
2864
|
-
}
|
|
2865
|
-
|
|
2866
|
-
float agx(float value) {
|
|
2867
|
-
float x = max(0.0, value);
|
|
2868
|
-
float encoded = log2(1.0 + x) / log2(17.0);
|
|
2869
|
-
return clamp(encoded * encoded * (3.0 - 2.0 * encoded), 0.0, 1.0);
|
|
2870
|
-
}
|
|
2871
|
-
|
|
2872
|
-
float neutral(float value) {
|
|
2873
|
-
float x = max(0.0, value);
|
|
2874
|
-
return min(1.0, (x * (1.0 + x / 7.5)) / (1.0 + x));
|
|
2875
|
-
}
|
|
2876
|
-
|
|
2877
|
-
float toneMapChannel(float value) {
|
|
2878
|
-
float exposed = max(0.0, value * u_exposure) / max(0.0001, u_whitePoint);
|
|
2879
|
-
if (u_toneOperator == 0) return min(1.0, exposed);
|
|
2880
|
-
if (u_toneOperator == 1) return exposed / (1.0 + exposed);
|
|
2881
|
-
if (u_toneOperator == 2) return exposed;
|
|
2882
|
-
if (u_toneOperator == 3) return filmic(exposed);
|
|
2883
|
-
if (u_toneOperator == 4) return uncharted2(exposed);
|
|
2884
|
-
if (u_toneOperator == 5) return agx(exposed);
|
|
2885
|
-
return neutral(exposed);
|
|
2886
|
-
}
|
|
2887
|
-
|
|
2888
|
-
vec3 applyToneMapping(vec3 color) {
|
|
2889
|
-
if (u_hasToneMapping == 0) return color;
|
|
2890
|
-
vec3 decoded = decodeColor(color);
|
|
2891
|
-
vec3 mapped = u_toneOperator == 2
|
|
2892
|
-
? acesFilmic(max(vec3(0.0), decoded * u_exposure) / max(0.0001, u_whitePoint))
|
|
2893
|
-
: vec3(toneMapChannel(decoded.r), toneMapChannel(decoded.g), toneMapChannel(decoded.b));
|
|
2894
|
-
return encodeColor(mapped);
|
|
2895
|
-
}
|
|
2896
|
-
|
|
2897
|
-
vec3 applyColorGrade(vec3 color, vec2 uv) {
|
|
2898
|
-
if (u_hasColorGrade == 0) return color;
|
|
2899
|
-
float contrastOffset = 0.5 - 0.5 * u_contrast;
|
|
2900
|
-
float redShift = u_temperature * 0.08 - u_tint * 0.02;
|
|
2901
|
-
float greenShift = u_tint * 0.06;
|
|
2902
|
-
float blueShift = -u_temperature * 0.08 - u_tint * 0.02;
|
|
2903
|
-
float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
|
2904
|
-
vec3 graded = color * u_contrast + vec3(contrastOffset + redShift, contrastOffset + greenShift, contrastOffset + blueShift);
|
|
2905
|
-
float distanceFromLuma = min(1.0, abs(graded.r - luma) + abs(graded.g - luma) + abs(graded.b - luma));
|
|
2906
|
-
float vibranceBoost = u_vibrance == 0.0 ? 0.0 : u_vibrance * (1.0 - distanceFromLuma);
|
|
2907
|
-
float saturation = u_saturation + vibranceBoost;
|
|
2908
|
-
graded = vec3(luma) + (graded - vec3(luma)) * saturation;
|
|
2909
|
-
vec2 centered = uv * 2.0 - 1.0;
|
|
2910
|
-
float vignette = 1.0 - u_vignette * clamp((length(centered) - 0.28) / 1.12, 0.0, 1.0);
|
|
2911
|
-
return clamp(graded * vignette, 0.0, 1.0);
|
|
2912
|
-
}
|
|
2913
|
-
|
|
2914
|
-
vec3 baseColorAt(vec2 uv) {
|
|
2915
|
-
vec2 clampedUv = clamp(uv, vec2(0.0), vec2(1.0));
|
|
2916
|
-
vec3 color = texture(u_source, clampedUv).rgb;
|
|
2917
|
-
return applyColorGrade(applyToneMapping(color), clampedUv);
|
|
2918
|
-
}
|
|
2919
|
-
|
|
2920
|
-
vec3 finalColorAt(vec2 uv) {
|
|
2921
|
-
vec3 center = baseColorAt(uv);
|
|
2922
|
-
if (u_hasColorGrade == 0 || u_sharpening <= 0.0) return center;
|
|
2923
|
-
vec3 blur = (
|
|
2924
|
-
baseColorAt(uv + vec2(-u_texelSize.x, 0.0)) +
|
|
2925
|
-
baseColorAt(uv + vec2(u_texelSize.x, 0.0)) +
|
|
2926
|
-
baseColorAt(uv + vec2(0.0, -u_texelSize.y)) +
|
|
2927
|
-
baseColorAt(uv + vec2(0.0, u_texelSize.y))
|
|
2928
|
-
) * 0.25;
|
|
2929
|
-
return clamp(center + (center - blur) * u_sharpening, 0.0, 1.0);
|
|
2930
|
-
}
|
|
2931
|
-
|
|
2932
|
-
float luma(vec3 color) {
|
|
2933
|
-
return dot(color, vec3(0.2126, 0.7152, 0.0722));
|
|
2934
|
-
}
|
|
2935
|
-
|
|
2936
|
-
void main() {
|
|
2937
|
-
vec3 center = finalColorAt(v_uv);
|
|
2938
|
-
float alpha = texture(u_source, clamp(v_uv, vec2(0.0), vec2(1.0))).a;
|
|
2939
|
-
if (u_hasFxaa == 0) {
|
|
2940
|
-
outColor = vec4(center, alpha);
|
|
2941
|
-
return;
|
|
2942
|
-
}
|
|
2943
|
-
vec3 north = finalColorAt(v_uv + vec2(0.0, -u_texelSize.y));
|
|
2944
|
-
vec3 south = finalColorAt(v_uv + vec2(0.0, u_texelSize.y));
|
|
2945
|
-
vec3 west = finalColorAt(v_uv + vec2(-u_texelSize.x, 0.0));
|
|
2946
|
-
vec3 east = finalColorAt(v_uv + vec2(u_texelSize.x, 0.0));
|
|
2947
|
-
float centerLuma = luma(center);
|
|
2948
|
-
float minLuma = min(centerLuma, min(min(luma(north), luma(south)), min(luma(west), luma(east))));
|
|
2949
|
-
float maxLuma = max(centerLuma, max(max(luma(north), luma(south)), max(luma(west), luma(east))));
|
|
2950
|
-
if (maxLuma - minLuma < u_edgeThreshold) {
|
|
2951
|
-
outColor = vec4(center, alpha);
|
|
2952
|
-
return;
|
|
2953
|
-
}
|
|
2954
|
-
vec3 average = (north + south + west + east) * 0.25;
|
|
2955
|
-
outColor = vec4(mix(center, average, clamp(u_subpixelBlend, 0.0, 1.0)), alpha);
|
|
2956
|
-
}
|
|
2957
|
-
`, "webgl2-ldr-postprocess");
|
|
2958
|
-
const program = this.gl.createProgram();
|
|
2959
|
-
if (!program) {
|
|
2960
|
-
this.gl.deleteShader(vertex);
|
|
2961
|
-
this.gl.deleteShader(fragment);
|
|
2962
|
-
throw new RenderDeviceError("Failed to allocate WebGL2 LDR postprocess shader", "WEBGL_ALLOCATION_FAILED");
|
|
2963
|
-
}
|
|
2964
|
-
this.gl.attachShader(program, vertex);
|
|
2965
|
-
this.gl.attachShader(program, fragment);
|
|
2966
|
-
this.gl.linkProgram(program);
|
|
2967
|
-
this.gl.deleteShader(vertex);
|
|
2968
|
-
this.gl.deleteShader(fragment);
|
|
2969
|
-
if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
|
|
2970
|
-
const log = this.gl.getProgramInfoLog(program) ?? "Unknown LDR postprocess shader link error";
|
|
2971
|
-
this.gl.deleteProgram(program);
|
|
2972
|
-
throw new RenderDeviceError("WebGL2 LDR postprocess shader link failed", "SHADER_LINK_FAILED", { log });
|
|
2973
|
-
}
|
|
2974
|
-
this.ldrPostprocessProgram = program;
|
|
2975
|
-
return program;
|
|
1184
|
+
this.host.textureRegistry.textureUploadModes.clear();
|
|
1185
|
+
if (this.host.textureRegistry.fallbackTexture) {
|
|
1186
|
+
this.gl.deleteTexture(this.host.textureRegistry.fallbackTexture);
|
|
1187
|
+
this.host.textureRegistry.fallbackTexture = null;
|
|
1188
|
+
}
|
|
1189
|
+
if (this.host.textureRegistry.fallbackCubeTexture) {
|
|
1190
|
+
this.gl.deleteTexture(this.host.textureRegistry.fallbackCubeTexture);
|
|
1191
|
+
this.host.textureRegistry.fallbackCubeTexture = null;
|
|
1192
|
+
}
|
|
1193
|
+
if (this.host.post.presentationProgram) {
|
|
1194
|
+
this.gl.deleteProgram(this.host.post.presentationProgram);
|
|
1195
|
+
this.host.post.presentationProgram = null;
|
|
1196
|
+
}
|
|
1197
|
+
if (this.host.post.ldrPostprocessProgram) {
|
|
1198
|
+
this.gl.deleteProgram(this.host.post.ldrPostprocessProgram);
|
|
1199
|
+
this.host.post.ldrPostprocessProgram = null;
|
|
1200
|
+
}
|
|
1201
|
+
if (this.host.post.bloomBrightExtractProgram) {
|
|
1202
|
+
this.gl.deleteProgram(this.host.post.bloomBrightExtractProgram);
|
|
1203
|
+
this.host.post.bloomBrightExtractProgram = null;
|
|
1204
|
+
}
|
|
1205
|
+
if (this.host.post.bloomBlurProgram) {
|
|
1206
|
+
this.gl.deleteProgram(this.host.post.bloomBlurProgram);
|
|
1207
|
+
this.host.post.bloomBlurProgram = null;
|
|
1208
|
+
}
|
|
1209
|
+
if (this.host.post.bloomCompositeProgram) {
|
|
1210
|
+
this.gl.deleteProgram(this.host.post.bloomCompositeProgram);
|
|
1211
|
+
this.host.post.bloomCompositeProgram = null;
|
|
1212
|
+
}
|
|
1213
|
+
if (this.host.post.bloomDownsampleProgram) {
|
|
1214
|
+
this.gl.deleteProgram(this.host.post.bloomDownsampleProgram);
|
|
1215
|
+
this.host.post.bloomDownsampleProgram = null;
|
|
1216
|
+
}
|
|
1217
|
+
if (this.host.post.bloomAccumulateProgram) {
|
|
1218
|
+
this.gl.deleteProgram(this.host.post.bloomAccumulateProgram);
|
|
1219
|
+
this.host.post.bloomAccumulateProgram = null;
|
|
1220
|
+
}
|
|
1221
|
+
if (this.host.post.outlineProgram) {
|
|
1222
|
+
this.gl.deleteProgram(this.host.post.outlineProgram);
|
|
1223
|
+
this.host.post.outlineProgram = null;
|
|
1224
|
+
}
|
|
1225
|
+
if (this.host.post.ssaoProgram) {
|
|
1226
|
+
this.gl.deleteProgram(this.host.post.ssaoProgram);
|
|
1227
|
+
this.host.post.ssaoProgram = null;
|
|
1228
|
+
}
|
|
1229
|
+
if (this.host.post.ssrProgram) {
|
|
1230
|
+
this.gl.deleteProgram(this.host.post.ssrProgram);
|
|
1231
|
+
this.host.post.ssrProgram = null;
|
|
1232
|
+
}
|
|
1233
|
+
if (this.host.post.depthOfFieldProgram) {
|
|
1234
|
+
this.gl.deleteProgram(this.host.post.depthOfFieldProgram);
|
|
1235
|
+
this.host.post.depthOfFieldProgram = null;
|
|
1236
|
+
}
|
|
1237
|
+
if (this.host.post.motionBlurProgram) {
|
|
1238
|
+
this.gl.deleteProgram(this.host.post.motionBlurProgram);
|
|
1239
|
+
this.host.post.motionBlurProgram = null;
|
|
1240
|
+
}
|
|
1241
|
+
if (this.host.post.motionBlurVelocityTexture) {
|
|
1242
|
+
this.gl.deleteTexture(this.host.post.motionBlurVelocityTexture);
|
|
1243
|
+
this.host.post.motionBlurVelocityTexture = null;
|
|
1244
|
+
this.host.post.motionBlurVelocitySize = null;
|
|
1245
|
+
}
|
|
1246
|
+
if (this.host.post.taaProgram) {
|
|
1247
|
+
this.gl.deleteProgram(this.host.post.taaProgram);
|
|
1248
|
+
this.host.post.taaProgram = null;
|
|
1249
|
+
}
|
|
1250
|
+
if (this.host.post.taaPresentationProgram) {
|
|
1251
|
+
this.gl.deleteProgram(this.host.post.taaPresentationProgram);
|
|
1252
|
+
this.host.post.taaPresentationProgram = null;
|
|
1253
|
+
}
|
|
1254
|
+
if (this.host.post.taaHistoryTexture) {
|
|
1255
|
+
this.gl.deleteTexture(this.host.post.taaHistoryTexture);
|
|
1256
|
+
this.host.post.taaHistoryTexture = null;
|
|
1257
|
+
this.host.post.taaHistorySize = null;
|
|
1258
|
+
}
|
|
1259
|
+
this.host.post.disposeBloomPingPongResources();
|
|
1260
|
+
this.host.post.disposeBloomPyramidResources();
|
|
1261
|
+
if (this.host.post.bloomBrightLutTexture) {
|
|
1262
|
+
this.gl.deleteTexture(this.host.post.bloomBrightLutTexture);
|
|
1263
|
+
this.host.post.bloomBrightLutTexture = null;
|
|
1264
|
+
this.host.post.bloomBrightLutThreshold = null;
|
|
1265
|
+
}
|
|
1266
|
+
if (this.host.post.bloomCompositeLutTexture) {
|
|
1267
|
+
this.gl.deleteTexture(this.host.post.bloomCompositeLutTexture);
|
|
1268
|
+
this.host.post.bloomCompositeLutTexture = null;
|
|
1269
|
+
this.host.post.bloomCompositeLutIntensity = null;
|
|
1270
|
+
this.host.post.bloomCompositeLutShoulder = null;
|
|
1271
|
+
}
|
|
1272
|
+
if (this.host.post.outlineBlendLutTexture) {
|
|
1273
|
+
this.gl.deleteTexture(this.host.post.outlineBlendLutTexture);
|
|
1274
|
+
this.host.post.outlineBlendLutTexture = null;
|
|
1275
|
+
this.host.post.outlineBlendLutKey = null;
|
|
1276
|
+
}
|
|
1277
|
+
if (this.host.post.presentationVertexArray) {
|
|
1278
|
+
this.gl.deleteVertexArray(this.host.post.presentationVertexArray);
|
|
1279
|
+
this.host.post.presentationVertexArray = null;
|
|
1280
|
+
}
|
|
1281
|
+
if (this.host.probe.depthReadbackProgram) {
|
|
1282
|
+
this.gl.deleteProgram(this.host.probe.depthReadbackProgram);
|
|
1283
|
+
this.host.probe.depthReadbackProgram = null;
|
|
1284
|
+
}
|
|
1285
|
+
this.host.textureRegistry.textures.clear();
|
|
1286
|
+
this.host.disposed = true;
|
|
2976
1287
|
}
|
|
2977
1288
|
compileShader(type, source, label) {
|
|
2978
1289
|
const shader = this.gl.createShader(type);
|
|
@@ -3013,790 +1324,6 @@ void main() {
|
|
|
3013
1324
|
}
|
|
3014
1325
|
return { attributes, uniforms, attributeDetails, uniformDetails };
|
|
3015
1326
|
}
|
|
3016
|
-
uploadUniforms(shader, uniforms) {
|
|
3017
|
-
let textureUnit = 0;
|
|
3018
|
-
for (const [name, value] of uniforms) {
|
|
3019
|
-
if (!shader.reflection.uniforms.has(name)) {
|
|
3020
|
-
continue;
|
|
3021
|
-
}
|
|
3022
|
-
const location = this.getUniformLocation(shader, name);
|
|
3023
|
-
if (location === null) {
|
|
3024
|
-
throw new RenderDeviceError("Material tried to bind a missing shader uniform", "MISSING_UNIFORM", { name });
|
|
3025
|
-
}
|
|
3026
|
-
if (isTextureBinding(value)) {
|
|
3027
|
-
this.uploadTextureUniform(location, value, textureUnit);
|
|
3028
|
-
textureUnit += 1;
|
|
3029
|
-
}
|
|
3030
|
-
else if (typeof value === "number") {
|
|
3031
|
-
this.gl.uniform1f(location, value);
|
|
3032
|
-
}
|
|
3033
|
-
else if (Array.isArray(value) || ArrayBuffer.isView(value)) {
|
|
3034
|
-
const length = value.length;
|
|
3035
|
-
const floatData = value;
|
|
3036
|
-
if (length === 16 || (length > 16 && length % 16 === 0 && /(?:Matrix|Matrices)$/.test(name))) {
|
|
3037
|
-
this.gl.uniformMatrix4fv(location, false, floatData);
|
|
3038
|
-
}
|
|
3039
|
-
else if (length > 16 && length % 4 === 0) {
|
|
3040
|
-
this.gl.uniform4fv(location, floatData);
|
|
3041
|
-
}
|
|
3042
|
-
else if (length === 4) {
|
|
3043
|
-
this.gl.uniform4fv(location, floatData);
|
|
3044
|
-
}
|
|
3045
|
-
else if (length === 3) {
|
|
3046
|
-
this.gl.uniform3fv(location, floatData);
|
|
3047
|
-
}
|
|
3048
|
-
else if (length === 2) {
|
|
3049
|
-
this.gl.uniform2fv(location, floatData);
|
|
3050
|
-
}
|
|
3051
|
-
else {
|
|
3052
|
-
throw new RenderDeviceError("Unsupported uniform array length", "UNSUPPORTED_UNIFORM", { name, length });
|
|
3053
|
-
}
|
|
3054
|
-
}
|
|
3055
|
-
else {
|
|
3056
|
-
throw new RenderDeviceError("Unsupported uniform value", "UNSUPPORTED_UNIFORM", { name, valueType: typeof value });
|
|
3057
|
-
}
|
|
3058
|
-
if (this.errorCheckMode === "strict") {
|
|
3059
|
-
const uniformError = this.readError();
|
|
3060
|
-
if (uniformError) {
|
|
3061
|
-
throw new RenderDeviceError(`WebGL2 uniform upload failed for ${name}: ${uniformError}`, "WEBGL_DRAW_FAILED", {
|
|
3062
|
-
name,
|
|
3063
|
-
stage: "uniform",
|
|
3064
|
-
error: uniformError
|
|
3065
|
-
});
|
|
3066
|
-
}
|
|
3067
|
-
}
|
|
3068
|
-
}
|
|
3069
|
-
}
|
|
3070
|
-
getUniformLocation(shader, name) {
|
|
3071
|
-
let cache = this.uniformLocationCache.get(shader);
|
|
3072
|
-
if (!cache) {
|
|
3073
|
-
cache = new Map();
|
|
3074
|
-
this.uniformLocationCache.set(shader, cache);
|
|
3075
|
-
}
|
|
3076
|
-
if (!cache.has(name)) {
|
|
3077
|
-
this.uniformLocationLookupCount += 1;
|
|
3078
|
-
cache.set(name, this.gl.getUniformLocation(shader.handle, name) ?? this.gl.getUniformLocation(shader.handle, `${name}[0]`));
|
|
3079
|
-
}
|
|
3080
|
-
return cache.get(name) ?? null;
|
|
3081
|
-
}
|
|
3082
|
-
uploadTextureUniform(location, binding, textureUnit) {
|
|
3083
|
-
const validation = binding.validate();
|
|
3084
|
-
if (!validation.ok) {
|
|
3085
|
-
throw new RenderDeviceError("Texture binding validation failed", "INVALID_TEXTURE_BINDING", {
|
|
3086
|
-
diagnostics: validation.diagnostics,
|
|
3087
|
-
name: binding.name
|
|
3088
|
-
});
|
|
3089
|
-
}
|
|
3090
|
-
this.activateTextureUnit(textureUnit);
|
|
3091
|
-
const dimension = binding.texture?.dimension ?? (binding.name.toLowerCase().includes("cubemap") || binding.name.toLowerCase().includes("cube") ? "cube" : "2d");
|
|
3092
|
-
const target = dimension === "cube" ? this.gl.TEXTURE_CUBE_MAP : this.gl.TEXTURE_2D;
|
|
3093
|
-
const handle = binding.texture ? this.getTextureHandle(binding.texture) : dimension === "cube" ? this.getFallbackCubeTextureHandle() : this.getFallbackTextureHandle();
|
|
3094
|
-
if (binding.texture) {
|
|
3095
|
-
const lowerName = binding.name.toLowerCase();
|
|
3096
|
-
if (lowerName.includes("environment"))
|
|
3097
|
-
this.nativeEnvironmentBindings += 1;
|
|
3098
|
-
if (lowerName.includes("shadow"))
|
|
3099
|
-
this.nativeShadowMapBindings += 1;
|
|
3100
|
-
}
|
|
3101
|
-
this.bindTextureForUnit(textureUnit, target, handle);
|
|
3102
|
-
const samplerHandle = this.getSamplerHandle(binding.sampler, target);
|
|
3103
|
-
this.stateCache.bindSampler(textureUnit, samplerHandle, () => this.gl.bindSampler(textureUnit, samplerHandle));
|
|
3104
|
-
this.gl.uniform1i(location, textureUnit);
|
|
3105
|
-
}
|
|
3106
|
-
activateTextureUnit(textureUnit) {
|
|
3107
|
-
if (this.activeTextureUnitIndex === textureUnit)
|
|
3108
|
-
return;
|
|
3109
|
-
this.stateCache.activeTexture(textureUnit, () => this.gl.activeTexture(this.gl.TEXTURE0 + textureUnit));
|
|
3110
|
-
this.activeTextureUnitIndex = textureUnit;
|
|
3111
|
-
}
|
|
3112
|
-
bindTextureForUnit(textureUnit, target, handle) {
|
|
3113
|
-
const key = `${textureUnit}:${target}`;
|
|
3114
|
-
if (this.textureUnitBindings.get(key) === handle)
|
|
3115
|
-
return;
|
|
3116
|
-
this.stateCache.bindTexture(target, handle, () => this.gl.bindTexture(target, handle));
|
|
3117
|
-
this.textureUnitBindings.set(key, handle);
|
|
3118
|
-
this.textureBindCount += 1;
|
|
3119
|
-
}
|
|
3120
|
-
setTextureParameterIfNeeded(handle, target, parameter, value) {
|
|
3121
|
-
let parameters = this.textureSamplerParameterCache.get(handle);
|
|
3122
|
-
if (!parameters) {
|
|
3123
|
-
parameters = new Map();
|
|
3124
|
-
this.textureSamplerParameterCache.set(handle, parameters);
|
|
3125
|
-
}
|
|
3126
|
-
if (parameters.get(parameter) === value)
|
|
3127
|
-
return;
|
|
3128
|
-
this.gl.texParameteri(target, parameter, value);
|
|
3129
|
-
parameters.set(parameter, value);
|
|
3130
|
-
this.samplerParameterUploadCount += 1;
|
|
3131
|
-
}
|
|
3132
|
-
applySamplerAnisotropy(maxAnisotropy, target = this.gl.TEXTURE_2D) {
|
|
3133
|
-
if (maxAnisotropy <= 1)
|
|
3134
|
-
return;
|
|
3135
|
-
if (!this.anisotropicFilteringExtension)
|
|
3136
|
-
return;
|
|
3137
|
-
this.gl.texParameterf(target, this.anisotropicFilteringExtension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(Math.max(1, maxAnisotropy), this.maxTextureAnisotropy));
|
|
3138
|
-
this.samplerAnisotropyUploadCount += 1;
|
|
3139
|
-
}
|
|
3140
|
-
getSamplerHandle(sampler, target) {
|
|
3141
|
-
const key = this.samplerKey(sampler, target);
|
|
3142
|
-
const cached = this.samplerObjectCache.get(key);
|
|
3143
|
-
if (cached)
|
|
3144
|
-
return cached;
|
|
3145
|
-
const handle = this.gl.createSampler();
|
|
3146
|
-
if (!handle) {
|
|
3147
|
-
throw new RenderDeviceError("Failed to allocate WebGL sampler", "WEBGL_ALLOCATION_FAILED");
|
|
3148
|
-
}
|
|
3149
|
-
this.gl.samplerParameteri(handle, this.gl.TEXTURE_MIN_FILTER, this.minFilter(sampler.minFilter));
|
|
3150
|
-
this.gl.samplerParameteri(handle, this.gl.TEXTURE_MAG_FILTER, this.magFilter(sampler.magFilter));
|
|
3151
|
-
this.gl.samplerParameteri(handle, this.gl.TEXTURE_WRAP_S, this.addressMode(sampler.addressU));
|
|
3152
|
-
this.gl.samplerParameteri(handle, this.gl.TEXTURE_WRAP_T, this.addressMode(sampler.addressV));
|
|
3153
|
-
this.samplerParameterUploadCount += 4;
|
|
3154
|
-
if (target === this.gl.TEXTURE_CUBE_MAP) {
|
|
3155
|
-
this.gl.samplerParameteri(handle, this.gl.TEXTURE_WRAP_R, this.addressMode(sampler.addressV));
|
|
3156
|
-
this.samplerParameterUploadCount += 1;
|
|
3157
|
-
}
|
|
3158
|
-
if (sampler.maxAnisotropy > 1 && this.anisotropicFilteringExtension) {
|
|
3159
|
-
this.gl.samplerParameterf(handle, this.anisotropicFilteringExtension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(Math.max(1, sampler.maxAnisotropy), this.maxTextureAnisotropy));
|
|
3160
|
-
this.samplerAnisotropyUploadCount += 1;
|
|
3161
|
-
}
|
|
3162
|
-
this.samplerObjectCache.set(key, handle);
|
|
3163
|
-
return handle;
|
|
3164
|
-
}
|
|
3165
|
-
samplerKey(sampler, target) {
|
|
3166
|
-
return [
|
|
3167
|
-
sampler.minFilter,
|
|
3168
|
-
sampler.magFilter,
|
|
3169
|
-
sampler.addressU,
|
|
3170
|
-
sampler.addressV,
|
|
3171
|
-
sampler.maxAnisotropy,
|
|
3172
|
-
target === this.gl.TEXTURE_CUBE_MAP ? "cube" : "2d"
|
|
3173
|
-
].join("|");
|
|
3174
|
-
}
|
|
3175
|
-
getFallbackTextureHandle() {
|
|
3176
|
-
if (this.fallbackTexture) {
|
|
3177
|
-
return this.fallbackTexture;
|
|
3178
|
-
}
|
|
3179
|
-
const handle = this.gl.createTexture();
|
|
3180
|
-
if (!handle) {
|
|
3181
|
-
throw new RenderDeviceError("Failed to allocate WebGL fallback texture", "WEBGL_ALLOCATION_FAILED");
|
|
3182
|
-
}
|
|
3183
|
-
this.stateCache.invalidate();
|
|
3184
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, handle);
|
|
3185
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
|
|
3186
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
3187
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
3188
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
3189
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, 1, 1, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, new Uint8Array([255, 255, 255, 255]));
|
|
3190
|
-
this.fallbackTexture = handle;
|
|
3191
|
-
return handle;
|
|
3192
|
-
}
|
|
3193
|
-
getFallbackCubeTextureHandle() {
|
|
3194
|
-
if (this.fallbackCubeTexture) {
|
|
3195
|
-
return this.fallbackCubeTexture;
|
|
3196
|
-
}
|
|
3197
|
-
const handle = this.gl.createTexture();
|
|
3198
|
-
if (!handle) {
|
|
3199
|
-
throw new RenderDeviceError("Failed to allocate WebGL fallback cube texture", "WEBGL_ALLOCATION_FAILED");
|
|
3200
|
-
}
|
|
3201
|
-
this.stateCache.invalidate();
|
|
3202
|
-
this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, handle);
|
|
3203
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
|
|
3204
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
3205
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
3206
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
3207
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_WRAP_R, this.gl.CLAMP_TO_EDGE);
|
|
3208
|
-
const pixel = new Uint8Array([255, 255, 255, 255]);
|
|
3209
|
-
for (const face of WEBGL_CUBE_FACES) {
|
|
3210
|
-
this.gl.texImage2D(this.cubeFaceTarget(face), 0, this.gl.RGBA, 1, 1, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixel);
|
|
3211
|
-
}
|
|
3212
|
-
this.fallbackCubeTexture = handle;
|
|
3213
|
-
return handle;
|
|
3214
|
-
}
|
|
3215
|
-
getTextureHandle(texture) {
|
|
3216
|
-
this.releaseDisposedTextureHandles();
|
|
3217
|
-
if (texture.disposed) {
|
|
3218
|
-
throw new RenderDeviceError("Texture is disposed", "DISPOSED_RESOURCE", { label: texture.label });
|
|
3219
|
-
}
|
|
3220
|
-
const cached = this.textures.get(texture);
|
|
3221
|
-
if (cached) {
|
|
3222
|
-
return cached;
|
|
3223
|
-
}
|
|
3224
|
-
const handle = this.gl.createTexture();
|
|
3225
|
-
if (!handle) {
|
|
3226
|
-
throw new RenderDeviceError("Failed to allocate WebGL texture", "WEBGL_ALLOCATION_FAILED", { label: texture.label });
|
|
3227
|
-
}
|
|
3228
|
-
this.stateCache.invalidate();
|
|
3229
|
-
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
3230
|
-
this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
3231
|
-
this.gl.pixelStorei(this.gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, this.gl.NONE);
|
|
3232
|
-
if (texture.dimension === "cube") {
|
|
3233
|
-
this.uploadCubeTexture(texture, handle);
|
|
3234
|
-
this.textureUploadModes.set(texture, "cube");
|
|
3235
|
-
this.textures.set(texture, handle);
|
|
3236
|
-
return handle;
|
|
3237
|
-
}
|
|
3238
|
-
this.gl.bindTexture(this.gl.TEXTURE_2D, handle);
|
|
3239
|
-
if (isCompressedTextureFormat(texture.format)) {
|
|
3240
|
-
const compressed = this.resolveCompressedTextureFormat(texture.format);
|
|
3241
|
-
if (compressed) {
|
|
3242
|
-
const uploadLevels = completeUploadLevels(texture.textureLevels);
|
|
3243
|
-
for (const [levelIndex, level] of uploadLevels.entries()) {
|
|
3244
|
-
this.gl.compressedTexImage2D(this.gl.TEXTURE_2D, levelIndex, compressed.internalFormat, level.width, level.height, 0, level.data);
|
|
3245
|
-
}
|
|
3246
|
-
const compressedUploadError = this.readError();
|
|
3247
|
-
if (!compressedUploadError) {
|
|
3248
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_BASE_LEVEL, 0);
|
|
3249
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAX_LEVEL, uploadLevels.length - 1);
|
|
3250
|
-
this.textureUploadModes.set(texture, "compressed");
|
|
3251
|
-
this.textures.set(texture, handle);
|
|
3252
|
-
return handle;
|
|
3253
|
-
}
|
|
3254
|
-
}
|
|
3255
|
-
const fallbackLevels = completeUploadLevels(texture.fallbackTextureLevels);
|
|
3256
|
-
if (fallbackLevels.length === 0) {
|
|
3257
|
-
this.gl.deleteTexture(handle);
|
|
3258
|
-
throw new RenderDeviceError("Compressed texture format is not supported and no RGBA8 fallback data was provided", "COMPRESSED_TEXTURE_UNSUPPORTED", {
|
|
3259
|
-
label: texture.label,
|
|
3260
|
-
format: texture.format
|
|
3261
|
-
});
|
|
3262
|
-
}
|
|
3263
|
-
this.uploadRgba8FallbackTexture(texture, fallbackLevels);
|
|
3264
|
-
this.textureUploadModes.set(texture, "fallback");
|
|
3265
|
-
this.textures.set(texture, handle);
|
|
3266
|
-
return handle;
|
|
3267
|
-
}
|
|
3268
|
-
if (texture.format === "depth24") {
|
|
3269
|
-
throw new RenderDeviceError("Depth textures cannot be uploaded to WebGL2 color samplers", "UNSUPPORTED_TEXTURE_FORMAT", {
|
|
3270
|
-
label: texture.label,
|
|
3271
|
-
format: texture.format
|
|
3272
|
-
});
|
|
3273
|
-
}
|
|
3274
|
-
if (texture.source) {
|
|
3275
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.rgba8TextureInternalFormat(texture), this.gl.RGBA, this.gl.UNSIGNED_BYTE, texture.source);
|
|
3276
|
-
this.gl.generateMipmap(this.gl.TEXTURE_2D);
|
|
3277
|
-
}
|
|
3278
|
-
else if (texture.mipLevels.length > 0) {
|
|
3279
|
-
const uploadFormat = this.textureUploadFormat(texture);
|
|
3280
|
-
const uploadLevels = completeUploadLevels(texture.textureLevels);
|
|
3281
|
-
for (const [levelIndex, level] of uploadLevels.entries()) {
|
|
3282
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, levelIndex, uploadFormat.internalFormat, level.width, level.height, 0, uploadFormat.format, uploadFormat.type, texturePixelUploadData(level.data, texture.format));
|
|
3283
|
-
}
|
|
3284
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_BASE_LEVEL, 0);
|
|
3285
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAX_LEVEL, uploadLevels.length - 1);
|
|
3286
|
-
}
|
|
3287
|
-
else {
|
|
3288
|
-
const uploadFormat = this.textureUploadFormat(texture);
|
|
3289
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, uploadFormat.internalFormat, texture.width, texture.height, 0, uploadFormat.format, uploadFormat.type, texture.data ? texturePixelUploadData(texture.data, texture.format) : null);
|
|
3290
|
-
// Float colour formats are not guaranteed mipmap-filterable in WebGL2:
|
|
3291
|
-
// RGBA32F/RGBA16F are only linear-filterable with OES_texture_float_linear, and
|
|
3292
|
-
// generateMipmap on a non-filterable format raises INVALID_OPERATION. Data
|
|
3293
|
-
// textures such as joint palettes are point-sampled with texelFetch and never
|
|
3294
|
-
// need mips, so skip generation and pin the level range instead.
|
|
3295
|
-
if (isFloatColorTextureFormat(texture.format)) {
|
|
3296
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_BASE_LEVEL, 0);
|
|
3297
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAX_LEVEL, 0);
|
|
3298
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
|
|
3299
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
3300
|
-
}
|
|
3301
|
-
else {
|
|
3302
|
-
this.gl.generateMipmap(this.gl.TEXTURE_2D);
|
|
3303
|
-
}
|
|
3304
|
-
}
|
|
3305
|
-
this.textureUploadModes.set(texture, texture.format);
|
|
3306
|
-
this.textures.set(texture, handle);
|
|
3307
|
-
return handle;
|
|
3308
|
-
}
|
|
3309
|
-
uploadCubeTexture(texture, handle) {
|
|
3310
|
-
this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, handle);
|
|
3311
|
-
const uploadFormat = this.textureUploadFormat(texture);
|
|
3312
|
-
for (const face of texture.cubeFaces) {
|
|
3313
|
-
const uploadLevels = completeUploadLevels(face.mipLevels);
|
|
3314
|
-
for (const [levelIndex, level] of uploadLevels.entries()) {
|
|
3315
|
-
this.gl.texImage2D(this.cubeFaceTarget(face.face), levelIndex, uploadFormat.internalFormat, level.width, level.height, 0, uploadFormat.format, uploadFormat.type, texturePixelUploadData(level.data, texture.format));
|
|
3316
|
-
}
|
|
3317
|
-
}
|
|
3318
|
-
const firstFaceLevels = completeUploadLevels(texture.cubeFaces[0]?.mipLevels ?? []);
|
|
3319
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_BASE_LEVEL, 0);
|
|
3320
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_MAX_LEVEL, Math.max(0, firstFaceLevels.length - 1));
|
|
3321
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
3322
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
3323
|
-
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_WRAP_R, this.gl.CLAMP_TO_EDGE);
|
|
3324
|
-
}
|
|
3325
|
-
uploadRgba8FallbackTexture(texture, fallbackLevels) {
|
|
3326
|
-
const internalFormat = this.rgba8TextureInternalFormat(texture);
|
|
3327
|
-
for (const [levelIndex, level] of fallbackLevels.entries()) {
|
|
3328
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, levelIndex, internalFormat, level.width, level.height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, texturePixelUploadData(level.data, "rgba8"));
|
|
3329
|
-
}
|
|
3330
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_BASE_LEVEL, 0);
|
|
3331
|
-
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAX_LEVEL, fallbackLevels.length - 1);
|
|
3332
|
-
}
|
|
3333
|
-
cubeFaceTarget(face) {
|
|
3334
|
-
switch (face) {
|
|
3335
|
-
case "px": return this.gl.TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
3336
|
-
case "nx": return this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X;
|
|
3337
|
-
case "py": return this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y;
|
|
3338
|
-
case "ny": return this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y;
|
|
3339
|
-
case "pz": return this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z;
|
|
3340
|
-
case "nz": return this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z;
|
|
3341
|
-
}
|
|
3342
|
-
}
|
|
3343
|
-
rgba8TextureInternalFormat(texture) {
|
|
3344
|
-
return texture.colorSpace === "srgb" ? this.gl.SRGB8_ALPHA8 : this.gl.RGBA;
|
|
3345
|
-
}
|
|
3346
|
-
textureUploadFormat(texture) {
|
|
3347
|
-
if (texture.format === "rgba8") {
|
|
3348
|
-
return { internalFormat: this.rgba8TextureInternalFormat(texture), format: this.gl.RGBA, type: this.gl.UNSIGNED_BYTE };
|
|
3349
|
-
}
|
|
3350
|
-
if (texture.colorSpace === "srgb") {
|
|
3351
|
-
throw new RenderDeviceError("Floating-point texture uploads must use linear colorSpace", "UNSUPPORTED_TEXTURE_FORMAT", {
|
|
3352
|
-
label: texture.label,
|
|
3353
|
-
format: texture.format,
|
|
3354
|
-
colorSpace: texture.colorSpace
|
|
3355
|
-
});
|
|
3356
|
-
}
|
|
3357
|
-
if (texture.format === "rgba16f") {
|
|
3358
|
-
return { internalFormat: this.gl.RGBA16F, format: this.gl.RGBA, type: this.gl.HALF_FLOAT };
|
|
3359
|
-
}
|
|
3360
|
-
if (texture.format === "rgba32f") {
|
|
3361
|
-
return { internalFormat: this.gl.RGBA32F, format: this.gl.RGBA, type: this.gl.FLOAT };
|
|
3362
|
-
}
|
|
3363
|
-
throw new RenderDeviceError("Unsupported texture upload format", "UNSUPPORTED_TEXTURE_FORMAT", {
|
|
3364
|
-
label: texture.label,
|
|
3365
|
-
format: texture.format
|
|
3366
|
-
});
|
|
3367
|
-
}
|
|
3368
|
-
resolveRenderTargetFormat(format) {
|
|
3369
|
-
if (format === "rgba8") {
|
|
3370
|
-
return { internalFormat: this.gl.RGBA, type: this.gl.UNSIGNED_BYTE };
|
|
3371
|
-
}
|
|
3372
|
-
if (!this.gl.getExtension("EXT_color_buffer_float")) {
|
|
3373
|
-
throw new RenderDeviceError("Floating-point color render targets require EXT_color_buffer_float", "HDR_RENDER_TARGET_UNSUPPORTED", { format });
|
|
3374
|
-
}
|
|
3375
|
-
if (format === "rgba16f") {
|
|
3376
|
-
return { internalFormat: this.gl.RGBA16F, type: this.gl.HALF_FLOAT };
|
|
3377
|
-
}
|
|
3378
|
-
return { internalFormat: this.gl.RGBA32F, type: this.gl.FLOAT };
|
|
3379
|
-
}
|
|
3380
|
-
releaseDisposedTextureHandles() {
|
|
3381
|
-
for (const [texture, handle] of [...this.textures]) {
|
|
3382
|
-
if (texture.disposed) {
|
|
3383
|
-
this.gl.deleteTexture(handle);
|
|
3384
|
-
this.textures.delete(texture);
|
|
3385
|
-
this.textureUploadModes.delete(texture);
|
|
3386
|
-
this.releasedTextureHandles += 1;
|
|
3387
|
-
}
|
|
3388
|
-
}
|
|
3389
|
-
}
|
|
3390
|
-
resolveCompressedTextureFormat(format) {
|
|
3391
|
-
switch (format) {
|
|
3392
|
-
case "bc1-rgba-unorm": {
|
|
3393
|
-
const extension = this.gl.getExtension("WEBGL_compressed_texture_s3tc");
|
|
3394
|
-
return extension ? { internalFormat: extension.COMPRESSED_RGBA_S3TC_DXT1_EXT } : null;
|
|
3395
|
-
}
|
|
3396
|
-
case "bc3-rgba-unorm": {
|
|
3397
|
-
const extension = this.gl.getExtension("WEBGL_compressed_texture_s3tc");
|
|
3398
|
-
return extension ? { internalFormat: extension.COMPRESSED_RGBA_S3TC_DXT5_EXT } : null;
|
|
3399
|
-
}
|
|
3400
|
-
case "etc2-rgba8unorm":
|
|
3401
|
-
return { internalFormat: 0x9278 };
|
|
3402
|
-
case "astc-4x4-rgba-unorm": {
|
|
3403
|
-
const extension = this.gl.getExtension("WEBGL_compressed_texture_astc");
|
|
3404
|
-
return extension ? { internalFormat: extension.COMPRESSED_RGBA_ASTC_4x4_KHR } : null;
|
|
3405
|
-
}
|
|
3406
|
-
}
|
|
3407
|
-
}
|
|
3408
|
-
magFilter(filter) {
|
|
3409
|
-
return filter === "nearest" ? this.gl.NEAREST : this.gl.LINEAR;
|
|
3410
|
-
}
|
|
3411
|
-
minFilter(filter) {
|
|
3412
|
-
switch (filter) {
|
|
3413
|
-
case "nearest":
|
|
3414
|
-
return this.gl.NEAREST;
|
|
3415
|
-
case "linear":
|
|
3416
|
-
return this.gl.LINEAR;
|
|
3417
|
-
case "nearest-mipmap-nearest":
|
|
3418
|
-
return this.gl.NEAREST_MIPMAP_NEAREST;
|
|
3419
|
-
case "linear-mipmap-nearest":
|
|
3420
|
-
return this.gl.LINEAR_MIPMAP_NEAREST;
|
|
3421
|
-
case "nearest-mipmap-linear":
|
|
3422
|
-
return this.gl.NEAREST_MIPMAP_LINEAR;
|
|
3423
|
-
case "linear-mipmap-linear":
|
|
3424
|
-
return this.gl.LINEAR_MIPMAP_LINEAR;
|
|
3425
|
-
}
|
|
3426
|
-
}
|
|
3427
|
-
addressMode(mode) {
|
|
3428
|
-
if (mode === "repeat")
|
|
3429
|
-
return this.gl.REPEAT;
|
|
3430
|
-
if (mode === "mirror-repeat")
|
|
3431
|
-
return this.gl.MIRRORED_REPEAT;
|
|
3432
|
-
return this.gl.CLAMP_TO_EDGE;
|
|
3433
|
-
}
|
|
3434
|
-
bindVertexFormat(shader, format) {
|
|
3435
|
-
const boundLocations = new Set();
|
|
3436
|
-
for (const attribute of format.attributes) {
|
|
3437
|
-
const location = this.resolveAttributeLocation(shader, attribute);
|
|
3438
|
-
if (location < 0) {
|
|
3439
|
-
continue;
|
|
3440
|
-
}
|
|
3441
|
-
if (attribute.type !== "float32") {
|
|
3442
|
-
throw new RenderDeviceError("Unsupported vertex attribute type", "UNSUPPORTED_VERTEX_ATTRIBUTE", {
|
|
3443
|
-
attribute: attribute.shaderName,
|
|
3444
|
-
type: attribute.type
|
|
3445
|
-
});
|
|
3446
|
-
}
|
|
3447
|
-
boundLocations.add(location);
|
|
3448
|
-
this.gl.enableVertexAttribArray(location);
|
|
3449
|
-
this.gl.vertexAttribDivisor(location, 0);
|
|
3450
|
-
this.gl.vertexAttribPointer(location, attribute.components, this.gl.FLOAT, attribute.normalized, format.stride, attribute.offset);
|
|
3451
|
-
}
|
|
3452
|
-
return boundLocations;
|
|
3453
|
-
}
|
|
3454
|
-
bindVertexArrayForCommand(command, shader, vertexBuffer) {
|
|
3455
|
-
const indexBuffer = command.indexBuffer ? this.requireBuffer(command.indexBuffer) : undefined;
|
|
3456
|
-
const key = this.vertexArrayCacheKey(command, shader, vertexBuffer, indexBuffer);
|
|
3457
|
-
const cached = this.vertexArrayCache.get(key);
|
|
3458
|
-
if (cached) {
|
|
3459
|
-
this.stateCache.bindVertexArray(cached.handle, () => this.gl.bindVertexArray(cached.handle));
|
|
3460
|
-
return cached;
|
|
3461
|
-
}
|
|
3462
|
-
const handle = this.gl.createVertexArray();
|
|
3463
|
-
if (!handle) {
|
|
3464
|
-
throw new RenderDeviceError("Failed to allocate WebGL vertex array", "WEBGL_ALLOCATION_FAILED");
|
|
3465
|
-
}
|
|
3466
|
-
this.vertexArrayCreateCount += 1;
|
|
3467
|
-
this.stateCache.bindVertexArray(handle, () => this.gl.bindVertexArray(handle));
|
|
3468
|
-
this.stateCache.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer.handle, () => this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer.handle));
|
|
3469
|
-
const boundLocations = this.bindVertexFormat(shader, command.vertexFormat);
|
|
3470
|
-
if (command.instanceAttributes && command.instanceAttributes.length > 0) {
|
|
3471
|
-
this.bindInstanceAttributes(shader, command.instanceAttributes, boundLocations);
|
|
3472
|
-
}
|
|
3473
|
-
if (indexBuffer) {
|
|
3474
|
-
this.stateCache.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer.handle, () => this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer.handle));
|
|
3475
|
-
}
|
|
3476
|
-
this.disableUnboundVertexAttributes(boundLocations);
|
|
3477
|
-
this.applyDefaultAttributes(shader, boundLocations);
|
|
3478
|
-
const entry = { key, handle, boundLocations };
|
|
3479
|
-
this.vertexArrayCache.set(key, entry);
|
|
3480
|
-
return entry;
|
|
3481
|
-
}
|
|
3482
|
-
bindNoVertexArray() {
|
|
3483
|
-
this.stateCache.bindVertexArray(null, () => this.gl.bindVertexArray(null));
|
|
3484
|
-
}
|
|
3485
|
-
vertexArrayCacheKey(command, shader, vertexBuffer, indexBuffer) {
|
|
3486
|
-
const instanceKey = (command.instanceAttributes ?? []).map((attribute) => {
|
|
3487
|
-
const buffer = this.requireBuffer(attribute.buffer);
|
|
3488
|
-
return `${attribute.shaderName}:${buffer.id}:${attribute.components}:${attribute.offset}:${attribute.stride}:${attribute.normalized === true ? 1 : 0}:${attribute.divisor ?? 1}`;
|
|
3489
|
-
}).join(",");
|
|
3490
|
-
return [
|
|
3491
|
-
shader.id,
|
|
3492
|
-
vertexBuffer.id,
|
|
3493
|
-
this.vertexFormatId(command.vertexFormat),
|
|
3494
|
-
indexBuffer?.id ?? 0,
|
|
3495
|
-
instanceKey
|
|
3496
|
-
].join("|");
|
|
3497
|
-
}
|
|
3498
|
-
vertexFormatId(format) {
|
|
3499
|
-
const existing = this.vertexFormatIds.get(format);
|
|
3500
|
-
if (existing !== undefined)
|
|
3501
|
-
return existing;
|
|
3502
|
-
const next = this.nextVertexFormatId;
|
|
3503
|
-
this.nextVertexFormatId += 1;
|
|
3504
|
-
this.vertexFormatIds.set(format, next);
|
|
3505
|
-
return next;
|
|
3506
|
-
}
|
|
3507
|
-
bindInstanceAttributes(shader, attributes, boundLocations) {
|
|
3508
|
-
for (const attribute of attributes) {
|
|
3509
|
-
const location = shader.reflection.attributes.get(attribute.shaderName);
|
|
3510
|
-
if (location === undefined || location < 0) {
|
|
3511
|
-
continue;
|
|
3512
|
-
}
|
|
3513
|
-
if (![1, 2, 3, 4].includes(attribute.components)) {
|
|
3514
|
-
throw new RenderDeviceError("Instance vertex attribute components must be 1, 2, 3, or 4", "INVALID_DRAW_COMMAND", {
|
|
3515
|
-
attribute: attribute.shaderName,
|
|
3516
|
-
components: attribute.components
|
|
3517
|
-
});
|
|
3518
|
-
}
|
|
3519
|
-
if (!Number.isInteger(attribute.offset) || attribute.offset < 0 || attribute.offset % 4 !== 0) {
|
|
3520
|
-
throw new RenderDeviceError("Instance vertex attribute offset must be non-negative and 4-byte aligned", "INVALID_DRAW_COMMAND", {
|
|
3521
|
-
attribute: attribute.shaderName,
|
|
3522
|
-
offset: attribute.offset
|
|
3523
|
-
});
|
|
3524
|
-
}
|
|
3525
|
-
if (!Number.isInteger(attribute.stride) || attribute.stride <= 0 || attribute.stride % 4 !== 0) {
|
|
3526
|
-
throw new RenderDeviceError("Instance vertex attribute stride must be positive and 4-byte aligned", "INVALID_DRAW_COMMAND", {
|
|
3527
|
-
attribute: attribute.shaderName,
|
|
3528
|
-
stride: attribute.stride
|
|
3529
|
-
});
|
|
3530
|
-
}
|
|
3531
|
-
if (attribute.offset + attribute.components * 4 > attribute.stride) {
|
|
3532
|
-
throw new RenderDeviceError("Instance vertex attribute range must fit inside its stride", "INVALID_DRAW_COMMAND", {
|
|
3533
|
-
attribute: attribute.shaderName,
|
|
3534
|
-
offset: attribute.offset,
|
|
3535
|
-
components: attribute.components,
|
|
3536
|
-
stride: attribute.stride
|
|
3537
|
-
});
|
|
3538
|
-
}
|
|
3539
|
-
const buffer = this.requireBuffer(attribute.buffer);
|
|
3540
|
-
boundLocations.add(location);
|
|
3541
|
-
this.stateCache.bindBuffer(this.gl.ARRAY_BUFFER, buffer.handle, () => this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer.handle));
|
|
3542
|
-
this.gl.enableVertexAttribArray(location);
|
|
3543
|
-
this.gl.vertexAttribPointer(location, attribute.components, this.gl.FLOAT, attribute.normalized ?? false, attribute.stride, attribute.offset);
|
|
3544
|
-
this.gl.vertexAttribDivisor(location, attribute.divisor ?? 1);
|
|
3545
|
-
}
|
|
3546
|
-
}
|
|
3547
|
-
resolveAttributeLocation(shader, attribute) {
|
|
3548
|
-
const reflected = shader.reflection.attributes.get(attribute.shaderName);
|
|
3549
|
-
if (reflected !== undefined) {
|
|
3550
|
-
return reflected;
|
|
3551
|
-
}
|
|
3552
|
-
return shader.reflection.attributes.get(attribute.semantic) ?? -1;
|
|
3553
|
-
}
|
|
3554
|
-
applyDefaultAttributes(shader, boundLocations) {
|
|
3555
|
-
const colorLocation = shader.reflection.attributes.get("a_color") ?? shader.reflection.attributes.get("color");
|
|
3556
|
-
if (colorLocation !== undefined && colorLocation >= 0 && !boundLocations.has(colorLocation)) {
|
|
3557
|
-
this.gl.disableVertexAttribArray(colorLocation);
|
|
3558
|
-
this.gl.vertexAttribDivisor(colorLocation, 0);
|
|
3559
|
-
this.gl.vertexAttrib4f(colorLocation, 1, 1, 1, 1);
|
|
3560
|
-
}
|
|
3561
|
-
const tangentLocation = shader.reflection.attributes.get("a_tangent") ?? shader.reflection.attributes.get("tangent");
|
|
3562
|
-
if (tangentLocation !== undefined && tangentLocation >= 0 && !boundLocations.has(tangentLocation)) {
|
|
3563
|
-
this.gl.disableVertexAttribArray(tangentLocation);
|
|
3564
|
-
this.gl.vertexAttribDivisor(tangentLocation, 0);
|
|
3565
|
-
this.gl.vertexAttrib4f(tangentLocation, 1, 0, 0, 1);
|
|
3566
|
-
}
|
|
3567
|
-
const uv1Location = shader.reflection.attributes.get("a_uv1") ?? shader.reflection.attributes.get("uv1");
|
|
3568
|
-
if (uv1Location !== undefined && uv1Location >= 0 && !boundLocations.has(uv1Location)) {
|
|
3569
|
-
this.gl.disableVertexAttribArray(uv1Location);
|
|
3570
|
-
this.gl.vertexAttribDivisor(uv1Location, 0);
|
|
3571
|
-
this.gl.vertexAttrib2f(uv1Location, 0, 0);
|
|
3572
|
-
}
|
|
3573
|
-
const instanceColorLocation = shader.reflection.attributes.get("a_instanceColor") ?? shader.reflection.attributes.get("instanceColor");
|
|
3574
|
-
if (instanceColorLocation !== undefined && instanceColorLocation >= 0 && !boundLocations.has(instanceColorLocation)) {
|
|
3575
|
-
this.gl.disableVertexAttribArray(instanceColorLocation);
|
|
3576
|
-
this.gl.vertexAttribDivisor(instanceColorLocation, 0);
|
|
3577
|
-
this.gl.vertexAttrib4f(instanceColorLocation, 1, 1, 1, 1);
|
|
3578
|
-
}
|
|
3579
|
-
}
|
|
3580
|
-
disableUnboundVertexAttributes(boundLocations) {
|
|
3581
|
-
for (let location = 0; location < this.maxVertexAttributes; location += 1) {
|
|
3582
|
-
if (!boundLocations.has(location)) {
|
|
3583
|
-
this.gl.disableVertexAttribArray(location);
|
|
3584
|
-
this.gl.vertexAttribDivisor(location, 0);
|
|
3585
|
-
}
|
|
3586
|
-
}
|
|
3587
|
-
}
|
|
3588
|
-
primitive(topology) {
|
|
3589
|
-
if (topology === "lines")
|
|
3590
|
-
return this.gl.LINES;
|
|
3591
|
-
if (topology === "points")
|
|
3592
|
-
return this.gl.POINTS;
|
|
3593
|
-
return this.gl.TRIANGLES;
|
|
3594
|
-
}
|
|
3595
|
-
applyRenderState(state) {
|
|
3596
|
-
const renderState = state ?? {
|
|
3597
|
-
depthTest: true,
|
|
3598
|
-
depthWrite: true,
|
|
3599
|
-
cullMode: "back",
|
|
3600
|
-
blend: false,
|
|
3601
|
-
depthCompare: "less-equal",
|
|
3602
|
-
colorWrite: [true, true, true, true],
|
|
3603
|
-
scissor: null,
|
|
3604
|
-
polygonOffset: null,
|
|
3605
|
-
stencil: null
|
|
3606
|
-
};
|
|
3607
|
-
this.stateCache.setEnabled(this.gl.DEPTH_TEST, renderState.depthTest, () => {
|
|
3608
|
-
if (renderState.depthTest)
|
|
3609
|
-
this.gl.enable(this.gl.DEPTH_TEST);
|
|
3610
|
-
else
|
|
3611
|
-
this.gl.disable(this.gl.DEPTH_TEST);
|
|
3612
|
-
});
|
|
3613
|
-
this.stateCache.depthMask(renderState.depthWrite, () => this.gl.depthMask(renderState.depthWrite));
|
|
3614
|
-
this.stateCache.depthFunc(renderState.depthCompare === "always" ? this.gl.ALWAYS : this.gl.LEQUAL, () => this.gl.depthFunc(renderState.depthCompare === "always" ? this.gl.ALWAYS : this.gl.LEQUAL));
|
|
3615
|
-
const colorWrite = renderState.colorWrite ?? [true, true, true, true];
|
|
3616
|
-
this.stateCache.colorMask(colorWrite[0], colorWrite[1], colorWrite[2], colorWrite[3], () => this.gl.colorMask(colorWrite[0], colorWrite[1], colorWrite[2], colorWrite[3]));
|
|
3617
|
-
if (renderState.scissor) {
|
|
3618
|
-
this.stateCache.setEnabled(this.gl.SCISSOR_TEST, true, () => this.gl.enable(this.gl.SCISSOR_TEST));
|
|
3619
|
-
this.stateCache.scissor(renderState.scissor.x, renderState.scissor.y, renderState.scissor.width, renderState.scissor.height, () => {
|
|
3620
|
-
this.gl.scissor(renderState.scissor.x, renderState.scissor.y, renderState.scissor.width, renderState.scissor.height);
|
|
3621
|
-
});
|
|
3622
|
-
}
|
|
3623
|
-
else {
|
|
3624
|
-
this.stateCache.setEnabled(this.gl.SCISSOR_TEST, false, () => this.gl.disable(this.gl.SCISSOR_TEST));
|
|
3625
|
-
}
|
|
3626
|
-
if (renderState.polygonOffset) {
|
|
3627
|
-
this.stateCache.setEnabled(this.gl.POLYGON_OFFSET_FILL, true, () => this.gl.enable(this.gl.POLYGON_OFFSET_FILL));
|
|
3628
|
-
this.stateCache.polygonOffset(renderState.polygonOffset.factor, renderState.polygonOffset.units, () => this.gl.polygonOffset(renderState.polygonOffset.factor, renderState.polygonOffset.units));
|
|
3629
|
-
}
|
|
3630
|
-
else {
|
|
3631
|
-
this.stateCache.setEnabled(this.gl.POLYGON_OFFSET_FILL, false, () => this.gl.disable(this.gl.POLYGON_OFFSET_FILL));
|
|
3632
|
-
}
|
|
3633
|
-
if (renderState.stencil) {
|
|
3634
|
-
const stencil = renderState.stencil;
|
|
3635
|
-
const compare = this.stencilCompare(stencil.compare ?? "always");
|
|
3636
|
-
const reference = stencil.reference ?? 0;
|
|
3637
|
-
const readMask = stencil.readMask ?? 0xff;
|
|
3638
|
-
const writeMask = stencil.writeMask ?? 0xff;
|
|
3639
|
-
const fail = this.stencilOperation(stencil.fail ?? "keep");
|
|
3640
|
-
const depthFail = this.stencilOperation(stencil.depthFail ?? "keep");
|
|
3641
|
-
const depthPass = this.stencilOperation(stencil.depthPass ?? "keep");
|
|
3642
|
-
this.stateCache.setEnabled(this.gl.STENCIL_TEST, true, () => this.gl.enable(this.gl.STENCIL_TEST));
|
|
3643
|
-
this.stateCache.stencilFunc(compare, reference, readMask, () => this.gl.stencilFunc(compare, reference, readMask));
|
|
3644
|
-
this.stateCache.stencilMask(writeMask, () => this.gl.stencilMask(writeMask));
|
|
3645
|
-
this.stateCache.stencilOp(fail, depthFail, depthPass, () => this.gl.stencilOp(fail, depthFail, depthPass));
|
|
3646
|
-
}
|
|
3647
|
-
else {
|
|
3648
|
-
this.stateCache.setEnabled(this.gl.STENCIL_TEST, false, () => this.gl.disable(this.gl.STENCIL_TEST));
|
|
3649
|
-
}
|
|
3650
|
-
if (renderState.cullMode === "none") {
|
|
3651
|
-
this.stateCache.setEnabled(this.gl.CULL_FACE, false, () => this.gl.disable(this.gl.CULL_FACE));
|
|
3652
|
-
}
|
|
3653
|
-
else {
|
|
3654
|
-
this.stateCache.setEnabled(this.gl.CULL_FACE, true, () => this.gl.enable(this.gl.CULL_FACE));
|
|
3655
|
-
this.stateCache.cullFace(renderState.cullMode === "front" ? this.gl.FRONT : this.gl.BACK, () => this.gl.cullFace(renderState.cullMode === "front" ? this.gl.FRONT : this.gl.BACK));
|
|
3656
|
-
}
|
|
3657
|
-
if (renderState.blend) {
|
|
3658
|
-
this.stateCache.setEnabled(this.gl.BLEND, true, () => this.gl.enable(this.gl.BLEND));
|
|
3659
|
-
this.stateCache.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA, () => this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA));
|
|
3660
|
-
}
|
|
3661
|
-
else {
|
|
3662
|
-
this.stateCache.setEnabled(this.gl.BLEND, false, () => this.gl.disable(this.gl.BLEND));
|
|
3663
|
-
}
|
|
3664
|
-
}
|
|
3665
|
-
requireBuffer(buffer) {
|
|
3666
|
-
if (!(buffer instanceof WebGL2Buffer) || !this.buffers.has(buffer) || buffer.disposed) {
|
|
3667
|
-
throw new RenderDeviceError("Buffer is not a live WebGL2 resource owned by this device", "INVALID_RESOURCE", {
|
|
3668
|
-
bufferId: buffer.id
|
|
3669
|
-
});
|
|
3670
|
-
}
|
|
3671
|
-
return buffer;
|
|
3672
|
-
}
|
|
3673
|
-
stencilCompare(compare) {
|
|
3674
|
-
switch (compare) {
|
|
3675
|
-
case "never": return this.gl.NEVER;
|
|
3676
|
-
case "less": return this.gl.LESS;
|
|
3677
|
-
case "less-equal": return this.gl.LEQUAL;
|
|
3678
|
-
case "greater": return this.gl.GREATER;
|
|
3679
|
-
case "greater-equal": return this.gl.GEQUAL;
|
|
3680
|
-
case "equal": return this.gl.EQUAL;
|
|
3681
|
-
case "not-equal": return this.gl.NOTEQUAL;
|
|
3682
|
-
case "always": return this.gl.ALWAYS;
|
|
3683
|
-
}
|
|
3684
|
-
}
|
|
3685
|
-
stencilOperation(operation) {
|
|
3686
|
-
switch (operation) {
|
|
3687
|
-
case "keep": return this.gl.KEEP;
|
|
3688
|
-
case "zero": return this.gl.ZERO;
|
|
3689
|
-
case "replace": return this.gl.REPLACE;
|
|
3690
|
-
case "increment": return this.gl.INCR;
|
|
3691
|
-
case "decrement": return this.gl.DECR;
|
|
3692
|
-
case "invert": return this.gl.INVERT;
|
|
3693
|
-
case "increment-wrap": return this.gl.INCR_WRAP;
|
|
3694
|
-
case "decrement-wrap": return this.gl.DECR_WRAP;
|
|
3695
|
-
}
|
|
3696
|
-
}
|
|
3697
|
-
requireShader(shader) {
|
|
3698
|
-
if (!(shader instanceof WebGL2ShaderProgram) || !this.shaders.has(shader) || shader.disposed) {
|
|
3699
|
-
throw new RenderDeviceError("Shader is not a live WebGL2 resource owned by this device", "INVALID_RESOURCE", {
|
|
3700
|
-
shaderId: shader.id
|
|
3701
|
-
});
|
|
3702
|
-
}
|
|
3703
|
-
return shader;
|
|
3704
|
-
}
|
|
3705
|
-
assertAlive() {
|
|
3706
|
-
if (this.disposed) {
|
|
3707
|
-
throw new RenderDeviceError("Render device is disposed", "DISPOSED_DEVICE");
|
|
3708
|
-
}
|
|
3709
|
-
if (this.contextLost) {
|
|
3710
|
-
throw new RenderDeviceError("Render context is lost", "CONTEXT_LOST");
|
|
3711
|
-
}
|
|
3712
|
-
}
|
|
3713
|
-
assertFrame() {
|
|
3714
|
-
this.assertAlive();
|
|
3715
|
-
if (!this.frameActive) {
|
|
3716
|
-
throw new RenderDeviceError("No active frame", "NO_ACTIVE_FRAME");
|
|
3717
|
-
}
|
|
3718
|
-
}
|
|
3719
|
-
readError() {
|
|
3720
|
-
const error = this.gl.getError();
|
|
3721
|
-
return error === this.gl.NO_ERROR ? null : `0x${error.toString(16)}`;
|
|
3722
|
-
}
|
|
3723
|
-
}
|
|
3724
|
-
function numberOption(options, key, fallback) {
|
|
3725
|
-
const value = options[key];
|
|
3726
|
-
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
3727
|
-
}
|
|
3728
|
-
function normalizeNativeBloomOptions(options) {
|
|
3729
|
-
const threshold = bloomNumberOption(options, "threshold", 0.75);
|
|
3730
|
-
const intensity = bloomNumberOption(options, "intensity", 0.35);
|
|
3731
|
-
const radius = bloomNumberOption(options, "radius", 1);
|
|
3732
|
-
if (threshold < 0 || threshold > 1) {
|
|
3733
|
-
throw new RenderDeviceError("Bloom threshold must be finite and in [0, 1].", "INVALID_POSTPROCESS_OPTIONS", { threshold });
|
|
3734
|
-
}
|
|
3735
|
-
if (intensity < 0) {
|
|
3736
|
-
throw new RenderDeviceError("Bloom intensity must be finite and non-negative.", "INVALID_POSTPROCESS_OPTIONS", { intensity });
|
|
3737
|
-
}
|
|
3738
|
-
if (!Number.isInteger(radius) || radius < 0 || radius > 16) {
|
|
3739
|
-
throw new RenderDeviceError("Bloom radius must be an integer in [0, 16].", "INVALID_POSTPROCESS_OPTIONS", { radius });
|
|
3740
|
-
}
|
|
3741
|
-
const softKnee = bloomNumberOption(options, "softKnee", 0);
|
|
3742
|
-
if (!(softKnee >= 0) || softKnee > 0.5) {
|
|
3743
|
-
throw new RenderDeviceError("Bloom softKnee must be finite and in [0, 0.5].", "INVALID_POSTPROCESS_OPTIONS", { softKnee });
|
|
3744
|
-
}
|
|
3745
|
-
const shoulder = bloomNumberOption(options, "shoulder", 0);
|
|
3746
|
-
if (!(shoulder >= 0) || shoulder > 1) {
|
|
3747
|
-
throw new RenderDeviceError("Bloom shoulder must be finite and in [0, 1].", "INVALID_POSTPROCESS_OPTIONS", { shoulder });
|
|
3748
|
-
}
|
|
3749
|
-
let quality;
|
|
3750
|
-
try {
|
|
3751
|
-
quality = normalizeBloomQualityPreset(options.quality);
|
|
3752
|
-
}
|
|
3753
|
-
catch {
|
|
3754
|
-
throw new RenderDeviceError("Bloom quality must be one of performance|balanced|cinematic.", "INVALID_POSTPROCESS_OPTIONS", { quality: options.quality });
|
|
3755
|
-
}
|
|
3756
|
-
return { threshold, intensity, radius, quality, softKnee, shoulder };
|
|
3757
|
-
}
|
|
3758
|
-
function normalizeNativeOutlineOptions(options) {
|
|
3759
|
-
const width = outlineNumberOption(options, "width", 1);
|
|
3760
|
-
const threshold = outlineNumberOption(options, "threshold", 0.22);
|
|
3761
|
-
const opacity = outlineNumberOption(options, "opacity", 0.85);
|
|
3762
|
-
const value = options.color;
|
|
3763
|
-
const sourceColor = value === undefined ? [255, 188, 64, 255] : value;
|
|
3764
|
-
if (!Array.isArray(sourceColor)
|
|
3765
|
-
|| (sourceColor.length !== 3 && sourceColor.length !== 4)
|
|
3766
|
-
|| sourceColor.some((channel) => typeof channel !== "number" || !Number.isFinite(channel) || channel < 0 || channel > 255)) {
|
|
3767
|
-
throw new RenderDeviceError("Outline color must contain three or four finite channels in [0, 255].", "INVALID_POSTPROCESS_OPTIONS", { color: value });
|
|
3768
|
-
}
|
|
3769
|
-
if (!Number.isInteger(width) || width < 1 || width > 6) {
|
|
3770
|
-
throw new RenderDeviceError("Outline width must be an integer in [1, 6].", "INVALID_POSTPROCESS_OPTIONS", { width });
|
|
3771
|
-
}
|
|
3772
|
-
if (threshold < 0 || threshold > 4) {
|
|
3773
|
-
throw new RenderDeviceError("Outline threshold must be finite and in [0, 4].", "INVALID_POSTPROCESS_OPTIONS", { threshold });
|
|
3774
|
-
}
|
|
3775
|
-
if (opacity < 0 || opacity > 1) {
|
|
3776
|
-
throw new RenderDeviceError("Outline opacity must be finite and in [0, 1].", "INVALID_POSTPROCESS_OPTIONS", { opacity });
|
|
3777
|
-
}
|
|
3778
|
-
const color = [
|
|
3779
|
-
sourceColor[0],
|
|
3780
|
-
sourceColor[1],
|
|
3781
|
-
sourceColor[2],
|
|
3782
|
-
(sourceColor[3] ?? 255)
|
|
3783
|
-
];
|
|
3784
|
-
return { width, threshold, opacity, color };
|
|
3785
|
-
}
|
|
3786
|
-
function normalizeNativeSsaoOptions(options) {
|
|
3787
|
-
const radius = ssaoNumberOption(options, "radius", 2);
|
|
3788
|
-
const intensity = ssaoNumberOption(options, "intensity", 0.38);
|
|
3789
|
-
const bias = ssaoNumberOption(options, "bias", 0.015);
|
|
3790
|
-
if (!Number.isInteger(radius) || radius < 1 || radius > 8) {
|
|
3791
|
-
throw new RenderDeviceError("SSAO radius must be an integer in [1, 8].", "INVALID_POSTPROCESS_OPTIONS", { radius });
|
|
3792
|
-
}
|
|
3793
|
-
if (intensity < 0 || intensity > 2) {
|
|
3794
|
-
throw new RenderDeviceError("SSAO intensity must be finite and in [0, 2].", "INVALID_POSTPROCESS_OPTIONS", { intensity });
|
|
3795
|
-
}
|
|
3796
|
-
if (bias < 0 || bias > 0.25) {
|
|
3797
|
-
throw new RenderDeviceError("SSAO bias must be finite and in [0, 0.25].", "INVALID_POSTPROCESS_OPTIONS", { bias });
|
|
3798
|
-
}
|
|
3799
|
-
return { radius, intensity, bias };
|
|
3800
1327
|
}
|
|
3801
1328
|
/**
|
|
3802
1329
|
* Camera depth range for linearizing sampleable GL depth in the native
|
|
@@ -3807,185 +1334,12 @@ function normalizeNativeSsaoOptions(options) {
|
|
|
3807
1334
|
* keep fixture-unit depth semantics (deterministic reference); the native
|
|
3808
1335
|
* programs document their GL-depth contract in-shader.
|
|
3809
1336
|
*/
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
const
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
const maxDistance = ssrNumberOption(options, "maxDistance", 16);
|
|
3818
|
-
if (intensity < 0 || intensity > 2) {
|
|
3819
|
-
throw new RenderDeviceError("SSR intensity must be finite and in [0, 2].", "INVALID_POSTPROCESS_OPTIONS", { intensity });
|
|
3820
|
-
}
|
|
3821
|
-
if (!Number.isInteger(maxDistance) || maxDistance < 1 || maxDistance > 64) {
|
|
3822
|
-
throw new RenderDeviceError("SSR maxDistance must be an integer in [1, 64].", "INVALID_POSTPROCESS_OPTIONS", { maxDistance });
|
|
3823
|
-
}
|
|
3824
|
-
return { intensity, maxDistance };
|
|
3825
|
-
}
|
|
3826
|
-
function normalizeNativeDepthOfFieldOptions(options) {
|
|
3827
|
-
const focusDepth = depthOfFieldNumberOption(options, "focusDepth", 0.5);
|
|
3828
|
-
const focusRange = depthOfFieldNumberOption(options, "focusRange", 0.12);
|
|
3829
|
-
const maxRadius = depthOfFieldNumberOption(options, "maxRadius", 2);
|
|
3830
|
-
if (focusDepth < 0 || focusDepth > 1) {
|
|
3831
|
-
throw new RenderDeviceError("Depth-of-field focusDepth must be finite and in [0, 1].", "INVALID_POSTPROCESS_OPTIONS", { focusDepth });
|
|
3832
|
-
}
|
|
3833
|
-
if (focusRange < 0.001 || focusRange > 1) {
|
|
3834
|
-
throw new RenderDeviceError("Depth-of-field focusRange must be finite and in [0.001, 1].", "INVALID_POSTPROCESS_OPTIONS", { focusRange });
|
|
3835
|
-
}
|
|
3836
|
-
if (!Number.isInteger(maxRadius) || maxRadius < 0 || maxRadius > 8) {
|
|
3837
|
-
throw new RenderDeviceError("Depth-of-field maxRadius must be an integer in [0, 8].", "INVALID_POSTPROCESS_OPTIONS", { maxRadius });
|
|
3838
|
-
}
|
|
3839
|
-
return { focusDepth, focusRange, maxRadius };
|
|
3840
|
-
}
|
|
3841
|
-
function normalizeNativeMotionBlurOptions(options, width, height) {
|
|
3842
|
-
const samples = motionBlurNumberOption(options, "samples", 5);
|
|
3843
|
-
const scale = motionBlurNumberOption(options, "scale", 1);
|
|
3844
|
-
const value = options.velocity;
|
|
3845
|
-
if (!(value instanceof Float32Array) && !Array.isArray(value)) {
|
|
3846
|
-
throw new RenderDeviceError("Motion blur requires a velocity Float32Array or number array.", "WEBGL_LDR_POSTPROCESS_VELOCITY_REQUIRED");
|
|
3847
|
-
}
|
|
3848
|
-
const velocity = value instanceof Float32Array ? value : new Float32Array(value);
|
|
3849
|
-
if (velocity.length !== width * height * 2) {
|
|
3850
|
-
throw new RenderDeviceError("Motion blur velocity must contain width * height * 2 float samples.", "INVALID_POSTPROCESS_OPTIONS", {
|
|
3851
|
-
expectedLength: width * height * 2,
|
|
3852
|
-
actualLength: velocity.length
|
|
3853
|
-
});
|
|
3854
|
-
}
|
|
3855
|
-
if (!Number.isInteger(samples) || samples < 2 || samples > 16) {
|
|
3856
|
-
throw new RenderDeviceError("Motion blur samples must be an integer in [2, 16].", "INVALID_POSTPROCESS_OPTIONS", { samples });
|
|
3857
|
-
}
|
|
3858
|
-
if (scale < 0 || scale > 8) {
|
|
3859
|
-
throw new RenderDeviceError("Motion blur scale must be finite and in [0, 8].", "INVALID_POSTPROCESS_OPTIONS", { scale });
|
|
3860
|
-
}
|
|
3861
|
-
return { samples, scale, velocity };
|
|
3862
|
-
}
|
|
3863
|
-
function normalizeNativeTaaOptions(options, width, height) {
|
|
3864
|
-
const blend = taaNumberOption(options, "blend", 0.18);
|
|
3865
|
-
const history = options.history;
|
|
3866
|
-
if (!(history instanceof Uint8Array)) {
|
|
3867
|
-
throw new RenderDeviceError("TAA requires a Uint8Array history buffer.", "WEBGL_LDR_POSTPROCESS_HISTORY_REQUIRED");
|
|
3868
|
-
}
|
|
3869
|
-
if (history.byteLength !== width * height * 4) {
|
|
3870
|
-
throw new RenderDeviceError("TAA history must contain width * height * 4 RGBA bytes.", "INVALID_POSTPROCESS_OPTIONS", {
|
|
3871
|
-
expectedLength: width * height * 4,
|
|
3872
|
-
actualLength: history.byteLength
|
|
3873
|
-
});
|
|
3874
|
-
}
|
|
3875
|
-
if (blend < 0 || blend > 0.95) {
|
|
3876
|
-
throw new RenderDeviceError("TAA blend must be finite and in [0, 0.95].", "INVALID_POSTPROCESS_OPTIONS", { blend });
|
|
3877
|
-
}
|
|
3878
|
-
return { blend, history };
|
|
3879
|
-
}
|
|
3880
|
-
function bloomNumberOption(options, key, fallback) {
|
|
3881
|
-
const value = options[key];
|
|
3882
|
-
if (value === undefined)
|
|
3883
|
-
return fallback;
|
|
3884
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3885
|
-
throw new RenderDeviceError(`Bloom ${key} must be a finite number.`, "INVALID_POSTPROCESS_OPTIONS", { key, value });
|
|
3886
|
-
}
|
|
3887
|
-
return value;
|
|
3888
|
-
}
|
|
3889
|
-
function outlineNumberOption(options, key, fallback) {
|
|
3890
|
-
const value = options[key];
|
|
3891
|
-
if (value === undefined)
|
|
3892
|
-
return fallback;
|
|
3893
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3894
|
-
throw new RenderDeviceError(`Outline ${key} must be a finite number.`, "INVALID_POSTPROCESS_OPTIONS", { key, value });
|
|
3895
|
-
}
|
|
3896
|
-
return value;
|
|
3897
|
-
}
|
|
3898
|
-
function ssaoNumberOption(options, key, fallback) {
|
|
3899
|
-
const value = options[key];
|
|
3900
|
-
if (value === undefined)
|
|
3901
|
-
return fallback;
|
|
3902
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3903
|
-
throw new RenderDeviceError(`SSAO ${key} must be a finite number.`, "INVALID_POSTPROCESS_OPTIONS", { key, value });
|
|
3904
|
-
}
|
|
3905
|
-
return value;
|
|
3906
|
-
}
|
|
3907
|
-
function ssrNumberOption(options, key, fallback) {
|
|
3908
|
-
const value = options[key];
|
|
3909
|
-
if (value === undefined)
|
|
3910
|
-
return fallback;
|
|
3911
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3912
|
-
throw new RenderDeviceError(`SSR ${key} must be a finite number.`, "INVALID_POSTPROCESS_OPTIONS", { key, value });
|
|
3913
|
-
}
|
|
3914
|
-
return value;
|
|
3915
|
-
}
|
|
3916
|
-
function depthOfFieldNumberOption(options, key, fallback) {
|
|
3917
|
-
const value = options[key];
|
|
3918
|
-
if (value === undefined)
|
|
3919
|
-
return fallback;
|
|
3920
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3921
|
-
throw new RenderDeviceError(`Depth-of-field ${key} must be a finite number.`, "INVALID_POSTPROCESS_OPTIONS", { key, value });
|
|
3922
|
-
}
|
|
3923
|
-
return value;
|
|
3924
|
-
}
|
|
3925
|
-
function motionBlurNumberOption(options, key, fallback) {
|
|
3926
|
-
const value = options[key];
|
|
3927
|
-
if (value === undefined)
|
|
3928
|
-
return fallback;
|
|
3929
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3930
|
-
throw new RenderDeviceError(`Motion blur ${key} must be a finite number.`, "INVALID_POSTPROCESS_OPTIONS", { key, value });
|
|
3931
|
-
}
|
|
3932
|
-
return value;
|
|
3933
|
-
}
|
|
3934
|
-
function taaNumberOption(options, key, fallback) {
|
|
3935
|
-
const value = options[key];
|
|
3936
|
-
if (value === undefined)
|
|
3937
|
-
return fallback;
|
|
3938
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3939
|
-
throw new RenderDeviceError(`TAA ${key} must be a finite number.`, "INVALID_POSTPROCESS_OPTIONS", { key, value });
|
|
3940
|
-
}
|
|
3941
|
-
return value;
|
|
3942
|
-
}
|
|
3943
|
-
function stringOption(options, key, fallback) {
|
|
3944
|
-
const value = options[key];
|
|
3945
|
-
return typeof value === "string" ? value : fallback;
|
|
3946
|
-
}
|
|
3947
|
-
function colorSpaceId(value) {
|
|
3948
|
-
return value === "srgb" ? 1 : 0;
|
|
3949
|
-
}
|
|
3950
|
-
function toneMappingOperatorId(value) {
|
|
3951
|
-
if (value === "linear")
|
|
3952
|
-
return 0;
|
|
3953
|
-
if (value === "reinhard")
|
|
3954
|
-
return 1;
|
|
3955
|
-
if (value === "aces")
|
|
3956
|
-
return 2;
|
|
3957
|
-
if (value === "filmic")
|
|
3958
|
-
return 3;
|
|
3959
|
-
if (value === "uncharted2")
|
|
3960
|
-
return 4;
|
|
3961
|
-
if (value === "agx")
|
|
3962
|
-
return 5;
|
|
3963
|
-
return 6;
|
|
3964
|
-
}
|
|
3965
|
-
function completeUploadLevels(levels) {
|
|
3966
|
-
const uploadLevels = [];
|
|
3967
|
-
for (const level of levels) {
|
|
3968
|
-
if (uploadLevels.length === 0) {
|
|
3969
|
-
uploadLevels.push(level);
|
|
3970
|
-
continue;
|
|
3971
|
-
}
|
|
3972
|
-
const previous = uploadLevels[uploadLevels.length - 1];
|
|
3973
|
-
const expectedWidth = Math.max(1, Math.floor(previous.width / 2));
|
|
3974
|
-
const expectedHeight = Math.max(1, Math.floor(previous.height / 2));
|
|
3975
|
-
if (level.width !== expectedWidth || level.height !== expectedHeight) {
|
|
3976
|
-
break;
|
|
3977
|
-
}
|
|
3978
|
-
uploadLevels.push(level);
|
|
3979
|
-
}
|
|
3980
|
-
return uploadLevels;
|
|
3981
|
-
}
|
|
3982
|
-
function texturePixelUploadData(data, format) {
|
|
3983
|
-
if (format === "rgba16f" && data instanceof Uint16Array)
|
|
3984
|
-
return data;
|
|
3985
|
-
if (format === "rgba32f" && data instanceof Float32Array)
|
|
3986
|
-
return data;
|
|
3987
|
-
if (format === "rgba8" && (data instanceof Uint8Array || data instanceof Uint8ClampedArray))
|
|
3988
|
-
return data;
|
|
3989
|
-
throw new RenderDeviceError("Texture pixel data type does not match texture format", "UNSUPPORTED_TEXTURE_FORMAT", { format });
|
|
1337
|
+
/** Next animation frame when available (browser), else a macrotask. */
|
|
1338
|
+
function scheduleParallelCompilePoll(poll) {
|
|
1339
|
+
const raf = globalThis.requestAnimationFrame;
|
|
1340
|
+
if (typeof raf === "function")
|
|
1341
|
+
raf(poll);
|
|
1342
|
+
else
|
|
1343
|
+
setTimeout(poll, 0);
|
|
3990
1344
|
}
|
|
3991
1345
|
//# sourceMappingURL=WebGL2Device.js.map
|