@driftengine/core 4.5.0 → 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 +51 -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 +23 -2
- package/dist/index.js +13 -1
- package/dist/render/backend/api.d.ts +17 -3
- 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/instanced.d.ts +24 -5
- package/dist/render/backend/webgl2/instanced.js +72 -15
- package/dist/render/backend/webgl2/renderer.d.ts +122 -8
- package/dist/render/backend/webgl2/renderer.js +238 -121
- package/dist/render/backend/webgpu/buffers.d.ts +10 -0
- package/dist/render/backend/webgpu/buffers.js +34 -3
- package/dist/render/backend/webgpu/depthPass.js +5 -1
- 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 +4 -1
- package/dist/render/backend/webgpu/flatPass.js +38 -9
- package/dist/render/backend/webgpu/glassTintPass.js +2 -1
- 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 +11 -1
- package/dist/render/backend/webgpu/instanced.js +21 -3
- package/dist/render/backend/webgpu/latePass.d.ts +6 -2
- package/dist/render/backend/webgpu/latePass.js +11 -4
- package/dist/render/backend/webgpu/postPass.d.ts +1 -1
- package/dist/render/backend/webgpu/renderer.d.ts +100 -10
- package/dist/render/backend/webgpu/renderer.js +462 -201
- 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/surfaceTexturePass.d.ts +17 -3
- package/dist/render/backend/webgpu/surfaceTexturePass.js +77 -38
- 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/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 +22 -33
- package/dist/render/lightBudget.js +24 -35
- 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/pointLightSelection.d.ts +7 -0
- package/dist/render/pointLightSelection.js +29 -4
- package/dist/render/rainField.d.ts +13 -0
- package/dist/render/rainField.js +27 -5
- package/dist/render/recon/lateDepth.d.ts +11 -0
- package/dist/render/recon/lateDepth.js +70 -0
- package/dist/render/recon/resolve.d.ts +34 -4
- package/dist/render/recon/resolve.js +161 -20
- package/dist/render/rendererHarness.js +4 -0
- package/dist/render/sceneTarget.d.ts +2 -0
- package/dist/render/sceneTarget.js +2 -0
- package/dist/render/shaders/depth.js +12 -9
- package/dist/render/shaders/flat/driftLight.d.ts +1 -1
- package/dist/render/shaders/flat/driftLight.js +32 -7
- package/dist/render/shaders/flat/index.js +5 -3
- package/dist/render/shaders/flat/main.d.ts +1 -1
- package/dist/render/shaders/flat/main.js +75 -23
- package/dist/render/shaders/flat/preamble.js +75 -20
- 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 +8 -8
- package/dist/render/shaders/generated/depth.wgsl.js +8 -8
- package/dist/render/shaders/generated/flat.wgsl.d.ts +1320 -1320
- package/dist/render/shaders/generated/flat.wgsl.js +1359 -1345
- package/dist/render/shaders/generated/lightVolume.wgsl.js +18 -4
- 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/recon/lateDepth.wgsl.js +38 -13
- 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/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/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 +51 -1
- package/src/render/backend/api.ts +21 -2
- package/src/render/backend/drawFog.ts +31 -0
- package/src/render/backend/materialChanges.ts +9 -2
- package/src/render/backend/webgl2/instanced.ts +80 -14
- package/src/render/backend/webgl2/renderer.ts +300 -143
- package/src/render/backend/webgpu/buffers.ts +42 -3
- package/src/render/backend/webgpu/depthPass.ts +5 -1
- package/src/render/backend/webgpu/drawCommand.ts +6 -0
- package/src/render/backend/webgpu/flatPass.ts +41 -11
- package/src/render/backend/webgpu/glassTintPass.ts +2 -1
- package/src/render/backend/webgpu/instanceCullPass.ts +165 -0
- package/src/render/backend/webgpu/instanced.ts +21 -3
- package/src/render/backend/webgpu/latePass.ts +12 -3
- package/src/render/backend/webgpu/renderer.ts +540 -226
- 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/surfaceTexturePass.ts +90 -50
- 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/instanceCull.ts +205 -0
- package/src/render/instances.ts +16 -0
- package/src/render/lightBudget.ts +25 -36
- package/src/render/lightGrid.ts +130 -0
- package/src/render/mesh.ts +59 -72
- package/src/render/occlusion.ts +51 -7
- package/src/render/pointLightSelection.ts +72 -4
- package/src/render/rainField.ts +39 -5
- package/src/render/recon/lateDepth.ts +83 -0
- package/src/render/recon/resolve.ts +206 -20
- package/src/render/rendererHarness.ts +4 -0
- package/src/render/sceneTarget.ts +4 -0
- package/src/render/shaders/depth.ts +12 -9
- package/src/render/shaders/flat/driftLight.ts +32 -7
- package/src/render/shaders/flat/index.ts +5 -3
- package/src/render/shaders/flat/main.ts +75 -23
- package/src/render/shaders/flat/preamble.ts +75 -20
- package/src/render/shaders/flat/surfaceEffects.ts +152 -0
- package/src/render/shaders/generated/depth.wgsl.ts +8 -8
- package/src/render/shaders/generated/flat.wgsl.ts +1361 -1345
- package/src/render/shaders/generated/lightVolume.wgsl.ts +20 -4
- 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/recon/lateDepth.wgsl.ts +38 -13
- 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/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/vertexDefaults.ts +2 -0
- package/src/world/hlod.ts +290 -0
package/dist/index.js
CHANGED
|
@@ -180,6 +180,9 @@ export { countSplatTiles, fillSplatTiles, splatPixelBox, splatTileGrid, splatTil
|
|
|
180
180
|
export { GI_SOURCE_FIELD, GI_SOURCE_PROBES, GI_SOURCE_SCREEN, newIndirectResult, traceIndirect, } from './render/gi/chain.js';
|
|
181
181
|
export { GLOBAL_FIELD_BLEND, composeGlobalField, createGlobalField, sampleGlobalField, } from './render/gi/globalField.js';
|
|
182
182
|
export { FIELD_FADE_SEC, LightField } from './render/driftLight/lightField.js';
|
|
183
|
+
export { DENSE_MAX_AXIS, DENSE_MAX_HEIGHT, bakeDenseField, } from './render/driftLight/denseField.js';
|
|
184
|
+
export { WorldLightField } from './render/driftLight/worldLightField.js';
|
|
185
|
+
export { SURFACE_EFFECT_TEXELS, packSurfaceEffects } from './render/surfaceEffects.js';
|
|
183
186
|
export { GI_SCREEN_MARCH, SCREEN_TRACE_BIAS_M, screenRayOrigin, traceScreen, } from './render/gi/traceScreen.js';
|
|
184
187
|
export { FIELD_MARCH, coneRadiusAt, newFieldHit, traceField } from './render/gi/traceField.js';
|
|
185
188
|
export { PROBE_VISIBILITY_SHARPNESS, bakeProbeVisibility, createProbeVisibility, probeUpdateSchedule, probeVisibilityWeight, sampleProbeVolume, visibleProbes, } from './render/gi/probeVolume.js';
|
|
@@ -266,7 +269,8 @@ export { isWeakGpuFamily } from './render/gpuCapability.js';
|
|
|
266
269
|
* which is the right time for a boot log and too late for a decision.
|
|
267
270
|
*/
|
|
268
271
|
export { describeGpu } from './render/gpuCapability.js';
|
|
269
|
-
export { DEFAULT_POINT_LIGHT_VIEW_RANGE, createPointLightBuffer, selectPointLights, } from './render/pointLightSelection.js';
|
|
272
|
+
export { DEFAULT_POINT_LIGHT_VIEW_RANGE, createPointLightBuffer, selectGridLights, selectPointLights, } from './render/pointLightSelection.js';
|
|
273
|
+
export { LIGHT_GRID_MAX_CELLS, createLightGrid, gatherLights } from './render/lightGrid.js';
|
|
270
274
|
export { createFlame, flameFrequencyHz, updateFlame } from './render/flameLight.js';
|
|
271
275
|
export { computeLightMatrix } from './render/lightMatrix.js';
|
|
272
276
|
export { PlumeRenderer } from './render/plumeRenderer.js';
|
|
@@ -306,6 +310,12 @@ export { SMOKE_FRAG } from './render/shaders/smoke.js';
|
|
|
306
310
|
export { WaterRenderer } from './render/waterRenderer.js';
|
|
307
311
|
export { MeshBuilder } from './geometry/meshBuilder.js';
|
|
308
312
|
export { concatMeshes, placeMesh } from './geometry/meshConcat.js';
|
|
313
|
+
export { emptySolid, mergeSolids, solidToMesh, solidVolume, transformSolid, } from './geometry/solid.js';
|
|
314
|
+
export { solidBox, solidExtrude, solidPrism, solidQuad, solidRoundedBox, solidSweep, } from './geometry/solidFlat.js';
|
|
315
|
+
export { solidCapsule, solidCone, solidCylinder, solidFrustum, solidHemisphere, solidIcosphere, solidLathe, solidSphere, solidTorus, solidTube, } from './geometry/solidRound.js';
|
|
316
|
+
export { solidIntersect, solidSubtract, solidUnion } from './geometry/csg.js';
|
|
317
|
+
export { boxBooleanCells, solidBoxBoolean } from './geometry/boxCsg.js';
|
|
318
|
+
export { smoothSolidNormals } from './geometry/solidNormals.js';
|
|
309
319
|
/* A tangent frame, which every map in the material track reads. */
|
|
310
320
|
export { generateTangents } from './geometry/tangents.js';
|
|
311
321
|
export { Spline, createSplineSample } from './geometry/spline.js';
|
|
@@ -474,6 +484,7 @@ export { parseSdfFont } from './render/sdfFont.js';
|
|
|
474
484
|
export { DEFAULT_SDF_TEXT_STYLE, SdfTextLayout } from './render/sdfTextLayout.js';
|
|
475
485
|
export { WindStreakRenderer } from './render/windStreakRenderer.js';
|
|
476
486
|
export { buildTree } from './geometry/treeBuilder.js';
|
|
487
|
+
export { batchBoxVisible, cullInstances, instancesBox } from './render/instanceCull.js';
|
|
477
488
|
/*
|
|
478
489
|
* Large worlds: the cell grid that streams and freezes, and the origin that rendering rebases
|
|
479
490
|
* against while the simulation never does. See `world/rebase.ts` for why that asymmetry is the
|
|
@@ -483,3 +494,4 @@ export { cellBounds, cellCoord, cellCoordInRange, cellCoordsOf, cellIdFor, cellI
|
|
|
483
494
|
export { renderOrigin, toRenderSpace, toWorldSpace } from './world/rebase.js';
|
|
484
495
|
export { cameraPositionFrom, cellPredictor, createCellStream, pumpCellStream, setCellStreamOrigin, } from './world/cellStream.js';
|
|
485
496
|
export { createFrozenCells, freezeCell, frozenEntities, frozenFingerprintContribution, isCellFrozen, thawCell, } from './world/freeze.js';
|
|
497
|
+
export { HLOD_NONE, HlodSet, createHlodDraws, projectionScaleOf } from './world/hlod.js';
|
|
@@ -4,7 +4,7 @@ import type { ReadonlyMat4 } from 'gl-matrix';
|
|
|
4
4
|
import type { MeshData } from '../mesh.ts';
|
|
5
5
|
import type { ProbeBakeOptions } from '../reflectionProbe.ts';
|
|
6
6
|
import type { Renderer, TranslucentMeshOptions } from './webgl2/renderer.ts';
|
|
7
|
-
import type { MeshInstances } from '../instances.ts';
|
|
7
|
+
import type { InstancedOptions, MeshInstances } from '../instances.ts';
|
|
8
8
|
import type { SurfaceMaterial } from '../surfaceTexture.ts';
|
|
9
9
|
import type { TextStyle } from '../textLayout.ts';
|
|
10
10
|
import type { SdfFont } from '../sdfFont.ts';
|
|
@@ -175,9 +175,23 @@ export interface MeshOptions {
|
|
|
175
175
|
}
|
|
176
176
|
export type RendererApi = Omit<{
|
|
177
177
|
[K in keyof Renderer]: Renderer[K];
|
|
178
|
-
}, 'gpuTimer' | 'createMesh' | 'createMeshIncremental' | 'updateMesh' | 'drawMesh' | 'disposeMesh' | 'drawTranslucentMesh' | 'drawLightVolume' | 'drawFilm' | 'createScatter' | 'drawScatter' | 'uploadScatter' | 'disposeScatter' | 'createInstanced' | 'uploadInstanced' | 'drawInstanced' | 'drawTranslucentInstanced' | 'disposeInstanced' | 'createWater' | 'drawWater' | 'disposeWater' | 'createPlumes' | 'drawPlumes' | 'disposePlumes' | 'setPlumeScale' | 'createCaustics' | 'drawCaustics' | 'disposeCaustics' | 'createParticles' | 'drawParticles' | 'disposeParticles' | 'createWindStreaks' | 'drawWindStreaks' | 'disposeWindStreaks' | 'createFlock' | 'drawFlock' | 'disposeFlock' | 'createBolts' | 'drawBolts' | 'disposeBolts' | 'createLines' | 'drawLines' | 'disposeLines' | 'createText' | 'setText' | 'setPlate' | 'drawText' | 'textWidth' | 'disposeText' | 'createSdfText' | 'setSdfText' | 'drawSdfText' | 'disposeSdfText' | 'createSurfaceTexture' | 'updateSurfaceTexture' | 'disposeSurfaceTexture' | 'setSurfaceTexture' | 'setMaterial'> & {
|
|
178
|
+
}, 'gpuTimer' | 'createMesh' | 'createMeshIncremental' | 'updateMesh' | 'drawMesh' | 'disposeMesh' | 'drawTranslucentMesh' | 'drawLightVolume' | 'drawFilm' | 'createScatter' | 'drawScatter' | 'uploadScatter' | 'disposeScatter' | 'createInstanced' | 'uploadInstanced' | 'drawInstanced' | 'drawTranslucentInstanced' | 'disposeInstanced' | 'createWater' | 'drawWater' | 'disposeWater' | 'createPlumes' | 'drawPlumes' | 'disposePlumes' | 'setPlumeScale' | 'createCaustics' | 'drawCaustics' | 'disposeCaustics' | 'createParticles' | 'drawParticles' | 'disposeParticles' | 'createWindStreaks' | 'drawWindStreaks' | 'disposeWindStreaks' | 'createFlock' | 'drawFlock' | 'disposeFlock' | 'createBolts' | 'drawBolts' | 'disposeBolts' | 'createLines' | 'drawLines' | 'disposeLines' | 'createText' | 'setText' | 'setPlate' | 'drawText' | 'textWidth' | 'disposeText' | 'createSdfText' | 'setSdfText' | 'drawSdfText' | 'disposeSdfText' | 'createSurfaceTexture' | 'createSurfaceTextureArray' | 'updateSurfaceTexture' | 'disposeSurfaceTexture' | 'setSurfaceTexture' | 'setMaterial'> & {
|
|
179
179
|
/** Upload a caller's image. See `SurfaceTextureHandle` for the boundary this guards. */
|
|
180
180
|
createSurfaceTexture(source: TexImageSource, options?: Parameters<Renderer['createSurfaceTexture']>[1]): SurfaceTextureHandle;
|
|
181
|
+
/**
|
|
182
|
+
* Upload several images of one size as the layers of one array texture.
|
|
183
|
+
*
|
|
184
|
+
* The same handle a single image returns — every surface texture is an array, and a plain image
|
|
185
|
+
* is an array of one — so it goes wherever a texture goes: any map of `setMaterial`. A mesh picks
|
|
186
|
+
* its image per vertex with `MeshData.layers`, and every map of the material is read at that
|
|
187
|
+
* layer, so an albedo array and an emissive array built in one order pair image with glow by
|
|
188
|
+
* index. **A merged mesh wearing many images is then one draw and one material change.**
|
|
189
|
+
*
|
|
190
|
+
* Every image must be the same size: the device allocates one size for every layer, and the
|
|
191
|
+
* refusal names the first image that differs. A layer past the end reads the last one.
|
|
192
|
+
* `updateSurfaceTexture` refuses an array.
|
|
193
|
+
*/
|
|
194
|
+
createSurfaceTextureArray(sources: readonly TexImageSource[], options?: Parameters<Renderer['createSurfaceTexture']>[1]): SurfaceTextureHandle;
|
|
181
195
|
/**
|
|
182
196
|
* Replace a texture's pixels, keeping the GPU object and its sampler state.
|
|
183
197
|
*
|
|
@@ -324,7 +338,7 @@ export type RendererApi = Omit<{
|
|
|
324
338
|
* would wear one expression. Both are refused where the variant is built rather than dropped
|
|
325
339
|
* quietly.
|
|
326
340
|
*/
|
|
327
|
-
createInstanced(mesh: MeshHandle, capacity: number): InstancedHandle;
|
|
341
|
+
createInstanced(mesh: MeshHandle, capacity: number, options?: InstancedOptions): InstancedHandle;
|
|
328
342
|
/**
|
|
329
343
|
* Push placement and colour to the device. Only `data.count` instances are written.
|
|
330
344
|
*
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a draw meets the medium between it and the eye: the value of the mesh shader's
|
|
3
|
+
* `uFogEnabled`, which both backends write from this one rule.
|
|
4
|
+
*
|
|
5
|
+
* **A surface recedes into the medium; light added to the frame fades in it.** A surface that
|
|
6
|
+
* covers what is behind it is mixed toward the medium's colour with distance, which is the haze
|
|
7
|
+
* standing in front of it. An additive draw covers nothing: what is behind it has already been
|
|
8
|
+
* fogged, and mixing the draw toward the medium's colour and then *adding* it puts that haze into
|
|
9
|
+
* the frame a second time. So a glow by day added the sky's grey in the shape of the glow, and
|
|
10
|
+
* added more of it the thicker the air — reported as solid grey cones under every street lamp on
|
|
11
|
+
* a hazy morning. Faded instead, added light loses what the medium scatters out of it and adds
|
|
12
|
+
* nothing of its own, which is how the same shader already treats the glow behind frosted glass.
|
|
13
|
+
*
|
|
14
|
+
* What fading gives up is the one thing mixing did for a glow: at great distance it disappears
|
|
15
|
+
* into the air instead of greying into it. That is what light in fog does. What would make it
|
|
16
|
+
* wrong is an additive draw standing for *lit air* rather than light — and that is what
|
|
17
|
+
* `drawLightVolume` is for, which is fogged by neither rule.
|
|
18
|
+
*/
|
|
19
|
+
/** Out of the medium entirely: `TranslucentMeshOptions.fog` set to false. */
|
|
20
|
+
export declare const FOG_OFF = 0;
|
|
21
|
+
/** Mixed toward the medium's colour with distance: every surface, and the pass's default. */
|
|
22
|
+
export declare const FOG_RECEDE = 1;
|
|
23
|
+
/** Scaled down by what the medium scatters and given none of its colour: added light. */
|
|
24
|
+
export declare const FOG_FADE = 2;
|
|
25
|
+
/** The medium rule for a draw that asked for fog or not, and adds its light or covers. */
|
|
26
|
+
export declare function fogModeOf(fog: boolean, additive: boolean): number;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a draw meets the medium between it and the eye: the value of the mesh shader's
|
|
3
|
+
* `uFogEnabled`, which both backends write from this one rule.
|
|
4
|
+
*
|
|
5
|
+
* **A surface recedes into the medium; light added to the frame fades in it.** A surface that
|
|
6
|
+
* covers what is behind it is mixed toward the medium's colour with distance, which is the haze
|
|
7
|
+
* standing in front of it. An additive draw covers nothing: what is behind it has already been
|
|
8
|
+
* fogged, and mixing the draw toward the medium's colour and then *adding* it puts that haze into
|
|
9
|
+
* the frame a second time. So a glow by day added the sky's grey in the shape of the glow, and
|
|
10
|
+
* added more of it the thicker the air — reported as solid grey cones under every street lamp on
|
|
11
|
+
* a hazy morning. Faded instead, added light loses what the medium scatters out of it and adds
|
|
12
|
+
* nothing of its own, which is how the same shader already treats the glow behind frosted glass.
|
|
13
|
+
*
|
|
14
|
+
* What fading gives up is the one thing mixing did for a glow: at great distance it disappears
|
|
15
|
+
* into the air instead of greying into it. That is what light in fog does. What would make it
|
|
16
|
+
* wrong is an additive draw standing for *lit air* rather than light — and that is what
|
|
17
|
+
* `drawLightVolume` is for, which is fogged by neither rule.
|
|
18
|
+
*/
|
|
19
|
+
/** Out of the medium entirely: `TranslucentMeshOptions.fog` set to false. */
|
|
20
|
+
export const FOG_OFF = 0;
|
|
21
|
+
/** Mixed toward the medium's colour with distance: every surface, and the pass's default. */
|
|
22
|
+
export const FOG_RECEDE = 1;
|
|
23
|
+
/** Scaled down by what the medium scatters and given none of its colour: added light. */
|
|
24
|
+
export const FOG_FADE = 2;
|
|
25
|
+
/** The medium rule for a draw that asked for fog or not, and adds its light or covers. */
|
|
26
|
+
export function fogModeOf(fog, additive) {
|
|
27
|
+
if (!fog)
|
|
28
|
+
return FOG_OFF;
|
|
29
|
+
return additive ? FOG_FADE : FOG_RECEDE;
|
|
30
|
+
}
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
export interface DrawMaterialOptions {
|
|
22
22
|
readonly opacity: number;
|
|
23
23
|
readonly lit: boolean;
|
|
24
|
-
|
|
24
|
+
/** How it meets the medium, as `fogModeOf` says; the pass's own is `FOG_RECEDE`. */
|
|
25
|
+
readonly fog: number;
|
|
25
26
|
readonly toneMapped: boolean;
|
|
26
27
|
/** Whether the draw refracts this time, which a backend decides by whether it has a snapshot. */
|
|
27
28
|
readonly refracting: boolean;
|
|
@@ -17,9 +17,14 @@
|
|
|
17
17
|
* What it gives up: a setter called with the value already set still counts, because it takes a
|
|
18
18
|
* slot on the backend that keeps slots, and comparing every field would cost more than the slot.
|
|
19
19
|
*/
|
|
20
|
+
import { FOG_RECEDE } from './drawFog.js';
|
|
20
21
|
/** Whether a draw's options differ from the pass's, so it takes a material and leaves one to restore. */
|
|
21
22
|
export function ownsMaterial(options) {
|
|
22
|
-
return (options.opacity < 1 ||
|
|
23
|
+
return (options.opacity < 1 ||
|
|
24
|
+
!options.lit ||
|
|
25
|
+
options.fog !== FOG_RECEDE ||
|
|
26
|
+
!options.toneMapped ||
|
|
27
|
+
options.refracting);
|
|
23
28
|
}
|
|
24
29
|
/** Whether the next draw shares the open material or opens a new one. */
|
|
25
30
|
export class MaterialChanges {
|
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
import type { MeshInstances } from '../../instances.ts';
|
|
2
2
|
import type { Mesh } from '../../mesh.ts';
|
|
3
|
+
import type { FrustumPlanes } from '../../../math/frustum.ts';
|
|
3
4
|
/**
|
|
4
|
-
* One mesh
|
|
5
|
+
* One batch of a mesh: its per-instance buffer and a vertex array of its own.
|
|
5
6
|
*
|
|
6
7
|
* The twin of the WebGPU batch and deliberately the same shape, because which floats go where is
|
|
7
|
-
* a decision shared through `instances.ts` and only the binding is per-backend.
|
|
8
|
+
* a decision shared through `instances.ts` and only the binding is per-backend. The vertex array is
|
|
9
|
+
* the batch's rather than the mesh's (`Mesh.createInstanceArray`), which is what lets one mesh carry
|
|
10
|
+
* a batch per region.
|
|
8
11
|
*
|
|
9
|
-
*
|
|
12
|
+
* **A culling batch holds a second buffer and array**, for the instances `cullInstances` keeps each
|
|
13
|
+
* camera draw. The full set stays in the first, because a shadow pass, a mirror and a probe each
|
|
14
|
+
* see a different part of the batch than the camera does, and they draw from it.
|
|
15
|
+
*
|
|
16
|
+
* Staging arrays are allocated here and rewritten in place, so a frame re-uploading or re-culling a
|
|
10
17
|
* batch allocates nothing.
|
|
11
18
|
*/
|
|
12
19
|
export declare class InstancedBatch {
|
|
13
20
|
readonly mesh: Mesh;
|
|
14
21
|
readonly capacity: number;
|
|
22
|
+
/** Whether the camera draw culls this batch. See `InstancedOptions.cull`. */
|
|
23
|
+
readonly cull: boolean;
|
|
24
|
+
/** The world box around every live instance, fitted at upload. See `instancesBox`. */
|
|
25
|
+
readonly box: Float32Array<ArrayBuffer>;
|
|
15
26
|
private readonly buffer;
|
|
27
|
+
private readonly vao;
|
|
16
28
|
private readonly staging;
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
private readonly kept;
|
|
30
|
+
constructor(gl: WebGL2RenderingContext, mesh: Mesh, capacity: number, cull?: boolean);
|
|
19
31
|
upload(gl: WebGL2RenderingContext, data: MeshInstances): void;
|
|
32
|
+
/** Draw the first `count` uploaded instances: every draw but a culling camera draw. */
|
|
33
|
+
draw(gl: WebGL2RenderingContext, count: number): void;
|
|
34
|
+
/**
|
|
35
|
+
* Cull `data` against `frustum`, upload what survives into the second buffer and draw it. Returns
|
|
36
|
+
* how many were drawn — 0 draws nothing. Only for a batch made with `cull`.
|
|
37
|
+
*/
|
|
38
|
+
drawCulled(gl: WebGL2RenderingContext, data: MeshInstances, frustum: FrustumPlanes): number;
|
|
20
39
|
dispose(gl: WebGL2RenderingContext): void;
|
|
21
40
|
}
|
|
@@ -1,34 +1,53 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cullInstances, instancesBox } from '../../instanceCull.js';
|
|
2
|
+
import { INSTANCE_FLOATS, INSTANCE_STRIDE, createMeshInstances, packInstances, } from '../../instances.js';
|
|
2
3
|
/**
|
|
3
|
-
* One mesh
|
|
4
|
+
* One batch of a mesh: its per-instance buffer and a vertex array of its own.
|
|
4
5
|
*
|
|
5
6
|
* The twin of the WebGPU batch and deliberately the same shape, because which floats go where is
|
|
6
|
-
* a decision shared through `instances.ts` and only the binding is per-backend.
|
|
7
|
+
* a decision shared through `instances.ts` and only the binding is per-backend. The vertex array is
|
|
8
|
+
* the batch's rather than the mesh's (`Mesh.createInstanceArray`), which is what lets one mesh carry
|
|
9
|
+
* a batch per region.
|
|
7
10
|
*
|
|
8
|
-
*
|
|
11
|
+
* **A culling batch holds a second buffer and array**, for the instances `cullInstances` keeps each
|
|
12
|
+
* camera draw. The full set stays in the first, because a shadow pass, a mirror and a probe each
|
|
13
|
+
* see a different part of the batch than the camera does, and they draw from it.
|
|
14
|
+
*
|
|
15
|
+
* Staging arrays are allocated here and rewritten in place, so a frame re-uploading or re-culling a
|
|
9
16
|
* batch allocates nothing.
|
|
10
17
|
*/
|
|
11
18
|
export class InstancedBatch {
|
|
12
19
|
mesh;
|
|
13
20
|
capacity;
|
|
21
|
+
/** Whether the camera draw culls this batch. See `InstancedOptions.cull`. */
|
|
22
|
+
cull;
|
|
23
|
+
/** The world box around every live instance, fitted at upload. See `instancesBox`. */
|
|
24
|
+
box = new Float32Array([1, 1, 1, -1, -1, -1]);
|
|
14
25
|
buffer;
|
|
26
|
+
vao;
|
|
15
27
|
staging;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (buffer === null)
|
|
19
|
-
throw new Error('InstancedBatch: createBuffer failed');
|
|
28
|
+
kept;
|
|
29
|
+
constructor(gl, mesh, capacity, cull = false) {
|
|
20
30
|
this.mesh = mesh;
|
|
21
31
|
this.capacity = capacity;
|
|
22
|
-
this.
|
|
32
|
+
this.cull = cull;
|
|
23
33
|
this.staging = new Float32Array(capacity * INSTANCE_FLOATS);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
34
|
+
this.buffer = allocate(gl, capacity);
|
|
35
|
+
this.vao = mesh.createInstanceArray(gl, this.buffer, INSTANCE_STRIDE);
|
|
36
|
+
if (cull) {
|
|
37
|
+
const buffer = allocate(gl, capacity);
|
|
38
|
+
this.kept = {
|
|
39
|
+
buffer,
|
|
40
|
+
vao: mesh.createInstanceArray(gl, buffer, INSTANCE_STRIDE),
|
|
41
|
+
instances: createMeshInstances(capacity),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.kept = null;
|
|
46
|
+
}
|
|
29
47
|
}
|
|
30
|
-
/** Pack and push the live prefix, in one call. */
|
|
31
48
|
upload(gl, data) {
|
|
49
|
+
if (this.cull)
|
|
50
|
+
instancesBox(data, this.mesh.bounds, this.box);
|
|
32
51
|
const count = Math.min(data.count, this.capacity);
|
|
33
52
|
if (count === 0)
|
|
34
53
|
return;
|
|
@@ -36,7 +55,45 @@ export class InstancedBatch {
|
|
|
36
55
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
37
56
|
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.staging, 0, count * INSTANCE_FLOATS);
|
|
38
57
|
}
|
|
58
|
+
/** Draw the first `count` uploaded instances: every draw but a culling camera draw. */
|
|
59
|
+
draw(gl, count) {
|
|
60
|
+
this.mesh.drawInstancesThrough(gl, this.vao, count);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Cull `data` against `frustum`, upload what survives into the second buffer and draw it. Returns
|
|
64
|
+
* how many were drawn — 0 draws nothing. Only for a batch made with `cull`.
|
|
65
|
+
*/
|
|
66
|
+
drawCulled(gl, data, frustum) {
|
|
67
|
+
const kept = this.kept;
|
|
68
|
+
if (kept === null)
|
|
69
|
+
return 0;
|
|
70
|
+
const count = cullInstances(data, this.mesh.bounds, frustum, kept.instances);
|
|
71
|
+
if (count === 0)
|
|
72
|
+
return 0;
|
|
73
|
+
packInstances(kept.instances, this.staging);
|
|
74
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, kept.buffer);
|
|
75
|
+
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.staging, 0, count * INSTANCE_FLOATS);
|
|
76
|
+
this.mesh.drawInstancesThrough(gl, kept.vao, count);
|
|
77
|
+
return count;
|
|
78
|
+
}
|
|
39
79
|
dispose(gl) {
|
|
80
|
+
gl.deleteVertexArray(this.vao);
|
|
40
81
|
gl.deleteBuffer(this.buffer);
|
|
82
|
+
if (this.kept !== null) {
|
|
83
|
+
gl.deleteVertexArray(this.kept.vao);
|
|
84
|
+
gl.deleteBuffer(this.kept.buffer);
|
|
85
|
+
}
|
|
41
86
|
}
|
|
42
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* An instance buffer sized to capacity. `DYNAMIC_DRAW` because a batch of vehicles is rewritten
|
|
90
|
+
* every frame — advisory, but a driver told the truth can place the buffer where a rewrite is cheap.
|
|
91
|
+
*/
|
|
92
|
+
function allocate(gl, capacity) {
|
|
93
|
+
const buffer = gl.createBuffer();
|
|
94
|
+
if (buffer === null)
|
|
95
|
+
throw new Error('InstancedBatch: createBuffer failed');
|
|
96
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
97
|
+
gl.bufferData(gl.ARRAY_BUFFER, Math.max(1, capacity) * INSTANCE_STRIDE, gl.DYNAMIC_DRAW);
|
|
98
|
+
return buffer;
|
|
99
|
+
}
|
|
@@ -15,6 +15,9 @@ import { GpuTimer } from '../../gpuTimer.ts';
|
|
|
15
15
|
import type { ColourGradeLut } from '../../colourGrade.ts';
|
|
16
16
|
import { LightField } from '../../driftLight/lightField.ts';
|
|
17
17
|
import type { LightFieldOptions, LightFieldSource } from '../../driftLight/lightField.ts';
|
|
18
|
+
import type { DenseLightVolume } from '../../driftLight/denseField.ts';
|
|
19
|
+
import { WorldLightField } from '../../driftLight/worldLightField.ts';
|
|
20
|
+
import type { WorldLightFieldOptions } from '../../driftLight/worldLightField.ts';
|
|
18
21
|
/**
|
|
19
22
|
* How far the rush's outermost tap reaches at full strength, in UV.
|
|
20
23
|
*
|
|
@@ -71,7 +74,7 @@ import type { WindStreakOptions } from '../../windStreakRenderer.ts';
|
|
|
71
74
|
import type { WindField } from '../../windField.ts';
|
|
72
75
|
import type { FlockParams } from '../../flockRenderer.ts';
|
|
73
76
|
import { InstancedBatch } from './instanced.ts';
|
|
74
|
-
import type { MeshInstances } from '../../instances.ts';
|
|
77
|
+
import type { InstancedOptions, MeshInstances } from '../../instances.ts';
|
|
75
78
|
/** Reused each frame: which shader light slot each bound cubemap serves. */
|
|
76
79
|
export type { ShadowCasterSink, ShadowCasters } from '../../shadowCasters.ts';
|
|
77
80
|
/** Lighting and atmosphere for a frame. The game decides what goes in it. */
|
|
@@ -108,6 +111,29 @@ export interface Environment extends Atmosphere {
|
|
|
108
111
|
* how strongly.
|
|
109
112
|
*/
|
|
110
113
|
nightFactor: number;
|
|
114
|
+
/**
|
|
115
|
+
* Seconds on the caller's clock, for the surfaces that animate — a sign's pulse, a ticker's
|
|
116
|
+
* scroll, a flipbook. The caller's rather than a clock read here, so a held clock holds every
|
|
117
|
+
* surface still and a replay replays them. 0 unless stated.
|
|
118
|
+
*/
|
|
119
|
+
surfaceTime?: number;
|
|
120
|
+
/**
|
|
121
|
+
* How wet the world is, 0 to 1: upward surfaces darken and polish, except materials that say
|
|
122
|
+
* they stay dry. The scene-wide counterpart of `drawFilm`, which stays for a puddle. 0 unless
|
|
123
|
+
* stated.
|
|
124
|
+
*/
|
|
125
|
+
wetness?: number;
|
|
126
|
+
/**
|
|
127
|
+
* The share of facade windows lit, 0 to 1, which a scene sets from its time of day. Windows switch
|
|
128
|
+
* on in steps by a per-window hash, so a rising share lights more windows rather than brightening
|
|
129
|
+
* the ones already lit. 0 unless stated.
|
|
130
|
+
*/
|
|
131
|
+
litWindows?: number;
|
|
132
|
+
/**
|
|
133
|
+
* The share of windows that stay lit however late it gets, 0 to 1, so the small hours are not a
|
|
134
|
+
* dark city. 0 unless stated.
|
|
135
|
+
*/
|
|
136
|
+
lateWindows?: number;
|
|
111
137
|
/**
|
|
112
138
|
* Emission that only shows where the dominant light does not reach, 0 and off by default.
|
|
113
139
|
*
|
|
@@ -441,6 +467,31 @@ export interface LightVolumeDrawOptions {
|
|
|
441
467
|
* boolean is refused everywhere else in this file.
|
|
442
468
|
*/
|
|
443
469
|
export interface TranslucentMeshOptions {
|
|
470
|
+
/**
|
|
471
|
+
* Add this surface's light to what is behind it instead of covering it: a glow, a beam, a pool
|
|
472
|
+
* of light under a lamp. Its colour times its opacity is added and nothing is darkened, so black
|
|
473
|
+
* is invisible and overlapping glows brighten — which is why such surfaces are authored nearly
|
|
474
|
+
* black where they fade. **Order does not matter** to a sum, so an additive draw is never held
|
|
475
|
+
* for the order-independent pass; it is drawn where it is asked for. Write depth off with it
|
|
476
|
+
* (`depthWrite: false`) or a glow hides the glows behind it.
|
|
477
|
+
*/
|
|
478
|
+
/**
|
|
479
|
+
* Drawn into the picture a reconstruction resolves, rather than after it. For a surface that
|
|
480
|
+
* moves with what it lies on — a glow on a wall, a pane in a window — whose one motion is that
|
|
481
|
+
* surface's, so the resolve can carry it with the surface.
|
|
482
|
+
*
|
|
483
|
+
* **Late is the default, and it is right for anything else.** A translucent surface writes no
|
|
484
|
+
* depth the motion pass could test and may move apart from what shows through it — a caption
|
|
485
|
+
* over a moving car — so a history can only smear it; after the upscale it is sharp and has none.
|
|
486
|
+
* **What late gives up** is the edge: drawn unjittered against a depth the jittered render
|
|
487
|
+
* covered, it meets a silhouette the render drew differently every frame, and a glow along an
|
|
488
|
+
* edge is let through on one frame and not the next. Reconstructed, it is resolved with the edge.
|
|
489
|
+
*
|
|
490
|
+
* Only a reconstructing frame draws anything late, so this changes nothing on WebGL2 or with
|
|
491
|
+
* `reconstruction` off. An order-independent blended set replays where it replays.
|
|
492
|
+
*/
|
|
493
|
+
readonly reconstructed?: boolean;
|
|
494
|
+
readonly additive?: boolean;
|
|
444
495
|
/**
|
|
445
496
|
* `false` draws the mesh exactly its own vertex colour times its own texture, with no
|
|
446
497
|
* ambient, sun, point lights, specular, reflectivity, grain or emissive touching it —
|
|
@@ -881,6 +932,11 @@ export declare class WebGL2Renderer implements RendererApi {
|
|
|
881
932
|
private oitActive;
|
|
882
933
|
/** True while the queue is being replayed, so a replayed draw does not record itself again. */
|
|
883
934
|
private oitReplaying;
|
|
935
|
+
/** `uSurfaceScene`, resolved once a pass. See `surfaceScene.ts`. */
|
|
936
|
+
private readonly surfaceScene;
|
|
937
|
+
/** The two halves of `uWriteMode`, kept here because a `vec2` is written whole. */
|
|
938
|
+
private oitWeight;
|
|
939
|
+
private ditherFade;
|
|
884
940
|
/** Said once, not per frame, where the context cannot give the float target the sum needs. */
|
|
885
941
|
private oitRefused;
|
|
886
942
|
/** Said once for the whole renderer. See `refuseOitMultisampled`. */
|
|
@@ -963,6 +1019,8 @@ export declare class WebGL2Renderer implements RendererApi {
|
|
|
963
1019
|
private readonly taaDepthToViewZ;
|
|
964
1020
|
private readonly aoInvProjection;
|
|
965
1021
|
private readonly aoProjScale;
|
|
1022
|
+
/** Where this frame's jitter put the occlusion, in the composite's uv. See `uAoOffset`. */
|
|
1023
|
+
private readonly aoOffset;
|
|
966
1024
|
/**
|
|
967
1025
|
* Whether this frame has already been resolved to the canvas.
|
|
968
1026
|
*
|
|
@@ -1054,12 +1112,15 @@ export declare class WebGL2Renderer implements RendererApi {
|
|
|
1054
1112
|
* world. See `prepareStaticPointShadows`.
|
|
1055
1113
|
*/
|
|
1056
1114
|
private pointShadowArray;
|
|
1057
|
-
/** The
|
|
1058
|
-
private
|
|
1059
|
-
/**
|
|
1115
|
+
/** The fixture atlas — cookies over profiles — allocated on first use. See `fixtureAtlas.ts`. */
|
|
1116
|
+
private fixtureTexture;
|
|
1117
|
+
/** The profiles as packed, kept so a new set of cookies can rebuild the atlas around them. */
|
|
1118
|
+
private iesAtlas;
|
|
1119
|
+
/** The cookie images, kept so a new set of profiles can rebuild the atlas around them. */
|
|
1120
|
+
private cookieImages;
|
|
1121
|
+
/** Rows of profile in the atlas. One until a consumer loads a profile, which is the row of ones. */
|
|
1060
1122
|
private iesRows;
|
|
1061
|
-
|
|
1062
|
-
/** Tiles in the cookie atlas. 0 is the white placeholder and the whole off path. */
|
|
1123
|
+
/** Cookie tiles in the atlas. 0 is none, and the whole off path. */
|
|
1063
1124
|
private cookieTiles;
|
|
1064
1125
|
/** Horizontal planes each profile occupies. 1 unless something asymmetric was loaded. */
|
|
1065
1126
|
private iesPlanes;
|
|
@@ -1358,6 +1419,11 @@ export declare class WebGL2Renderer implements RendererApi {
|
|
|
1358
1419
|
* other half of the same question.
|
|
1359
1420
|
*/
|
|
1360
1421
|
occluded(bounds: Bounds, model: ReadonlyMat4): boolean;
|
|
1422
|
+
/**
|
|
1423
|
+
* Whether a world-space box is wholly behind the declared occluders — the tighter question for
|
|
1424
|
+
* something that is a box, such as a region. False with no occlusion buffer. See `occluded`.
|
|
1425
|
+
*/
|
|
1426
|
+
occludedBox(min: ArrayLike<number>, max: ArrayLike<number>): boolean;
|
|
1361
1427
|
private readonly passes;
|
|
1362
1428
|
/** Built once so invoking somebody else's pass allocates nothing. See `PassDefinition.draw`. */
|
|
1363
1429
|
/**
|
|
@@ -1473,7 +1539,17 @@ export declare class WebGL2Renderer implements RendererApi {
|
|
|
1473
1539
|
*/
|
|
1474
1540
|
setSpotCookies(images: readonly TexImageSource[]): void;
|
|
1475
1541
|
setIesProfiles(profiles: readonly PhotometricProfile[]): void;
|
|
1476
|
-
/**
|
|
1542
|
+
/**
|
|
1543
|
+
* The fixture atlas from the profiles and cookies in hand: the profiles' rows at the bottom, the
|
|
1544
|
+
* cookies' tiles on top, one `RGBA16F` texture. See `fixtureAtlas.ts` for the layout.
|
|
1545
|
+
*
|
|
1546
|
+
* **Half float, matching what the other backend must use**: a 32-bit float texture is not
|
|
1547
|
+
* filterable in core WebGPU, and both tables are curves and images that want linear filtering.
|
|
1548
|
+
* Linear and clamped: a profile is sampled between two angles, and a cookie's own inset is what
|
|
1549
|
+
* keeps a tile from its neighbour — clamping alone cannot, the seam being interior to the row.
|
|
1550
|
+
*/
|
|
1551
|
+
private buildFixtureAtlas;
|
|
1552
|
+
/** Bind the fixture atlas and say what is in it. Always, for the reason `bindClusters` gives. */
|
|
1477
1553
|
private bindIesAtlas;
|
|
1478
1554
|
private bindClusters;
|
|
1479
1555
|
/**
|
|
@@ -1633,6 +1709,13 @@ export declare class WebGL2Renderer implements RendererApi {
|
|
|
1633
1709
|
* the consumer's decision. What it gains is a GPU object with sane sampler state.
|
|
1634
1710
|
*/
|
|
1635
1711
|
createSurfaceTexture(source: TexImageSource, options?: SurfaceTextureOptions): SurfaceTexture;
|
|
1712
|
+
/**
|
|
1713
|
+
* Upload several images of one size as the layers of one array, for a merged mesh that names a
|
|
1714
|
+
* layer per vertex (`MeshData.layers`). One material binding then covers every image, which is
|
|
1715
|
+
* what makes a block wearing forty facades one draw. Every layer must be the same size, and the
|
|
1716
|
+
* refusal names the first that is not.
|
|
1717
|
+
*/
|
|
1718
|
+
createSurfaceTextureArray(sources: readonly TexImageSource[], options?: SurfaceTextureOptions): SurfaceTexture;
|
|
1636
1719
|
/**
|
|
1637
1720
|
* Replace a surface texture's pixels, keeping the GPU object and its sampler state.
|
|
1638
1721
|
*
|
|
@@ -1762,6 +1845,29 @@ export declare class WebGL2Renderer implements RendererApi {
|
|
|
1762
1845
|
*/
|
|
1763
1846
|
setEnvironmentAmbient(_amount: number): void;
|
|
1764
1847
|
setSurfaceGrain(amount: number): void;
|
|
1848
|
+
/**
|
|
1849
|
+
* One float of material state, into every flat program.
|
|
1850
|
+
*
|
|
1851
|
+
* **Every one, for `setMaterial`'s reason**: an instanced or skinned draw runs a program of its
|
|
1852
|
+
* own and is entitled to the material its caller set before it. These setters wrote the plain
|
|
1853
|
+
* program alone until 2026-09-30, so on this backend a batch drew with the pass defaults — grain
|
|
1854
|
+
* full, no reflection, no relief — while the other backend, whose material block every variant
|
|
1855
|
+
* reads, drew what was asked.
|
|
1856
|
+
*/
|
|
1857
|
+
private writeFlatFloat;
|
|
1858
|
+
/**
|
|
1859
|
+
* How much of the surfaces drawn next survives a screen-door dither, for crossfading two levels
|
|
1860
|
+
* of detail of one thing.
|
|
1861
|
+
*
|
|
1862
|
+
* 0 is off and is what `bindMeshPass` restores. A positive amount keeps that share of the
|
|
1863
|
+
* pattern's cells, a negative one keeps the complement, so the level fading in drawn at `t` and
|
|
1864
|
+
* the one fading out at `-t` cover every pixel exactly once — no hole, no pixel drawn twice.
|
|
1865
|
+
* Material state like `setSurfaceGrain`; instanced draws read it too, and shadow casters, which
|
|
1866
|
+
* are a pass of their own, do not. See `uDither` in `flat/preamble.ts` for what it costs.
|
|
1867
|
+
*/
|
|
1868
|
+
setDitherFade(amount: number): void;
|
|
1869
|
+
/** `uWriteMode`: the order-independent weight and the dither, which share one uniform row. */
|
|
1870
|
+
private writeMode;
|
|
1765
1871
|
/**
|
|
1766
1872
|
* How strong the microscopic relief on the surfaces drawn next is, and how coarse.
|
|
1767
1873
|
*
|
|
@@ -1852,7 +1958,7 @@ export declare class WebGL2Renderer implements RendererApi {
|
|
|
1852
1958
|
* One batch per mesh: the attributes bind to the mesh's own vertex array, of which a mesh has
|
|
1853
1959
|
* one. `Mesh.attachInstances` is what refuses a second, and says why.
|
|
1854
1960
|
*/
|
|
1855
|
-
createInstanced(mesh: Mesh, capacity: number): InstancedBatch;
|
|
1961
|
+
createInstanced(mesh: Mesh, capacity: number, options?: InstancedOptions): InstancedBatch;
|
|
1856
1962
|
/** Push placement and colour. Only the live prefix. */
|
|
1857
1963
|
uploadInstanced(batch: InstancedBatch, data: MeshInstances): void;
|
|
1858
1964
|
/** Draw every live instance, opaque. */
|
|
@@ -3051,6 +3157,14 @@ export declare class WebGL2Renderer implements RendererApi {
|
|
|
3051
3157
|
* the volume is summed into the frame once every brick has landed.
|
|
3052
3158
|
*/
|
|
3053
3159
|
createLightField(lights: readonly LightFieldSource[], options?: Omit<LightFieldOptions, 'falloff'>): LightField;
|
|
3160
|
+
/**
|
|
3161
|
+
* Hand a world's DriftLight volume to the renderer: every fixed light of a city, summed offline by
|
|
3162
|
+
* `bakeDenseField`, standing in past the frame's exact choice. Replaces any field made before, of
|
|
3163
|
+
* either kind; the scene calls `field.follow(buffer.complete, ...)` each frame as it would for
|
|
3164
|
+
* `createLightField`, and marks the lights the volume summed `inLightField` so none is counted
|
|
3165
|
+
* twice. See `driftLight/worldLightField.ts`.
|
|
3166
|
+
*/
|
|
3167
|
+
createWorldLightField(volume: DenseLightVolume, options?: WorldLightFieldOptions): WorldLightField;
|
|
3054
3168
|
/** Let go of the field and its volumes; the scene's lights are all exact again. */
|
|
3055
3169
|
disposeLightField(): void;
|
|
3056
3170
|
private forgetLightFieldVolumes;
|