@driftengine/core 3.63.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/CHANGELOG.json +111 -0
- package/NOTICE +20 -0
- package/README.md +1 -1
- package/dist/core/loop.js +18 -2
- package/dist/core/storage.js +5 -0
- package/dist/geometry/meshBuilder.d.ts +1 -1
- package/dist/geometry/meshBuilder.js +6 -2
- package/dist/index.d.ts +69 -4
- package/dist/index.js +112 -2
- package/dist/input/input.js +6 -1
- package/dist/math/exact.d.ts +13 -3
- package/dist/math/exact.js +68 -3
- package/dist/math/frustum.d.ts +17 -2
- package/dist/math/frustum.js +24 -0
- package/dist/render/backend/api.d.ts +34 -1
- package/dist/render/backend/api.js +22 -1
- package/dist/render/backend/budget.d.ts +7 -6
- package/dist/render/backend/budget.js +7 -6
- package/dist/render/backend/createRenderer.d.ts +57 -0
- package/dist/render/backend/createRenderer.js +51 -2
- package/dist/render/backend/materialChanges.d.ts +41 -0
- package/dist/render/backend/materialChanges.js +38 -0
- package/dist/render/backend/select.js +8 -0
- package/dist/render/backend/webgl2/renderer.d.ts +80 -1
- package/dist/render/backend/webgl2/renderer.js +208 -10
- package/dist/render/backend/webgpu/buffers.d.ts +20 -1
- package/dist/render/backend/webgpu/buffers.js +116 -58
- package/dist/render/backend/webgpu/fieldCompose.d.ts +156 -0
- package/dist/render/backend/webgpu/fieldCompose.js +396 -0
- package/dist/render/backend/webgpu/giFieldPass.d.ts +66 -0
- package/dist/render/backend/webgpu/giFieldPass.js +137 -0
- package/dist/render/backend/webgpu/gpuDrivenPass.d.ts +728 -0
- package/dist/render/backend/webgpu/gpuDrivenPass.js +2473 -0
- package/dist/render/backend/webgpu/linePass.d.ts +4 -14
- package/dist/render/backend/webgpu/linePass.js +4 -33
- package/dist/render/backend/webgpu/probeBake.d.ts +148 -0
- package/dist/render/backend/webgpu/probeBake.js +493 -0
- package/dist/render/backend/webgpu/renderer.d.ts +379 -24
- package/dist/render/backend/webgpu/renderer.js +1369 -76
- package/dist/render/backend/webgpu/scatterPass.js +15 -1
- package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +19 -9
- package/dist/render/backend/webgpu/surfaceTexturePass.js +58 -32
- package/dist/render/causticsRenderer.d.ts +3 -1
- package/dist/render/causticsRenderer.js +4 -1
- package/dist/render/depthConvention.d.ts +12 -0
- package/dist/render/depthConvention.js +14 -0
- package/dist/render/deviceFeatures.d.ts +32 -0
- package/dist/render/deviceFeatures.js +41 -0
- package/dist/render/fog.d.ts +79 -0
- package/dist/render/fog.js +138 -0
- package/dist/render/frame/alias.d.ts +30 -0
- package/dist/render/frame/alias.js +61 -0
- package/dist/render/frame/deps.d.ts +37 -0
- package/dist/render/frame/deps.js +122 -0
- package/dist/render/frame/flushGraph.d.ts +43 -0
- package/dist/render/frame/flushGraph.js +84 -0
- package/dist/render/frame/graphSchedule.d.ts +49 -0
- package/dist/render/frame/graphSchedule.js +120 -0
- package/dist/render/frame/index.d.ts +15 -0
- package/dist/render/frame/index.js +8 -0
- package/dist/render/frame/lifetime.d.ts +24 -0
- package/dist/render/frame/lifetime.js +36 -0
- package/dist/render/frame/passTimings.d.ts +42 -0
- package/dist/render/frame/passTimings.js +38 -0
- package/dist/render/frame/validate.d.ts +15 -0
- package/dist/render/frame/validate.js +22 -0
- package/dist/render/frame/virtual.d.ts +44 -0
- package/dist/render/frame/virtual.js +61 -0
- package/dist/render/gi/chain.d.ts +82 -0
- package/dist/render/gi/chain.js +135 -0
- package/dist/render/gi/denoise.d.ts +114 -0
- package/dist/render/gi/denoise.js +169 -0
- package/dist/render/gi/fieldScene.d.ts +125 -0
- package/dist/render/gi/fieldScene.js +219 -0
- package/dist/render/gi/globalField.d.ts +157 -0
- package/dist/render/gi/globalField.js +373 -0
- package/dist/render/gi/probeGridFit.d.ts +24 -0
- package/dist/render/gi/probeGridFit.js +71 -0
- package/dist/render/gi/probeTrace.d.ts +82 -0
- package/dist/render/gi/probeTrace.js +128 -0
- package/dist/render/gi/probeVolume.d.ts +136 -0
- package/dist/render/gi/probeVolume.js +191 -0
- package/dist/render/gi/reflection.d.ts +73 -0
- package/dist/render/gi/reflection.js +109 -0
- package/dist/render/gi/traceField.d.ts +91 -0
- package/dist/render/gi/traceField.js +129 -0
- package/dist/render/gi/traceScreen.d.ts +68 -0
- package/dist/render/gi/traceScreen.js +82 -0
- package/dist/render/gpuScene.d.ts +38 -0
- package/dist/render/gpuScene.js +41 -0
- package/dist/render/gpudriven/alphaTest.d.ts +28 -0
- package/dist/render/gpudriven/alphaTest.js +32 -0
- package/dist/render/gpudriven/clusterUpload.d.ts +59 -0
- package/dist/render/gpudriven/clusterUpload.js +75 -0
- package/dist/render/gpudriven/clusterWorld.d.ts +57 -0
- package/dist/render/gpudriven/clusterWorld.js +155 -0
- package/dist/render/gpudriven/compact.d.ts +51 -0
- package/dist/render/gpudriven/compact.js +68 -0
- package/dist/render/gpudriven/cullClusters.d.ts +129 -0
- package/dist/render/gpudriven/cullClusters.js +237 -0
- package/dist/render/gpudriven/decodeTables.d.ts +64 -0
- package/dist/render/gpudriven/decodeTables.js +219 -0
- package/dist/render/gpudriven/frustum.d.ts +25 -0
- package/dist/render/gpudriven/frustum.js +59 -0
- package/dist/render/gpudriven/geometryHarness.d.ts +15 -0
- package/dist/render/gpudriven/geometryHarness.js +31 -0
- package/dist/render/gpudriven/hzb.d.ts +60 -0
- package/dist/render/gpudriven/hzb.js +97 -0
- package/dist/render/gpudriven/ibl.d.ts +85 -0
- package/dist/render/gpudriven/ibl.js +129 -0
- package/dist/render/gpudriven/indirect.d.ts +67 -0
- package/dist/render/gpudriven/indirect.js +77 -0
- package/dist/render/gpudriven/instances.d.ts +43 -0
- package/dist/render/gpudriven/instances.js +172 -0
- package/dist/render/gpudriven/lit.d.ts +165 -0
- package/dist/render/gpudriven/lit.js +165 -0
- package/dist/render/gpudriven/lodCut.d.ts +28 -0
- package/dist/render/gpudriven/lodCut.js +38 -0
- package/dist/render/gpudriven/materialBin.d.ts +60 -0
- package/dist/render/gpudriven/materialBin.js +108 -0
- package/dist/render/gpudriven/materialTable.d.ts +88 -0
- package/dist/render/gpudriven/materialTable.js +115 -0
- package/dist/render/gpudriven/pipeline.d.ts +135 -0
- package/dist/render/gpudriven/pipeline.js +237 -0
- package/dist/render/gpudriven/rangeAlloc.d.ts +50 -0
- package/dist/render/gpudriven/rangeAlloc.js +112 -0
- package/dist/render/gpudriven/sceneUpload.d.ts +96 -0
- package/dist/render/gpudriven/sceneUpload.js +115 -0
- package/dist/render/gpudriven/shadeBins.d.ts +92 -0
- package/dist/render/gpudriven/shadeBins.js +182 -0
- package/dist/render/gpudriven/shadow.d.ts +136 -0
- package/dist/render/gpudriven/shadow.js +224 -0
- package/dist/render/gpudriven/shadowCamera.d.ts +87 -0
- package/dist/render/gpudriven/shadowCamera.js +345 -0
- package/dist/render/gpudriven/streamScene.d.ts +194 -0
- package/dist/render/gpudriven/streamScene.js +459 -0
- package/dist/render/gpudriven/surfaceFrame.d.ts +25 -0
- package/dist/render/gpudriven/surfaceFrame.js +51 -0
- package/dist/render/gpudriven/twoPhase.d.ts +122 -0
- package/dist/render/gpudriven/twoPhase.js +160 -0
- package/dist/render/gpudriven/visbuffer.d.ts +25 -0
- package/dist/render/gpudriven/visbuffer.js +37 -0
- package/dist/render/halfFloat.d.ts +10 -0
- package/dist/render/halfFloat.js +23 -4
- package/dist/render/inference/attentionTiled.d.ts +27 -0
- package/dist/render/inference/attentionTiled.js +117 -0
- package/dist/render/inference/denseKernels.d.ts +29 -0
- package/dist/render/inference/denseKernels.js +312 -0
- package/dist/render/inference/device.d.ts +21 -0
- package/dist/render/inference/device.js +32 -0
- package/dist/render/inference/deviceGraph.d.ts +34 -0
- package/dist/render/inference/deviceGraph.js +17 -0
- package/dist/render/inference/fuse.d.ts +15 -0
- package/dist/render/inference/fuse.js +37 -0
- package/dist/render/inference/kernelKit.d.ts +52 -0
- package/dist/render/inference/kernelKit.js +70 -0
- package/dist/render/inference/kernels.d.ts +3 -0
- package/dist/render/inference/kernels.js +11 -0
- package/dist/render/inference/plan.d.ts +13 -0
- package/dist/render/inference/plan.js +18 -0
- package/dist/render/inference/reuse.d.ts +39 -0
- package/dist/render/inference/reuse.js +65 -0
- package/dist/render/inference/runner.d.ts +31 -0
- package/dist/render/inference/runner.js +175 -0
- package/dist/render/inference/schedule.d.ts +39 -0
- package/dist/render/inference/schedule.js +59 -0
- package/dist/render/inference/shapeKernels.d.ts +10 -0
- package/dist/render/inference/shapeKernels.js +80 -0
- package/dist/render/inference/spatialKernels.d.ts +21 -0
- package/dist/render/inference/spatialKernels.js +179 -0
- package/dist/render/inference/splatRaster.wgsl.d.ts +75 -0
- package/dist/render/inference/splatRaster.wgsl.js +337 -0
- package/dist/render/inference/splatTiles.d.ts +79 -0
- package/dist/render/inference/splatTiles.js +161 -0
- package/dist/render/lineBatch.d.ts +2 -5
- package/dist/render/lineBatch.js +4 -24
- package/dist/render/mesh.d.ts +4 -0
- package/dist/render/mesh.js +45 -1
- package/dist/render/pass.d.ts +145 -8
- package/dist/render/prefilterEnvMap.d.ts +22 -0
- package/dist/render/prefilterEnvMap.js +31 -0
- package/dist/render/readback.d.ts +30 -0
- package/dist/render/readback.js +47 -0
- package/dist/render/recon/clamp.d.ts +36 -0
- package/dist/render/recon/clamp.js +92 -0
- package/dist/render/recon/disocclusion.d.ts +60 -0
- package/dist/render/recon/disocclusion.js +109 -0
- package/dist/render/recon/frameGen.d.ts +81 -0
- package/dist/render/recon/frameGen.js +150 -0
- package/dist/render/recon/frameSizes.d.ts +34 -0
- package/dist/render/recon/frameSizes.js +58 -0
- package/dist/render/recon/jitter.d.ts +60 -0
- package/dist/render/recon/jitter.js +118 -0
- package/dist/render/recon/motionVectors.d.ts +55 -0
- package/dist/render/recon/motionVectors.js +107 -0
- package/dist/render/recon/reproject.d.ts +41 -0
- package/dist/render/recon/reproject.js +131 -0
- package/dist/render/recon/resolve.d.ts +90 -0
- package/dist/render/recon/resolve.js +313 -0
- package/dist/render/recon/tier.d.ts +24 -0
- package/dist/render/recon/tier.js +8 -0
- package/dist/render/reflectionProbe.d.ts +26 -0
- package/dist/render/reflectionProbe.js +33 -0
- package/dist/render/renderQuality.d.ts +69 -0
- package/dist/render/renderQuality.js +22 -0
- package/dist/render/screenSpaceReflection.d.ts +23 -0
- package/dist/render/screenSpaceReflection.js +22 -3
- package/dist/render/sdfFont.js +2 -0
- package/dist/render/segmentQuads.d.ts +13 -0
- package/dist/render/segmentQuads.js +32 -0
- package/dist/render/shaders/flat/lobes.d.ts +27 -0
- package/dist/render/shaders/flat/lobes.js +33 -3
- package/dist/render/shaders/flat/preamble.d.ts +7 -0
- package/dist/render/shaders/flat/preamble.js +24 -1
- package/dist/render/shaders/flat/probeGrid.d.ts +1 -1
- package/dist/render/shaders/flat/probeGrid.js +71 -2
- package/dist/render/shaders/generated/flat.wgsl.d.ts +48 -8
- package/dist/render/shaders/generated/flat.wgsl.js +64 -24
- package/dist/render/shaders/gi/composeField.wgsl.d.ts +56 -0
- package/dist/render/shaders/gi/composeField.wgsl.js +231 -0
- package/dist/render/shaders/gi/marchField.wgsl.d.ts +30 -0
- package/dist/render/shaders/gi/marchField.wgsl.js +141 -0
- package/dist/render/shaders/gi/probeBake.wgsl.d.ts +113 -0
- package/dist/render/shaders/gi/probeBake.wgsl.js +635 -0
- package/dist/render/shaders/gi/probeTrace.wgsl.d.ts +72 -0
- package/dist/render/shaders/gi/probeTrace.wgsl.js +261 -0
- package/dist/render/shaders/gi/probeVolume.wgsl.d.ts +49 -0
- package/dist/render/shaders/gi/probeVolume.wgsl.js +242 -0
- package/dist/render/shaders/gi/sampleField.wgsl.d.ts +32 -0
- package/dist/render/shaders/gi/sampleField.wgsl.js +134 -0
- package/dist/render/shaders/gpudriven/blendRaster.wgsl.d.ts +26 -0
- package/dist/render/shaders/gpudriven/blendRaster.wgsl.js +339 -0
- package/dist/render/shaders/gpudriven/compact.wgsl.d.ts +29 -0
- package/dist/render/shaders/gpudriven/compact.wgsl.js +58 -0
- package/dist/render/shaders/gpudriven/cull.wgsl.d.ts +90 -0
- package/dist/render/shaders/gpudriven/cull.wgsl.js +423 -0
- package/dist/render/shaders/gpudriven/decode.wgsl.d.ts +72 -0
- package/dist/render/shaders/gpudriven/decode.wgsl.js +349 -0
- package/dist/render/shaders/gpudriven/environment.wgsl.d.ts +44 -0
- package/dist/render/shaders/gpudriven/environment.wgsl.js +137 -0
- package/dist/render/shaders/gpudriven/fog.wgsl.d.ts +28 -0
- package/dist/render/shaders/gpudriven/fog.wgsl.js +107 -0
- package/dist/render/shaders/gpudriven/frameBlock.wgsl.d.ts +13 -0
- package/dist/render/shaders/gpudriven/frameBlock.wgsl.js +62 -0
- package/dist/render/shaders/gpudriven/materialBin.wgsl.d.ts +51 -0
- package/dist/render/shaders/gpudriven/materialBin.wgsl.js +112 -0
- package/dist/render/shaders/gpudriven/materialTable.wgsl.d.ts +25 -0
- package/dist/render/shaders/gpudriven/materialTable.wgsl.js +43 -0
- package/dist/render/shaders/gpudriven/meshTransform.wgsl.d.ts +18 -0
- package/dist/render/shaders/gpudriven/meshTransform.wgsl.js +37 -0
- package/dist/render/shaders/gpudriven/present.wgsl.d.ts +43 -0
- package/dist/render/shaders/gpudriven/present.wgsl.js +127 -0
- package/dist/render/shaders/gpudriven/shade.wgsl.d.ts +127 -0
- package/dist/render/shaders/gpudriven/shade.wgsl.js +874 -0
- package/dist/render/shaders/gpudriven/shadow.wgsl.d.ts +44 -0
- package/dist/render/shaders/gpudriven/shadow.wgsl.js +308 -0
- package/dist/render/shaders/gpudriven/visbufferRaster.wgsl.d.ts +28 -0
- package/dist/render/shaders/gpudriven/visbufferRaster.wgsl.js +245 -0
- package/dist/render/shaders/network.wgsl.d.ts +101 -0
- package/dist/render/shaders/network.wgsl.js +206 -0
- package/dist/render/shaders/recon/motion.wgsl.d.ts +44 -0
- package/dist/render/shaders/recon/motion.wgsl.js +96 -0
- package/dist/render/shaders/recon/resolve.wgsl.d.ts +51 -0
- package/dist/render/shaders/recon/resolve.wgsl.js +733 -0
- package/dist/render/temporalAa.js +8 -33
- package/dist/render/textLayout.js +12 -6
- package/dist/render/textRenderer.d.ts +3 -1
- package/dist/render/textRenderer.js +4 -1
- package/dist/render/translucentQueue.d.ts +6 -0
- package/dist/render/translucentQueue.js +11 -0
- package/dist/render/windStreakRenderer.d.ts +2 -1
- package/dist/render/windStreakRenderer.js +3 -1
- package/dist/world/cell.d.ts +63 -0
- package/dist/world/cell.js +181 -0
- package/dist/world/cellStream.d.ts +103 -0
- package/dist/world/cellStream.js +198 -0
- package/dist/world/freeze.d.ts +81 -0
- package/dist/world/freeze.js +114 -0
- package/dist/world/rebase.d.ts +29 -0
- package/dist/world/rebase.js +41 -0
- package/package.json +8 -3
- package/scripts/frames.mjs +92 -0
- package/scripts/gpuCompute.mjs +323 -0
- package/scripts/png.d.mts +16 -0
- package/scripts/png.mjs +25 -0
- package/src/core/loop.ts +19 -2
- package/src/core/storage.ts +5 -0
- package/src/geometry/meshBuilder.ts +5 -1
- package/src/index.ts +246 -4
- package/src/input/input.ts +6 -1
- package/src/math/exact.ts +69 -3
- package/src/math/frustum.ts +52 -3
- package/src/render/backend/api.ts +42 -1
- package/src/render/backend/budget.ts +7 -6
- package/src/render/backend/createRenderer.ts +92 -3
- package/src/render/backend/materialChanges.ts +54 -0
- package/src/render/backend/select.ts +8 -0
- package/src/render/backend/webgl2/renderer.ts +211 -9
- package/src/render/backend/webgpu/buffers.ts +182 -69
- package/src/render/backend/webgpu/fieldCompose.ts +482 -0
- package/src/render/backend/webgpu/giFieldPass.ts +200 -0
- package/src/render/backend/webgpu/gpuDrivenPass.ts +2993 -0
- package/src/render/backend/webgpu/linePass.ts +4 -39
- package/src/render/backend/webgpu/probeBake.ts +588 -0
- package/src/render/backend/webgpu/renderer.ts +1481 -76
- package/src/render/backend/webgpu/scatterPass.ts +15 -1
- package/src/render/backend/webgpu/surfaceTexturePass.ts +63 -36
- package/src/render/causticsRenderer.ts +5 -2
- package/src/render/depthConvention.ts +15 -0
- package/src/render/deviceFeatures.ts +77 -0
- package/src/render/fog.ts +185 -0
- package/src/render/frame/alias.ts +97 -0
- package/src/render/frame/deps.ts +155 -0
- package/src/render/frame/flushGraph.ts +135 -0
- package/src/render/frame/graphSchedule.ts +170 -0
- package/src/render/frame/index.ts +52 -0
- package/src/render/frame/lifetime.ts +61 -0
- package/src/render/frame/passTimings.ts +69 -0
- package/src/render/frame/validate.ts +40 -0
- package/src/render/frame/virtual.ts +91 -0
- package/src/render/gi/chain.ts +225 -0
- package/src/render/gi/denoise.ts +276 -0
- package/src/render/gi/fieldScene.ts +264 -0
- package/src/render/gi/globalField.ts +543 -0
- package/src/render/gi/probeGridFit.ts +89 -0
- package/src/render/gi/probeTrace.ts +143 -0
- package/src/render/gi/probeVolume.ts +288 -0
- package/src/render/gi/reflection.ts +163 -0
- package/src/render/gi/traceField.ts +223 -0
- package/src/render/gi/traceScreen.ts +106 -0
- package/src/render/gpuScene.ts +80 -0
- package/src/render/gpudriven/alphaTest.ts +33 -0
- package/src/render/gpudriven/clusterUpload.ts +123 -0
- package/src/render/gpudriven/clusterWorld.ts +239 -0
- package/src/render/gpudriven/compact.ts +80 -0
- package/src/render/gpudriven/cullClusters.ts +333 -0
- package/src/render/gpudriven/decodeTables.ts +332 -0
- package/src/render/gpudriven/frustum.ts +70 -0
- package/src/render/gpudriven/geometryHarness.ts +51 -0
- package/src/render/gpudriven/hzb.ts +113 -0
- package/src/render/gpudriven/ibl.ts +147 -0
- package/src/render/gpudriven/indirect.ts +89 -0
- package/src/render/gpudriven/instances.ts +234 -0
- package/src/render/gpudriven/lit.ts +329 -0
- package/src/render/gpudriven/lodCut.ts +62 -0
- package/src/render/gpudriven/materialBin.ts +131 -0
- package/src/render/gpudriven/materialTable.ts +164 -0
- package/src/render/gpudriven/pipeline.ts +336 -0
- package/src/render/gpudriven/rangeAlloc.ts +122 -0
- package/src/render/gpudriven/sceneUpload.ts +173 -0
- package/src/render/gpudriven/shadeBins.ts +222 -0
- package/src/render/gpudriven/shadow.ts +285 -0
- package/src/render/gpudriven/shadowCamera.ts +406 -0
- package/src/render/gpudriven/streamScene.ts +575 -0
- package/src/render/gpudriven/surfaceFrame.ts +68 -0
- package/src/render/gpudriven/twoPhase.ts +214 -0
- package/src/render/gpudriven/visbuffer.ts +41 -0
- package/src/render/halfFloat.ts +22 -4
- package/src/render/inference/attentionTiled.ts +132 -0
- package/src/render/inference/denseKernels.ts +369 -0
- package/src/render/inference/device.ts +44 -0
- package/src/render/inference/deviceGraph.ts +39 -0
- package/src/render/inference/fuse.ts +47 -0
- package/src/render/inference/kernelKit.ts +120 -0
- package/src/render/inference/kernels.ts +18 -0
- package/src/render/inference/plan.ts +26 -0
- package/src/render/inference/reuse.ts +79 -0
- package/src/render/inference/runner.ts +204 -0
- package/src/render/inference/schedule.ts +80 -0
- package/src/render/inference/shapeKernels.ts +112 -0
- package/src/render/inference/spatialKernels.ts +220 -0
- package/src/render/inference/splatRaster.wgsl.ts +348 -0
- package/src/render/inference/splatTiles.ts +186 -0
- package/src/render/lineBatch.ts +4 -24
- package/src/render/mesh.ts +46 -1
- package/src/render/pass.ts +155 -10
- package/src/render/prefilterEnvMap.ts +33 -0
- package/src/render/readback.ts +73 -0
- package/src/render/recon/clamp.ts +113 -0
- package/src/render/recon/disocclusion.ts +143 -0
- package/src/render/recon/frameGen.ts +191 -0
- package/src/render/recon/frameSizes.ts +64 -0
- package/src/render/recon/jitter.ts +126 -0
- package/src/render/recon/motionVectors.ts +138 -0
- package/src/render/recon/reproject.ts +179 -0
- package/src/render/recon/resolve.ts +444 -0
- package/src/render/recon/tier.ts +31 -0
- package/src/render/reflectionProbe.ts +34 -0
- package/src/render/renderQuality.ts +87 -0
- package/src/render/screenSpaceReflection.ts +37 -3
- package/src/render/sdfFont.ts +2 -0
- package/src/render/segmentQuads.ts +39 -0
- package/src/render/shaders/flat/lobes.ts +35 -3
- package/src/render/shaders/flat/preamble.ts +25 -1
- package/src/render/shaders/flat/probeGrid.ts +77 -2
- package/src/render/shaders/generated/flat.wgsl.ts +64 -24
- package/src/render/shaders/gi/composeField.wgsl.ts +239 -0
- package/src/render/shaders/gi/marchField.wgsl.ts +146 -0
- package/src/render/shaders/gi/probeBake.wgsl.ts +649 -0
- package/src/render/shaders/gi/probeTrace.wgsl.ts +269 -0
- package/src/render/shaders/gi/probeVolume.wgsl.ts +246 -0
- package/src/render/shaders/gi/sampleField.wgsl.ts +140 -0
- package/src/render/shaders/gpudriven/blendRaster.wgsl.ts +343 -0
- package/src/render/shaders/gpudriven/compact.wgsl.ts +59 -0
- package/src/render/shaders/gpudriven/cull.wgsl.ts +433 -0
- package/src/render/shaders/gpudriven/decode.wgsl.ts +373 -0
- package/src/render/shaders/gpudriven/environment.wgsl.ts +141 -0
- package/src/render/shaders/gpudriven/fog.wgsl.ts +110 -0
- package/src/render/shaders/gpudriven/frameBlock.wgsl.ts +62 -0
- package/src/render/shaders/gpudriven/materialBin.wgsl.ts +116 -0
- package/src/render/shaders/gpudriven/materialTable.wgsl.ts +46 -0
- package/src/render/shaders/gpudriven/meshTransform.wgsl.ts +37 -0
- package/src/render/shaders/gpudriven/present.wgsl.ts +129 -0
- package/src/render/shaders/gpudriven/shade.wgsl.ts +884 -0
- package/src/render/shaders/gpudriven/shadow.wgsl.ts +322 -0
- package/src/render/shaders/gpudriven/visbufferRaster.wgsl.ts +251 -0
- package/src/render/shaders/network.wgsl.ts +238 -0
- package/src/render/shaders/recon/motion.wgsl.ts +101 -0
- package/src/render/shaders/recon/resolve.wgsl.ts +741 -0
- package/src/render/temporalAa.ts +9 -33
- package/src/render/textLayout.ts +12 -6
- package/src/render/textRenderer.ts +5 -2
- package/src/render/translucentQueue.ts +11 -0
- package/src/render/windStreakRenderer.ts +4 -2
- package/src/world/cell.ts +231 -0
- package/src/world/cellStream.ts +278 -0
- package/src/world/freeze.ts +157 -0
- package/src/world/rebase.ts +56 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FrameBudget } from '../budget.ts';
|
|
2
|
+
import { MaterialChanges, ownsMaterial } from '../materialChanges.ts';
|
|
2
3
|
import { mat4 } from 'gl-matrix';
|
|
3
4
|
import {
|
|
4
5
|
DEPTH_CLEAR,
|
|
@@ -40,6 +41,8 @@ import { DecalQueue } from '../../decalQueue.ts';
|
|
|
40
41
|
import type { DecalProjector } from '../../decalProjector.ts';
|
|
41
42
|
import { OitPass } from '../../oitPass.ts';
|
|
42
43
|
import { OIT_MULTISAMPLE_REFUSAL } from '../../orderIndependent.ts';
|
|
44
|
+
import { INDIRECT_LIGHT_WEBGL2_REFUSAL } from '../../gi/probeTrace.ts';
|
|
45
|
+
import type { FieldSource } from '../../gi/globalField.ts';
|
|
43
46
|
import { TranslucentQueue } from '../../translucentQueue.ts';
|
|
44
47
|
import { createFrustum, frustumFromViewProjection } from '../../../math/frustum.ts';
|
|
45
48
|
import type { Frustum } from '../../../math/frustum.ts';
|
|
@@ -110,7 +113,7 @@ import { SkinPaletteTexture } from './skinPaletteTexture.ts';
|
|
|
110
113
|
/* The codes the shader reads, stated once in `vertexDefaults.ts` for both backends. */
|
|
111
114
|
import { LIGHT_VOLUME_VERT, lightVolumeFrag } from '../../shaders/lightVolume.ts';
|
|
112
115
|
import { PANEL_FRAG, PANEL_VERT } from '../../shaders/panel.ts';
|
|
113
|
-
import { ReflectionProbe } from '../../reflectionProbe.ts';
|
|
116
|
+
import { ReflectionProbe, cubeFaceProjection } from '../../reflectionProbe.ts';
|
|
114
117
|
import type { ProbeBakeOptions } from '../../reflectionProbe.ts';
|
|
115
118
|
import { EnvProbeArray } from '../../envProbeArray.ts';
|
|
116
119
|
import { ProbeGrid, SINGLE_PROBE, UNIT_STEP, WORLD_ORIGIN, sameGrid } from '../../probeGrid.ts';
|
|
@@ -1369,6 +1372,13 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
1369
1372
|
reversedDepth = false;
|
|
1370
1373
|
/** `GL_DEPTH_REMAP * camera.viewProjection`, rebuilt once a frame. */
|
|
1371
1374
|
private readonly sceneViewProj = new Float32Array(16);
|
|
1375
|
+
/**
|
|
1376
|
+
* The same matrix with clip y negated, for the six faces of a probe.
|
|
1377
|
+
*
|
|
1378
|
+
* Its own buffer rather than `sceneViewProj`, because `cubeFaceProjection` reads what
|
|
1379
|
+
* `sceneMatrix` just wrote and the two would be the same array.
|
|
1380
|
+
*/
|
|
1381
|
+
private readonly cubeFaceViewProj = new Float32Array(16);
|
|
1372
1382
|
/**
|
|
1373
1383
|
* One buffer per shadow matrix that outlives a call, and that is not fussiness.
|
|
1374
1384
|
*
|
|
@@ -1401,7 +1411,12 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
1401
1411
|
* the camera's matrix unchanged and multiplies nothing.
|
|
1402
1412
|
*/
|
|
1403
1413
|
private viewProjFor(camera: { readonly viewProjection: ReadonlyMat4 }): ReadonlyMat4 {
|
|
1404
|
-
const scene = this.
|
|
1414
|
+
const scene = this.probePassActive
|
|
1415
|
+
? (cubeFaceProjection(
|
|
1416
|
+
this.cubeFaceViewProj,
|
|
1417
|
+
this.sceneMatrix(camera.viewProjection) as unknown as ArrayLike<number>,
|
|
1418
|
+
) as unknown as ReadonlyMat4)
|
|
1419
|
+
: this.sceneMatrix(camera.viewProjection);
|
|
1405
1420
|
/*
|
|
1406
1421
|
* **The jitter goes on here and nowhere else.** This is the one funnel every geometry upload
|
|
1407
1422
|
* passes through, so one line covers the mesh passes, the sky, the water and the effects
|
|
@@ -1504,6 +1519,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
1504
1519
|
*/
|
|
1505
1520
|
private readonly casterSink: ShadowCasterSink = {
|
|
1506
1521
|
mesh: (mesh, model) => {
|
|
1522
|
+
this.shadowDrawBudget.ask();
|
|
1507
1523
|
const { gl } = this;
|
|
1508
1524
|
gl.uniformMatrix4fv(this.depthUniforms['uModel'] ?? null, false, model);
|
|
1509
1525
|
/*
|
|
@@ -1524,6 +1540,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
1524
1540
|
const gpuBatch = batch as InstancedBatch;
|
|
1525
1541
|
const count = Math.min(data.count, gpuBatch.capacity);
|
|
1526
1542
|
if (count === 0) return;
|
|
1543
|
+
this.shadowDrawBudget.ask();
|
|
1527
1544
|
const u = this.depthInstancedUniforms;
|
|
1528
1545
|
gl.useProgram(this.depthInstancedProgram);
|
|
1529
1546
|
gl.uniformMatrix4fv(u['uLightViewProj'] ?? null, false, this.activeDepthViewProj);
|
|
@@ -1533,6 +1550,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
1533
1550
|
gl.useProgram(this.depthProgram);
|
|
1534
1551
|
},
|
|
1535
1552
|
skinnedMesh: (mesh, model, palette) => {
|
|
1553
|
+
this.shadowDrawBudget.ask();
|
|
1536
1554
|
const { gl } = this;
|
|
1537
1555
|
const u = this.depthSkinnedUniforms;
|
|
1538
1556
|
gl.useProgram(this.depthSkinnedProgram);
|
|
@@ -1555,6 +1573,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
1555
1573
|
},
|
|
1556
1574
|
scatter: (scatter, data, windX, windZ, windGust, timeSeconds, trample = null) => {
|
|
1557
1575
|
if (data.count === 0) return;
|
|
1576
|
+
this.scatterDepthBudget.ask();
|
|
1558
1577
|
const { gl } = this;
|
|
1559
1578
|
const u = this.scatterDepthUniforms;
|
|
1560
1579
|
gl.useProgram(this.scatterDepthProgram);
|
|
@@ -1680,6 +1699,44 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
1680
1699
|
this.occlusion?.addOccluder(min as Float32Array, max as Float32Array, model);
|
|
1681
1700
|
}
|
|
1682
1701
|
|
|
1702
|
+
/**
|
|
1703
|
+
* Declare a baked distance field that indirect light may be traced against.
|
|
1704
|
+
*
|
|
1705
|
+
* **Recorded by nothing on this backend, and that is the refusal rather than an oversight.**
|
|
1706
|
+
* Composing the world's field and marching probes through it is compute, and WebGL2 has no
|
|
1707
|
+
* compute stage — `INDIRECT_LIGHT_WEBGL2_REFUSAL` says so once a frame-loop when
|
|
1708
|
+
* `quality.indirectLight` is on. The method exists here because `RendererApi` is this class's
|
|
1709
|
+
* shape, and a consumer that declares its fields unconditionally must not have to ask which
|
|
1710
|
+
* backend it got: this is a no-op for the same reason `addOccluder` is one when the profile
|
|
1711
|
+
* asked for no occlusion buffer.
|
|
1712
|
+
*
|
|
1713
|
+
* The field is in the model matrix's own space and the matrix must carry uniform scale only.
|
|
1714
|
+
* `composeGlobalField` gives the reason: a distance is not preserved by a non-uniform scale.
|
|
1715
|
+
*/
|
|
1716
|
+
addDistanceField(_field: FieldSource, _model: ReadonlyMat4, _albedo?: ArrayLike<number>): void {
|
|
1717
|
+
/* Deliberately nothing. See the comment above. */
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
/** Forget the fields declared this frame. A no-op here, as `addDistanceField` is. */
|
|
1721
|
+
clearDistanceFields(): void {
|
|
1722
|
+
/* Deliberately nothing. See `addDistanceField`. */
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
/** Never measured here, because nothing is composed. See `addDistanceField`. */
|
|
1726
|
+
get distanceFieldMs(): number | null {
|
|
1727
|
+
return null;
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
/** Never traced here either, so there is no refresh to time. See `addDistanceField`. */
|
|
1731
|
+
get indirectBakeMs(): number | null {
|
|
1732
|
+
return null;
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
/** Nothing to read, for the same reason. A consumer may call it unconditionally. */
|
|
1736
|
+
readDistanceFieldTimings(): void {
|
|
1737
|
+
/* Deliberately nothing. See `addDistanceField`. */
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1683
1740
|
/**
|
|
1684
1741
|
* Whether a mesh is entirely behind the occluders declared this frame.
|
|
1685
1742
|
*
|
|
@@ -1719,7 +1776,14 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
1719
1776
|
registerPass(definition: PassDefinition): PassHandle {
|
|
1720
1777
|
const handle = registerIn(this.passes, definition);
|
|
1721
1778
|
/* Identity: this backend's clip space is the one the projections are built for. */
|
|
1722
|
-
|
|
1779
|
+
/* Both are identity here: this backend runs the GLSL natively, so there is nothing to
|
|
1780
|
+
correct and nothing a generator has flipped. */
|
|
1781
|
+
this.passDevice ??= {
|
|
1782
|
+
backend: 'webgl2',
|
|
1783
|
+
gl: this.gl,
|
|
1784
|
+
clipCorrection: IDENTITY_CLIP,
|
|
1785
|
+
depthCorrection: IDENTITY_CLIP,
|
|
1786
|
+
};
|
|
1723
1787
|
if (definition.prepare !== undefined) this.preparingPasses++;
|
|
1724
1788
|
definition.init?.(this.passDevice);
|
|
1725
1789
|
return handle;
|
|
@@ -2900,6 +2964,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
2900
2964
|
|
|
2901
2965
|
setMaterial(material: SurfaceMaterial | null): void {
|
|
2902
2966
|
if (this.contextLost) return;
|
|
2967
|
+
this.materials.dirty();
|
|
2903
2968
|
this.currentSurfaceTexture = material?.albedo ?? null;
|
|
2904
2969
|
/*
|
|
2905
2970
|
* Written to every flat program, because material state persists across draws and a skinned
|
|
@@ -3072,6 +3137,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3072
3137
|
*/
|
|
3073
3138
|
setSurfaceReflectivity(amount: number): void {
|
|
3074
3139
|
if (this.contextLost) return;
|
|
3140
|
+
this.materials.dirty();
|
|
3075
3141
|
this.useFlatProgram();
|
|
3076
3142
|
this.gl.uniform1f(this.flatUniforms['uReflectivity'] ?? null, Math.min(1, Math.max(0, amount)));
|
|
3077
3143
|
}
|
|
@@ -3090,6 +3156,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3090
3156
|
*/
|
|
3091
3157
|
setEnvironmentGain(gain: number): void {
|
|
3092
3158
|
if (this.contextLost) return;
|
|
3159
|
+
this.materials.dirty();
|
|
3093
3160
|
this.useFlatProgram();
|
|
3094
3161
|
this.gl.uniform1f(this.flatUniforms['uEnvironmentGain'] ?? null, Math.max(0, gain));
|
|
3095
3162
|
}
|
|
@@ -3119,6 +3186,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3119
3186
|
|
|
3120
3187
|
setSurfaceGrain(amount: number): void {
|
|
3121
3188
|
if (this.contextLost) return;
|
|
3189
|
+
this.materials.dirty();
|
|
3122
3190
|
this.useFlatProgram();
|
|
3123
3191
|
this.gl.uniform1f(this.flatUniforms['uGrain'] ?? null, Math.min(1, Math.max(0, amount)));
|
|
3124
3192
|
}
|
|
@@ -3148,6 +3216,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3148
3216
|
*/
|
|
3149
3217
|
setSurfaceRelief(amount: number, cyclesPerMetre = 60): void {
|
|
3150
3218
|
if (this.contextLost) return;
|
|
3219
|
+
this.materials.dirty();
|
|
3151
3220
|
this.useFlatProgram();
|
|
3152
3221
|
const u = this.flatUniforms;
|
|
3153
3222
|
this.gl.uniform1f(u['uRelief'] ?? null, Math.min(1, Math.max(0, amount)));
|
|
@@ -3181,6 +3250,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3181
3250
|
*/
|
|
3182
3251
|
setSurfaceTextureRelief(scale: number): void {
|
|
3183
3252
|
if (this.contextLost) return;
|
|
3253
|
+
this.materials.dirty();
|
|
3184
3254
|
this.useFlatProgram();
|
|
3185
3255
|
this.gl.uniform1f(
|
|
3186
3256
|
this.flatUniforms['uTextureRelief'] ?? null,
|
|
@@ -3211,6 +3281,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3211
3281
|
*/
|
|
3212
3282
|
setEmissiveGain(gain: number): void {
|
|
3213
3283
|
if (this.contextLost) return;
|
|
3284
|
+
this.materials.dirty();
|
|
3214
3285
|
this.useFlatProgram();
|
|
3215
3286
|
this.gl.uniform1f(this.flatUniforms['uEmissiveGain'] ?? null, gain);
|
|
3216
3287
|
}
|
|
@@ -3338,6 +3409,10 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3338
3409
|
const lit = options.lit ?? true;
|
|
3339
3410
|
const fog = options.fog ?? true;
|
|
3340
3411
|
const toneMapped = options.toneMapped ?? true;
|
|
3412
|
+
/* An instanced draw does not refract. See `materialChanges.ts`. */
|
|
3413
|
+
const own = ownsMaterial({ opacity, lit, fog, toneMapped, refracting: false });
|
|
3414
|
+
if (own) this.materials.dirty();
|
|
3415
|
+
this.takeMaterial();
|
|
3341
3416
|
const depthWrite = options.depthWrite ?? true;
|
|
3342
3417
|
const layer = Math.min(Math.max(Math.round(options.depthLayer ?? 0), 0), MAX_DEPTH_LAYER);
|
|
3343
3418
|
|
|
@@ -3409,6 +3484,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3409
3484
|
if (!lit) gl.uniform1i(u['uLightingEnabled'] ?? null, 1);
|
|
3410
3485
|
if (!fog) gl.uniform1i(u['uFogEnabled'] ?? null, 1);
|
|
3411
3486
|
if (!toneMapped) gl.uniform1i(u['uOutputTransform'] ?? null, this.gradeCode());
|
|
3487
|
+
if (own) this.materials.dirty();
|
|
3412
3488
|
this.useFlatProgram();
|
|
3413
3489
|
}
|
|
3414
3490
|
|
|
@@ -3517,7 +3593,9 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3517
3593
|
// raining dust into the sea.
|
|
3518
3594
|
const surface = env.underwater?.surfaceY;
|
|
3519
3595
|
const submerged = surface !== undefined && (camera.position[1] ?? 0) < surface;
|
|
3520
|
-
streaks.draw(this.gl, this.frameViewFor(camera), wind, timeSeconds, tint, submerged)
|
|
3596
|
+
if (streaks.draw(this.gl, this.frameViewFor(camera), wind, timeSeconds, tint, submerged)) {
|
|
3597
|
+
this.windStreakBudget.ask();
|
|
3598
|
+
}
|
|
3521
3599
|
}
|
|
3522
3600
|
|
|
3523
3601
|
/**
|
|
@@ -3554,7 +3632,9 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3554
3632
|
style: TextStyle,
|
|
3555
3633
|
timeSec: number,
|
|
3556
3634
|
): void {
|
|
3557
|
-
text.draw(viewportWidth, viewportHeight, originX, originY, style, timeSec)
|
|
3635
|
+
if (text.draw(viewportWidth, viewportHeight, originX, originY, style, timeSec)) {
|
|
3636
|
+
this.textBudget.ask();
|
|
3637
|
+
}
|
|
3558
3638
|
}
|
|
3559
3639
|
|
|
3560
3640
|
/** Width of the string this handle currently holds, in pixels at a given cell size. */
|
|
@@ -3649,6 +3729,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3649
3729
|
this.gradeExposure(),
|
|
3650
3730
|
)
|
|
3651
3731
|
) {
|
|
3732
|
+
this.sdfTextBudget.ask();
|
|
3652
3733
|
this.restoreSurfaceTextureUnit();
|
|
3653
3734
|
}
|
|
3654
3735
|
}
|
|
@@ -3671,6 +3752,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3671
3752
|
windX = 0,
|
|
3672
3753
|
windZ = 0,
|
|
3673
3754
|
): void {
|
|
3755
|
+
this.flockBudget.ask();
|
|
3674
3756
|
flock.draw(this.gl, this.frameViewFor(camera), timeSeconds, params, tint, windX, windZ);
|
|
3675
3757
|
}
|
|
3676
3758
|
|
|
@@ -3794,8 +3876,10 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3794
3876
|
if (data.count === 0) return;
|
|
3795
3877
|
const { gl } = this;
|
|
3796
3878
|
const u = batch.uniforms;
|
|
3797
|
-
gl.useProgram(batch.program);
|
|
3798
3879
|
const count = batch.upload(gl, data);
|
|
3880
|
+
if (count === 0) return;
|
|
3881
|
+
this.boltBudget.ask();
|
|
3882
|
+
gl.useProgram(batch.program);
|
|
3799
3883
|
gl.uniformMatrix4fv(u['uViewProj'] ?? null, false, this.viewProjFor(camera));
|
|
3800
3884
|
gl.uniform3fv(u['uCameraPos'] ?? null, camera.position);
|
|
3801
3885
|
gl.uniform1f(u['uTime'] ?? null, timeSeconds);
|
|
@@ -3866,8 +3950,10 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
3866
3950
|
if (data.count === 0) return;
|
|
3867
3951
|
const { gl } = this;
|
|
3868
3952
|
const u = lines.uniforms;
|
|
3869
|
-
gl.useProgram(lines.program);
|
|
3870
3953
|
const count = lines.upload(gl, data);
|
|
3954
|
+
if (count === 0) return;
|
|
3955
|
+
this.lineBudget.ask();
|
|
3956
|
+
gl.useProgram(lines.program);
|
|
3871
3957
|
gl.uniformMatrix4fv(u['uViewProj'] ?? null, false, this.viewProjFor(camera));
|
|
3872
3958
|
gl.uniformMatrix4fv(u['uModel'] ?? null, false, model);
|
|
3873
3959
|
gl.uniform3fv(u['uCameraPos'] ?? null, camera.position);
|
|
@@ -4124,6 +4210,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
4124
4210
|
windZ = 0,
|
|
4125
4211
|
): void {
|
|
4126
4212
|
if (!this.quality.water) return;
|
|
4213
|
+
this.waterBudget.ask();
|
|
4127
4214
|
water.draw(
|
|
4128
4215
|
this.gl,
|
|
4129
4216
|
this.frameViewFor(camera),
|
|
@@ -4156,7 +4243,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
4156
4243
|
strength = 1,
|
|
4157
4244
|
): void {
|
|
4158
4245
|
if (caustics === null || !this.quality.water) return;
|
|
4159
|
-
caustics.draw(
|
|
4246
|
+
const drew = caustics.draw(
|
|
4160
4247
|
this.gl,
|
|
4161
4248
|
this.frameViewFor(camera),
|
|
4162
4249
|
timeSeconds,
|
|
@@ -4169,6 +4256,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
4169
4256
|
windZ,
|
|
4170
4257
|
strength,
|
|
4171
4258
|
);
|
|
4259
|
+
if (drew) this.causticsBudget.ask();
|
|
4172
4260
|
}
|
|
4173
4261
|
|
|
4174
4262
|
/**
|
|
@@ -4234,6 +4322,23 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
4234
4322
|
return this.canvas.width / Math.max(this.canvas.height, 1);
|
|
4235
4323
|
}
|
|
4236
4324
|
|
|
4325
|
+
/**
|
|
4326
|
+
* The size the world is drawn at, which on this backend is always the drawing buffer.
|
|
4327
|
+
*
|
|
4328
|
+
* **Here so that a contributed pass has one question to ask on both backends.** WebGPU can draw
|
|
4329
|
+
* the world smaller than the canvas and let its composite enlarge it — `quality.reconstruction`
|
|
4330
|
+
* — and a pass filling a target of its own has to follow that size or draw a picture the frame
|
|
4331
|
+
* pass clips. This backend has no compute stage and no reconstruction, so the answer never moves;
|
|
4332
|
+
* a pass that reads it is correct on both, and one that reads `canvas.width` is correct on one.
|
|
4333
|
+
*/
|
|
4334
|
+
get sceneWidth(): number {
|
|
4335
|
+
return Math.max(1, this.canvas.width);
|
|
4336
|
+
}
|
|
4337
|
+
|
|
4338
|
+
get sceneHeight(): number {
|
|
4339
|
+
return Math.max(1, this.canvas.height);
|
|
4340
|
+
}
|
|
4341
|
+
|
|
4237
4342
|
/**
|
|
4238
4343
|
* Point rendering back at the frame's own target, whole.
|
|
4239
4344
|
*
|
|
@@ -5212,6 +5317,9 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
5212
5317
|
*/
|
|
5213
5318
|
fillPanel(rect: InsetRect, color: Vec3, alpha: number): void {
|
|
5214
5319
|
if (alpha <= 0 || rect.width <= 0 || rect.height <= 0) return;
|
|
5320
|
+
/* Counted against no ceiling: the other backend refuses past its own, and a consumer here
|
|
5321
|
+
should be able to see that coming. See `budget.ts`. */
|
|
5322
|
+
this.panelBudget.ask();
|
|
5215
5323
|
const { gl } = this;
|
|
5216
5324
|
|
|
5217
5325
|
gl.useProgram(this.panelProgram);
|
|
@@ -5508,6 +5616,25 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
5508
5616
|
*/
|
|
5509
5617
|
private readonly budget = new FrameBudget();
|
|
5510
5618
|
private readonly drawBudget = this.budget.line('draws', null);
|
|
5619
|
+
/**
|
|
5620
|
+
* Every line the other backend declares, in its order and with none of its ceilings.
|
|
5621
|
+
*
|
|
5622
|
+
* **Counted after the same guards**, so one scene reports one number on both: the verbs each
|
|
5623
|
+
* ask once they are past the checks that make them draw nothing on either backend — a panel
|
|
5624
|
+
* with no alpha, a string with no glyphs, a beam with no strength, a calm wind — and a material
|
|
5625
|
+
* change is counted by the rule both share (`materialChanges.ts`). `webgpu/renderer.test.ts`
|
|
5626
|
+
* runs one scene through both and compares every line.
|
|
5627
|
+
*/
|
|
5628
|
+
private readonly materialBudget = this.budget.line('materials', null);
|
|
5629
|
+
/** Whether the next mesh draw shares the open material or opens one, by the rule both count. */
|
|
5630
|
+
private readonly materials = new MaterialChanges();
|
|
5631
|
+
|
|
5632
|
+
/** A mesh draw: counted as a material change when something has changed the material since. */
|
|
5633
|
+
private takeMaterial(): void {
|
|
5634
|
+
if (this.materials.open) return;
|
|
5635
|
+
this.materialBudget.ask();
|
|
5636
|
+
this.materials.slot = 0;
|
|
5637
|
+
}
|
|
5511
5638
|
/**
|
|
5512
5639
|
* Declared here and never asked, because this backend builds none.
|
|
5513
5640
|
*
|
|
@@ -5519,6 +5646,19 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
5519
5646
|
* being compared against should also be zero once the other backend's cache is warm.
|
|
5520
5647
|
*/
|
|
5521
5648
|
private readonly bindGroupBudget = this.budget.line('bind groups', null);
|
|
5649
|
+
private readonly shadowDrawBudget = this.budget.line('shadow draws', null);
|
|
5650
|
+
private readonly scatterDepthBudget = this.budget.line('scatter shadow draws', null);
|
|
5651
|
+
private readonly waterBudget = this.budget.line('water bodies', null);
|
|
5652
|
+
private readonly lightVolumeBudget = this.budget.line('light volumes', null);
|
|
5653
|
+
private readonly windStreakBudget = this.budget.line('wind streak fields', null);
|
|
5654
|
+
private readonly flockBudget = this.budget.line('flocks', null);
|
|
5655
|
+
private readonly boltBudget = this.budget.line('bolt batches', null);
|
|
5656
|
+
private readonly causticsBudget = this.budget.line('caustics', null);
|
|
5657
|
+
private readonly textBudget = this.budget.line('text draws', null);
|
|
5658
|
+
private readonly sdfTextBudget = this.budget.line('sdf text draws', null);
|
|
5659
|
+
private readonly lineBudget = this.budget.line('line draws', null);
|
|
5660
|
+
/** The other backend's panel ceiling, reported here as a count with none. */
|
|
5661
|
+
private readonly panelBudget = this.budget.line('panels', null);
|
|
5522
5662
|
|
|
5523
5663
|
/** What the frame just drawn asked for. See `budget.ts`, and the note on `budget` above. */
|
|
5524
5664
|
get frameBudget(): FrameBudget {
|
|
@@ -5617,6 +5757,9 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
5617
5757
|
* from one `RenderQuality` — see `OIT_MULTISAMPLE_REFUSAL` for why it is a constant and not two
|
|
5618
5758
|
* literals kept in step by hand.
|
|
5619
5759
|
*/
|
|
5760
|
+
/** Said once rather than every frame, as the translucent set's own refusal is. */
|
|
5761
|
+
private indirectLightRefused = false;
|
|
5762
|
+
|
|
5620
5763
|
private refuseOitMultisampled(): void {
|
|
5621
5764
|
if (this.oitMultisampleRefused) return;
|
|
5622
5765
|
this.oitMultisampleRefused = true;
|
|
@@ -5626,6 +5769,15 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
5626
5769
|
beginFrame(clearColor: Vec3): void {
|
|
5627
5770
|
if (this.contextLost) return;
|
|
5628
5771
|
this.budget.reset();
|
|
5772
|
+
this.materials.dirty();
|
|
5773
|
+
/*
|
|
5774
|
+
* Said once, for the reason `refuseOitMultisampled` gives: a quality setting that is enabled
|
|
5775
|
+
* and does nothing is the fault the capability clamp exists to prevent.
|
|
5776
|
+
*/
|
|
5777
|
+
if (this.quality.indirectLight && !this.indirectLightRefused) {
|
|
5778
|
+
this.indirectLightRefused = true;
|
|
5779
|
+
console.warn(INDIRECT_LIGHT_WEBGL2_REFUSAL);
|
|
5780
|
+
}
|
|
5629
5781
|
|
|
5630
5782
|
const { gl } = this;
|
|
5631
5783
|
this.reflectionReadyThisFrame = false;
|
|
@@ -5908,6 +6060,15 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
5908
6060
|
) {
|
|
5909
6061
|
const flat = this.flatUniforms;
|
|
5910
6062
|
const options = this.oitReplayOptions;
|
|
6063
|
+
/*
|
|
6064
|
+
* **The copy a refracting pane reads is taken here, before the buffers are bound.** Taking
|
|
6065
|
+
* it puts the scene's framebuffer back as the one drawn into, so taken inside the replay —
|
|
6066
|
+
* at the first pane that refracts, which is where it was taken until 2026-09-19 — it sent
|
|
6067
|
+
* that pane into the scene instead of the accumulation, and every refracting pane came out
|
|
6068
|
+
* flat paint with the effect on. The opaque frame is finished here, which is what a pane
|
|
6069
|
+
* should show; the latch then serves every pane in the replay. Only when something refracts.
|
|
6070
|
+
*/
|
|
6071
|
+
if (this.translucentQueue.refracts) this.sceneTarget?.snapshotColor();
|
|
5911
6072
|
this.oit.accumulateOit(this.canvas.width, this.canvas.height, oitDepth, (weighted) => {
|
|
5912
6073
|
this.oitReplaying = true;
|
|
5913
6074
|
this.useFlatProgram();
|
|
@@ -6106,6 +6267,8 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
6106
6267
|
|
|
6107
6268
|
/** Bind the flat pass once per frame; then issue any number of drawMesh calls. */
|
|
6108
6269
|
bindMeshPass(camera: Camera, env: Environment): void {
|
|
6270
|
+
/* The pass's own material is reopened, so the next draw opens one. See `materialChanges.ts`. */
|
|
6271
|
+
this.materials.dirty();
|
|
6109
6272
|
/*
|
|
6110
6273
|
* Captured here rather than taken as an argument to `endFrame`, because this is the
|
|
6111
6274
|
* camera the world was drawn with and a caller should not have to hand it over twice.
|
|
@@ -6451,6 +6614,8 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
6451
6614
|
* are two numbers now.
|
|
6452
6615
|
*/
|
|
6453
6616
|
gl.uniform1f(u['uEnvironmentEdge'] ?? null, array?.edge ?? 1);
|
|
6617
|
+
/* Never on this backend: what fills a visibility map is a compute dispatch. See `probeGrid.ts`. */
|
|
6618
|
+
gl.uniform1f(u['uProbeVisibilityEnabled'] ?? null, 0);
|
|
6454
6619
|
gl.uniform1f(u['uEnvironmentIrradianceLevel'] ?? null, array?.irradianceLevel ?? 0);
|
|
6455
6620
|
/*
|
|
6456
6621
|
* Where the probes stand: four uniforms whatever the probe count, because this shader is
|
|
@@ -6589,6 +6754,14 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
6589
6754
|
* passes one cannot leak it into the next draw.
|
|
6590
6755
|
*/
|
|
6591
6756
|
tint: Vec3 | null = null,
|
|
6757
|
+
/**
|
|
6758
|
+
* Where the mesh was last frame, which this backend takes and ignores.
|
|
6759
|
+
*
|
|
6760
|
+
* Accepted rather than absent so that one scene draws through both renderers unchanged — the
|
|
6761
|
+
* parity rule this repository is built on. Reconstruction is WebGPU's, having no compute stage
|
|
6762
|
+
* here, so there is no motion target for this to be written into.
|
|
6763
|
+
*/
|
|
6764
|
+
_previousModel: ReadonlyMat4 | null = null,
|
|
6592
6765
|
): void {
|
|
6593
6766
|
if (this.contextLost) return;
|
|
6594
6767
|
/* Geometry that has not all arrived is not drawn. See `Mesh.complete`. */
|
|
@@ -6613,6 +6786,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
6613
6786
|
*/
|
|
6614
6787
|
if (this.quality.cullDraws && this.occluded(mesh.bounds, model)) return;
|
|
6615
6788
|
this.drawBudget.ask();
|
|
6789
|
+
this.takeMaterial();
|
|
6616
6790
|
const { gl } = this;
|
|
6617
6791
|
/*
|
|
6618
6792
|
* A rigged mesh takes the skinned program, an unrigged one the plain program.
|
|
@@ -6777,7 +6951,6 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
6777
6951
|
if (!mesh.complete) return;
|
|
6778
6952
|
|
|
6779
6953
|
if (opacity <= 0) return;
|
|
6780
|
-
this.drawBudget.ask();
|
|
6781
6954
|
|
|
6782
6955
|
/*
|
|
6783
6956
|
* **Recorded rather than drawn**, when the effect is on and this is not already the replay.
|
|
@@ -6788,6 +6961,9 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
6788
6961
|
this.translucentQueue.record(mesh, model, opacity, options);
|
|
6789
6962
|
return;
|
|
6790
6963
|
}
|
|
6964
|
+
/* Counted where it is submitted, as the other backend counts it: once per replay pass under
|
|
6965
|
+
order-independent transparency, and not once more when it was recorded. */
|
|
6966
|
+
this.drawBudget.ask();
|
|
6791
6967
|
|
|
6792
6968
|
const { gl } = this;
|
|
6793
6969
|
const u = this.flatUniforms;
|
|
@@ -6845,6 +7021,11 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
6845
7021
|
* or a multiplicative blend for the whole set and turned depth writes off for all of it. A
|
|
6846
7022
|
* replayed draw that reset either would break the pass around it.
|
|
6847
7023
|
*/
|
|
7024
|
+
/* Taken for itself when any option differs from the pass, and put back below: the rule both
|
|
7025
|
+
backends count material changes by. See `materialChanges.ts`. */
|
|
7026
|
+
const own = ownsMaterial({ opacity, lit, fog, toneMapped, refracting });
|
|
7027
|
+
if (own) this.materials.dirty();
|
|
7028
|
+
this.takeMaterial();
|
|
6848
7029
|
const ownsState = !this.oitReplaying;
|
|
6849
7030
|
if (ownsState) {
|
|
6850
7031
|
gl.enable(gl.BLEND);
|
|
@@ -6879,6 +7060,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
6879
7060
|
if (!lit) gl.uniform1i(u['uLightingEnabled'] ?? null, 1);
|
|
6880
7061
|
if (!fog) gl.uniform1i(u['uFogEnabled'] ?? null, 1);
|
|
6881
7062
|
if (!toneMapped) gl.uniform1i(u['uOutputTransform'] ?? null, this.gradeCode());
|
|
7063
|
+
if (own) this.materials.dirty();
|
|
6882
7064
|
}
|
|
6883
7065
|
|
|
6884
7066
|
/**
|
|
@@ -6991,6 +7173,23 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
6991
7173
|
this.useFlatProgram();
|
|
6992
7174
|
this.gl.uniform1i(this.flatUniforms['uOutputTransform'] ?? null, 0);
|
|
6993
7175
|
this.gl.uniform1f(this.flatUniforms['uOutputExposure'] ?? null, 1);
|
|
7176
|
+
this.materials.dirty();
|
|
7177
|
+
/*
|
|
7178
|
+
* **Clockwise for the duration, because a face is rendered mirrored.** `cubeFaceProjection`
|
|
7179
|
+
* negates clip y so the face is stored the way a cubemap reads it, and negating one axis
|
|
7180
|
+
* reverses every triangle's winding: without this the room is culled inside out and the cube
|
|
7181
|
+
* holds its own back faces.
|
|
7182
|
+
*
|
|
7183
|
+
* **A perturbation survives this line and it is kept anyway**, which is worth the sentence.
|
|
7184
|
+
* Deleting it moves `ibl-check.mjs`'s figures — 12.5 to 13.1 of 255 on the movement check and
|
|
7185
|
+
* 182.0 to 184.9 on the mirror rung — so it is not dead; but no check *fails*, because every
|
|
7186
|
+
* room this repository bakes into a probe is made of closed boxes whose two sides carry the
|
|
7187
|
+
* same colour, and looking at the far one's outside instead of the near one's inside draws
|
|
7188
|
+
* almost the same picture. What it actually decides is a scene with **one-sided** geometry: a
|
|
7189
|
+
* room built from single quads facing inward disappears from its own probe without it, and
|
|
7190
|
+
* there is no such scene here to fail on.
|
|
7191
|
+
*/
|
|
7192
|
+
this.gl.frontFace(this.gl.CW);
|
|
6994
7193
|
let baked = false;
|
|
6995
7194
|
try {
|
|
6996
7195
|
baked = probe.bake(this.gl, this.probeOrigin, clearColor, drawFace);
|
|
@@ -7011,9 +7210,11 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
7011
7210
|
);
|
|
7012
7211
|
}
|
|
7013
7212
|
} finally {
|
|
7213
|
+
this.gl.frontFace(this.gl.CCW);
|
|
7014
7214
|
this.useFlatProgram();
|
|
7015
7215
|
this.gl.uniform1i(this.flatUniforms['uOutputTransform'] ?? null, this.gradeCode());
|
|
7016
7216
|
this.gl.uniform1f(this.flatUniforms['uOutputExposure'] ?? null, this.gradeExposure());
|
|
7217
|
+
this.materials.dirty();
|
|
7017
7218
|
/*
|
|
7018
7219
|
* Cleared even if a caller's own draw threw, because leaving this set would keep every
|
|
7019
7220
|
* later frame reading the placeholder and quietly reflecting nothing.
|
|
@@ -7180,6 +7381,7 @@ export class WebGL2Renderer implements RendererApi {
|
|
|
7180
7381
|
/* At zero it draws nothing rather than adding black — which now also covers a clear night,
|
|
7181
7382
|
where the beam has no medium to be seen in and skipping it is the whole saving. */
|
|
7182
7383
|
if (shown <= 0) return;
|
|
7384
|
+
this.lightVolumeBudget.ask();
|
|
7183
7385
|
const { gl } = this;
|
|
7184
7386
|
const u = this.lightVolumeUniforms;
|
|
7185
7387
|
gl.useProgram(this.lightVolumeProgram);
|