@driftengine/core 4.8.7 → 4.10.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 +123 -11
- package/README.md +43 -38
- package/dist/index.d.ts +8 -1
- package/dist/index.js +11 -3
- package/dist/render/ambientHarmonics.d.ts +1 -1
- package/dist/render/ambientHarmonics.js +1 -1
- package/dist/render/areaLights.d.ts +4 -4
- package/dist/render/areaLights.js +1 -1
- package/dist/render/atmosphere.d.ts +13 -0
- package/dist/render/atmosphere.js +9 -1
- package/dist/render/backend/api.d.ts +19 -4
- package/dist/render/backend/createRenderer.d.ts +6 -0
- package/dist/render/backend/createRenderer.js +4 -1
- package/dist/render/backend/select.js +11 -5
- package/dist/render/backend/webgl2/boneAnimations.d.ts +29 -0
- package/dist/render/backend/webgl2/boneAnimations.js +80 -0
- package/dist/render/backend/webgl2/instanced.d.ts +5 -1
- package/dist/render/backend/webgl2/instanced.js +13 -1
- package/dist/render/backend/webgl2/renderer.d.ts +180 -4
- package/dist/render/backend/webgl2/renderer.js +550 -40
- package/dist/render/backend/webgl2/skinPaletteTexture.d.ts +5 -3
- package/dist/render/backend/webgl2/skinPaletteTexture.js +6 -4
- package/dist/render/backend/webgpu/boneAnimations.d.ts +34 -0
- package/dist/render/backend/webgpu/boneAnimations.js +76 -0
- package/dist/render/backend/webgpu/buffers.d.ts +19 -4
- package/dist/render/backend/webgpu/buffers.js +18 -11
- package/dist/render/backend/webgpu/compressedUpload.d.ts +0 -1
- package/dist/render/backend/webgpu/compressedUpload.js +53 -8
- package/dist/render/backend/webgpu/depthPass.d.ts +59 -3
- package/dist/render/backend/webgpu/depthPass.js +49 -14
- package/dist/render/backend/webgpu/device.d.ts +7 -1
- package/dist/render/backend/webgpu/device.js +31 -3
- package/dist/render/backend/webgpu/drawCommand.d.ts +18 -4
- package/dist/render/backend/webgpu/drawCommand.js +10 -3
- package/dist/render/backend/webgpu/flatPass.d.ts +100 -42
- package/dist/render/backend/webgpu/flatPass.js +191 -43
- package/dist/render/backend/webgpu/instanced.d.ts +14 -1
- package/dist/render/backend/webgpu/instanced.js +24 -1
- package/dist/render/backend/webgpu/materialStore.d.ts +101 -0
- package/dist/render/backend/webgpu/materialStore.js +265 -0
- package/dist/render/backend/webgpu/pipelineCache.d.ts +6 -0
- package/dist/render/backend/webgpu/pipelineCache.js +7 -0
- package/dist/render/backend/webgpu/postPass.d.ts +51 -9
- package/dist/render/backend/webgpu/postPass.js +16 -2
- package/dist/render/backend/webgpu/reflectionSurfacePass.d.ts +30 -0
- package/dist/render/backend/webgpu/reflectionSurfacePass.js +100 -0
- package/dist/render/backend/webgpu/renderer.d.ts +283 -37
- package/dist/render/backend/webgpu/renderer.js +1363 -202
- package/dist/render/backend/webgpu/skinPaletteRing.d.ts +7 -3
- package/dist/render/backend/webgpu/skinPaletteRing.js +13 -7
- package/dist/render/backend/webgpu/skinPaletteTexture.d.ts +6 -0
- package/dist/render/backend/webgpu/skinPaletteTexture.js +7 -1
- package/dist/render/backend/webgpu/staticBundles.d.ts +125 -0
- package/dist/render/backend/webgpu/staticBundles.js +241 -0
- package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +10 -3
- package/dist/render/backend/webgpu/surfaceTexturePass.js +20 -2
- package/dist/render/backend/webgpu/uniformRing.d.ts +21 -0
- package/dist/render/backend/webgpu/uniformRing.js +9 -1
- package/dist/render/bloomChain.d.ts +3 -3
- package/dist/render/boneAnimation.d.ts +92 -0
- package/dist/render/boneAnimation.js +133 -0
- package/dist/render/compressedSource.d.ts +33 -13
- package/dist/render/compressedSource.js +70 -25
- package/dist/render/displayRange.d.ts +31 -0
- package/dist/render/displayRange.js +47 -0
- package/dist/render/filmicCurve.d.ts +74 -0
- package/dist/render/filmicCurve.js +203 -0
- package/dist/render/fog.d.ts +4 -1
- package/dist/render/fog.js +12 -2
- package/dist/render/frame/resources.d.ts +2 -2
- package/dist/render/frame/resources.js +6 -0
- package/dist/render/frameReflections.d.ts +40 -0
- package/dist/render/frameReflections.js +48 -0
- package/dist/render/glCompressed.js +83 -0
- package/dist/render/instances.d.ts +26 -0
- package/dist/render/lightBudget.d.ts +10 -0
- package/dist/render/lightBudget.js +10 -0
- package/dist/render/lightmap.d.ts +1 -1
- package/dist/render/mesh.d.ts +5 -0
- package/dist/render/mesh.js +6 -0
- package/dist/render/pass.d.ts +49 -0
- package/dist/render/pointLightSelection.d.ts +4 -4
- package/dist/render/reflectionSurfaceTargets.d.ts +28 -0
- package/dist/render/reflectionSurfaceTargets.js +99 -0
- package/dist/render/renderQuality.d.ts +39 -8
- package/dist/render/renderQuality.js +4 -0
- package/dist/render/sceneTarget.d.ts +5 -0
- package/dist/render/sceneTarget.js +24 -1
- package/dist/render/screenSpaceReflection.d.ts +7 -1
- package/dist/render/screenSpaceReflection.js +5 -0
- package/dist/render/shaders/arcane.d.ts +1 -1
- package/dist/render/shaders/bolt.d.ts +1 -1
- package/dist/render/shaders/boneAnimation.d.ts +19 -0
- package/dist/render/shaders/boneAnimation.js +63 -0
- package/dist/render/shaders/caustics.d.ts +1 -1
- package/dist/render/shaders/depth.d.ts +7 -0
- package/dist/render/shaders/depth.js +35 -10
- package/dist/render/shaders/film.d.ts +1 -1
- package/dist/render/shaders/filmLook.js +2 -1
- package/dist/render/shaders/fire.d.ts +1 -1
- package/dist/render/shaders/flat/glassTint.d.ts +1 -1
- package/dist/render/shaders/flat/glassTint.js +2 -0
- package/dist/render/shaders/flat/index.d.ts +16 -0
- package/dist/render/shaders/flat/index.js +33 -5
- package/dist/render/shaders/flat/main.d.ts +1 -1
- package/dist/render/shaders/flat/main.js +43 -5
- package/dist/render/shaders/flat/models.js +1 -1
- package/dist/render/shaders/flat/overlay.d.ts +16 -0
- package/dist/render/shaders/flat/overlay.js +117 -0
- package/dist/render/shaders/flat/pointShadow.js +3 -3
- package/dist/render/shaders/flat/preamble.js +38 -24
- package/dist/render/shaders/flat/reflectionSurface.d.ts +21 -0
- package/dist/render/shaders/flat/reflectionSurface.js +61 -0
- package/dist/render/shaders/fog.d.ts +1 -1
- package/dist/render/shaders/fog.js +9 -2
- package/dist/render/shaders/fringe.d.ts +29 -0
- package/dist/render/shaders/fringe.js +55 -0
- package/dist/render/shaders/generated/arcane.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/arcane.wgsl.js +1 -1
- package/dist/render/shaders/generated/bolt.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/bolt.wgsl.js +1 -1
- package/dist/render/shaders/generated/caustics.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/caustics.wgsl.js +1 -1
- package/dist/render/shaders/generated/depth.wgsl.d.ts +93 -0
- package/dist/render/shaders/generated/depth.wgsl.js +93 -0
- package/dist/render/shaders/generated/film.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/film.wgsl.js +1 -1
- package/dist/render/shaders/generated/fire.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/fire.wgsl.js +1 -1
- package/dist/render/shaders/generated/flat.wgsl.d.ts +3254 -2920
- package/dist/render/shaders/generated/flat.wgsl.js +3292 -2957
- package/dist/render/shaders/generated/line.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/line.wgsl.js +1 -1
- package/dist/render/shaders/generated/particle.wgsl.d.ts +4 -4
- package/dist/render/shaders/generated/particle.wgsl.js +4 -4
- package/dist/render/shaders/generated/rush.wgsl.d.ts +56 -26
- package/dist/render/shaders/generated/rush.wgsl.js +56 -26
- package/dist/render/shaders/generated/scatter.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/scatter.wgsl.js +1 -1
- package/dist/render/shaders/generated/smoke.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/smoke.wgsl.js +1 -1
- package/dist/render/shaders/generated/ssrResolve.wgsl.d.ts +29 -0
- package/dist/render/shaders/generated/ssrResolve.wgsl.js +29 -0
- package/dist/render/shaders/generated/ssrTrace.wgsl.d.ts +22 -2
- package/dist/render/shaders/generated/ssrTrace.wgsl.js +22 -2
- package/dist/render/shaders/generated/water.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/water.wgsl.js +1 -1
- package/dist/render/shaders/gpudriven/fog.wgsl.d.ts +2 -2
- package/dist/render/shaders/gpudriven/fog.wgsl.js +11 -3
- package/dist/render/shaders/line.d.ts +1 -1
- package/dist/render/shaders/outputTransform.d.ts +7 -0
- package/dist/render/shaders/outputTransform.js +28 -14
- package/dist/render/shaders/particle.d.ts +3 -3
- package/dist/render/shaders/rush.js +54 -11
- package/dist/render/shaders/scatter.d.ts +1 -1
- package/dist/render/shaders/smoke.d.ts +1 -1
- package/dist/render/shaders/ssrResolve.d.ts +17 -0
- package/dist/render/shaders/ssrResolve.js +51 -0
- package/dist/render/shaders/ssrTrace.js +26 -0
- package/dist/render/shaders/vertexChannel.d.ts +7 -0
- package/dist/render/shaders/vertexChannel.js +26 -0
- package/dist/render/shaders/water.d.ts +1 -1
- package/dist/render/ssrPass.d.ts +16 -0
- package/dist/render/ssrPass.js +106 -1
- package/dist/render/staticDraws.d.ts +47 -0
- package/dist/render/staticDraws.js +43 -0
- package/dist/render/surfaceOverlay.d.ts +132 -0
- package/dist/render/surfaceOverlay.js +85 -0
- package/dist/render/surfaceTexture.d.ts +57 -7
- package/dist/render/surfaceTexture.js +125 -17
- package/dist/render/temporalAa.d.ts +14 -0
- package/dist/render/temporalAa.js +20 -0
- package/dist/render/vertexDefaults.d.ts +17 -0
- package/dist/render/vertexDefaults.js +24 -0
- package/package.json +6 -6
- package/src/index.ts +24 -2
- package/src/render/ambientHarmonics.ts +1 -1
- package/src/render/areaLights.ts +4 -4
- package/src/render/atmosphere.ts +22 -1
- package/src/render/backend/api.ts +22 -3
- package/src/render/backend/createRenderer.ts +18 -1
- package/src/render/backend/select.ts +10 -5
- package/src/render/backend/webgl2/boneAnimations.ts +105 -0
- package/src/render/backend/webgl2/instanced.ts +20 -1
- package/src/render/backend/webgl2/renderer.ts +672 -37
- package/src/render/backend/webgl2/skinPaletteTexture.ts +6 -4
- package/src/render/backend/webgpu/boneAnimations.ts +97 -0
- package/src/render/backend/webgpu/buffers.ts +42 -16
- package/src/render/backend/webgpu/compressedUpload.ts +59 -9
- package/src/render/backend/webgpu/depthPass.ts +51 -10
- package/src/render/backend/webgpu/device.ts +42 -3
- package/src/render/backend/webgpu/drawCommand.ts +22 -4
- package/src/render/backend/webgpu/flatPass.ts +250 -40
- package/src/render/backend/webgpu/instanced.ts +32 -1
- package/src/render/backend/webgpu/materialStore.ts +276 -0
- package/src/render/backend/webgpu/pipelineCache.ts +7 -0
- package/src/render/backend/webgpu/postPass.ts +18 -0
- package/src/render/backend/webgpu/reflectionSurfacePass.ts +114 -0
- package/src/render/backend/webgpu/renderer.ts +1655 -230
- package/src/render/backend/webgpu/skinPaletteRing.ts +13 -7
- package/src/render/backend/webgpu/skinPaletteTexture.ts +7 -1
- package/src/render/backend/webgpu/staticBundles.ts +363 -0
- package/src/render/backend/webgpu/surfaceTexturePass.ts +29 -3
- package/src/render/backend/webgpu/uniformRing.ts +10 -1
- package/src/render/bloomChain.ts +3 -3
- package/src/render/boneAnimation.ts +223 -0
- package/src/render/compressedSource.ts +121 -29
- package/src/render/displayRange.ts +61 -0
- package/src/render/filmicCurve.ts +229 -0
- package/src/render/fog.ts +19 -3
- package/src/render/frame/resources.ts +6 -0
- package/src/render/frameReflections.ts +72 -0
- package/src/render/glCompressed.ts +83 -0
- package/src/render/instances.ts +27 -0
- package/src/render/lightBudget.ts +11 -0
- package/src/render/lightmap.ts +1 -1
- package/src/render/mesh.ts +6 -0
- package/src/render/pass.ts +53 -1
- package/src/render/pointLightSelection.ts +4 -4
- package/src/render/reflectionSurfaceTargets.ts +105 -0
- package/src/render/renderQuality.ts +44 -8
- package/src/render/sceneTarget.ts +30 -2
- package/src/render/screenSpaceReflection.ts +7 -1
- package/src/render/shaders/boneAnimation.ts +63 -0
- package/src/render/shaders/depth.ts +45 -10
- package/src/render/shaders/filmLook.ts +2 -1
- package/src/render/shaders/flat/glassTint.ts +5 -1
- package/src/render/shaders/flat/index.ts +49 -5
- package/src/render/shaders/flat/main.ts +43 -5
- package/src/render/shaders/flat/models.ts +1 -1
- package/src/render/shaders/flat/overlay.ts +117 -0
- package/src/render/shaders/flat/pointShadow.ts +3 -3
- package/src/render/shaders/flat/preamble.ts +38 -24
- package/src/render/shaders/flat/reflectionSurface.ts +61 -0
- package/src/render/shaders/fog.ts +9 -2
- package/src/render/shaders/fringe.ts +59 -0
- package/src/render/shaders/generated/arcane.wgsl.ts +1 -1
- package/src/render/shaders/generated/bolt.wgsl.ts +1 -1
- package/src/render/shaders/generated/caustics.wgsl.ts +1 -1
- package/src/render/shaders/generated/depth.wgsl.ts +95 -0
- package/src/render/shaders/generated/film.wgsl.ts +1 -1
- package/src/render/shaders/generated/fire.wgsl.ts +1 -1
- package/src/render/shaders/generated/flat.wgsl.ts +3292 -2957
- package/src/render/shaders/generated/line.wgsl.ts +1 -1
- package/src/render/shaders/generated/particle.wgsl.ts +4 -4
- package/src/render/shaders/generated/rush.wgsl.ts +56 -26
- package/src/render/shaders/generated/scatter.wgsl.ts +1 -1
- package/src/render/shaders/generated/smoke.wgsl.ts +1 -1
- package/src/render/shaders/generated/ssrResolve.wgsl.ts +30 -0
- package/src/render/shaders/generated/ssrTrace.wgsl.ts +22 -2
- package/src/render/shaders/generated/water.wgsl.ts +1 -1
- package/src/render/shaders/gpudriven/fog.wgsl.ts +11 -3
- package/src/render/shaders/outputTransform.ts +30 -14
- package/src/render/shaders/rush.ts +54 -11
- package/src/render/shaders/ssrResolve.ts +52 -0
- package/src/render/shaders/ssrTrace.ts +26 -0
- package/src/render/shaders/vertexChannel.ts +27 -0
- package/src/render/ssrPass.ts +138 -1
- package/src/render/staticDraws.ts +95 -0
- package/src/render/surfaceOverlay.ts +195 -0
- package/src/render/surfaceTexture.ts +161 -27
- package/src/render/temporalAa.ts +20 -0
- package/src/render/vertexDefaults.ts +28 -0
|
@@ -10,7 +10,12 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { SurfaceModel } from './surfaceModel.ts';
|
|
12
12
|
import { layerSize, refuseArrayUpdate, sourceSize } from './textureSource.ts';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
compressedLayers,
|
|
15
|
+
isCompressedSource,
|
|
16
|
+
planBlocks,
|
|
17
|
+
refuseBlockUpdate,
|
|
18
|
+
} from './compressedSource.ts';
|
|
14
19
|
import type {
|
|
15
20
|
BlockFormat,
|
|
16
21
|
CompressedTextureFormat,
|
|
@@ -119,7 +124,7 @@ export interface SurfaceMaterial<Texture = SurfaceTexture> {
|
|
|
119
124
|
* which is every light's default too, so a scene that names no channel is lit as it always was.
|
|
120
125
|
*
|
|
121
126
|
* A point or spot light shades this surface only where its `PointLightSet.lightChannels` and this
|
|
122
|
-
* share a bit —
|
|
127
|
+
* share a bit — lighting channels. A character's own key and rim lights on channel 2,
|
|
123
128
|
* and the character's materials on 3, light the character and leave the floor around it as the
|
|
124
129
|
* stage's lights alone have it. **What it does not reach**: the sun, the sky and the probes, area
|
|
125
130
|
* lights, DriftLight's volume and the GPU-driven pipeline light every surface whatever its mask.
|
|
@@ -153,6 +158,22 @@ export interface SurfaceMaterial<Texture = SurfaceTexture> {
|
|
|
153
158
|
* which is the opposite of what the caller asked for.
|
|
154
159
|
*/
|
|
155
160
|
occlusionStrength?: number;
|
|
161
|
+
/**
|
|
162
|
+
* How much of the environment this material's draws mirror, 0 to 1: the number
|
|
163
|
+
* `setSurfaceReflectivity` sets for every draw, stated by the material for its own. Absent, its
|
|
164
|
+
* draws wear the setter's, as every material's did before this existed.
|
|
165
|
+
*
|
|
166
|
+
* **Here so a static list can carry it.** A list keeps each entry's material and none of the
|
|
167
|
+
* renderer's state between draws (`createStaticDraws`), so a stage whose batches each mirror their
|
|
168
|
+
* own share of a baked reflection says so in the material it records. What it gives up is nothing a
|
|
169
|
+
* setter could do: one called after this material is set is ignored for the material's draws.
|
|
170
|
+
*/
|
|
171
|
+
reflectivity?: number;
|
|
172
|
+
/**
|
|
173
|
+
* How bright the environment this material's draws reflect is: `setEnvironmentGain`'s number,
|
|
174
|
+
* stated by the material for its own, and absent the setter's. Held non-negative.
|
|
175
|
+
*/
|
|
176
|
+
environmentGain?: number;
|
|
156
177
|
/**
|
|
157
178
|
* Scales the emissive map, per channel. Default 1.
|
|
158
179
|
*
|
|
@@ -176,14 +197,14 @@ export interface SurfaceMaterial<Texture = SurfaceTexture> {
|
|
|
176
197
|
modelMap?: Texture | null;
|
|
177
198
|
/**
|
|
178
199
|
* Whether a lamp's and the sun's highlight on this surface is GGX's own, `π · D · Vis · F · N·L`,
|
|
179
|
-
* as
|
|
180
|
-
* peak of one. **False by default**, every surface as it was.
|
|
200
|
+
* as physically based renderers and this engine's skin and eye shade it, rather than the engine's
|
|
201
|
+
* lobe scaled to a peak of one. **False by default**, every surface as it was.
|
|
181
202
|
*
|
|
182
203
|
* The peak-normalised lobe is a look control: the specular attribute says how strong a highlight
|
|
183
204
|
* is and roughness how wide, apart. Physical, they are entangled as they are in a real surface —
|
|
184
205
|
* the peak is `1 / (4 α²)` of the light head-on, so a polished surface's highlight is many times
|
|
185
206
|
* the look's and a rough one's lower and broader — and the specular attribute is read as the
|
|
186
|
-
* reflectance at normal incidence, F0:
|
|
207
|
+
* reflectance at normal incidence, F0: `0.08 × Specular`, 0.04 at its default. Fresnel
|
|
187
208
|
* then brightens every surface toward grazing, not only a metal. A rectangle's highlight is the
|
|
188
209
|
* lobe integrated over it with the attribute as F0 already, so it is unchanged either way.
|
|
189
210
|
*
|
|
@@ -292,7 +313,16 @@ export class SurfaceTexture {
|
|
|
292
313
|
/** The per-layer effects table, or null for a texture given none. See `surfaceEffects.ts`. */
|
|
293
314
|
private effectsTable: WebGLTexture | null = null;
|
|
294
315
|
/** The block format a compressed texture holds, or null for one uploaded from images. */
|
|
295
|
-
private
|
|
316
|
+
private blockFormat: BlockFormat | null;
|
|
317
|
+
/** How the texture is sampled, kept so blocks swapped in by `update` are sampled the same way. */
|
|
318
|
+
private readonly sampling: { wrap: number; nearest: boolean; anisotropy: number };
|
|
319
|
+
/** Level 0's size, which `flatLayer` copies; kept as `update` changes it. */
|
|
320
|
+
private width = 0;
|
|
321
|
+
private height = 0;
|
|
322
|
+
/** The texture's storage format, which `flatLayer`'s copy matches so the copy converts nothing. */
|
|
323
|
+
private readonly storage: number;
|
|
324
|
+
/** Layer 0 as a plain 2D texture, made by `flatLayer` and dropped when the pixels change. */
|
|
325
|
+
private flat: WebGLTexture | null = null;
|
|
296
326
|
|
|
297
327
|
/**
|
|
298
328
|
* One image, or an array of images that must share one size (`layerSize` refuses otherwise).
|
|
@@ -327,6 +357,9 @@ export class SurfaceTexture {
|
|
|
327
357
|
this.layers = 1;
|
|
328
358
|
this.blockFormat = null;
|
|
329
359
|
this.mipmapped = false;
|
|
360
|
+
this.width = capture.width;
|
|
361
|
+
this.height = capture.height;
|
|
362
|
+
this.storage = capture.float ? gl.RGBA16F : gl.RGBA8;
|
|
330
363
|
gl.texStorage3D(
|
|
331
364
|
gl.TEXTURE_2D_ARRAY,
|
|
332
365
|
1,
|
|
@@ -340,6 +373,9 @@ export class SurfaceTexture {
|
|
|
340
373
|
this.layers = baked.layers.length;
|
|
341
374
|
this.blockFormat = null;
|
|
342
375
|
this.mipmapped = false;
|
|
376
|
+
this.width = baked.width;
|
|
377
|
+
this.height = baked.height;
|
|
378
|
+
this.storage = gl.RGBA8;
|
|
343
379
|
/* A typed array refuses either flag set, so both are put down here rather than assumed. */
|
|
344
380
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
345
381
|
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
@@ -377,6 +413,7 @@ export class SurfaceTexture {
|
|
|
377
413
|
`generateMipmap` cannot write a compressed format. */
|
|
378
414
|
this.layers = blocks.length;
|
|
379
415
|
this.blockFormat = (blocks[0] as CompressedTextureSource).format;
|
|
416
|
+
this.storage = gl.NONE;
|
|
380
417
|
this.mipmapped = (options.mipmap ?? true) && plan.levels > 1;
|
|
381
418
|
uploadCompressedArray(gl, plan.name, blocks, this.mipmapped ? plan.levels : 1);
|
|
382
419
|
} else {
|
|
@@ -384,29 +421,19 @@ export class SurfaceTexture {
|
|
|
384
421
|
this.layers = sources.length;
|
|
385
422
|
this.blockFormat = null;
|
|
386
423
|
this.mipmapped = options.mipmap ?? true;
|
|
424
|
+
const { width, height } = layerSize(sources);
|
|
425
|
+
this.width = width;
|
|
426
|
+
this.height = height;
|
|
427
|
+
this.storage = this.srgb ? gl.SRGB8_ALPHA8 : gl.RGBA8;
|
|
387
428
|
uploadImages(gl, sources, this.srgb);
|
|
388
429
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, nearest ? gl.NEAREST : gl.LINEAR);
|
|
396
|
-
gl.texParameteri(
|
|
397
|
-
gl.TEXTURE_2D_ARRAY,
|
|
398
|
-
gl.TEXTURE_MIN_FILTER,
|
|
399
|
-
this.mipmapped
|
|
400
|
-
? nearest
|
|
401
|
-
? gl.NEAREST_MIPMAP_LINEAR
|
|
402
|
-
: gl.LINEAR_MIPMAP_LINEAR
|
|
403
|
-
: nearest
|
|
404
|
-
? gl.NEAREST
|
|
405
|
-
: gl.LINEAR,
|
|
406
|
-
);
|
|
407
|
-
|
|
430
|
+
this.sampling = {
|
|
431
|
+
wrap,
|
|
432
|
+
nearest: options.filter === 'nearest',
|
|
433
|
+
anisotropy: options.anisotropy ?? DEFAULT_ANISOTROPY,
|
|
434
|
+
};
|
|
435
|
+
this.applySampling(gl);
|
|
408
436
|
if (this.mipmapped && this.blockFormat === null) gl.generateMipmap(gl.TEXTURE_2D_ARRAY);
|
|
409
|
-
applyAnisotropy(gl, options.anisotropy ?? DEFAULT_ANISOTROPY);
|
|
410
437
|
gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
|
|
411
438
|
|
|
412
439
|
/* Half floats, nearest, clamped: a table read by texelFetch, whose every whole number is under
|
|
@@ -457,11 +484,22 @@ export class SurfaceTexture {
|
|
|
457
484
|
* Not a hot path: it re-uploads the whole image and regenerates the chain. A caller
|
|
458
485
|
* doing this every frame at any size wants to know that it costs what it costs.
|
|
459
486
|
*/
|
|
460
|
-
update(
|
|
487
|
+
update(
|
|
488
|
+
gl: WebGL2RenderingContext,
|
|
489
|
+
source: TexImageSource | CompressedTextureSource,
|
|
490
|
+
compressed: readonly CompressedTextureFormat[] = [],
|
|
491
|
+
): void {
|
|
461
492
|
if (this.texture === null) return;
|
|
462
493
|
refuseArrayUpdate(this.layers);
|
|
494
|
+
if (isCompressedSource(source)) {
|
|
495
|
+
this.swapToBlocks(gl, source, compressed);
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
463
498
|
refuseBlockUpdate(this.blockFormat);
|
|
464
499
|
const { width, height } = sourceSize(source);
|
|
500
|
+
this.width = width;
|
|
501
|
+
this.height = height;
|
|
502
|
+
this.dropFlat(gl);
|
|
465
503
|
gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);
|
|
466
504
|
/* Unflipped, matching the constructor. See it for why, and for what it cost. */
|
|
467
505
|
gl.texImage3D(
|
|
@@ -480,6 +518,56 @@ export class SurfaceTexture {
|
|
|
480
518
|
gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
|
|
481
519
|
}
|
|
482
520
|
|
|
521
|
+
/**
|
|
522
|
+
* Blocks in place of the image, behind the same handle: **a new GL object** rather than the
|
|
523
|
+
* image's levels respecified, because a chain shorter than the image's would leave the levels
|
|
524
|
+
* past it allocated, and immutable storage could not be respecified at all. Sampled as the image
|
|
525
|
+
* was, and refused before anything changes where the context does not take the format.
|
|
526
|
+
*/
|
|
527
|
+
private swapToBlocks(
|
|
528
|
+
gl: WebGL2RenderingContext,
|
|
529
|
+
source: CompressedTextureSource,
|
|
530
|
+
compressed: readonly CompressedTextureFormat[],
|
|
531
|
+
): void {
|
|
532
|
+
const plan = planBlocks([source], this.srgb, compressed);
|
|
533
|
+
const texture = gl.createTexture();
|
|
534
|
+
if (texture === null) throw new Error('SurfaceTexture: createTexture failed');
|
|
535
|
+
this.dropFlat(gl);
|
|
536
|
+
if (this.texture !== null) gl.deleteTexture(this.texture);
|
|
537
|
+
this.texture = texture;
|
|
538
|
+
this.blockFormat = source.format;
|
|
539
|
+
this.width = source.width;
|
|
540
|
+
this.height = source.height;
|
|
541
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, texture);
|
|
542
|
+
uploadCompressedArray(gl, plan.name, [source], this.mipmapped ? plan.levels : 1);
|
|
543
|
+
this.applySampling(gl);
|
|
544
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Wrap, filters and anisotropy on the bound texture. Nearest where the caller said their pixels
|
|
549
|
+
* are the subject; see `filter`. The mip chain is still blended between levels, because that is
|
|
550
|
+
* minification and this option is about magnification.
|
|
551
|
+
*/
|
|
552
|
+
private applySampling(gl: WebGL2RenderingContext): void {
|
|
553
|
+
const { wrap, nearest, anisotropy } = this.sampling;
|
|
554
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, wrap);
|
|
555
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, wrap);
|
|
556
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, nearest ? gl.NEAREST : gl.LINEAR);
|
|
557
|
+
gl.texParameteri(
|
|
558
|
+
gl.TEXTURE_2D_ARRAY,
|
|
559
|
+
gl.TEXTURE_MIN_FILTER,
|
|
560
|
+
this.mipmapped
|
|
561
|
+
? nearest
|
|
562
|
+
? gl.NEAREST_MIPMAP_LINEAR
|
|
563
|
+
: gl.LINEAR_MIPMAP_LINEAR
|
|
564
|
+
: nearest
|
|
565
|
+
? gl.NEAREST
|
|
566
|
+
: gl.LINEAR,
|
|
567
|
+
);
|
|
568
|
+
applyAnisotropy(gl, anisotropy);
|
|
569
|
+
}
|
|
570
|
+
|
|
483
571
|
/**
|
|
484
572
|
* Attach the only layer as the bound framebuffer's colour: a scene capture's target, drawn into
|
|
485
573
|
* by `captureScene`. Engine-internal, as `bind` is.
|
|
@@ -494,8 +582,54 @@ export class SurfaceTexture {
|
|
|
494
582
|
gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);
|
|
495
583
|
}
|
|
496
584
|
|
|
585
|
+
/**
|
|
586
|
+
* Layer 0 as a plain 2D texture: what a `sampler2D` can be handed, which an array cannot. Copied
|
|
587
|
+
* the first time it is asked for, by a framebuffer blit into storage of the same format, and kept
|
|
588
|
+
* until `update` or `dispose`. Engine-internal: a surface overlay's atlas is bound where the
|
|
589
|
+
* lit stage's one 2D image slot is (`surfaceOverlay.ts`).
|
|
590
|
+
*
|
|
591
|
+
* **Null for blocks**, which no framebuffer can read; the caller says so. What it costs is a copy
|
|
592
|
+
* of level 0 in memory beside the array, and the bindings of both framebuffer targets, which are
|
|
593
|
+
* read back before the blit and put back after it — a sync query, paid once per image.
|
|
594
|
+
*/
|
|
595
|
+
flatLayer(gl: WebGL2RenderingContext): WebGLTexture | null {
|
|
596
|
+
if (this.texture === null || this.blockFormat !== null) return null;
|
|
597
|
+
if (this.flat !== null) return this.flat;
|
|
598
|
+
const flat = gl.createTexture();
|
|
599
|
+
const read = gl.createFramebuffer();
|
|
600
|
+
const draw = gl.createFramebuffer();
|
|
601
|
+
if (flat === null || read === null || draw === null) return null;
|
|
602
|
+
gl.bindTexture(gl.TEXTURE_2D, flat);
|
|
603
|
+
gl.texStorage2D(gl.TEXTURE_2D, 1, this.storage, this.width, this.height);
|
|
604
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
605
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
606
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
607
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
608
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
609
|
+
const heldRead = gl.getParameter(gl.READ_FRAMEBUFFER_BINDING) as WebGLFramebuffer | null;
|
|
610
|
+
const heldDraw = gl.getParameter(gl.DRAW_FRAMEBUFFER_BINDING) as WebGLFramebuffer | null;
|
|
611
|
+
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, read);
|
|
612
|
+
gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, this.texture, 0, 0);
|
|
613
|
+
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, draw);
|
|
614
|
+
gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, flat, 0);
|
|
615
|
+
const [w, h] = [this.width, this.height];
|
|
616
|
+
gl.blitFramebuffer(0, 0, w, h, 0, 0, w, h, gl.COLOR_BUFFER_BIT, gl.NEAREST);
|
|
617
|
+
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, heldRead);
|
|
618
|
+
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, heldDraw);
|
|
619
|
+
gl.deleteFramebuffer(read);
|
|
620
|
+
gl.deleteFramebuffer(draw);
|
|
621
|
+
this.flat = flat;
|
|
622
|
+
return flat;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
private dropFlat(gl: WebGL2RenderingContext): void {
|
|
626
|
+
if (this.flat !== null) gl.deleteTexture(this.flat);
|
|
627
|
+
this.flat = null;
|
|
628
|
+
}
|
|
629
|
+
|
|
497
630
|
dispose(gl: WebGL2RenderingContext): void {
|
|
498
631
|
if (this.texture === null) return;
|
|
632
|
+
this.dropFlat(gl);
|
|
499
633
|
gl.deleteTexture(this.texture);
|
|
500
634
|
this.texture = null;
|
|
501
635
|
if (this.effectsTable !== null) gl.deleteTexture(this.effectsTable);
|
package/src/render/temporalAa.ts
CHANGED
|
@@ -451,6 +451,17 @@ export class TemporalHistory {
|
|
|
451
451
|
private picture = false;
|
|
452
452
|
private width = 0;
|
|
453
453
|
private height = 0;
|
|
454
|
+
/** Whether this frame of the renderer's has opened one of the sequence, and what it answered. */
|
|
455
|
+
private opened = false;
|
|
456
|
+
private answer = false;
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* A frame of the renderer's began: the next `openFrame` opens a frame of the sequence. Called at
|
|
460
|
+
* `beginFrame`, by both backends.
|
|
461
|
+
*/
|
|
462
|
+
nextFrame(): void {
|
|
463
|
+
this.opened = false;
|
|
464
|
+
}
|
|
454
465
|
|
|
455
466
|
/**
|
|
456
467
|
* Open a frame at this target size, and answer whether the history may be sampled.
|
|
@@ -458,13 +469,22 @@ export class TemporalHistory {
|
|
|
458
469
|
* **The jitter advances whether or not it may be.** Holding the sequence still on the frames a
|
|
459
470
|
* resize or a cut discarded would sample the same position twice running, which is one sample
|
|
460
471
|
* and not two.
|
|
472
|
+
*
|
|
473
|
+
* **Once a frame, however many times it is asked.** A renderer asks where the scene's camera
|
|
474
|
+
* arrives, and a frame binds that camera again after a scene capture or anything else that bound
|
|
475
|
+
* another; each asking opened a frame of its own, so the sequence stepped twice in such a frame
|
|
476
|
+
* and the edges of the picture swam. Asked again, it gives the answer it gave. What it gives up:
|
|
477
|
+
* a size changed between two asks in one frame is seen at the next frame, not at once.
|
|
461
478
|
*/
|
|
462
479
|
openFrame(width: number, height: number): boolean {
|
|
480
|
+
if (this.opened) return this.answer;
|
|
481
|
+
this.opened = true;
|
|
463
482
|
this.frameIndex++;
|
|
464
483
|
const usable = this.picture && width === this.width && height === this.height;
|
|
465
484
|
if (!usable) this.picture = false;
|
|
466
485
|
this.width = width;
|
|
467
486
|
this.height = height;
|
|
487
|
+
this.answer = usable;
|
|
468
488
|
return usable;
|
|
469
489
|
}
|
|
470
490
|
|
|
@@ -113,8 +113,18 @@ export const OUTPUT_TRANSFORM_CODE: Readonly<Record<string, number>> = {
|
|
|
113
113
|
srgb: 1,
|
|
114
114
|
aces: 2,
|
|
115
115
|
shoulder: 3,
|
|
116
|
+
filmic: 4,
|
|
116
117
|
};
|
|
117
118
|
|
|
119
|
+
/**
|
|
120
|
+
* The code a **forward** pass grades with: the transform's own, except `filmic`, which only the
|
|
121
|
+
* composite carries the constants for, and which a pass grading itself therefore draws as `aces`.
|
|
122
|
+
* Both backends' `gradeCode` read this, so neither can hand a forward stage a code it lacks.
|
|
123
|
+
*/
|
|
124
|
+
export function forwardTransformCode(transform: string): number {
|
|
125
|
+
return transform === 'filmic' ? 2 : (OUTPUT_TRANSFORM_CODE[transform] ?? 0);
|
|
126
|
+
}
|
|
127
|
+
|
|
118
128
|
/**
|
|
119
129
|
* How far the speed rush reaches, and how far a motion-blurred pixel may travel, both in UV.
|
|
120
130
|
*
|
|
@@ -123,3 +133,21 @@ export const OUTPUT_TRANSFORM_CODE: Readonly<Record<string, number>> = {
|
|
|
123
133
|
*/
|
|
124
134
|
export const RUSH_REACH_UV = 0.012;
|
|
125
135
|
export const MOTION_BLUR_MAX_UV = 0.03;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* A longest smear as `setCameraMotionBlur` takes it: a share of the frame, above zero and at most
|
|
139
|
+
* half, and the default where the number is not one. Shared, so both backends cap one way.
|
|
140
|
+
*/
|
|
141
|
+
export function clampMotionShare(share: number): number {
|
|
142
|
+
return Number.isFinite(share) && share > 0 ? Math.min(share, 0.5) : MOTION_BLUR_MAX_UV;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Said once where a draw names where it was last frame and the frame blurs by motion, but keeps no
|
|
147
|
+
* motion target to blur that draw by: each object's own motion is drawn only under a
|
|
148
|
+
* reconstruction on WebGPU, and anywhere else the camera's motion alone smears the frame.
|
|
149
|
+
*/
|
|
150
|
+
export const OBJECT_BLUR_UNKEPT =
|
|
151
|
+
"[driftengine] motion blur follows each draw's own motion only under a reconstruction " +
|
|
152
|
+
"(DriftTR, WebGPU), which draws the motion target it reads; here the camera's motion alone " +
|
|
153
|
+
'blurs the frame, and a moving object is smeared only as the camera moved past it.';
|