@driftengine/core 4.4.2 → 4.6.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 +97 -0
- package/README.md +1 -1
- package/dist/geometry/boxCsg.d.ts +28 -0
- package/dist/geometry/boxCsg.js +139 -0
- package/dist/geometry/csg.d.ts +36 -0
- package/dist/geometry/csg.js +329 -0
- package/dist/geometry/meshBuilder.js +13 -0
- package/dist/geometry/meshConcat.js +1 -0
- package/dist/geometry/pixelFont.js +2 -0
- package/dist/geometry/solid.d.ts +61 -0
- package/dist/geometry/solid.js +152 -0
- package/dist/geometry/solidFlat.d.ts +35 -0
- package/dist/geometry/solidFlat.js +428 -0
- package/dist/geometry/solidHarness.d.ts +19 -0
- package/dist/geometry/solidHarness.js +66 -0
- package/dist/geometry/solidNormals.d.ts +17 -0
- package/dist/geometry/solidNormals.js +86 -0
- package/dist/geometry/solidRound.d.ts +41 -0
- package/dist/geometry/solidRound.js +323 -0
- package/dist/geometry/solidWriter.d.ts +16 -0
- package/dist/geometry/solidWriter.js +42 -0
- package/dist/index.d.ts +28 -3
- package/dist/index.js +20 -1
- package/dist/render/backend/api.d.ts +34 -14
- package/dist/render/backend/drawFog.d.ts +26 -0
- package/dist/render/backend/drawFog.js +30 -0
- package/dist/render/backend/materialChanges.d.ts +2 -1
- package/dist/render/backend/materialChanges.js +6 -1
- package/dist/render/backend/webgl2/glassTintPrograms.d.ts +13 -0
- package/dist/render/backend/webgl2/glassTintPrograms.js +38 -0
- package/dist/render/backend/webgl2/instanced.d.ts +24 -5
- package/dist/render/backend/webgl2/instanced.js +72 -15
- package/dist/render/backend/webgl2/renderer.d.ts +201 -16
- package/dist/render/backend/webgl2/renderer.js +596 -224
- package/dist/render/backend/webgpu/buffers.d.ts +29 -1
- package/dist/render/backend/webgpu/buffers.js +61 -4
- package/dist/render/backend/webgpu/depthPass.d.ts +1 -1
- package/dist/render/backend/webgpu/depthPass.js +7 -2
- package/dist/render/backend/webgpu/drawCommand.d.ts +5 -0
- package/dist/render/backend/webgpu/drawCommand.js +1 -0
- package/dist/render/backend/webgpu/flatPass.d.ts +6 -1
- package/dist/render/backend/webgpu/flatPass.js +57 -9
- package/dist/render/backend/webgpu/glassTintPass.d.ts +28 -0
- package/dist/render/backend/webgpu/glassTintPass.js +206 -0
- package/dist/render/backend/webgpu/gpuDrivenPass.d.ts +60 -1
- package/dist/render/backend/webgpu/gpuDrivenPass.js +305 -5
- package/dist/render/backend/webgpu/instanceCullPass.d.ts +34 -0
- package/dist/render/backend/webgpu/instanceCullPass.js +144 -0
- package/dist/render/backend/webgpu/instanced.d.ts +23 -2
- package/dist/render/backend/webgpu/instanced.js +41 -4
- package/dist/render/backend/webgpu/latePass.d.ts +30 -0
- package/dist/render/backend/webgpu/latePass.js +140 -0
- package/dist/render/backend/webgpu/lightVolumePass.js +5 -1
- package/dist/render/backend/webgpu/motionPass.d.ts +95 -0
- package/dist/render/backend/webgpu/motionPass.js +491 -0
- package/dist/render/backend/webgpu/pipelineCache.d.ts +10 -1
- package/dist/render/backend/webgpu/pipelineCache.js +11 -1
- package/dist/render/backend/webgpu/pointGlassTintPass.d.ts +32 -0
- package/dist/render/backend/webgpu/pointGlassTintPass.js +193 -0
- package/dist/render/backend/webgpu/pointShadowPass.d.ts +35 -6
- package/dist/render/backend/webgpu/pointShadowPass.js +105 -20
- package/dist/render/backend/webgpu/postPass.d.ts +3 -13
- package/dist/render/backend/webgpu/renderer.d.ts +271 -64
- package/dist/render/backend/webgpu/renderer.js +1395 -580
- package/dist/render/backend/webgpu/scatterPass.js +2 -1
- package/dist/render/backend/webgpu/sdfTextPass.js +6 -1
- package/dist/render/backend/webgpu/shaders/instanceCull.wgsl.d.ts +18 -0
- package/dist/render/backend/webgpu/shaders/instanceCull.wgsl.js +59 -0
- package/dist/render/backend/webgpu/skinPaletteRing.d.ts +4 -0
- package/dist/render/backend/webgpu/skinPaletteRing.js +4 -0
- package/dist/render/backend/webgpu/snapshotMips.d.ts +29 -0
- package/dist/render/backend/webgpu/snapshotMips.js +52 -0
- package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +22 -3
- package/dist/render/backend/webgpu/surfaceTexturePass.js +78 -39
- package/dist/render/driftLight/bake.d.ts +7 -0
- package/dist/render/driftLight/bake.js +61 -56
- package/dist/render/driftLight/denseField.d.ts +46 -0
- package/dist/render/driftLight/denseField.js +109 -0
- package/dist/render/driftLight/lightField.d.ts +10 -5
- package/dist/render/driftLight/lightField.js +25 -19
- package/dist/render/driftLight/presence.d.ts +50 -0
- package/dist/render/driftLight/presence.js +43 -0
- package/dist/render/driftLight/uniforms.d.ts +3 -3
- package/dist/render/driftLight/uniforms.js +5 -6
- package/dist/render/driftLight/worldLightField.d.ts +41 -0
- package/dist/render/driftLight/worldLightField.js +66 -0
- package/dist/render/fixtureAtlas.d.ts +20 -0
- package/dist/render/fixtureAtlas.js +49 -0
- package/dist/render/glass.d.ts +45 -0
- package/dist/render/glass.js +39 -0
- package/dist/render/glassCasters.d.ts +40 -0
- package/dist/render/glassCasters.js +84 -0
- package/dist/render/glassShadow.d.ts +78 -0
- package/dist/render/glassShadow.js +125 -0
- package/dist/render/globalMediumPass.d.ts +2 -3
- package/dist/render/globalMediumPass.js +2 -8
- package/dist/render/gpudriven/lit.d.ts +12 -0
- package/dist/render/gpudriven/lit.js +23 -0
- package/dist/render/gpudriven/materialTable.d.ts +15 -5
- package/dist/render/gpudriven/materialTable.js +26 -6
- package/dist/render/gpudriven/pipeline.d.ts +1 -1
- package/dist/render/gpudriven/pipeline.js +4 -3
- package/dist/render/gpudriven/sunGlass.d.ts +35 -0
- package/dist/render/gpudriven/sunGlass.js +89 -0
- package/dist/render/instanceCull.d.ts +63 -0
- package/dist/render/instanceCull.js +160 -0
- package/dist/render/instances.d.ts +15 -0
- package/dist/render/lightBudget.d.ts +36 -35
- package/dist/render/lightBudget.js +38 -37
- package/dist/render/lightGrid.d.ts +42 -0
- package/dist/render/lightGrid.js +87 -0
- package/dist/render/mesh.d.ts +18 -24
- package/dist/render/mesh.js +51 -68
- package/dist/render/occlusion.d.ts +10 -0
- package/dist/render/occlusion.js +36 -7
- package/dist/render/pointGlassTint.d.ts +59 -0
- package/dist/render/pointGlassTint.js +198 -0
- package/dist/render/pointLightSelection.d.ts +7 -0
- package/dist/render/pointLightSelection.js +29 -4
- package/dist/render/pointShadowArray.d.ts +56 -3
- package/dist/render/pointShadowArray.js +127 -16
- package/dist/render/pointShadowMap.d.ts +23 -1
- package/dist/render/pointShadowMap.js +27 -1
- package/dist/render/rainField.d.ts +13 -0
- package/dist/render/rainField.js +27 -5
- package/dist/render/recon/changeFrames.d.ts +15 -0
- package/dist/render/recon/changeFrames.js +21 -0
- package/dist/render/recon/lateDepth.d.ts +11 -0
- package/dist/render/recon/lateDepth.js +70 -0
- package/dist/render/recon/lateRouting.d.ts +14 -0
- package/dist/render/recon/lateRouting.js +18 -0
- package/dist/render/recon/mover.d.ts +57 -0
- package/dist/render/recon/mover.js +86 -0
- package/dist/render/recon/resolve.d.ts +34 -4
- package/dist/render/recon/resolve.js +161 -20
- package/dist/render/renderQuality.d.ts +35 -0
- package/dist/render/renderQuality.js +7 -0
- package/dist/render/rendererHarness.js +16 -0
- package/dist/render/sceneTarget.d.ts +9 -1
- package/dist/render/sceneTarget.js +60 -12
- package/dist/render/shaders/depth.d.ts +16 -1
- package/dist/render/shaders/depth.js +94 -15
- package/dist/render/shaders/flat/directionalShadow.js +91 -6
- package/dist/render/shaders/flat/driftLight.d.ts +1 -1
- package/dist/render/shaders/flat/driftLight.js +32 -7
- package/dist/render/shaders/flat/glassTint.d.ts +6 -0
- package/dist/render/shaders/flat/glassTint.js +25 -0
- package/dist/render/shaders/flat/index.d.ts +13 -0
- package/dist/render/shaders/flat/index.js +9 -3
- package/dist/render/shaders/flat/lampGlass.d.ts +1 -0
- package/dist/render/shaders/flat/lampGlass.js +183 -0
- package/dist/render/shaders/flat/main.d.ts +1 -1
- package/dist/render/shaders/flat/main.js +190 -38
- package/dist/render/shaders/flat/pointShadow.d.ts +1 -1
- package/dist/render/shaders/flat/pointShadow.js +2 -0
- package/dist/render/shaders/flat/preamble.js +96 -26
- package/dist/render/shaders/flat/surfaceEffects.d.ts +29 -0
- package/dist/render/shaders/flat/surfaceEffects.js +152 -0
- package/dist/render/shaders/generated/depth.wgsl.d.ts +230 -7
- package/dist/render/shaders/generated/depth.wgsl.js +230 -7
- package/dist/render/shaders/generated/flat.wgsl.d.ts +1644 -1596
- package/dist/render/shaders/generated/flat.wgsl.js +1683 -1621
- package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +3 -13
- package/dist/render/shaders/generated/globalMedium.wgsl.js +3 -13
- package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +3 -13
- package/dist/render/shaders/generated/lightVolume.wgsl.js +21 -17
- package/dist/render/shaders/generated/octahedralResolve.wgsl.d.ts +29 -0
- package/dist/render/shaders/generated/octahedralResolve.wgsl.js +29 -0
- package/dist/render/shaders/generated/rush.wgsl.d.ts +21 -16
- package/dist/render/shaders/generated/rush.wgsl.js +21 -16
- package/dist/render/shaders/generated/sdfText.wgsl.d.ts +2 -2
- package/dist/render/shaders/generated/sdfText.wgsl.js +2 -2
- package/dist/render/shaders/generated/text.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/text.wgsl.js +1 -1
- package/dist/render/shaders/gi/driftLight.wgsl.d.ts +1 -1
- package/dist/render/shaders/gi/driftLight.wgsl.js +27 -4
- package/dist/render/shaders/globalMedium.js +6 -6
- package/dist/render/shaders/gpudriven/blendRaster.wgsl.d.ts +7 -0
- package/dist/render/shaders/gpudriven/blendRaster.wgsl.js +86 -1
- package/dist/render/shaders/gpudriven/cull.wgsl.d.ts +1 -1
- package/dist/render/shaders/gpudriven/cull.wgsl.js +11 -2
- package/dist/render/shaders/gpudriven/materialTable.wgsl.d.ts +1 -1
- package/dist/render/shaders/gpudriven/materialTable.wgsl.js +3 -1
- package/dist/render/shaders/gpudriven/shade.wgsl.js +50 -1
- package/dist/render/shaders/gpudriven/sunGlass.wgsl.d.ts +9 -0
- package/dist/render/shaders/gpudriven/sunGlass.wgsl.js +133 -0
- package/dist/render/shaders/lightVolume.js +6 -6
- package/dist/render/shaders/octahedralResolve.d.ts +8 -0
- package/dist/render/shaders/octahedralResolve.js +48 -17
- package/dist/render/shaders/recon/lateDepth.wgsl.d.ts +1 -0
- package/dist/render/shaders/recon/lateDepth.wgsl.js +69 -0
- package/dist/render/shaders/recon/motion.wgsl.d.ts +1 -1
- package/dist/render/shaders/recon/motion.wgsl.js +84 -0
- package/dist/render/shaders/recon/resolve.wgsl.d.ts +8 -7
- package/dist/render/shaders/recon/resolve.wgsl.js +161 -27
- package/dist/render/shaders/rush.js +11 -1
- package/dist/render/shaders/sdfText.d.ts +1 -1
- package/dist/render/shaders/sdfText.js +3 -2
- package/dist/render/shaders/text.d.ts +1 -1
- package/dist/render/shaders/text.js +18 -9
- package/dist/render/shadowCasters.d.ts +20 -1
- package/dist/render/shadowCasters.js +15 -1
- package/dist/render/shadowMap.d.ts +54 -5
- package/dist/render/shadowMap.js +190 -36
- package/dist/render/sunGlassTint.d.ts +25 -0
- package/dist/render/sunGlassTint.js +79 -0
- package/dist/render/surfaceEffects.d.ts +83 -0
- package/dist/render/surfaceEffects.js +75 -0
- package/dist/render/surfaceScene.d.ts +8 -0
- package/dist/render/surfaceScene.js +8 -0
- package/dist/render/surfaceTexture.d.ts +18 -2
- package/dist/render/surfaceTexture.js +68 -15
- package/dist/render/temporalAa.d.ts +25 -6
- package/dist/render/temporalAa.js +45 -15
- package/dist/render/textureSource.d.ts +30 -0
- package/dist/render/textureSource.js +53 -0
- package/dist/render/translucentQueue.d.ts +6 -0
- package/dist/render/translucentQueue.js +15 -1
- package/dist/render/vertexDefaults.js +2 -0
- package/dist/world/hlod.d.ts +104 -0
- package/dist/world/hlod.js +214 -0
- package/package.json +6 -6
- package/src/geometry/boxCsg.ts +186 -0
- package/src/geometry/csg.ts +384 -0
- package/src/geometry/meshBuilder.ts +15 -0
- package/src/geometry/meshConcat.ts +1 -0
- package/src/geometry/pixelFont.ts +2 -0
- package/src/geometry/solid.ts +189 -0
- package/src/geometry/solidFlat.ts +522 -0
- package/src/geometry/solidHarness.ts +83 -0
- package/src/geometry/solidNormals.ts +103 -0
- package/src/geometry/solidRound.ts +443 -0
- package/src/geometry/solidWriter.ts +58 -0
- package/src/index.ts +61 -1
- package/src/render/backend/api.ts +36 -11
- package/src/render/backend/drawFog.ts +31 -0
- package/src/render/backend/materialChanges.ts +9 -2
- package/src/render/backend/webgl2/glassTintPrograms.ts +58 -0
- package/src/render/backend/webgl2/instanced.ts +80 -14
- package/src/render/backend/webgl2/renderer.ts +700 -250
- package/src/render/backend/webgpu/buffers.ts +92 -5
- package/src/render/backend/webgpu/depthPass.ts +7 -2
- package/src/render/backend/webgpu/drawCommand.ts +6 -0
- package/src/render/backend/webgpu/flatPass.ts +62 -11
- package/src/render/backend/webgpu/glassTintPass.ts +245 -0
- package/src/render/backend/webgpu/gpuDrivenPass.ts +349 -5
- package/src/render/backend/webgpu/instanceCullPass.ts +165 -0
- package/src/render/backend/webgpu/instanced.ts +42 -4
- package/src/render/backend/webgpu/latePass.ts +161 -0
- package/src/render/backend/webgpu/lightVolumePass.ts +5 -1
- package/src/render/backend/webgpu/motionPass.ts +535 -0
- package/src/render/backend/webgpu/pipelineCache.ts +12 -1
- package/src/render/backend/webgpu/pointGlassTintPass.ts +233 -0
- package/src/render/backend/webgpu/pointShadowPass.ts +158 -26
- package/src/render/backend/webgpu/renderer.ts +1671 -670
- package/src/render/backend/webgpu/scatterPass.ts +2 -1
- package/src/render/backend/webgpu/sdfTextPass.ts +6 -1
- package/src/render/backend/webgpu/shaders/instanceCull.wgsl.ts +61 -0
- package/src/render/backend/webgpu/skinPaletteRing.ts +4 -0
- package/src/render/backend/webgpu/snapshotMips.ts +80 -0
- package/src/render/backend/webgpu/surfaceTexturePass.ts +91 -51
- package/src/render/driftLight/bake.ts +85 -62
- package/src/render/driftLight/denseField.ts +149 -0
- package/src/render/driftLight/lightField.ts +33 -18
- package/src/render/driftLight/presence.ts +69 -0
- package/src/render/driftLight/uniforms.ts +8 -9
- package/src/render/driftLight/worldLightField.ts +83 -0
- package/src/render/fixtureAtlas.ts +63 -0
- package/src/render/glass.ts +74 -0
- package/src/render/glassCasters.ts +164 -0
- package/src/render/glassShadow.ts +153 -0
- package/src/render/globalMediumPass.ts +4 -11
- package/src/render/gpudriven/lit.ts +31 -0
- package/src/render/gpudriven/materialTable.ts +28 -6
- package/src/render/gpudriven/pipeline.ts +4 -3
- package/src/render/gpudriven/sunGlass.ts +117 -0
- package/src/render/instanceCull.ts +205 -0
- package/src/render/instances.ts +16 -0
- package/src/render/lightBudget.ts +41 -38
- package/src/render/lightGrid.ts +130 -0
- package/src/render/mesh.ts +59 -72
- package/src/render/occlusion.ts +51 -7
- package/src/render/pointGlassTint.ts +250 -0
- package/src/render/pointLightSelection.ts +72 -4
- package/src/render/pointShadowArray.ts +188 -22
- package/src/render/pointShadowMap.ts +41 -0
- package/src/render/rainField.ts +39 -5
- package/src/render/recon/changeFrames.ts +24 -0
- package/src/render/recon/lateDepth.ts +83 -0
- package/src/render/recon/lateRouting.ts +29 -0
- package/src/render/recon/mover.ts +118 -0
- package/src/render/recon/resolve.ts +206 -20
- package/src/render/renderQuality.ts +47 -0
- package/src/render/rendererHarness.ts +16 -0
- package/src/render/sceneTarget.ts +62 -11
- package/src/render/shaders/depth.ts +118 -15
- package/src/render/shaders/flat/directionalShadow.ts +97 -6
- package/src/render/shaders/flat/driftLight.ts +32 -7
- package/src/render/shaders/flat/glassTint.ts +25 -0
- package/src/render/shaders/flat/index.ts +22 -3
- package/src/render/shaders/flat/lampGlass.ts +185 -0
- package/src/render/shaders/flat/main.ts +190 -38
- package/src/render/shaders/flat/pointShadow.ts +2 -0
- package/src/render/shaders/flat/preamble.ts +96 -26
- package/src/render/shaders/flat/surfaceEffects.ts +152 -0
- package/src/render/shaders/generated/depth.wgsl.ts +237 -7
- package/src/render/shaders/generated/flat.wgsl.ts +1685 -1621
- package/src/render/shaders/generated/globalMedium.wgsl.ts +3 -13
- package/src/render/shaders/generated/lightVolume.wgsl.ts +23 -17
- package/src/render/shaders/generated/octahedralResolve.wgsl.ts +30 -0
- package/src/render/shaders/generated/rush.wgsl.ts +21 -16
- package/src/render/shaders/generated/sdfText.wgsl.ts +2 -2
- package/src/render/shaders/generated/text.wgsl.ts +1 -1
- package/src/render/shaders/gi/driftLight.wgsl.ts +27 -4
- package/src/render/shaders/globalMedium.ts +6 -6
- package/src/render/shaders/gpudriven/blendRaster.wgsl.ts +88 -1
- package/src/render/shaders/gpudriven/cull.wgsl.ts +11 -2
- package/src/render/shaders/gpudriven/materialTable.wgsl.ts +3 -1
- package/src/render/shaders/gpudriven/shade.wgsl.ts +50 -1
- package/src/render/shaders/gpudriven/sunGlass.wgsl.ts +139 -0
- package/src/render/shaders/lightVolume.ts +6 -6
- package/src/render/shaders/octahedralResolve.ts +50 -17
- package/src/render/shaders/recon/lateDepth.wgsl.ts +72 -0
- package/src/render/shaders/recon/motion.wgsl.ts +84 -0
- package/src/render/shaders/recon/resolve.wgsl.ts +161 -27
- package/src/render/shaders/rush.ts +11 -1
- package/src/render/shaders/sdfText.ts +3 -2
- package/src/render/shaders/text.ts +18 -9
- package/src/render/shadowCasters.ts +28 -1
- package/src/render/shadowMap.ts +231 -37
- package/src/render/sunGlassTint.ts +86 -0
- package/src/render/surfaceEffects.ts +132 -0
- package/src/render/surfaceScene.ts +16 -0
- package/src/render/surfaceTexture.ts +110 -19
- package/src/render/temporalAa.ts +78 -14
- package/src/render/textureSource.ts +72 -0
- package/src/render/translucentQueue.ts +20 -1
- package/src/render/vertexDefaults.ts +2 -0
- package/src/world/hlod.ts +290 -0
|
@@ -59,6 +59,8 @@
|
|
|
59
59
|
* generated, so taking it mirrors the picture — and mirrors the winding with it, which is how it
|
|
60
60
|
* reads as a culling problem. `PassDevice` carries both matrices and says which is which.
|
|
61
61
|
*/
|
|
62
|
+
import { type GlassOptions } from '../../glass.ts';
|
|
63
|
+
import type { GlassShadows } from '../../renderQuality.ts';
|
|
62
64
|
import { type FogOptions } from '../../fog.ts';
|
|
63
65
|
import { StreamingScene } from '../../gpudriven/streamScene.ts';
|
|
64
66
|
import { type GpuDrivenTextures } from '../../gpudriven/materialTable.ts';
|
|
@@ -69,7 +71,7 @@ import type { PassContext, PassDefinition, PassDevice, PrepareContext } from '..
|
|
|
69
71
|
* Five blocks since 2026-09-17 — the three texture programs, the UV scale and the map strengths
|
|
70
72
|
* joined the eight — and `gpudriven/materialTable.ts` writes them.
|
|
71
73
|
*/
|
|
72
|
-
export declare const MATERIAL_FLOATS =
|
|
74
|
+
export declare const MATERIAL_FLOATS = 28;
|
|
73
75
|
/** Floats a vertex in the one interleaved buffer: position, normal, colour, uv. */
|
|
74
76
|
export declare const VERTEX_FLOATS = 12;
|
|
75
77
|
/**
|
|
@@ -186,6 +188,14 @@ export interface GpuDrivenMaterial {
|
|
|
186
188
|
* blend and said nothing else gets — visible, and therefore findable.
|
|
187
189
|
*/
|
|
188
190
|
readonly opacity?: number;
|
|
191
|
+
/**
|
|
192
|
+
* Glass: how much light passes, how milky it is, and the colour it takes — `GlassOptions`, as the
|
|
193
|
+
* forward path's `drawTranslucentMesh` takes it. Absent, or letting nothing through, is not glass.
|
|
194
|
+
*
|
|
195
|
+
* **A glass material is drawn in the blended half whatever `blend` says**, because a visibility
|
|
196
|
+
* buffer holds one surface a pixel and glass is the pane and what is behind it.
|
|
197
|
+
*/
|
|
198
|
+
readonly glass?: GlassOptions;
|
|
189
199
|
}
|
|
190
200
|
/** What the pass needs told once a frame, before `beginFrame`. */
|
|
191
201
|
export interface GpuDrivenView {
|
|
@@ -288,6 +298,12 @@ export interface GpuDrivenShadowOptions {
|
|
|
288
298
|
* texels, and reaches toward the sun as far as the scene does.
|
|
289
299
|
*/
|
|
290
300
|
readonly followRadius?: number;
|
|
301
|
+
/**
|
|
302
|
+
* What the sun keeps through glass: `RenderQualityOptions.glassShadows`, which a contributed pass
|
|
303
|
+
* is not handed and so takes here. `'full'` by default, as there; `'half'` halves the tint and
|
|
304
|
+
* `'off'` draws a glass material's shadow as nothing, which is what it cast before.
|
|
305
|
+
*/
|
|
306
|
+
readonly glass?: GlassShadows;
|
|
291
307
|
}
|
|
292
308
|
export declare class GpuDrivenPass implements PassDefinition {
|
|
293
309
|
readonly label = "driftengine.gpu-driven";
|
|
@@ -410,6 +426,30 @@ export declare class GpuDrivenPass implements PassDefinition {
|
|
|
410
426
|
private latentClamp;
|
|
411
427
|
private latentRepeat;
|
|
412
428
|
private shadowView;
|
|
429
|
+
/** The nearest pane's depth from the sun: the shadow texture's second layer, where glass casts. */
|
|
430
|
+
private glassDepthView;
|
|
431
|
+
/** What the panes let through, as the sun sees them, with the chain frost reads. */
|
|
432
|
+
private glassTintTexture;
|
|
433
|
+
private glassTintTarget;
|
|
434
|
+
private glassTintSampled;
|
|
435
|
+
private glassTintMips;
|
|
436
|
+
/** One white texel, bound where no glass casts, which the lookup reads as none. */
|
|
437
|
+
private glassTintNone;
|
|
438
|
+
private readonly glassMode;
|
|
439
|
+
/** Whether the sun's glass pass runs at all: a glass material, and glass shadows not off. */
|
|
440
|
+
private readonly castsGlass;
|
|
441
|
+
private glassList;
|
|
442
|
+
private glassArgs;
|
|
443
|
+
private glassLodBuffer;
|
|
444
|
+
private readonly lodParamsGlass;
|
|
445
|
+
private shadowCullSettingsGlass;
|
|
446
|
+
private glassLodGroup;
|
|
447
|
+
private glassCullGroup;
|
|
448
|
+
private glassCompactGroup;
|
|
449
|
+
private glassDepthPipeline;
|
|
450
|
+
private glassDepthGroup;
|
|
451
|
+
private glassTintPipeline;
|
|
452
|
+
private glassTintGroup;
|
|
413
453
|
/**
|
|
414
454
|
* What is bound as the probe where the frame has none.
|
|
415
455
|
*
|
|
@@ -521,7 +561,18 @@ export declare class GpuDrivenPass implements PassDefinition {
|
|
|
521
561
|
private visibilityTexture;
|
|
522
562
|
private depthTexture;
|
|
523
563
|
private colourTexture;
|
|
564
|
+
/** Level 0: what the shading writes, the resolve lays over and the blit presents. */
|
|
524
565
|
private colourView;
|
|
566
|
+
/** Every level, for glass to read at the level its frost picks. Level 0 alone with no glass. */
|
|
567
|
+
private colourSampledView;
|
|
568
|
+
/** The chain glass reads, filled from the shaded picture each frame; null in a scene with none. */
|
|
569
|
+
private colourMips;
|
|
570
|
+
/** Whether any material is glass, which is what earns the colour its chain: see `buildTargets`. */
|
|
571
|
+
private readonly hasGlass;
|
|
572
|
+
/** The pipelines the chain draws with, one a format. */
|
|
573
|
+
private readonly mipPipelineCache;
|
|
574
|
+
private readonly mipPipelines;
|
|
575
|
+
private glassSampler;
|
|
525
576
|
private visibility;
|
|
526
577
|
private hzb;
|
|
527
578
|
private levelStart;
|
|
@@ -794,8 +845,16 @@ export declare class GpuDrivenPass implements PassDefinition {
|
|
|
794
845
|
* second render pass where it ended, so `shadow` in the stage times is all of it.
|
|
795
846
|
*/
|
|
796
847
|
private drawShadow;
|
|
848
|
+
/**
|
|
849
|
+
* The sun's glass, after its opaque map: the glass cut from the light, then the panes drawn
|
|
850
|
+
* twice — where the nearest one is, and what they let through, multiplied — and the tint's
|
|
851
|
+
* chain filled for frost to read. The forward path's `flushSunGlass`, in this pipeline's terms.
|
|
852
|
+
*/
|
|
853
|
+
private drawShadowGlass;
|
|
797
854
|
/** One half of the map: the first clears it, the second draws over it and closes the stage's time. */
|
|
798
855
|
private drawShadowHalf;
|
|
856
|
+
/** The linear sampler glass reads the colour's and the tint's chains through, made once. */
|
|
857
|
+
private glassSamplerFor;
|
|
799
858
|
private drawPhase;
|
|
800
859
|
draw(ctx: PassContext): void;
|
|
801
860
|
dispose(device: PassDevice): void;
|
|
@@ -70,6 +70,9 @@ import { FRUSTUM_FLOATS, frustumPlanes } from '../../gpudriven/frustum.js';
|
|
|
70
70
|
import { VIS_EMPTY } from '../../gpudriven/visbuffer.js';
|
|
71
71
|
import { jitterClip } from '../../recon/jitter.js';
|
|
72
72
|
import { GPU_DRIVEN_ORDERED, GPU_DRIVEN_PASSES, GPU_DRIVEN_RESOURCES, gpuDrivenLive, gpuDrivenRefusal, gpuDrivenSupported, recordGpuDrivenStages, } from '../../gpudriven/pipeline.js';
|
|
73
|
+
import { resolveGlass } from '../../glass.js';
|
|
74
|
+
import { GLASS_TINT_BLEND } from './glassTintPass.js';
|
|
75
|
+
import { SnapshotMips } from './snapshotMips.js';
|
|
73
76
|
import { createDeps, resetDeps } from '../../frame/deps.js';
|
|
74
77
|
import { createGraphPasses, createGraphScratch, scheduleGraph } from '../../frame/graphSchedule.js';
|
|
75
78
|
import { hzbMipCount, hzbMipSize } from '../../gpudriven/hzb.js';
|
|
@@ -384,6 +387,30 @@ export class GpuDrivenPass {
|
|
|
384
387
|
latentClamp = null;
|
|
385
388
|
latentRepeat = null;
|
|
386
389
|
shadowView = null;
|
|
390
|
+
/** The nearest pane's depth from the sun: the shadow texture's second layer, where glass casts. */
|
|
391
|
+
glassDepthView = null;
|
|
392
|
+
/** What the panes let through, as the sun sees them, with the chain frost reads. */
|
|
393
|
+
glassTintTexture = null;
|
|
394
|
+
glassTintTarget = null;
|
|
395
|
+
glassTintSampled = null;
|
|
396
|
+
glassTintMips = null;
|
|
397
|
+
/** One white texel, bound where no glass casts, which the lookup reads as none. */
|
|
398
|
+
glassTintNone = null;
|
|
399
|
+
glassMode;
|
|
400
|
+
/** Whether the sun's glass pass runs at all: a glass material, and glass shadows not off. */
|
|
401
|
+
castsGlass;
|
|
402
|
+
glassList = null;
|
|
403
|
+
glassArgs = null;
|
|
404
|
+
glassLodBuffer = null;
|
|
405
|
+
lodParamsGlass = new Float32Array(8);
|
|
406
|
+
shadowCullSettingsGlass = null;
|
|
407
|
+
glassLodGroup = null;
|
|
408
|
+
glassCullGroup = null;
|
|
409
|
+
glassCompactGroup = null;
|
|
410
|
+
glassDepthPipeline = null;
|
|
411
|
+
glassDepthGroup = null;
|
|
412
|
+
glassTintPipeline = null;
|
|
413
|
+
glassTintGroup = null;
|
|
387
414
|
/**
|
|
388
415
|
* What is bound as the probe where the frame has none.
|
|
389
416
|
*
|
|
@@ -497,7 +524,27 @@ export class GpuDrivenPass {
|
|
|
497
524
|
visibilityTexture = null;
|
|
498
525
|
depthTexture = null;
|
|
499
526
|
colourTexture = null;
|
|
527
|
+
/** Level 0: what the shading writes, the resolve lays over and the blit presents. */
|
|
500
528
|
colourView = null;
|
|
529
|
+
/** Every level, for glass to read at the level its frost picks. Level 0 alone with no glass. */
|
|
530
|
+
colourSampledView = null;
|
|
531
|
+
/** The chain glass reads, filled from the shaded picture each frame; null in a scene with none. */
|
|
532
|
+
colourMips = null;
|
|
533
|
+
/** Whether any material is glass, which is what earns the colour its chain: see `buildTargets`. */
|
|
534
|
+
hasGlass;
|
|
535
|
+
/** The pipelines the chain draws with, one a format. */
|
|
536
|
+
mipPipelineCache = new Map();
|
|
537
|
+
mipPipelines = {
|
|
538
|
+
get: (key, describe) => {
|
|
539
|
+
const held = this.mipPipelineCache.get(key);
|
|
540
|
+
if (held !== undefined)
|
|
541
|
+
return held;
|
|
542
|
+
const made = this.device.createRenderPipeline(describe());
|
|
543
|
+
this.mipPipelineCache.set(key, made);
|
|
544
|
+
return made;
|
|
545
|
+
},
|
|
546
|
+
};
|
|
547
|
+
glassSampler = null;
|
|
501
548
|
visibility = null;
|
|
502
549
|
hzb = null;
|
|
503
550
|
levelStart = null;
|
|
@@ -613,7 +660,10 @@ export class GpuDrivenPass {
|
|
|
613
660
|
this.decode = packDecodeTables(this.programs.programs);
|
|
614
661
|
this.scene = scene;
|
|
615
662
|
this.materials = materials;
|
|
663
|
+
this.hasGlass = materials.some((material) => resolveGlass(material.glass, glassProbe));
|
|
616
664
|
this.shadowSize = shadow.mapSize ?? DEFAULT_RENDER_QUALITY.directionalShadowMapSize;
|
|
665
|
+
this.glassMode = shadow.glass ?? DEFAULT_RENDER_QUALITY.glassShadows;
|
|
666
|
+
this.castsGlass = this.hasGlass && this.glassMode !== 'off';
|
|
617
667
|
this.shadowMaxDistance =
|
|
618
668
|
shadow.maxDistance ?? DEFAULT_RENDER_QUALITY.directionalShadowMaxDistance;
|
|
619
669
|
this.shadowMaxSlope = shadow.maxSlope ?? DEFAULT_RENDER_QUALITY.directionalShadowMaxSlope;
|
|
@@ -840,6 +890,10 @@ export class GpuDrivenPass {
|
|
|
840
890
|
this.shadowArgs = this.storage(device, 'draw shadow', shadowArgs, INDIRECT | COPY_SRC);
|
|
841
891
|
this.shadowArgsTwo = this.storage(device, 'draw shadow two', shadowArgs, INDIRECT | COPY_SRC);
|
|
842
892
|
this.shadowSelected = this.empty(device, 'shadow selected', count * 4);
|
|
893
|
+
/* The sun's glass: its own list and arguments, over the light's selection once the map is done. */
|
|
894
|
+
this.glassList = this.empty(device, 'shadow glass list', count * 4);
|
|
895
|
+
this.glassArgs = this.storage(device, 'draw shadow glass', shadowArgs, INDIRECT | COPY_SRC);
|
|
896
|
+
this.glassLodBuffer = this.empty(device, 'lod params glass', 8 * 4);
|
|
843
897
|
this.shadowKeep = this.empty(device, 'shadow keep', count * 4);
|
|
844
898
|
this.shadowPlanes = this.empty(device, 'shadow planes', FRUSTUM_FLOATS * 4);
|
|
845
899
|
this.shadowHistories = [
|
|
@@ -862,6 +916,8 @@ export class GpuDrivenPass {
|
|
|
862
916
|
this.shadowCullValues[CULL_CONES] = 1;
|
|
863
917
|
this.shadowCullSettings = this.storage(device, 'cull settings, shadow', this.shadowCullValues);
|
|
864
918
|
this.shadowCullSettingsTwo = this.storage(device, 'cull settings, shadow two', this.shadowCullValues);
|
|
919
|
+
/* The glass pass's: no pyramid and no cones, since a pane casts from either side. */
|
|
920
|
+
this.shadowCullSettingsGlass = this.storage(device, 'cull settings, shadow glass', this.shadowCullValues);
|
|
865
921
|
this.shadowCompactSettings = this.storage(device, 'phase shadow', Uint32Array.from([PHASE_ONE, count]));
|
|
866
922
|
this.shadowCompactSettingsTwo = this.storage(device, 'phase shadow two', Uint32Array.from([PHASE_TWO, count]));
|
|
867
923
|
/* Nonzero is hidden, and the light hides nothing: see `CULL_INSTANCES_WGSL`. */
|
|
@@ -875,11 +931,47 @@ export class GpuDrivenPass {
|
|
|
875
931
|
*/
|
|
876
932
|
this.shadowTexture = device.createTexture({
|
|
877
933
|
label: 'gpu-driven shadow',
|
|
878
|
-
|
|
934
|
+
/* A second layer for the nearest pane where a material is glass, and none where none is. */
|
|
935
|
+
size: {
|
|
936
|
+
width: this.shadowSize,
|
|
937
|
+
height: this.shadowSize,
|
|
938
|
+
depthOrArrayLayers: this.castsGlass ? 2 : 1,
|
|
939
|
+
},
|
|
879
940
|
format: SHADOW_FORMAT,
|
|
880
941
|
usage: RENDER_ATTACHMENT | TEXTURE_BINDING,
|
|
881
942
|
});
|
|
882
|
-
|
|
943
|
+
const layer = (at) => this.shadowTexture.createView({
|
|
944
|
+
dimension: '2d',
|
|
945
|
+
baseArrayLayer: at,
|
|
946
|
+
arrayLayerCount: 1,
|
|
947
|
+
});
|
|
948
|
+
this.shadowView = layer(0);
|
|
949
|
+
this.glassDepthView = this.castsGlass ? layer(1) : null;
|
|
950
|
+
const tintSize = this.glassMode === 'half' ? Math.max(1, this.shadowSize >> 1) : this.shadowSize;
|
|
951
|
+
this.glassTintTexture = this.castsGlass
|
|
952
|
+
? device.createTexture({
|
|
953
|
+
label: 'gpu-driven glass tint',
|
|
954
|
+
size: { width: tintSize, height: tintSize },
|
|
955
|
+
format: 'rgba8unorm',
|
|
956
|
+
mipLevelCount: Math.floor(Math.log2(tintSize)) + 1,
|
|
957
|
+
usage: RENDER_ATTACHMENT | TEXTURE_BINDING,
|
|
958
|
+
})
|
|
959
|
+
: null;
|
|
960
|
+
if (this.glassTintTexture !== null) {
|
|
961
|
+
this.glassTintTarget = this.glassTintTexture.createView({
|
|
962
|
+
baseMipLevel: 0,
|
|
963
|
+
mipLevelCount: 1,
|
|
964
|
+
});
|
|
965
|
+
this.glassTintSampled = this.glassTintTexture.createView();
|
|
966
|
+
this.glassTintMips = new SnapshotMips(device, this.mipPipelines, this.glassTintTexture, 'rgba8unorm', null, 'gpu-driven glass tint mips');
|
|
967
|
+
}
|
|
968
|
+
this.glassTintNone = device.createTexture({
|
|
969
|
+
label: 'gpu-driven no glass',
|
|
970
|
+
size: { width: 1, height: 1 },
|
|
971
|
+
format: 'rgba8unorm',
|
|
972
|
+
usage: TEXTURE_BINDING | TEXTURE_COPY_DST,
|
|
973
|
+
});
|
|
974
|
+
device.queue.writeTexture({ texture: this.glassTintNone }, new Uint8Array([255, 255, 255, 255]), { bytesPerRow: 4 }, { width: 1, height: 1 });
|
|
883
975
|
this.emptyEnvironment = device.createTexture({
|
|
884
976
|
label: 'gpu-driven no environment',
|
|
885
977
|
size: { width: 1, height: 1, depthOrArrayLayers: 1 },
|
|
@@ -1171,6 +1263,37 @@ export class GpuDrivenPass {
|
|
|
1171
1263
|
});
|
|
1172
1264
|
this.shadowGroup = shadowRasterFor(this.shadowList);
|
|
1173
1265
|
this.shadowGroupTwo = shadowRasterFor(this.shadowListTwo);
|
|
1266
|
+
/*
|
|
1267
|
+
* **The nearest pane, from the sun: the same raster, culling nothing**, since a pane casts from
|
|
1268
|
+
* either side; into the shadow texture's second layer. Built only where glass casts.
|
|
1269
|
+
*/
|
|
1270
|
+
if (this.castsGlass) {
|
|
1271
|
+
this.glassDepthPipeline = device.createRenderPipeline({
|
|
1272
|
+
label: 'gpu-driven shadow glass',
|
|
1273
|
+
layout: 'auto',
|
|
1274
|
+
vertex: { module: raster, entryPoint: 'vertexMain' },
|
|
1275
|
+
primitive: { topology: 'triangle-list', cullMode: 'none', frontFace: 'cw' },
|
|
1276
|
+
depthStencil: {
|
|
1277
|
+
format: SHADOW_FORMAT,
|
|
1278
|
+
depthWriteEnabled: true,
|
|
1279
|
+
depthCompare: 'less',
|
|
1280
|
+
depthBias: 4,
|
|
1281
|
+
depthBiasSlopeScale: 1.1,
|
|
1282
|
+
},
|
|
1283
|
+
});
|
|
1284
|
+
this.glassDepthGroup = device.createBindGroup({
|
|
1285
|
+
layout: this.glassDepthPipeline.getBindGroupLayout(0),
|
|
1286
|
+
entries: [
|
|
1287
|
+
{ binding: 0, resource: { buffer: this.shadowMatrix } },
|
|
1288
|
+
{ binding: 1, resource: { buffer: this.glassList } },
|
|
1289
|
+
{ binding: 2, resource: { buffer: this.clusterMeta } },
|
|
1290
|
+
{ binding: 3, resource: { buffer: this.indices } },
|
|
1291
|
+
{ binding: 4, resource: { buffer: this.vertices } },
|
|
1292
|
+
{ binding: 5, resource: { buffer: this.transformBuffer } },
|
|
1293
|
+
{ binding: 6, resource: { buffer: this.materialOf } },
|
|
1294
|
+
],
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1174
1297
|
/*
|
|
1175
1298
|
* **The transparent half's raster: one indirect draw into two targets at once.**
|
|
1176
1299
|
*
|
|
@@ -1236,6 +1359,38 @@ export class GpuDrivenPass {
|
|
|
1236
1359
|
},
|
|
1237
1360
|
});
|
|
1238
1361
|
this.watchBlendPipeline(device);
|
|
1362
|
+
/*
|
|
1363
|
+
* **What a pane lets through, from the sun**: the blended raster's vertex stage handed the
|
|
1364
|
+
* light's matrix and the glass list, and \`glassTintFrag\` for the colour — white target, a
|
|
1365
|
+
* multiplying blend, no depth, so every pane on a ray counts in any order.
|
|
1366
|
+
*/
|
|
1367
|
+
if (this.castsGlass) {
|
|
1368
|
+
this.glassTintPipeline = device.createRenderPipeline({
|
|
1369
|
+
label: 'gpu-driven shadow tint',
|
|
1370
|
+
layout: 'auto',
|
|
1371
|
+
vertex: { module: blend, entryPoint: 'blendVert' },
|
|
1372
|
+
fragment: {
|
|
1373
|
+
module: blend,
|
|
1374
|
+
entryPoint: 'glassTintFrag',
|
|
1375
|
+
targets: [{ format: 'rgba8unorm', blend: GLASS_TINT_BLEND }],
|
|
1376
|
+
},
|
|
1377
|
+
primitive: { topology: 'triangle-list', cullMode: 'none' },
|
|
1378
|
+
});
|
|
1379
|
+
this.glassTintGroup = device.createBindGroup({
|
|
1380
|
+
layout: this.glassTintPipeline.getBindGroupLayout(0),
|
|
1381
|
+
entries: [
|
|
1382
|
+
{ binding: 0, resource: { buffer: this.shadowMatrix } },
|
|
1383
|
+
{ binding: 1, resource: { buffer: this.glassList } },
|
|
1384
|
+
{ binding: 2, resource: { buffer: this.clusterMeta } },
|
|
1385
|
+
{ binding: 3, resource: { buffer: this.indices } },
|
|
1386
|
+
{ binding: 4, resource: { buffer: this.vertices } },
|
|
1387
|
+
{ binding: 5, resource: { buffer: this.transformBuffer } },
|
|
1388
|
+
{ binding: 6, resource: { buffer: this.materialOf } },
|
|
1389
|
+
{ binding: 7, resource: { buffer: this.materialTable } },
|
|
1390
|
+
{ binding: 8, resource: { buffer: this.frameBuffer } },
|
|
1391
|
+
],
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1239
1394
|
/*
|
|
1240
1395
|
* **Premultiplied over, where `renderer.ts`'s composite is a lerp**, and `blendRaster.wgsl.ts`
|
|
1241
1396
|
* carries why: this pipeline's colour target has a coverage mask in its alpha, which the blit
|
|
@@ -1402,6 +1557,39 @@ export class GpuDrivenPass {
|
|
|
1402
1557
|
shadowCullFor(this.shadowCullSettings),
|
|
1403
1558
|
shadowCullFor(this.shadowCullSettingsTwo),
|
|
1404
1559
|
];
|
|
1560
|
+
/*
|
|
1561
|
+
* **The sun's glass cut: the light's selection again, of the glass alone**, once the map is
|
|
1562
|
+
* drawn and those buffers are free. The camera's level of detail, as the map's; every pane in
|
|
1563
|
+
* the light's frustum kept, as the blended half keeps every pane — so compacted as phase two
|
|
1564
|
+
* against a history of zeros, exactly as that half is.
|
|
1565
|
+
*/
|
|
1566
|
+
if (this.castsGlass) {
|
|
1567
|
+
this.glassLodGroup = device.createBindGroup({
|
|
1568
|
+
layout: this.lodPipeline.getBindGroupLayout(0),
|
|
1569
|
+
entries: [
|
|
1570
|
+
{ binding: 0, resource: { buffer: this.glassLodBuffer } },
|
|
1571
|
+
{ binding: 1, resource: { buffer: this.clusterLod } },
|
|
1572
|
+
{ binding: 2, resource: { buffer: this.shadowSelected } },
|
|
1573
|
+
{ binding: 3, resource: { buffer: this.clusterMeta } },
|
|
1574
|
+
{ binding: 4, resource: { buffer: this.instanceNone } },
|
|
1575
|
+
{ binding: 5, resource: { buffer: this.materialOf } },
|
|
1576
|
+
{ binding: 6, resource: { buffer: this.materialTable } },
|
|
1577
|
+
],
|
|
1578
|
+
});
|
|
1579
|
+
this.glassCullGroup = shadowCullFor(this.shadowCullSettingsGlass);
|
|
1580
|
+
this.glassCompactGroup = device.createBindGroup({
|
|
1581
|
+
layout: this.compactPipeline.getBindGroupLayout(0),
|
|
1582
|
+
entries: [
|
|
1583
|
+
{ binding: 0, resource: { buffer: this.blendCompactSettings } },
|
|
1584
|
+
{ binding: 1, resource: { buffer: this.shadowSelected } },
|
|
1585
|
+
{ binding: 2, resource: { buffer: this.shadowKeep } },
|
|
1586
|
+
{ binding: 3, resource: { buffer: this.zeroHistory } },
|
|
1587
|
+
{ binding: 4, resource: { buffer: this.glassList } },
|
|
1588
|
+
{ binding: 5, resource: { buffer: this.historySink } },
|
|
1589
|
+
{ binding: 6, resource: { buffer: this.glassArgs } },
|
|
1590
|
+
],
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1405
1593
|
this.shadowSeedGroup = device.createBindGroup({
|
|
1406
1594
|
layout: this.shadowSeedPipeline.getBindGroupLayout(0),
|
|
1407
1595
|
entries: [
|
|
@@ -1582,11 +1770,22 @@ export class GpuDrivenPass {
|
|
|
1582
1770
|
label: 'gpu-driven colour',
|
|
1583
1771
|
size: { width: stride, height },
|
|
1584
1772
|
format: 'rgba16float',
|
|
1773
|
+
/*
|
|
1774
|
+
* **A chain only where a material is glass**, which a frosted pane reads a coarser level of,
|
|
1775
|
+
* as the forward path's refraction copy does. A scene with no glass allocates exactly the one
|
|
1776
|
+
* level it always did.
|
|
1777
|
+
*/
|
|
1778
|
+
mipLevelCount: this.hasGlass ? Math.floor(Math.log2(Math.max(stride, height))) + 1 : 1,
|
|
1585
1779
|
/* `RENDER_ATTACHMENT` only so a clear-only render pass can empty it each frame: a storage
|
|
1586
1780
|
texture has no clear, and the alternative is a dispatch over every pixel. */
|
|
1587
1781
|
usage: STORAGE_BINDING | TEXTURE_BINDING | RENDER_ATTACHMENT,
|
|
1588
1782
|
});
|
|
1589
|
-
|
|
1783
|
+
/* A storage binding takes one level, so everything that writes or presents reads level 0. */
|
|
1784
|
+
this.colourView = this.colourTexture.createView({ baseMipLevel: 0, mipLevelCount: 1 });
|
|
1785
|
+
this.colourSampledView = this.colourTexture.createView();
|
|
1786
|
+
this.colourMips = this.hasGlass
|
|
1787
|
+
? new SnapshotMips(device, this.mipPipelines, this.colourTexture, 'rgba16float', null, 'gpu-driven colour mips')
|
|
1788
|
+
: null;
|
|
1590
1789
|
this.oitAccum = device.createTexture({
|
|
1591
1790
|
label: 'gpu-driven oit accum',
|
|
1592
1791
|
size: { width: stride, height },
|
|
@@ -1726,12 +1925,22 @@ export class GpuDrivenPass {
|
|
|
1726
1925
|
{ binding: 16, resource: this.latentRepeat },
|
|
1727
1926
|
{ binding: 17, resource: { buffer: this.decodeNodes } },
|
|
1728
1927
|
{ binding: 18, resource: { buffer: this.decodeWeights } },
|
|
1928
|
+
/* The sun's glass, or the opaque map and a white texel where none casts. */
|
|
1929
|
+
{
|
|
1930
|
+
binding: 19,
|
|
1931
|
+
resource: this.glassDepthView ?? this.shadowView,
|
|
1932
|
+
},
|
|
1933
|
+
{
|
|
1934
|
+
binding: 20,
|
|
1935
|
+
resource: this.glassTintSampled ?? this.glassTintNone.createView(),
|
|
1936
|
+
},
|
|
1937
|
+
{ binding: 21, resource: this.glassSamplerFor(device) },
|
|
1729
1938
|
],
|
|
1730
1939
|
});
|
|
1731
1940
|
this.blitGroup = device.createBindGroup({
|
|
1732
1941
|
layout: this.blitPipeline.getBindGroupLayout(0),
|
|
1733
1942
|
entries: [
|
|
1734
|
-
{ binding: 0, resource: this.
|
|
1943
|
+
{ binding: 0, resource: this.colourView },
|
|
1735
1944
|
/* The depth the raster wrote, sampled so the blit can hand it to the frame. */
|
|
1736
1945
|
...(this.presentDepth
|
|
1737
1946
|
? [
|
|
@@ -1774,6 +1983,12 @@ export class GpuDrivenPass {
|
|
|
1774
1983
|
{ binding: 13, resource: this.latentRepeat },
|
|
1775
1984
|
{ binding: 14, resource: { buffer: this.decodeNodes } },
|
|
1776
1985
|
{ binding: 15, resource: { buffer: this.decodeWeights } },
|
|
1986
|
+
/* What the opaque half drew, for glass to show: `blendRaster.wgsl.ts`. */
|
|
1987
|
+
{ binding: 16, resource: this.colourSampledView },
|
|
1988
|
+
{
|
|
1989
|
+
binding: 17,
|
|
1990
|
+
resource: this.glassSamplerFor(device),
|
|
1991
|
+
},
|
|
1777
1992
|
],
|
|
1778
1993
|
});
|
|
1779
1994
|
/*
|
|
@@ -1979,6 +2194,16 @@ export class GpuDrivenPass {
|
|
|
1979
2194
|
queue.writeBuffer(this.shadowCullSettings, 0, this.shadowCullValues);
|
|
1980
2195
|
this.shadowCullValues[3] = this.occlusion ? 1 : 0;
|
|
1981
2196
|
queue.writeBuffer(this.shadowCullSettingsTwo, 0, this.shadowCullValues);
|
|
2197
|
+
if (this.castsGlass) {
|
|
2198
|
+
/* No pyramid and no cones, and the cones put back for the next frame's first write. */
|
|
2199
|
+
this.shadowCullValues[3] = 0;
|
|
2200
|
+
this.shadowCullValues[CULL_CONES] = 0;
|
|
2201
|
+
queue.writeBuffer(this.shadowCullSettingsGlass, 0, this.shadowCullValues);
|
|
2202
|
+
this.shadowCullValues[CULL_CONES] = 1;
|
|
2203
|
+
this.lodParamsGlass.set(this.lodParamsBlend);
|
|
2204
|
+
this.lodParamsGlass[7] = 1;
|
|
2205
|
+
queue.writeBuffer(this.glassLodBuffer, 0, this.lodParamsGlass);
|
|
2206
|
+
}
|
|
1982
2207
|
queue.writeBuffer(this.planesBuffer, 0, this.planes);
|
|
1983
2208
|
queue.writeBuffer(this.frameBuffer, 0, params);
|
|
1984
2209
|
queue.writeBuffer(this.lodBuffer, 0, this.lodParams);
|
|
@@ -2038,7 +2263,9 @@ export class GpuDrivenPass {
|
|
|
2038
2263
|
* one: the table is written when the pass is built. A scene with nothing blended schedules the
|
|
2039
2264
|
* three transparent stages away entirely and encodes the frame it encoded before they existed.
|
|
2040
2265
|
*/
|
|
2041
|
-
|
|
2266
|
+
/* Glass is the blended half's whatever its flag says: a visibility buffer holds one surface. */
|
|
2267
|
+
this.shape.blended =
|
|
2268
|
+
this.hasGlass || this.materials.some((material) => material.blend === true);
|
|
2042
2269
|
/* `instanceCount` is the one word the compaction touches; the other three never change. */
|
|
2043
2270
|
encoder.clearBuffer(argsOne, 4, 4);
|
|
2044
2271
|
encoder.clearBuffer(argsTwo, 4, 4);
|
|
@@ -2212,6 +2439,8 @@ export class GpuDrivenPass {
|
|
|
2212
2439
|
*/
|
|
2213
2440
|
if (!this.blendUsable || this.blendPipeline === null || this.blendRasterGroup === null)
|
|
2214
2441
|
return;
|
|
2442
|
+
/* The shaded picture's chain, which glass reads: after `shade`, before the panes. */
|
|
2443
|
+
this.colourMips?.record(encoder);
|
|
2215
2444
|
const pass = encoder.beginRenderPass({
|
|
2216
2445
|
label: 'gpu-driven blend draw',
|
|
2217
2446
|
colorAttachments: [
|
|
@@ -2519,6 +2748,57 @@ export class GpuDrivenPass {
|
|
|
2519
2748
|
second.end();
|
|
2520
2749
|
this.drawShadowHalf(encoder, 1, writes);
|
|
2521
2750
|
this.shadowFlipped = !this.shadowFlipped;
|
|
2751
|
+
if (this.castsGlass && this.blendUsable)
|
|
2752
|
+
this.drawShadowGlass(encoder, groups);
|
|
2753
|
+
}
|
|
2754
|
+
/**
|
|
2755
|
+
* The sun's glass, after its opaque map: the glass cut from the light, then the panes drawn
|
|
2756
|
+
* twice — where the nearest one is, and what they let through, multiplied — and the tint's
|
|
2757
|
+
* chain filled for frost to read. The forward path's `flushSunGlass`, in this pipeline's terms.
|
|
2758
|
+
*/
|
|
2759
|
+
drawShadowGlass(encoder, groups) {
|
|
2760
|
+
encoder.clearBuffer(this.glassArgs, 4, 4);
|
|
2761
|
+
const cut = encoder.beginComputePass({ label: 'gpu-driven shadow glass cut' });
|
|
2762
|
+
cut.setPipeline(this.lodPipeline);
|
|
2763
|
+
cut.setBindGroup(0, this.glassLodGroup);
|
|
2764
|
+
cut.dispatchWorkgroups(groups);
|
|
2765
|
+
cut.setPipeline(this.cullPipeline);
|
|
2766
|
+
cut.setBindGroup(0, this.glassCullGroup);
|
|
2767
|
+
cut.dispatchWorkgroups(groups);
|
|
2768
|
+
cut.setPipeline(this.compactPipeline);
|
|
2769
|
+
cut.setBindGroup(0, this.glassCompactGroup);
|
|
2770
|
+
cut.dispatchWorkgroups(groups);
|
|
2771
|
+
cut.end();
|
|
2772
|
+
const depth = encoder.beginRenderPass({
|
|
2773
|
+
label: 'gpu-driven shadow glass',
|
|
2774
|
+
colorAttachments: [],
|
|
2775
|
+
depthStencilAttachment: {
|
|
2776
|
+
view: this.glassDepthView,
|
|
2777
|
+
depthClearValue: SHADOW_DEPTH_CLEAR,
|
|
2778
|
+
depthLoadOp: 'clear',
|
|
2779
|
+
depthStoreOp: 'store',
|
|
2780
|
+
},
|
|
2781
|
+
});
|
|
2782
|
+
depth.setPipeline(this.glassDepthPipeline);
|
|
2783
|
+
depth.setBindGroup(0, this.glassDepthGroup);
|
|
2784
|
+
depth.drawIndirect(this.glassArgs, 0);
|
|
2785
|
+
depth.end();
|
|
2786
|
+
const tint = encoder.beginRenderPass({
|
|
2787
|
+
label: 'gpu-driven shadow tint',
|
|
2788
|
+
colorAttachments: [
|
|
2789
|
+
{
|
|
2790
|
+
view: this.glassTintTarget,
|
|
2791
|
+
clearValue: { r: 1, g: 1, b: 1, a: 1 },
|
|
2792
|
+
loadOp: 'clear',
|
|
2793
|
+
storeOp: 'store',
|
|
2794
|
+
},
|
|
2795
|
+
],
|
|
2796
|
+
});
|
|
2797
|
+
tint.setPipeline(this.glassTintPipeline);
|
|
2798
|
+
tint.setBindGroup(0, this.glassTintGroup);
|
|
2799
|
+
tint.drawIndirect(this.glassArgs, 0);
|
|
2800
|
+
tint.end();
|
|
2801
|
+
this.glassTintMips?.record(encoder);
|
|
2522
2802
|
}
|
|
2523
2803
|
/** One half of the map: the first clears it, the second draws over it and closes the stage's time. */
|
|
2524
2804
|
drawShadowHalf(encoder, half, writes) {
|
|
@@ -2540,6 +2820,18 @@ export class GpuDrivenPass {
|
|
|
2540
2820
|
pass.drawIndirect((half === 0 ? this.shadowArgs : this.shadowArgsTwo), 0);
|
|
2541
2821
|
pass.end();
|
|
2542
2822
|
}
|
|
2823
|
+
/** The linear sampler glass reads the colour's and the tint's chains through, made once. */
|
|
2824
|
+
glassSamplerFor(device) {
|
|
2825
|
+
this.glassSampler ??= device.createSampler({
|
|
2826
|
+
label: 'gpu-driven glass',
|
|
2827
|
+
magFilter: 'linear',
|
|
2828
|
+
minFilter: 'linear',
|
|
2829
|
+
mipmapFilter: 'linear',
|
|
2830
|
+
addressModeU: 'clamp-to-edge',
|
|
2831
|
+
addressModeV: 'clamp-to-edge',
|
|
2832
|
+
});
|
|
2833
|
+
return this.glassSampler;
|
|
2834
|
+
}
|
|
2543
2835
|
drawPhase(encoder, phase, clear) {
|
|
2544
2836
|
const pass = encoder.beginRenderPass({
|
|
2545
2837
|
label: `gpu-driven phase ${phase + 1}`,
|
|
@@ -2597,6 +2889,8 @@ export class GpuDrivenPass {
|
|
|
2597
2889
|
return;
|
|
2598
2890
|
this.disposeTargets();
|
|
2599
2891
|
this.shadowTexture?.destroy();
|
|
2892
|
+
this.glassTintTexture?.destroy();
|
|
2893
|
+
this.glassTintNone?.destroy();
|
|
2600
2894
|
this.emptyEnvironment?.destroy();
|
|
2601
2895
|
this.latents?.destroy();
|
|
2602
2896
|
this.queries?.destroy();
|
|
@@ -2635,6 +2929,10 @@ export class GpuDrivenPass {
|
|
|
2635
2929
|
this.shadowListTwo,
|
|
2636
2930
|
this.shadowSelected,
|
|
2637
2931
|
this.shadowKeep,
|
|
2932
|
+
this.glassList,
|
|
2933
|
+
this.glassArgs,
|
|
2934
|
+
this.glassLodBuffer,
|
|
2935
|
+
this.shadowCullSettingsGlass,
|
|
2638
2936
|
this.shadowPlanes,
|
|
2639
2937
|
this.shadowCullSettings,
|
|
2640
2938
|
this.shadowCullSettingsTwo,
|
|
@@ -2678,3 +2976,5 @@ function multiply(out, a, b) {
|
|
|
2678
2976
|
}
|
|
2679
2977
|
}
|
|
2680
2978
|
}
|
|
2979
|
+
/** Where `hasGlass` reads each material's glass through; only the answer is kept. */
|
|
2980
|
+
const glassProbe = { transmission: 0, frost: 0, tint: [1, 1, 1] };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Views a batch can be culled for in one frame. See the header. */
|
|
2
|
+
export declare const MAX_CULL_SLOTS = 4;
|
|
3
|
+
/** One set of survivors: the compacted instances, the indirect record, and what the cull reads. */
|
|
4
|
+
export interface CullSlot {
|
|
5
|
+
readonly instances: GPUBuffer;
|
|
6
|
+
readonly args: GPUBuffer;
|
|
7
|
+
readonly params: GPUBuffer;
|
|
8
|
+
readonly group: GPUBindGroup;
|
|
9
|
+
/** How many instances the last queued job tested, which sizes its dispatch. */
|
|
10
|
+
count: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class InstanceCullPass {
|
|
13
|
+
private readonly device;
|
|
14
|
+
private readonly pipeline;
|
|
15
|
+
private readonly layout;
|
|
16
|
+
private readonly jobs;
|
|
17
|
+
private queued;
|
|
18
|
+
private readonly paramsStaging;
|
|
19
|
+
private readonly paramFloats;
|
|
20
|
+
private readonly paramWords;
|
|
21
|
+
private readonly argsStaging;
|
|
22
|
+
constructor(device: GPUDevice);
|
|
23
|
+
/** A slot reading `source`, a batch's full instance buffer of `capacity` instances. */
|
|
24
|
+
createSlot(source: GPUBuffer, capacity: number, label: string): CullSlot;
|
|
25
|
+
/**
|
|
26
|
+
* Queue a cull of `count` instances against six `planes`, the mesh's local sphere being
|
|
27
|
+
* (centre, radius). Returns false when the frame's job ring is full, and the caller draws uncut.
|
|
28
|
+
*/
|
|
29
|
+
queue(slot: CullSlot, planes: Float32Array, centre: ArrayLike<number>, radius: number, count: number, indexCount: number): boolean;
|
|
30
|
+
/** Dispatch everything queued, in one compute pass and one submit. Nothing queued is nothing done. */
|
|
31
|
+
flush(): void;
|
|
32
|
+
}
|
|
33
|
+
/** Every buffer a slot owns, destroyed with its batch. */
|
|
34
|
+
export declare function destroySlot(slot: CullSlot): void;
|