@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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveConditionals } from './conditionals.js';
|
|
2
|
+
import { SUN_STATIC_LAYER } from '../shadowMap.js';
|
|
2
3
|
import { CUTOUT_COVERAGE_GLSL } from './cutoutCoverage.js';
|
|
3
4
|
import { SKINNING_GLSL } from './skinning.js';
|
|
4
5
|
import { CHANNEL_ATTRIBUTE, CHANNEL_BEND } from './vertexChannel.js';
|
|
@@ -62,16 +63,22 @@ ${CHANNEL_BEND}
|
|
|
62
63
|
* uniforms declared after every other, so no field of the plain variant moves and a binder written
|
|
63
64
|
* against it stays right for this one; and two outputs after vLightPosition, which keeps location 0.
|
|
64
65
|
*/
|
|
65
|
-
layout(location = 5) in
|
|
66
|
+
layout(location = 5) in vec3 aUv;
|
|
66
67
|
uniform vec2 uUvScale;
|
|
67
68
|
uniform float uAlphaCutout;
|
|
68
69
|
#endif
|
|
69
70
|
|
|
70
71
|
out vec4 vLightPosition;
|
|
71
72
|
#if CUTOUT
|
|
72
|
-
|
|
73
|
+
/* The texture coordinate and, in z, the texture-array layer the face wears. */
|
|
74
|
+
out vec3 vUv;
|
|
73
75
|
flat out float vAlphaCutout;
|
|
74
76
|
#endif
|
|
77
|
+
#if GLASS
|
|
78
|
+
/* Where on the pane this is, for the tint's own normal and its angle to the light. Last, so the
|
|
79
|
+
outputs before it keep the locations the plain variants give them. */
|
|
80
|
+
out vec3 vGlassWorld;
|
|
81
|
+
#endif
|
|
75
82
|
|
|
76
83
|
void main() {
|
|
77
84
|
#if SKINNED
|
|
@@ -96,15 +103,18 @@ void main() {
|
|
|
96
103
|
vLightPosition = uLightViewProj * vec4(bent, world.w);
|
|
97
104
|
gl_Position = vLightPosition;
|
|
98
105
|
#if CUTOUT
|
|
99
|
-
vUv = aUv * uUvScale;
|
|
106
|
+
vUv = vec3(aUv.xy * uUvScale, aUv.z);
|
|
100
107
|
vAlphaCutout = uAlphaCutout;
|
|
101
108
|
#endif
|
|
109
|
+
#if GLASS
|
|
110
|
+
vGlassWorld = bent;
|
|
111
|
+
#endif
|
|
102
112
|
}
|
|
103
113
|
`;
|
|
104
114
|
/** The rigid variant: the world, a prop, a mesh with no rig behind it. */
|
|
105
|
-
export const DEPTH_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: false, CUTOUT: false }, 'depth');
|
|
115
|
+
export const DEPTH_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: false, CUTOUT: false, GLASS: false }, 'depth');
|
|
106
116
|
/** The skinned variant, which reads a joint palette and moves the vertex by it. */
|
|
107
|
-
export const DEPTH_SKINNED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: true, INSTANCED: false, CUTOUT: false }, 'depth-skinned');
|
|
117
|
+
export const DEPTH_SKINNED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: true, INSTANCED: false, CUTOUT: false, GLASS: false }, 'depth-skinned');
|
|
108
118
|
/**
|
|
109
119
|
* The variant an instanced draw casts its shadow through.
|
|
110
120
|
*
|
|
@@ -113,7 +123,7 @@ export const DEPTH_SKINNED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINN
|
|
|
113
123
|
* right place and the rest stacked underneath it, which reads as a lighting fault rather than as
|
|
114
124
|
* a missing variant, and is the shape the per-draw ring exists to prevent one level up.
|
|
115
125
|
*/
|
|
116
|
-
export const DEPTH_INSTANCED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: true, CUTOUT: false }, 'depth-instanced');
|
|
126
|
+
export const DEPTH_INSTANCED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: true, CUTOUT: false, GLASS: false }, 'depth-instanced');
|
|
117
127
|
/**
|
|
118
128
|
* The variants a cutout caster casts through: a leaf card, a chain link, a fence, whose shape is in
|
|
119
129
|
* its texture's alpha rather than in its geometry.
|
|
@@ -124,20 +134,20 @@ export const DEPTH_INSTANCED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKI
|
|
|
124
134
|
* leaves every opaque caster byte for byte as it was. What it costs is one more program each, and
|
|
125
135
|
* a skinned cutout, which nothing has asked for, is not among them.
|
|
126
136
|
*/
|
|
127
|
-
export const DEPTH_CUTOUT_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: false, CUTOUT: true }, 'depth-cutout');
|
|
128
|
-
export const DEPTH_INSTANCED_CUTOUT_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: true, CUTOUT: true }, 'depth-instanced-cutout');
|
|
137
|
+
export const DEPTH_CUTOUT_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: false, CUTOUT: true, GLASS: false }, 'depth-cutout');
|
|
138
|
+
export const DEPTH_INSTANCED_CUTOUT_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: true, CUTOUT: true, GLASS: false }, 'depth-instanced-cutout');
|
|
129
139
|
export const DEPTH_FRAG = `#version 300 es
|
|
130
140
|
precision highp float;
|
|
131
141
|
in vec4 vLightPosition;
|
|
132
142
|
|
|
133
|
-
uniform highp
|
|
143
|
+
uniform highp sampler2DArray uPreviousShadowMap;
|
|
134
144
|
uniform int uPeelShadowLayer;
|
|
135
145
|
|
|
136
146
|
void main() {
|
|
137
147
|
if (uPeelShadowLayer != 0) {
|
|
138
148
|
vec3 p = vLightPosition.xyz / vLightPosition.w;
|
|
139
149
|
vec2 uv = p.xy * 0.5 + 0.5;
|
|
140
|
-
float previousDepth = texture(uPreviousShadowMap, uv).r;
|
|
150
|
+
float previousDepth = texture(uPreviousShadowMap, vec3(uv, ${SUN_STATIC_LAYER}.0)).r;
|
|
141
151
|
// Discard the already-recorded surface and everything in front of it. The
|
|
142
152
|
// ordinary depth test then stores the next independently fading occluder.
|
|
143
153
|
if (gl_FragCoord.z <= previousDepth + 0.00001) discard;
|
|
@@ -159,22 +169,91 @@ void main() {
|
|
|
159
169
|
export const DEPTH_CUTOUT_FRAG = `#version 300 es
|
|
160
170
|
precision highp float;
|
|
161
171
|
in vec4 vLightPosition;
|
|
162
|
-
in
|
|
172
|
+
in vec3 vUv;
|
|
163
173
|
flat in float vAlphaCutout;
|
|
164
174
|
|
|
165
|
-
uniform highp
|
|
175
|
+
uniform highp sampler2DArray uPreviousShadowMap;
|
|
166
176
|
uniform int uPeelShadowLayer;
|
|
167
|
-
uniform highp
|
|
177
|
+
uniform highp sampler2DArray uCutoutMap;
|
|
168
178
|
${CUTOUT_COVERAGE_GLSL}
|
|
169
179
|
void main() {
|
|
170
180
|
/* Credited for its mip level as the surface's own test is, so a leaf casts the shape it draws. */
|
|
171
|
-
|
|
181
|
+
vec3 at = vec3(vUv.xy, floor(vUv.z + 0.5));
|
|
182
|
+
float alpha = cutoutAlpha(texture(uCutoutMap, at).a, vUv.xy * vec2(textureSize(uCutoutMap, 0).xy));
|
|
172
183
|
if (uPeelShadowLayer != 0) {
|
|
173
184
|
vec3 p = vLightPosition.xyz / vLightPosition.w;
|
|
174
185
|
vec2 uv = p.xy * 0.5 + 0.5;
|
|
175
|
-
float previousDepth = textureLod(uPreviousShadowMap, uv, 0.0).r;
|
|
186
|
+
float previousDepth = textureLod(uPreviousShadowMap, vec3(uv, ${SUN_STATIC_LAYER}.0), 0.0).r;
|
|
176
187
|
if (gl_FragCoord.z <= previousDepth + 0.00001) discard;
|
|
177
188
|
}
|
|
178
189
|
if (alpha < vAlphaCutout) discard;
|
|
179
190
|
}
|
|
180
191
|
`;
|
|
192
|
+
/**
|
|
193
|
+
* The glass tint's vertex stages: every way a caster is drawn, with the world position handed on.
|
|
194
|
+
*
|
|
195
|
+
* **The same five as the depth pass, and for the same reason**: a pane must cast its colour from
|
|
196
|
+
* exactly where it casts its depth, deformed and placed the same way, or the coloured patch parts
|
|
197
|
+
* from the pane's own shadow edge. The only addition is `vGlassWorld`.
|
|
198
|
+
*/
|
|
199
|
+
export const GLASS_TINT_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: false, CUTOUT: false, GLASS: true }, 'glass-tint');
|
|
200
|
+
export const GLASS_TINT_SKINNED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: true, INSTANCED: false, CUTOUT: false, GLASS: true }, 'glass-tint-skinned');
|
|
201
|
+
export const GLASS_TINT_INSTANCED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: true, CUTOUT: false, GLASS: true }, 'glass-tint-instanced');
|
|
202
|
+
export const GLASS_TINT_CUTOUT_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: false, CUTOUT: true, GLASS: true }, 'glass-tint-cutout');
|
|
203
|
+
export const GLASS_TINT_INSTANCED_CUTOUT_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: true, CUTOUT: true, GLASS: true }, 'glass-tint-instanced-cutout');
|
|
204
|
+
/**
|
|
205
|
+
* What a pane lets through: its transmission and colour, less what it reflects toward the light,
|
|
206
|
+
* and how clear it is — `glassShadow.ts`'s `paneTexel`, stated for the device. Drawn with a
|
|
207
|
+
* multiplying blend and no depth test, so every pane on a ray contributes whatever order they
|
|
208
|
+
* come in.
|
|
209
|
+
*
|
|
210
|
+
* **The pane's normal is its triangle's**, from the derivatives of its world position, first and in
|
|
211
|
+
* uniform control flow: a pane is flat, a sign does not matter to a cosine taken absolutely, and it
|
|
212
|
+
* spares the five vertex stages a normal they would carry for this alone. What it gives up is a
|
|
213
|
+
* curved pane, whose Fresnel steps per triangle; what would change it is glass that is mostly bulbs.
|
|
214
|
+
*/
|
|
215
|
+
const GLASS_TINT_BODY = /* glsl */ `
|
|
216
|
+
vec3 n = normalize(cross(dFdx(vGlassWorld), dFdy(vGlassWorld)));
|
|
217
|
+
vec3 toLight = uGlassLight.w > 0.5 ? normalize(uGlassLight.xyz - vGlassWorld) : uGlassLight.xyz;
|
|
218
|
+
float cosLight = abs(dot(n, toLight));
|
|
219
|
+
float reflected = 0.04 + 0.96 * pow(1.0 - cosLight, 5.0);
|
|
220
|
+
outTint = vec4(uGlassPane.rgb * (1.0 - reflected), uGlassPane.a);
|
|
221
|
+
`;
|
|
222
|
+
export const GLASS_TINT_FRAG = `#version 300 es
|
|
223
|
+
precision highp float;
|
|
224
|
+
in vec4 vLightPosition;
|
|
225
|
+
in vec3 vGlassWorld;
|
|
226
|
+
|
|
227
|
+
/* rgb: transmission times tint; a: clarity, one less the frost. */
|
|
228
|
+
uniform vec4 uGlassPane;
|
|
229
|
+
/* xyz: the light's position (w 1) or the direction toward it (w 0). */
|
|
230
|
+
uniform vec4 uGlassLight;
|
|
231
|
+
|
|
232
|
+
out vec4 outTint;
|
|
233
|
+
|
|
234
|
+
void main() {
|
|
235
|
+
${GLASS_TINT_BODY}
|
|
236
|
+
}
|
|
237
|
+
`;
|
|
238
|
+
/** A cut-out pane: its colour lands only where its depth does, by the depth cutout's own test. */
|
|
239
|
+
export const GLASS_TINT_CUTOUT_FRAG = `#version 300 es
|
|
240
|
+
precision highp float;
|
|
241
|
+
in vec4 vLightPosition;
|
|
242
|
+
in vec3 vUv;
|
|
243
|
+
flat in float vAlphaCutout;
|
|
244
|
+
in vec3 vGlassWorld;
|
|
245
|
+
|
|
246
|
+
uniform vec4 uGlassPane;
|
|
247
|
+
uniform vec4 uGlassLight;
|
|
248
|
+
uniform highp sampler2DArray uCutoutMap;
|
|
249
|
+
${CUTOUT_COVERAGE_GLSL}
|
|
250
|
+
out vec4 outTint;
|
|
251
|
+
|
|
252
|
+
void main() {
|
|
253
|
+
/* First, in uniform control flow, as the depth cutout samples it. */
|
|
254
|
+
vec3 at = vec3(vUv.xy, floor(vUv.z + 0.5));
|
|
255
|
+
float alpha = cutoutAlpha(texture(uCutoutMap, at).a, vUv.xy * vec2(textureSize(uCutoutMap, 0).xy));
|
|
256
|
+
${GLASS_TINT_BODY}
|
|
257
|
+
if (alpha < vAlphaCutout) discard;
|
|
258
|
+
}
|
|
259
|
+
`;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Filtering the directional cascade, with receiver-plane depth gradient compensation. */
|
|
2
2
|
import { DIRECTIONAL_SHADOW_FADE_START, MAX_SHADOW_FILTER_TAPS } from '../../renderQuality.js';
|
|
3
|
+
import { SUN_DYNAMIC_LAYER, SUN_GLASS_MOVING_LAYER, SUN_GLASS_STATIC_LAYER, SUN_PEELED_LAYER, SUN_STATIC_LAYER, } from '../../shadowMap.js';
|
|
4
|
+
import { FROST_RADIUS_CAP, FROST_SPREAD } from '../../glassShadow.js';
|
|
3
5
|
export const DIRECTIONALSHADOW_GLSL = `vec2 receiverPlaneDepthGradient(vec3 p) {
|
|
4
6
|
vec3 dx = dFdx(p);
|
|
5
7
|
vec3 dy = dFdy(p);
|
|
@@ -126,10 +128,10 @@ float shadowFactor(float directionalNdl) {
|
|
|
126
128
|
*/
|
|
127
129
|
float coarseCompare = p.z - 1.0 / uShadowDepthSpan;
|
|
128
130
|
float coarse =
|
|
129
|
-
directionalVisibility(p.z, coarseCompare, textureLod(
|
|
130
|
-
directionalVisibility(p.z, coarseCompare, textureLod(
|
|
131
|
+
directionalVisibility(p.z, coarseCompare, textureLod(uSunShadows, vec3(p.xy, ${SUN_STATIC_LAYER}.0), 0.0).r) *
|
|
132
|
+
directionalVisibility(p.z, coarseCompare, textureLod(uSunShadows, vec3(p.xy, ${SUN_DYNAMIC_LAYER}.0), 0.0).r);
|
|
131
133
|
if (uPeeledShadowEnabled != 0) {
|
|
132
|
-
coarse *= directionalVisibility(p.z, coarseCompare, textureLod(
|
|
134
|
+
coarse *= directionalVisibility(p.z, coarseCompare, textureLod(uSunShadows, vec3(p.xy, ${SUN_PEELED_LAYER}.0), 0.0).r);
|
|
133
135
|
}
|
|
134
136
|
float strength = uShadowStrength * edgeFade * lowElevationFade;
|
|
135
137
|
if (receiverFade <= 0.0) return mix(1.0, coarse, strength);
|
|
@@ -190,11 +192,11 @@ float shadowFactor(float directionalNdl) {
|
|
|
190
192
|
* \`shadowMap.ts\` allocates these with one storage level and \`NEAREST\` filtering, so
|
|
191
193
|
* there is no mip to select and level zero is the only thing \`texture\` could have read.
|
|
192
194
|
*/
|
|
193
|
-
float staticDepth = textureLod(
|
|
194
|
-
float dynamicDepth = textureLod(
|
|
195
|
+
float staticDepth = textureLod(uSunShadows, vec3(sampleUv, ${SUN_STATIC_LAYER}.0), 0.0).r;
|
|
196
|
+
float dynamicDepth = textureLod(uSunShadows, vec3(sampleUv, ${SUN_DYNAMIC_LAYER}.0), 0.0).r;
|
|
195
197
|
staticLit += directionalVisibility(tapReceiverDepth, compare, staticDepth);
|
|
196
198
|
if (uPeeledShadowEnabled != 0) {
|
|
197
|
-
float peeledDepth = textureLod(
|
|
199
|
+
float peeledDepth = textureLod(uSunShadows, vec3(sampleUv, ${SUN_PEELED_LAYER}.0), 0.0).r;
|
|
198
200
|
peeledLit += directionalVisibility(tapReceiverDepth, compare, peeledDepth);
|
|
199
201
|
} else {
|
|
200
202
|
peeledLit += 1.0;
|
|
@@ -214,6 +216,89 @@ float shadowFactor(float directionalNdl) {
|
|
|
214
216
|
|
|
215
217
|
return mix(1.0, mix(coarse, lit, receiverFade), strength);
|
|
216
218
|
}
|
|
219
|
+
|
|
220
|
+
/*
|
|
221
|
+
* One of the sun's two glass layers at receiver p: how milky the nearest pane is and how far behind
|
|
222
|
+
* it this receiver stands, the spread that follows (glassShadow.ts's frostRadius, capped), and the
|
|
223
|
+
* tint's level for that spread. Then glassShadow.ts's spreadTint: the outline from taps at the base
|
|
224
|
+
* radius — where the clear pane's patch ends — and the colour from the spread taps, each read coarse,
|
|
225
|
+
* unmixed from the ground around it and weighed by the pane's share of it, so a frosted patch mixes
|
|
226
|
+
* its panes' colours and keeps the light the clear one lets through. What it gives up is a pane lying
|
|
227
|
+
* behind the receiver lending it colour within the spread, which only a receiver between two panes
|
|
228
|
+
* meets. One function for both layers, because two copies were most of the lit shaders' growth.
|
|
229
|
+
*/
|
|
230
|
+
vec3 sunGlassLayer(vec3 p, float paneLayer, float tintLayer, float bias, float texel, float uvPerMetre) {
|
|
231
|
+
float tintSize = float(textureSize(uSunGlassTints, 0).x);
|
|
232
|
+
float clarity = textureLod(uSunGlassTints, vec3(p.xy, tintLayer), 0.0).a;
|
|
233
|
+
float behind =
|
|
234
|
+
max(p.z - textureLod(uSunShadows, vec3(p.xy, paneLayer), 0.0).r, 0.0) * uShadowDepthSpan;
|
|
235
|
+
float radius = clamp(
|
|
236
|
+
(1.0 - clarity) * ${FROST_SPREAD.toFixed(6)} * behind * uvPerMetre,
|
|
237
|
+
texel,
|
|
238
|
+
texel * ${FROST_RADIUS_CAP.toFixed(1)}
|
|
239
|
+
);
|
|
240
|
+
float lod = log2(max(radius * tintSize, 1.0));
|
|
241
|
+
float cover = 0.0;
|
|
242
|
+
vec3 colour = vec3(0.0);
|
|
243
|
+
float found = 0.0;
|
|
244
|
+
for (int i = 0; i < ${MAX_SHADOW_FILTER_TAPS}; i++) {
|
|
245
|
+
if (i >= uShadowFilterTaps) break;
|
|
246
|
+
vec2 offset = DIRECTIONAL_PCF_OFFSETS[i];
|
|
247
|
+
vec2 edgeUv = p.xy + offset * texel;
|
|
248
|
+
cover += p.z > textureLod(uSunShadows, vec3(edgeUv, paneLayer), 0.0).r + bias ? 1.0 : 0.0;
|
|
249
|
+
/* The spread taps weigh by the pane's unmixed share rather than a depth test: continuous, so a
|
|
250
|
+
colour crossing between two panes blends rather than stepping through sixteen bands. */
|
|
251
|
+
vec4 pane = glassUnmix(textureLod(uSunGlassTints, vec3(p.xy + offset * radius, tintLayer), lod), clarity);
|
|
252
|
+
colour += pane.rgb * pane.a;
|
|
253
|
+
found += pane.a;
|
|
254
|
+
}
|
|
255
|
+
float taps = float(max(uShadowFilterTaps, 1));
|
|
256
|
+
return mix(vec3(1.0), found > 0.0 ? colour / found : vec3(1.0), cover / taps);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/*
|
|
260
|
+
* What the sun's light keeps of itself through glass at this receiver: glassShadow.ts's tap rule
|
|
261
|
+
* and frost spread, over shadowFactor's own taps. A tap counts a pane only when the receiver is
|
|
262
|
+
* farther from the sun than that pane (the glass depth layers), so a surface on the sun's side of a
|
|
263
|
+
* pane, and the pane itself, keep the sun's own colour; the taps average with equal weight, so the
|
|
264
|
+
* spread moves light rather than losing it. Frost widens the taps by how far behind the nearest pane
|
|
265
|
+
* the receiver is, capped, with the tap count unchanged. What it gives up is spread past the edge of
|
|
266
|
+
* an opaque frame's shadow, which this lookup never sees. Faded with the opaque shadow's own fades.
|
|
267
|
+
*/
|
|
268
|
+
vec3 sunGlassLookup(float directionalNdl) {
|
|
269
|
+
vec3 p = vLightPos.xyz / vLightPos.w;
|
|
270
|
+
p = p * 0.5 + 0.5;
|
|
271
|
+
/* Map units per metre along the receiver, from derivatives taken first in uniform control flow,
|
|
272
|
+
so a frost spread stated in metres lands the same whatever size of light matrix a consumer built. */
|
|
273
|
+
float uvPerMetre = length(dFdx(p.xy)) / max(length(dFdx(vWorldPos)), 1e-6);
|
|
274
|
+
if (uShadowStrength <= 0.0 || textureSize(uSunGlassTints, 0).x <= 1) return vec3(1.0);
|
|
275
|
+
if (directionalNdl <= 0.0) return vec3(1.0);
|
|
276
|
+
if (p.z > 1.0 || p.x < 0.0 || p.x > 1.0 || p.y < 0.0 || p.y > 1.0) return vec3(1.0);
|
|
277
|
+
vec2 fromCentre = abs(p.xy - 0.5) * 2.0;
|
|
278
|
+
float edgeFade = 1.0 - smoothstep(0.72, 0.98, max(fromCentre.x, fromCentre.y));
|
|
279
|
+
edgeFade *= 1.0 - smoothstep(0.90, 1.0, p.z);
|
|
280
|
+
float shadowSlope = length(uDirectionalDir.xz) / max(uDirectionalDir.y, 0.001);
|
|
281
|
+
float lowElevationFade = 1.0 - smoothstep(
|
|
282
|
+
uShadowMaxSlope * ${DIRECTIONAL_SHADOW_FADE_START.toFixed(2)},
|
|
283
|
+
uShadowMaxSlope,
|
|
284
|
+
shadowSlope
|
|
285
|
+
);
|
|
286
|
+
float strength = uShadowStrength * edgeFade * lowElevationFade;
|
|
287
|
+
if (strength <= 0.0) return vec3(1.0);
|
|
288
|
+
|
|
289
|
+
float bias = 0.14 / uShadowDepthSpan;
|
|
290
|
+
float texel = 1.35 / uShadowMapSize;
|
|
291
|
+
vec3 staticTint = sunGlassLayer(p, ${SUN_GLASS_STATIC_LAYER}.0, 0.0, bias, texel, uvPerMetre);
|
|
292
|
+
vec3 movingTint = sunGlassLayer(p, ${SUN_GLASS_MOVING_LAYER}.0, 1.0, bias, texel, uvPerMetre);
|
|
293
|
+
return mix(vec3(1.0), staticTint * movingTint, strength);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* The way in, asking first whether this build reads glass at all (GLASS_SHADOWS). A constant, so
|
|
297
|
+
the lookup's derivatives are still taken in uniform control flow. */
|
|
298
|
+
vec3 sunGlassTint(float directionalNdl) {
|
|
299
|
+
if (GLASS_SHADOWS) return sunGlassLookup(directionalNdl);
|
|
300
|
+
return vec3(1.0);
|
|
301
|
+
}
|
|
217
302
|
#endif
|
|
218
303
|
|
|
219
304
|
/**
|
|
@@ -26,4 +26,4 @@
|
|
|
26
26
|
* `textureLod` throughout, by the 2026-08-07 rule: this is reached through branches no compiler can
|
|
27
27
|
* prove uniform. Both samplers are declared `highp` because GLSL ES gives 3D samplers no default.
|
|
28
28
|
*/
|
|
29
|
-
export declare const DRIFT_LIGHT_GLSL = "\n/** x how much of the summed light is in the frame (0 off), y the radius, z the band, w the scale. */\nuniform vec4 uDriftLight;\n/** xyz the first
|
|
29
|
+
export declare const DRIFT_LIGHT_GLSL = "\n/** x how much of the summed light is in the frame (0 off), y the radius, z the band, w the scale. */\nuniform vec4 uDriftLight;\n/** xyz the first sample; w metres between samples \u2014 a third of a brick, or negated for a dense volume. */\nuniform vec4 uDriftLightOrigin;\nuniform highp usampler3D uDriftLightIndex; // wgsl:share shadow\nuniform highp sampler3D uDriftLightAtlas;\n\n/** The share of this pixel's field light the volume stands in for: 0 inside the radius, 1 past it. */\nfloat driftLightShare(vec3 world) {\n if (uDriftLight.x <= 0.0) return 0.0;\n float away = distance(world, uCameraPos);\n return smoothstep(uDriftLight.y - uDriftLight.z, uDriftLight.y, away) * uDriftLight.x;\n}\n\n/**\n * A sample's light and direction turned into the light on a surface facing `n`: Lambert for a\n * single light, a quarter for light arriving from everywhere (see `bake.ts`). One statement for\n * both kinds of volume.\n */\nvec3 driftLightFacing(vec4 light, vec4 toward, vec3 n) {\n vec3 arriving = light.rgb / light.a;\n vec3 from = toward.xyz / light.a;\n float facing = max(dot(n, from), 0.0) + (1.0 - min(length(from), 1.0)) * 0.25;\n return arriving * facing;\n}\n\n/**\n * The same from a dense volume: one sample a texel, the light in the lower half of y and its\n * direction in the upper. A lookup kept inside the samples never filters across the halves.\n */\nvec3 driftLightDense(vec3 world, vec3 n, float spacing) {\n ivec3 size = textureSize(uDriftLightAtlas, 0);\n vec3 dims = vec3(float(size.x), float(size.y / 2), float(size.z));\n vec3 at = (world + n * (0.5 * spacing) - uDriftLightOrigin.xyz) / spacing;\n if (any(lessThan(at, vec3(0.0))) || any(greaterThan(at, dims - 1.0))) return vec3(0.0);\n vec3 uvw = (at + 0.5) / vec3(dims.x, dims.y * 2.0, dims.z);\n vec4 light = textureLod(uDriftLightAtlas, uvw, 0.0);\n if (light.a < 1e-3) return vec3(0.0);\n vec4 toward = textureLod(uDriftLightAtlas, uvw + vec3(0.0, 0.5, 0.0), 0.0);\n return driftLightFacing(light, toward, n);\n}\n\n/** The summed light arriving on a surface at `world` facing `n`. A negative spacing is dense. */\nvec3 driftLightIrradiance(vec3 world, vec3 n) {\n float spacing = uDriftLightOrigin.w;\n if (spacing < 0.0) return driftLightDense(world, n, -spacing);\n vec3 at = (world + n * (0.5 * spacing) - uDriftLightOrigin.xyz) / (3.0 * spacing);\n ivec3 cell = ivec3(floor(at));\n if (any(lessThan(cell, ivec3(0))) || any(greaterThanEqual(cell, textureSize(uDriftLightIndex, 0)))) {\n return vec3(0.0);\n }\n uint id = texelFetch(uDriftLightIndex, cell, 0).r;\n if (id == 0u) return vec3(0.0);\n /* A brick is eight texels across (its light block, then its direction block) and four up and deep. */\n ivec3 size = textureSize(uDriftLightAtlas, 0);\n int brick = int(id) - 1;\n int across = size.x / 8;\n int down = size.y / 4;\n vec3 corner = vec3(\n float((brick % across) * 8),\n float(((brick / across) % down) * 4),\n float((brick / (across * down)) * 4)\n );\n vec3 texel = 1.0 / vec3(size);\n vec3 inside = (at - vec3(cell)) * 3.0 + 0.5;\n vec4 light = textureLod(uDriftLightAtlas, (corner + inside) * texel, 0.0);\n if (light.a < 1e-3) return vec3(0.0);\n vec4 toward = textureLod(uDriftLightAtlas, (corner + vec3(4.0, 0.0, 0.0) + inside) * texel, 0.0);\n return driftLightFacing(light, toward, n);\n}\n";
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
export const DRIFT_LIGHT_GLSL = /* glsl */ `
|
|
30
30
|
/** x how much of the summed light is in the frame (0 off), y the radius, z the band, w the scale. */
|
|
31
31
|
uniform vec4 uDriftLight;
|
|
32
|
-
/** xyz the first
|
|
32
|
+
/** xyz the first sample; w metres between samples — a third of a brick, or negated for a dense volume. */
|
|
33
33
|
uniform vec4 uDriftLightOrigin;
|
|
34
34
|
uniform highp usampler3D uDriftLightIndex; // wgsl:share shadow
|
|
35
35
|
uniform highp sampler3D uDriftLightAtlas;
|
|
@@ -41,9 +41,38 @@ float driftLightShare(vec3 world) {
|
|
|
41
41
|
return smoothstep(uDriftLight.y - uDriftLight.z, uDriftLight.y, away) * uDriftLight.x;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* A sample's light and direction turned into the light on a surface facing \`n\`: Lambert for a
|
|
46
|
+
* single light, a quarter for light arriving from everywhere (see \`bake.ts\`). One statement for
|
|
47
|
+
* both kinds of volume.
|
|
48
|
+
*/
|
|
49
|
+
vec3 driftLightFacing(vec4 light, vec4 toward, vec3 n) {
|
|
50
|
+
vec3 arriving = light.rgb / light.a;
|
|
51
|
+
vec3 from = toward.xyz / light.a;
|
|
52
|
+
float facing = max(dot(n, from), 0.0) + (1.0 - min(length(from), 1.0)) * 0.25;
|
|
53
|
+
return arriving * facing;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The same from a dense volume: one sample a texel, the light in the lower half of y and its
|
|
58
|
+
* direction in the upper. A lookup kept inside the samples never filters across the halves.
|
|
59
|
+
*/
|
|
60
|
+
vec3 driftLightDense(vec3 world, vec3 n, float spacing) {
|
|
61
|
+
ivec3 size = textureSize(uDriftLightAtlas, 0);
|
|
62
|
+
vec3 dims = vec3(float(size.x), float(size.y / 2), float(size.z));
|
|
63
|
+
vec3 at = (world + n * (0.5 * spacing) - uDriftLightOrigin.xyz) / spacing;
|
|
64
|
+
if (any(lessThan(at, vec3(0.0))) || any(greaterThan(at, dims - 1.0))) return vec3(0.0);
|
|
65
|
+
vec3 uvw = (at + 0.5) / vec3(dims.x, dims.y * 2.0, dims.z);
|
|
66
|
+
vec4 light = textureLod(uDriftLightAtlas, uvw, 0.0);
|
|
67
|
+
if (light.a < 1e-3) return vec3(0.0);
|
|
68
|
+
vec4 toward = textureLod(uDriftLightAtlas, uvw + vec3(0.0, 0.5, 0.0), 0.0);
|
|
69
|
+
return driftLightFacing(light, toward, n);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The summed light arriving on a surface at \`world\` facing \`n\`. A negative spacing is dense. */
|
|
45
73
|
vec3 driftLightIrradiance(vec3 world, vec3 n) {
|
|
46
74
|
float spacing = uDriftLightOrigin.w;
|
|
75
|
+
if (spacing < 0.0) return driftLightDense(world, n, -spacing);
|
|
47
76
|
vec3 at = (world + n * (0.5 * spacing) - uDriftLightOrigin.xyz) / (3.0 * spacing);
|
|
48
77
|
ivec3 cell = ivec3(floor(at));
|
|
49
78
|
if (any(lessThan(cell, ivec3(0))) || any(greaterThanEqual(cell, textureSize(uDriftLightIndex, 0)))) {
|
|
@@ -66,10 +95,6 @@ vec3 driftLightIrradiance(vec3 world, vec3 n) {
|
|
|
66
95
|
vec4 light = textureLod(uDriftLightAtlas, (corner + inside) * texel, 0.0);
|
|
67
96
|
if (light.a < 1e-3) return vec3(0.0);
|
|
68
97
|
vec4 toward = textureLod(uDriftLightAtlas, (corner + vec3(4.0, 0.0, 0.0) + inside) * texel, 0.0);
|
|
69
|
-
|
|
70
|
-
vec3 from = toward.xyz / light.a;
|
|
71
|
-
/* Lambert for a single light, a quarter for light arriving from everywhere: see \`bake.ts\`. */
|
|
72
|
-
float facing = max(dot(n, from), 0.0) + (1.0 - min(length(from), 1.0)) * 0.25;
|
|
73
|
-
return arriving * facing;
|
|
98
|
+
return driftLightFacing(light, toward, n);
|
|
74
99
|
}
|
|
75
100
|
`;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the lit stage shares between every glass tint it reads: whether it reads any, and
|
|
3
|
+
* `glassShadow.ts`'s `unmixTint`, stated once for the sun's lookup and the lamps'. At depth zero,
|
|
4
|
+
* outside every conditional, so each lookup can call it whichever shadows a permutation compiles.
|
|
5
|
+
*/
|
|
6
|
+
export declare function glassTintGlsl(glassShadows: boolean): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the lit stage shares between every glass tint it reads: whether it reads any, and
|
|
3
|
+
* `glassShadow.ts`'s `unmixTint`, stated once for the sun's lookup and the lamps'. At depth zero,
|
|
4
|
+
* outside every conditional, so each lookup can call it whichever shadows a permutation compiles.
|
|
5
|
+
*/
|
|
6
|
+
export function glassTintGlsl(glassShadows) {
|
|
7
|
+
return /* glsl */ `
|
|
8
|
+
/*
|
|
9
|
+
* Whether this build reads glass at all, which every way into the lookups asks first — and as a
|
|
10
|
+
* branch's own condition, never negated: see \`overridableConstants\` in scripts/wgsl/transform.mjs.
|
|
11
|
+
*/
|
|
12
|
+
const bool GLASS_SHADOWS = ${glassShadows ? 'true' : 'false'}; // wgsl:override
|
|
13
|
+
/*
|
|
14
|
+
* A coarse level of a glass tint with the open ground's white taken back out, by how milky the pane
|
|
15
|
+
* at the centre is: rgb the pane's colour, a its share of the texel (glassShadow.ts's unmixTint).
|
|
16
|
+
* A clear centre is never read coarse, so it is returned as it stands.
|
|
17
|
+
*/
|
|
18
|
+
vec4 glassUnmix(vec4 mip, float centreClarity) {
|
|
19
|
+
if (centreClarity >= 1.0) return vec4(mip.rgb, 1.0);
|
|
20
|
+
float share = clamp((1.0 - mip.a) / (1.0 - centreClarity), 0.0, 1.0);
|
|
21
|
+
if (share <= 0.0) return vec4(1.0, 1.0, 1.0, 0.0);
|
|
22
|
+
return vec4(clamp((mip.rgb - vec3(1.0 - share)) / share, 0.0, 1.0), share);
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
}
|
|
@@ -79,6 +79,19 @@ export interface FlatShaderOptions {
|
|
|
79
79
|
* for its instructions not to be there.
|
|
80
80
|
*/
|
|
81
81
|
readonly nightEmissive: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Whether this build reads glass in its shadows at all: `glassShadows` other than `'off'`. True
|
|
84
|
+
* when absent, which is what the generated WGSL is built with.
|
|
85
|
+
*
|
|
86
|
+
* **Not a permutation axis, and the payload is why.** Every lit permutation carries the glass
|
|
87
|
+
* lookups, and a second copy of each without them would be most of the generated file again. So
|
|
88
|
+
* it is one switch, `GLASS_SHADOWS`, that every way into the lookups branches on first: written
|
|
89
|
+
* into this source for WebGL2, and a pipeline-overridable constant on the generated WGSL, which
|
|
90
|
+
* the device compiles away as it would under `#if`. That matters because the lookups returning
|
|
91
|
+
* at their first line still cost the lit pass its registers — 0.42 ms at 720p on WebGL2 on the
|
|
92
|
+
* courtyard at night, measured, and nothing once compiled out.
|
|
93
|
+
*/
|
|
94
|
+
readonly glassShadows?: boolean;
|
|
82
95
|
/**
|
|
83
96
|
* How many point lights this build declares room for. `MAX_POINT_LIGHTS` when absent.
|
|
84
97
|
*
|
|
@@ -7,11 +7,13 @@ import { preambleGlsl } from './preamble.js';
|
|
|
7
7
|
import { LOBES_GLSL } from './lobes.js';
|
|
8
8
|
import { POINTSHADOW_GLSL } from './pointShadow.js';
|
|
9
9
|
import { DIRECTIONALSHADOW_GLSL } from './directionalShadow.js';
|
|
10
|
+
import { glassTintGlsl } from './glassTint.js';
|
|
10
11
|
import { MORPH_GLSL } from '../morph.js';
|
|
11
12
|
import { SKINNING_GLSL } from '../skinning.js';
|
|
12
13
|
import { SURFACE_GLSL } from './surface.js';
|
|
13
14
|
import { MAIN_GLSL } from './main.js';
|
|
14
15
|
import { DRIFT_LIGHT_GLSL } from './driftLight.js';
|
|
16
|
+
import { SURFACE_EFFECTS_GLSL } from './surfaceEffects.js';
|
|
15
17
|
import { CHANNEL_ATTRIBUTE, CHANNEL_BEND } from '../vertexChannel.js';
|
|
16
18
|
import { FULL_LIGHT_BUDGET } from '../../uniformVectorBudget.js';
|
|
17
19
|
/**
|
|
@@ -26,7 +28,7 @@ layout(location = 1) in vec3 aNormal;
|
|
|
26
28
|
layout(location = 2) in vec3 aColor;
|
|
27
29
|
layout(location = 3) in float aEmissive;
|
|
28
30
|
layout(location = 4) in float aSpecular;
|
|
29
|
-
layout(location = 5) in
|
|
31
|
+
layout(location = 5) in vec3 aUv;
|
|
30
32
|
layout(location = 6) in vec3 aEmissiveColor;
|
|
31
33
|
layout(location = 7) in float aRoughness;
|
|
32
34
|
layout(location = 8) in float aGrain;
|
|
@@ -144,7 +146,7 @@ out vec3 vWorldPos;
|
|
|
144
146
|
out float vEmissive;
|
|
145
147
|
out float vSpecular;
|
|
146
148
|
out vec4 vLightPos;
|
|
147
|
-
out
|
|
149
|
+
out vec3 vUv;
|
|
148
150
|
out vec3 vEmissiveColor;
|
|
149
151
|
out float vRoughness;
|
|
150
152
|
out float vGrain;
|
|
@@ -241,7 +243,7 @@ void main() {
|
|
|
241
243
|
vColor = aColor * tint;
|
|
242
244
|
vEmissive = aEmissive;
|
|
243
245
|
vSpecular = aSpecular;
|
|
244
|
-
vUv = aUv * uUvScale;
|
|
246
|
+
vUv = vec3(aUv.xy * uUvScale, aUv.z);
|
|
245
247
|
vEmissiveColor = aEmissiveColor;
|
|
246
248
|
vRoughness = aRoughness;
|
|
247
249
|
vGrain = aGrain;
|
|
@@ -354,6 +356,9 @@ export function flatFrag(options) {
|
|
|
354
356
|
* is at depth zero, and it is still declared before `pointShadow` uses it.
|
|
355
357
|
*/
|
|
356
358
|
OCTAHEDRAL_GLSL,
|
|
359
|
+
/* Depth zero as well: both glass lookups, sun and lamps, call it, and every permutation
|
|
360
|
+
declares its switch, which the pipelines set whether the permutation reads it or not. */
|
|
361
|
+
glassTintGlsl(options.glassShadows ?? true),
|
|
357
362
|
LOBES_GLSL,
|
|
358
363
|
POINTSHADOW_GLSL,
|
|
359
364
|
DIRECTIONALSHADOW_GLSL,
|
|
@@ -382,6 +387,7 @@ export function flatFrag(options) {
|
|
|
382
387
|
/* Unconditional for the same reason, and called only where a cutoff was asked for. */
|
|
383
388
|
CUTOUT_COVERAGE_GLSL,
|
|
384
389
|
DRIFT_LIGHT_GLSL,
|
|
390
|
+
SURFACE_EFFECTS_GLSL,
|
|
385
391
|
MAIN_GLSL,
|
|
386
392
|
].join('\n'), {
|
|
387
393
|
POINT_SHADOWS: options.pointShadows,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LAMP_GLASS_GLSL: string;
|