@bloopjs/toodle 0.0.103 → 0.1.1
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/dist/Toodle.d.ts +50 -20
- package/dist/Toodle.d.ts.map +1 -1
- package/dist/backends/IBackendShader.d.ts +48 -0
- package/dist/backends/IBackendShader.d.ts.map +1 -0
- package/dist/backends/IRenderBackend.d.ts +92 -0
- package/dist/backends/IRenderBackend.d.ts.map +1 -0
- package/dist/backends/ITextureAtlas.d.ts +34 -0
- package/dist/backends/ITextureAtlas.d.ts.map +1 -0
- package/dist/backends/detection.d.ts +16 -0
- package/dist/backends/detection.d.ts.map +1 -0
- package/dist/backends/mod.d.ts +9 -0
- package/dist/backends/mod.d.ts.map +1 -0
- package/dist/backends/webgl2/WebGLBackend.d.ts +51 -0
- package/dist/backends/webgl2/WebGLBackend.d.ts.map +1 -0
- package/dist/backends/webgl2/WebGLQuadShader.d.ts +17 -0
- package/dist/backends/webgl2/WebGLQuadShader.d.ts.map +1 -0
- package/dist/backends/webgl2/glsl/quad.glsl.d.ts +12 -0
- package/dist/backends/webgl2/glsl/quad.glsl.d.ts.map +1 -0
- package/dist/backends/webgl2/mod.d.ts +3 -0
- package/dist/backends/webgl2/mod.d.ts.map +1 -0
- package/dist/backends/webgpu/ShaderDescriptor.d.ts.map +1 -0
- package/dist/{textures → backends/webgpu}/TextureComputeShader.d.ts +1 -1
- package/dist/backends/webgpu/TextureComputeShader.d.ts.map +1 -0
- package/dist/backends/webgpu/WebGPUBackend.d.ts +67 -0
- package/dist/backends/webgpu/WebGPUBackend.d.ts.map +1 -0
- package/dist/backends/webgpu/WebGPUQuadShader.d.ts +18 -0
- package/dist/backends/webgpu/WebGPUQuadShader.d.ts.map +1 -0
- package/dist/backends/webgpu/mod.d.ts +3 -0
- package/dist/backends/webgpu/mod.d.ts.map +1 -0
- package/dist/backends/webgpu/parser.d.ts.map +1 -0
- package/dist/{shaders → backends/webgpu}/postprocess/blur.d.ts +1 -1
- package/dist/backends/webgpu/postprocess/blur.d.ts.map +1 -0
- package/dist/{shaders → backends/webgpu}/postprocess/mod.d.ts +1 -1
- package/dist/backends/webgpu/postprocess/mod.d.ts.map +1 -0
- package/dist/backends/webgpu/samplers.d.ts.map +1 -0
- package/dist/backends/webgpu/wgsl/example.wgsl.d.ts.map +1 -0
- package/dist/backends/webgpu/wgsl/hello.wgsl.d.ts.map +1 -0
- package/dist/backends/webgpu/wgsl/helloInstanced.wgsl.d.ts.map +1 -0
- package/dist/backends/webgpu/wgsl/pixel-scraping.wgsl.d.ts.map +1 -0
- package/dist/backends/webgpu/wgsl/quad.wgsl.d.ts.map +1 -0
- package/dist/coreTypes/EngineUniform.d.ts.map +1 -0
- package/dist/mod.d.ts +3 -2
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +6741 -6151
- package/dist/mod.js.map +28 -23
- package/dist/scene/Batcher.d.ts +2 -2
- package/dist/scene/Batcher.d.ts.map +1 -1
- package/dist/scene/QuadNode.d.ts +3 -2
- package/dist/scene/QuadNode.d.ts.map +1 -1
- package/dist/scene/RenderComponent.d.ts +2 -2
- package/dist/scene/RenderComponent.d.ts.map +1 -1
- package/dist/scene/SceneNode.d.ts +2 -2
- package/dist/scene/SceneNode.d.ts.map +1 -1
- package/dist/text/TextShader.d.ts +8 -6
- package/dist/text/TextShader.d.ts.map +1 -1
- package/dist/textures/AssetManager.d.ts +21 -5
- package/dist/textures/AssetManager.d.ts.map +1 -1
- package/dist/textures/types.d.ts +4 -2
- package/dist/textures/types.d.ts.map +1 -1
- package/dist/textures/util.d.ts.map +1 -1
- package/dist/utils/boilerplate.d.ts +1 -1
- package/dist/utils/boilerplate.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Toodle.ts +155 -171
- package/src/backends/IBackendShader.ts +52 -0
- package/src/backends/IRenderBackend.ts +118 -0
- package/src/backends/ITextureAtlas.ts +35 -0
- package/src/backends/detection.ts +46 -0
- package/src/backends/mod.ts +29 -0
- package/src/backends/webgl2/WebGLBackend.ts +256 -0
- package/src/backends/webgl2/WebGLQuadShader.ts +278 -0
- package/src/backends/webgl2/glsl/quad.glsl.ts +114 -0
- package/src/backends/webgl2/mod.ts +2 -0
- package/src/{textures → backends/webgpu}/TextureComputeShader.ts +2 -48
- package/src/backends/webgpu/WebGPUBackend.ts +350 -0
- package/src/{shaders/QuadShader.ts → backends/webgpu/WebGPUQuadShader.ts} +226 -170
- package/src/backends/webgpu/mod.ts +2 -0
- package/src/{shaders → backends/webgpu}/parser.ts +2 -2
- package/src/{shaders → backends/webgpu}/postprocess/blur.ts +2 -2
- package/src/{shaders → backends/webgpu}/postprocess/mod.ts +1 -1
- package/src/mod.ts +3 -2
- package/src/scene/Batcher.ts +3 -3
- package/src/scene/QuadNode.ts +7 -6
- package/src/scene/RenderComponent.ts +2 -2
- package/src/scene/SceneNode.ts +11 -12
- package/src/text/TextNode.ts +2 -2
- package/src/text/TextShader.ts +17 -11
- package/src/textures/AssetManager.ts +119 -94
- package/src/textures/types.ts +4 -2
- package/src/textures/util.ts +0 -65
- package/src/utils/boilerplate.ts +1 -1
- package/dist/shaders/EngineUniform.d.ts.map +0 -1
- package/dist/shaders/IShader.d.ts +0 -15
- package/dist/shaders/IShader.d.ts.map +0 -1
- package/dist/shaders/QuadShader.d.ts +0 -18
- package/dist/shaders/QuadShader.d.ts.map +0 -1
- package/dist/shaders/ShaderDescriptor.d.ts.map +0 -1
- package/dist/shaders/mod.d.ts +0 -6
- package/dist/shaders/mod.d.ts.map +0 -1
- package/dist/shaders/parser.d.ts.map +0 -1
- package/dist/shaders/postprocess/blur.d.ts.map +0 -1
- package/dist/shaders/postprocess/mod.d.ts.map +0 -1
- package/dist/shaders/samplers.d.ts.map +0 -1
- package/dist/shaders/wgsl/example.wgsl.d.ts.map +0 -1
- package/dist/shaders/wgsl/hello.wgsl.d.ts.map +0 -1
- package/dist/shaders/wgsl/helloInstanced.wgsl.d.ts.map +0 -1
- package/dist/shaders/wgsl/quad.wgsl.d.ts.map +0 -1
- package/dist/textures/TextureComputeShader.d.ts.map +0 -1
- package/dist/textures/pixel-scraping.wgsl.d.ts.map +0 -1
- package/src/shaders/IShader.ts +0 -20
- package/src/shaders/mod.ts +0 -5
- /package/dist/{shaders → backends/webgpu}/ShaderDescriptor.d.ts +0 -0
- /package/dist/{shaders → backends/webgpu}/parser.d.ts +0 -0
- /package/dist/{shaders → backends/webgpu}/samplers.d.ts +0 -0
- /package/dist/{shaders → backends/webgpu}/wgsl/example.wgsl.d.ts +0 -0
- /package/dist/{shaders → backends/webgpu}/wgsl/hello.wgsl.d.ts +0 -0
- /package/dist/{shaders → backends/webgpu}/wgsl/helloInstanced.wgsl.d.ts +0 -0
- /package/dist/{textures → backends/webgpu/wgsl}/pixel-scraping.wgsl.d.ts +0 -0
- /package/dist/{shaders → backends/webgpu}/wgsl/quad.wgsl.d.ts +0 -0
- /package/dist/{shaders → coreTypes}/EngineUniform.d.ts +0 -0
- /package/src/{shaders → backends/webgpu}/ShaderDescriptor.ts +0 -0
- /package/src/{shaders → backends/webgpu}/samplers.ts +0 -0
- /package/src/{shaders → backends/webgpu}/wgsl/example.wgsl.ts +0 -0
- /package/src/{shaders → backends/webgpu}/wgsl/hello.wgsl.ts +0 -0
- /package/src/{shaders → backends/webgpu}/wgsl/helloInstanced.wgsl.ts +0 -0
- /package/src/{textures → backends/webgpu/wgsl}/pixel-scraping.wgsl.ts +0 -0
- /package/src/{shaders → backends/webgpu}/wgsl/quad.wgsl.ts +0 -0
- /package/src/{shaders → coreTypes}/EngineUniform.ts +0 -0
package/src/text/TextNode.ts
CHANGED
|
@@ -23,8 +23,8 @@ export class TextNode extends SceneNode {
|
|
|
23
23
|
|
|
24
24
|
const em2px = shader.font.lineHeight / (opts.fontSize ?? DEFAULT_FONT_SIZE);
|
|
25
25
|
|
|
26
|
-
if (!opts.shrinkToFit && !opts.
|
|
27
|
-
opts.
|
|
26
|
+
if (!opts.shrinkToFit && !opts.size) {
|
|
27
|
+
opts.size = { width: width / em2px, height: height / em2px };
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
super({
|
package/src/text/TextShader.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { WgslReflect } from "wgsl_reflect";
|
|
2
|
+
import type { IBackendShader } from "../backends/IBackendShader";
|
|
3
|
+
import type { WebGPUBackend } from "../backends/webgpu/WebGPUBackend";
|
|
4
|
+
import type { EngineUniform } from "../coreTypes/EngineUniform";
|
|
2
5
|
import type { SceneNode } from "../scene/SceneNode";
|
|
3
|
-
import type { EngineUniform } from "../shaders/EngineUniform";
|
|
4
|
-
import type { IShader } from "../shaders/IShader";
|
|
5
6
|
import type { FontPipeline } from "./FontPipeline";
|
|
6
7
|
import type { MsdfFont } from "./MsdfFont";
|
|
7
8
|
import { findLargestFontSize, measureText, shapeText } from "./shaping";
|
|
@@ -15,8 +16,10 @@ if (!struct) {
|
|
|
15
16
|
}
|
|
16
17
|
const textDescriptorInstanceSize = struct.size;
|
|
17
18
|
|
|
18
|
-
export class TextShader implements
|
|
19
|
-
|
|
19
|
+
export class TextShader implements IBackendShader {
|
|
20
|
+
readonly label = "text";
|
|
21
|
+
|
|
22
|
+
#backend: WebGPUBackend;
|
|
20
23
|
#pipeline: GPURenderPipeline;
|
|
21
24
|
#bindGroups: GPUBindGroup[] = [];
|
|
22
25
|
#font: MsdfFont;
|
|
@@ -30,13 +33,14 @@ export class TextShader implements IShader {
|
|
|
30
33
|
#textBlockOffset = 0;
|
|
31
34
|
|
|
32
35
|
constructor(
|
|
33
|
-
|
|
36
|
+
backend: WebGPUBackend,
|
|
34
37
|
pipeline: FontPipeline,
|
|
35
38
|
font: MsdfFont,
|
|
36
|
-
|
|
39
|
+
_colorFormat: GPUTextureFormat,
|
|
37
40
|
instanceCount: number,
|
|
38
41
|
) {
|
|
39
|
-
this.#
|
|
42
|
+
this.#backend = backend;
|
|
43
|
+
const device = backend.device;
|
|
40
44
|
this.#font = font;
|
|
41
45
|
this.#pipeline = pipeline.pipeline;
|
|
42
46
|
this.#maxCharCount = pipeline.maxCharCount;
|
|
@@ -102,7 +106,8 @@ export class TextShader implements IShader {
|
|
|
102
106
|
this.#bindGroups.push(engineUniformsBindGroup);
|
|
103
107
|
}
|
|
104
108
|
|
|
105
|
-
startFrame(
|
|
109
|
+
startFrame(uniform: EngineUniform): void {
|
|
110
|
+
const device = this.#backend.device;
|
|
106
111
|
device.queue.writeBuffer(
|
|
107
112
|
this.#engineUniformsBuffer,
|
|
108
113
|
0,
|
|
@@ -112,9 +117,10 @@ export class TextShader implements IShader {
|
|
|
112
117
|
this.#textBlockOffset = 0;
|
|
113
118
|
}
|
|
114
119
|
|
|
115
|
-
processBatch(
|
|
120
|
+
processBatch(nodes: SceneNode[]): number {
|
|
116
121
|
if (nodes.length === 0) return 0;
|
|
117
122
|
|
|
123
|
+
const renderPass = this.#backend.renderPass;
|
|
118
124
|
renderPass.setPipeline(this.#pipeline);
|
|
119
125
|
for (let i = 0; i < this.#bindGroups.length; i++) {
|
|
120
126
|
renderPass.setBindGroup(i, this.#bindGroups[i]);
|
|
@@ -178,7 +184,7 @@ export class TextShader implements IShader {
|
|
|
178
184
|
);
|
|
179
185
|
|
|
180
186
|
// Write instance data
|
|
181
|
-
this.#device.queue.writeBuffer(
|
|
187
|
+
this.#backend.device.queue.writeBuffer(
|
|
182
188
|
this.#descriptorBuffer,
|
|
183
189
|
textDescriptorOffset * Float32Array.BYTES_PER_ELEMENT,
|
|
184
190
|
this.#cpuDescriptorBuffer,
|
|
@@ -186,7 +192,7 @@ export class TextShader implements IShader {
|
|
|
186
192
|
textDescriptorInstanceSize / Float32Array.BYTES_PER_ELEMENT,
|
|
187
193
|
);
|
|
188
194
|
|
|
189
|
-
this.#device.queue.writeBuffer(
|
|
195
|
+
this.#backend.device.queue.writeBuffer(
|
|
190
196
|
this.#textBlockBuffer,
|
|
191
197
|
this.#textBlockOffset * Float32Array.BYTES_PER_ELEMENT,
|
|
192
198
|
this.#cpuTextBlockBuffer,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
import type { IRenderBackend } from "../backends/IRenderBackend";
|
|
2
|
+
import { TextureComputeShader } from "../backends/webgpu/TextureComputeShader";
|
|
3
|
+
import type { WebGPUBackend } from "../backends/webgpu/WebGPUBackend";
|
|
1
4
|
import type { Size } from "../coreTypes/Size";
|
|
2
5
|
import type { Vec2 } from "../coreTypes/Vec2";
|
|
3
|
-
import type { Limits } from "../limits";
|
|
4
6
|
import { JumboQuadNode } from "../scene/JumboQuadNode";
|
|
5
7
|
import { QuadNode } from "../scene/QuadNode";
|
|
6
8
|
import type { SceneNode } from "../scene/SceneNode";
|
|
7
9
|
import { FontPipeline } from "../text/FontPipeline";
|
|
8
10
|
import { MsdfFont } from "../text/MsdfFont";
|
|
9
11
|
import { TextShader } from "../text/TextShader";
|
|
10
|
-
import { assert } from "../utils/mod";
|
|
11
12
|
import { Bundles } from "./Bundles";
|
|
12
|
-
import { TextureComputeShader } from "./TextureComputeShader";
|
|
13
13
|
import type {
|
|
14
14
|
AtlasBundleOpts,
|
|
15
15
|
AtlasCoords,
|
|
@@ -26,51 +26,63 @@ export type FontId = string;
|
|
|
26
26
|
export type AssetManagerOptions = {
|
|
27
27
|
/** Existing Bundles instance to use for CPU-side storage. If not provided, a new one is created. */
|
|
28
28
|
bundles?: Bundles;
|
|
29
|
-
/**
|
|
30
|
-
|
|
29
|
+
/** Which texture atlas to use (default: "default") */
|
|
30
|
+
atlasId?: string;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export class AssetManager {
|
|
34
|
-
readonly textureAtlas: GPUTexture;
|
|
35
34
|
readonly bundles: Bundles;
|
|
36
|
-
#
|
|
37
|
-
#
|
|
35
|
+
#backend: IRenderBackend;
|
|
36
|
+
#atlasId: string;
|
|
38
37
|
#fonts: Map<string, TextShader> = new Map();
|
|
39
|
-
#cropComputeShader: TextureComputeShader;
|
|
40
|
-
#limits: Limits;
|
|
38
|
+
#cropComputeShader: TextureComputeShader | null = null;
|
|
41
39
|
#availableIndices: Set<number> = new Set();
|
|
42
40
|
|
|
43
|
-
constructor(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
this.bundles =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.#limits.textureArrayLayers,
|
|
61
|
-
],
|
|
62
|
-
format,
|
|
63
|
-
usage:
|
|
64
|
-
GPUTextureUsage.TEXTURE_BINDING |
|
|
65
|
-
GPUTextureUsage.COPY_DST |
|
|
66
|
-
GPUTextureUsage.RENDER_ATTACHMENT,
|
|
67
|
-
});
|
|
68
|
-
this.#cropComputeShader = TextureComputeShader.create(device);
|
|
41
|
+
constructor(backend: IRenderBackend, options: AssetManagerOptions = {}) {
|
|
42
|
+
this.#backend = backend;
|
|
43
|
+
this.#atlasId = options.atlasId ?? "default";
|
|
44
|
+
|
|
45
|
+
const atlas = backend.getTextureAtlas(this.#atlasId);
|
|
46
|
+
if (!atlas) {
|
|
47
|
+
throw new Error(`Atlas "${this.#atlasId}" not found`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.bundles = options.bundles ?? new Bundles({ atlasSize: atlas.size });
|
|
51
|
+
|
|
52
|
+
// Initialize compute shader only for WebGPU backend
|
|
53
|
+
if (backend.type === "webgpu") {
|
|
54
|
+
const device = (backend as WebGPUBackend).device;
|
|
55
|
+
this.#cropComputeShader = TextureComputeShader.create(device);
|
|
56
|
+
}
|
|
57
|
+
|
|
69
58
|
this.#availableIndices = new Set(
|
|
70
|
-
Array.from({ length:
|
|
59
|
+
Array.from({ length: atlas.layers }, (_, i) => i),
|
|
71
60
|
);
|
|
72
61
|
}
|
|
73
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Get the atlas ID this asset manager uses.
|
|
65
|
+
*/
|
|
66
|
+
get atlasId(): string {
|
|
67
|
+
return this.#atlasId;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get the GPU texture atlas. For WebGPU, returns GPUTexture.
|
|
72
|
+
* @deprecated Access via backend.getTextureAtlas(atlasId).handle instead
|
|
73
|
+
*/
|
|
74
|
+
get textureAtlas(): GPUTexture {
|
|
75
|
+
return this.#backend.getTextureAtlas(this.#atlasId)!.handle as GPUTexture;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get the atlas dimensions
|
|
80
|
+
*/
|
|
81
|
+
get atlasSize(): Size {
|
|
82
|
+
const atlas = this.#backend.getTextureAtlas(this.#atlasId);
|
|
83
|
+
return { width: atlas!.size, height: atlas!.size };
|
|
84
|
+
}
|
|
85
|
+
|
|
74
86
|
/**
|
|
75
87
|
* True dimensions of a loaded texture, prior to any transparent pixel cropping.
|
|
76
88
|
*
|
|
@@ -80,9 +92,10 @@ export class AssetManager {
|
|
|
80
92
|
getSize(id: TextureId): Size {
|
|
81
93
|
const coords = this.extra.getAtlasCoords(id);
|
|
82
94
|
const originalScale = coords[0].uvScale;
|
|
95
|
+
// Use atlasSize instead of textureAtlas.width/height for WebGL2 compatibility
|
|
83
96
|
return {
|
|
84
|
-
width: originalScale.width * this.
|
|
85
|
-
height: originalScale.height * this.
|
|
97
|
+
width: originalScale.width * this.atlasSize.width,
|
|
98
|
+
height: originalScale.height * this.atlasSize.height,
|
|
86
99
|
};
|
|
87
100
|
}
|
|
88
101
|
|
|
@@ -95,9 +108,10 @@ export class AssetManager {
|
|
|
95
108
|
getCroppedSize(id: TextureId): Size {
|
|
96
109
|
const scaledUvs = this.extra.getAtlasCoords(id)[0].uvScaleCropped;
|
|
97
110
|
if (scaledUvs) {
|
|
111
|
+
// Use atlasSize instead of textureAtlas.width/height for WebGL2 compatibility
|
|
98
112
|
return {
|
|
99
|
-
width: scaledUvs.width * this.
|
|
100
|
-
height: scaledUvs.height * this.
|
|
113
|
+
width: scaledUvs.width * this.atlasSize.width,
|
|
114
|
+
height: scaledUvs.height * this.atlasSize.height,
|
|
101
115
|
};
|
|
102
116
|
}
|
|
103
117
|
return this.getSize(id);
|
|
@@ -165,12 +179,20 @@ export class AssetManager {
|
|
|
165
179
|
*
|
|
166
180
|
* Note: this will consume one texture atlas per texture.
|
|
167
181
|
* For more efficient loading of multiple textures, consider {@link loadBundle}
|
|
182
|
+
*
|
|
183
|
+
* @throws Error if using WebGL backend (use registerBundle instead)
|
|
168
184
|
*/
|
|
169
185
|
async loadTexture(
|
|
170
186
|
id: TextureId,
|
|
171
187
|
url: URL | ImageBitmap,
|
|
172
188
|
options?: Partial<TextureBundleOpts>,
|
|
173
189
|
) {
|
|
190
|
+
if (this.#backend.type !== "webgpu") {
|
|
191
|
+
throw new Error(
|
|
192
|
+
"loadTexture is only supported with WebGPU backend. Use registerBundle with prebaked atlases instead.",
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
174
196
|
const bitmap =
|
|
175
197
|
url instanceof ImageBitmap ? url : await getBitmapFromUrl(url);
|
|
176
198
|
|
|
@@ -180,24 +202,25 @@ export class AssetManager {
|
|
|
180
202
|
);
|
|
181
203
|
const atlasIndex = this.extra.nextAvailableAtlasIndex();
|
|
182
204
|
|
|
183
|
-
if (options?.cropTransparentPixels) {
|
|
205
|
+
if (options?.cropTransparentPixels && this.#cropComputeShader) {
|
|
184
206
|
textureWrapper =
|
|
185
207
|
await this.#cropComputeShader.processTexture(textureWrapper);
|
|
186
208
|
}
|
|
187
209
|
|
|
188
210
|
this.#copyTextureToAtlas(textureWrapper.texture, atlasIndex);
|
|
189
211
|
|
|
212
|
+
const { width: atlasWidth, height: atlasHeight } = this.atlasSize;
|
|
190
213
|
const coords: AtlasCoords = {
|
|
191
214
|
uvOffset: { x: 0, y: 0 },
|
|
192
215
|
cropOffset: textureWrapper.cropOffset,
|
|
193
216
|
uvScale: {
|
|
194
|
-
width: textureWrapper.texture.width /
|
|
195
|
-
height: textureWrapper.texture.height /
|
|
217
|
+
width: textureWrapper.texture.width / atlasWidth,
|
|
218
|
+
height: textureWrapper.texture.height / atlasHeight,
|
|
196
219
|
},
|
|
197
220
|
originalSize: textureWrapper.originalSize,
|
|
198
221
|
uvScaleCropped: {
|
|
199
|
-
width: textureWrapper.texture.width /
|
|
200
|
-
height: textureWrapper.texture.height /
|
|
222
|
+
width: textureWrapper.texture.width / atlasWidth,
|
|
223
|
+
height: textureWrapper.texture.height / atlasHeight,
|
|
201
224
|
},
|
|
202
225
|
atlasIndex,
|
|
203
226
|
};
|
|
@@ -228,7 +251,8 @@ export class AssetManager {
|
|
|
228
251
|
await this.#registerBundleFromAtlases(bundleId, opts);
|
|
229
252
|
}
|
|
230
253
|
|
|
231
|
-
|
|
254
|
+
const autoLoad = opts.autoLoad ?? true;
|
|
255
|
+
if (autoLoad) {
|
|
232
256
|
await this.loadBundle(bundleId);
|
|
233
257
|
}
|
|
234
258
|
return bundleId;
|
|
@@ -291,23 +315,36 @@ export class AssetManager {
|
|
|
291
315
|
* @param id - The id of the font to load
|
|
292
316
|
* @param url - The url of the font to load
|
|
293
317
|
* @param fallbackCharacter - The character to use as a fallback if the font does not contain a character to be rendererd
|
|
318
|
+
*
|
|
319
|
+
* @throws Error if using WebGL backend (fonts not supported in WebGL mode)
|
|
294
320
|
*/
|
|
295
321
|
async loadFont(id: string, url: URL, fallbackCharacter = "_") {
|
|
322
|
+
if (this.#backend.type !== "webgpu") {
|
|
323
|
+
throw new Error(
|
|
324
|
+
"loadFont is only supported with WebGPU backend. Text rendering is not available in WebGL mode.",
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const webgpuBackend = this.#backend as WebGPUBackend;
|
|
329
|
+
const device = webgpuBackend.device;
|
|
330
|
+
const presentationFormat = webgpuBackend.presentationFormat;
|
|
331
|
+
const limits = this.#backend.limits;
|
|
332
|
+
|
|
296
333
|
const font = await MsdfFont.create(id, url);
|
|
297
334
|
font.fallbackCharacter = fallbackCharacter;
|
|
298
335
|
const fontPipeline = await FontPipeline.create(
|
|
299
|
-
|
|
336
|
+
device,
|
|
300
337
|
font,
|
|
301
|
-
|
|
302
|
-
|
|
338
|
+
presentationFormat,
|
|
339
|
+
limits.maxTextLength,
|
|
303
340
|
);
|
|
304
341
|
|
|
305
342
|
const textShader = new TextShader(
|
|
306
|
-
this.#
|
|
343
|
+
this.#backend as WebGPUBackend,
|
|
307
344
|
fontPipeline,
|
|
308
345
|
font,
|
|
309
|
-
|
|
310
|
-
|
|
346
|
+
presentationFormat,
|
|
347
|
+
limits.instanceCount,
|
|
311
348
|
);
|
|
312
349
|
this.#fonts.set(id, textShader);
|
|
313
350
|
return id;
|
|
@@ -352,7 +389,8 @@ export class AssetManager {
|
|
|
352
389
|
* @private
|
|
353
390
|
*/
|
|
354
391
|
#createTextureFromImageBitmap(bitmap: ImageBitmap, name: string): GPUTexture {
|
|
355
|
-
const
|
|
392
|
+
const device = (this.#backend as WebGPUBackend).device;
|
|
393
|
+
const texture = device.createTexture({
|
|
356
394
|
label: `${name} Intermediary Texture`,
|
|
357
395
|
size: [bitmap.width, bitmap.height],
|
|
358
396
|
format: "rgba8unorm",
|
|
@@ -363,7 +401,7 @@ export class AssetManager {
|
|
|
363
401
|
GPUTextureUsage.RENDER_ATTACHMENT,
|
|
364
402
|
});
|
|
365
403
|
|
|
366
|
-
|
|
404
|
+
device.queue.copyExternalImageToTexture(
|
|
367
405
|
{
|
|
368
406
|
source: bitmap,
|
|
369
407
|
},
|
|
@@ -379,20 +417,27 @@ export class AssetManager {
|
|
|
379
417
|
bundleId: BundleId,
|
|
380
418
|
opts: TextureBundleOpts,
|
|
381
419
|
) {
|
|
420
|
+
if (this.#backend.type !== "webgpu") {
|
|
421
|
+
throw new Error(
|
|
422
|
+
"Dynamic texture bundle registration is only supported with WebGPU backend. Use prebaked atlases instead.",
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const device = (this.#backend as WebGPUBackend).device;
|
|
382
427
|
const images = new Map<string, TextureWithMetadata>();
|
|
383
428
|
|
|
384
|
-
let
|
|
429
|
+
let _networkLoadTime = 0;
|
|
385
430
|
await Promise.all(
|
|
386
431
|
Object.entries(opts.textures).map(async ([id, url]) => {
|
|
387
432
|
const now = performance.now();
|
|
388
433
|
const bitmap = await getBitmapFromUrl(url);
|
|
389
|
-
|
|
434
|
+
_networkLoadTime += performance.now() - now;
|
|
390
435
|
let textureWrapper: TextureWithMetadata = this.#wrapBitmapToTexture(
|
|
391
436
|
bitmap,
|
|
392
437
|
id,
|
|
393
438
|
);
|
|
394
439
|
|
|
395
|
-
if (opts.cropTransparentPixels) {
|
|
440
|
+
if (opts.cropTransparentPixels && this.#cropComputeShader) {
|
|
396
441
|
textureWrapper =
|
|
397
442
|
await this.#cropComputeShader.processTexture(textureWrapper);
|
|
398
443
|
}
|
|
@@ -402,8 +447,8 @@ export class AssetManager {
|
|
|
402
447
|
|
|
403
448
|
const atlases = await packBitmapsToAtlas(
|
|
404
449
|
images,
|
|
405
|
-
this.#limits.textureSize,
|
|
406
|
-
|
|
450
|
+
this.#backend.limits.textureSize,
|
|
451
|
+
device,
|
|
407
452
|
);
|
|
408
453
|
|
|
409
454
|
this.bundles.registerDynamicBundle(bundleId, atlases);
|
|
@@ -466,6 +511,8 @@ export class AssetManager {
|
|
|
466
511
|
* @returns Usage stats for texture atlases
|
|
467
512
|
*/
|
|
468
513
|
getAtlasUsage: () => {
|
|
514
|
+
const atlas = this.#backend.getTextureAtlas(this.#atlasId);
|
|
515
|
+
const totalLayers = atlas?.layers ?? 0;
|
|
469
516
|
return {
|
|
470
517
|
/**
|
|
471
518
|
* The number of texture atlases that are currently unused
|
|
@@ -475,11 +522,11 @@ export class AssetManager {
|
|
|
475
522
|
/**
|
|
476
523
|
* The number of texture atlases that are currently in use.
|
|
477
524
|
*/
|
|
478
|
-
used:
|
|
525
|
+
used: totalLayers - this.#availableIndices.size,
|
|
479
526
|
/**
|
|
480
527
|
* The total number of texture atlases that can be loaded.
|
|
481
528
|
*/
|
|
482
|
-
total:
|
|
529
|
+
total: totalLayers,
|
|
483
530
|
};
|
|
484
531
|
},
|
|
485
532
|
|
|
@@ -488,7 +535,9 @@ export class AssetManager {
|
|
|
488
535
|
*
|
|
489
536
|
*/
|
|
490
537
|
nextAvailableAtlasIndex: () => {
|
|
491
|
-
|
|
538
|
+
const atlas = this.#backend.getTextureAtlas(this.#atlasId);
|
|
539
|
+
const totalLayers = atlas?.layers ?? 0;
|
|
540
|
+
for (let i = 0; i < totalLayers; i++) {
|
|
492
541
|
if (this.#availableIndices.has(i)) {
|
|
493
542
|
this.#availableIndices.delete(i);
|
|
494
543
|
return i;
|
|
@@ -506,34 +555,8 @@ export class AssetManager {
|
|
|
506
555
|
loadAtlas: async (atlas: CpuTextureAtlas) => {
|
|
507
556
|
const atlasIndex = this.extra.nextAvailableAtlasIndex();
|
|
508
557
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
width: this.textureAtlas.width,
|
|
512
|
-
height: this.textureAtlas.height,
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
// WebGPU requires 256-byte bytesPerRow
|
|
516
|
-
const rowBytes = w * 2;
|
|
517
|
-
assert(rowBytes % 256 === 0, "rowBytes must be a multiple of 256");
|
|
518
|
-
|
|
519
|
-
this.#device.queue.writeTexture(
|
|
520
|
-
{ texture: this.textureAtlas, origin: { x: 0, y: 0, z: atlasIndex } },
|
|
521
|
-
atlas.rg8Bytes,
|
|
522
|
-
{ bytesPerRow: rowBytes, rowsPerImage: h },
|
|
523
|
-
{ width: w, height: h, depthOrArrayLayers: 1 },
|
|
524
|
-
);
|
|
525
|
-
} else {
|
|
526
|
-
this.#device.queue.copyExternalImageToTexture(
|
|
527
|
-
{
|
|
528
|
-
source: atlas.texture,
|
|
529
|
-
},
|
|
530
|
-
{
|
|
531
|
-
texture: this.textureAtlas,
|
|
532
|
-
origin: [0, 0, atlasIndex],
|
|
533
|
-
},
|
|
534
|
-
[atlas.texture.width, atlas.texture.height, 1],
|
|
535
|
-
);
|
|
536
|
-
}
|
|
558
|
+
// Delegate to backend for actual GPU upload
|
|
559
|
+
await this.#backend.uploadAtlas(atlas, atlasIndex, this.#atlasId);
|
|
537
560
|
|
|
538
561
|
for (const [id, region] of atlas.textureRegions) {
|
|
539
562
|
this.bundles.addTextureEntry(id, { ...region, atlasIndex });
|
|
@@ -568,7 +591,8 @@ export class AssetManager {
|
|
|
568
591
|
}
|
|
569
592
|
|
|
570
593
|
#copyTextureToAtlas(texture: GPUTexture, atlasIndex: number) {
|
|
571
|
-
const
|
|
594
|
+
const device = (this.#backend as WebGPUBackend).device;
|
|
595
|
+
const copyEncoder: GPUCommandEncoder = device.createCommandEncoder();
|
|
572
596
|
copyEncoder.copyTextureToTexture(
|
|
573
597
|
{
|
|
574
598
|
texture: texture,
|
|
@@ -583,12 +607,13 @@ export class AssetManager {
|
|
|
583
607
|
[texture.width, texture.height, 1],
|
|
584
608
|
);
|
|
585
609
|
|
|
586
|
-
|
|
610
|
+
device.queue.submit([copyEncoder.finish()]);
|
|
587
611
|
}
|
|
612
|
+
|
|
588
613
|
/**
|
|
589
614
|
* Destroy the texture atlas. This should free up ~4gb of gpu memory (and make all draw calls fail)
|
|
590
615
|
*/
|
|
591
616
|
destroy() {
|
|
592
|
-
this.
|
|
617
|
+
this.#backend.destroy();
|
|
593
618
|
}
|
|
594
619
|
}
|
package/src/textures/types.ts
CHANGED
|
@@ -107,7 +107,8 @@ export type TextureBundleOpts = {
|
|
|
107
107
|
*/
|
|
108
108
|
cropTransparentPixels?: boolean;
|
|
109
109
|
/**
|
|
110
|
-
* Whether the bundle should be loaded automatically on registration
|
|
110
|
+
* Whether the bundle should be loaded automatically on registration.
|
|
111
|
+
* @default true
|
|
111
112
|
*/
|
|
112
113
|
autoLoad?: boolean;
|
|
113
114
|
};
|
|
@@ -135,7 +136,8 @@ export type AtlasBundleOpts = {
|
|
|
135
136
|
atlases: AtlasDef[];
|
|
136
137
|
|
|
137
138
|
/**
|
|
138
|
-
* Whether the bundle should be loaded automatically on registration
|
|
139
|
+
* Whether the bundle should be loaded automatically on registration.
|
|
140
|
+
* @default true
|
|
139
141
|
*/
|
|
140
142
|
autoLoad?: boolean;
|
|
141
143
|
|
package/src/textures/util.ts
CHANGED
|
@@ -16,71 +16,6 @@ export async function getBitmapFromUrl(url: URL): Promise<ImageBitmap> {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
/**
|
|
20
|
-
* Converts an image Blob to ImageData.
|
|
21
|
-
*
|
|
22
|
-
* @param blob - The Blob containing the image.
|
|
23
|
-
* @returns A Promise resolving to the image as ImageData.
|
|
24
|
-
*/
|
|
25
|
-
async function blobToImageData(blob: Blob) {
|
|
26
|
-
const imageBitmap: ImageBitmap = await createImageBitmap(blob);
|
|
27
|
-
|
|
28
|
-
const canvas = document.createElement("canvas");
|
|
29
|
-
const ctx = canvas.getContext("2d");
|
|
30
|
-
|
|
31
|
-
if (!ctx) {
|
|
32
|
-
throw new Error("Failed to get 2D context from canvas");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
canvas.width = imageBitmap.width;
|
|
36
|
-
canvas.height = imageBitmap.height;
|
|
37
|
-
|
|
38
|
-
ctx.drawImage(imageBitmap, 0, 0);
|
|
39
|
-
|
|
40
|
-
const imageData: ImageData = ctx.getImageData(
|
|
41
|
-
0,
|
|
42
|
-
0,
|
|
43
|
-
canvas.width,
|
|
44
|
-
canvas.height,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
imageBitmap.close();
|
|
48
|
-
|
|
49
|
-
return imageData;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Creates a checkerboard pattern ImageData in black and purple.
|
|
54
|
-
*
|
|
55
|
-
* @param width - Width of the image.
|
|
56
|
-
* @param height - Height of the image.
|
|
57
|
-
* @param tileSize - Size of each checker tile (default is 8).
|
|
58
|
-
* @returns The generated ImageData object.
|
|
59
|
-
*/
|
|
60
|
-
function createCheckerboardImageData(
|
|
61
|
-
width: number,
|
|
62
|
-
height: number,
|
|
63
|
-
tileSize = 8,
|
|
64
|
-
): ImageData {
|
|
65
|
-
const data = new Uint8ClampedArray(width * height * 4);
|
|
66
|
-
|
|
67
|
-
const purple = [128, 0, 128, 255]; // #800080
|
|
68
|
-
const black = [0, 0, 0, 255]; // #000000
|
|
69
|
-
|
|
70
|
-
for (let y = 0; y < height; y++) {
|
|
71
|
-
for (let x = 0; x < width; x++) {
|
|
72
|
-
const usePurple =
|
|
73
|
-
(Math.floor(x / tileSize) + Math.floor(y / tileSize)) % 2 === 0;
|
|
74
|
-
const color = usePurple ? purple : black;
|
|
75
|
-
const idx = (y * width + x) * 4;
|
|
76
|
-
|
|
77
|
-
data.set(color, idx);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return new ImageData(data, width, height);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
19
|
export async function loadZip(
|
|
85
20
|
zipUrl: URL,
|
|
86
21
|
): Promise<{ path: string; bitmap: ImageBitmap }[]> {
|
package/src/utils/boilerplate.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
makeBindGroupLayoutDescriptors,
|
|
3
3
|
makeShaderDataDefinitions,
|
|
4
4
|
} from "webgpu-utils";
|
|
5
|
-
import type { ShaderDescriptor } from "../
|
|
5
|
+
import type { ShaderDescriptor } from "../backends/webgpu/ShaderDescriptor";
|
|
6
6
|
import { assert } from "./assert";
|
|
7
7
|
|
|
8
8
|
// convenience functions to wrap verbose webgpu apis - not part of public api
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EngineUniform.d.ts","sourceRoot":"","sources":["../../src/shaders/EngineUniform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,IAAI,CAAC;CAG5B,CAAC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { SceneNode } from "../scene/SceneNode";
|
|
2
|
-
import type { EngineUniform } from "./EngineUniform";
|
|
3
|
-
export interface IShader {
|
|
4
|
-
startFrame: (device: GPUDevice, uniform: EngineUniform) => void;
|
|
5
|
-
/**
|
|
6
|
-
* Process a batch of nodes.
|
|
7
|
-
*
|
|
8
|
-
* @param renderPass - The render pass to use.
|
|
9
|
-
* @param nodes - The nodes to process.
|
|
10
|
-
* @returns The number of draw calls made.
|
|
11
|
-
*/
|
|
12
|
-
processBatch: (renderPass: GPURenderPassEncoder, nodes: SceneNode[]) => number;
|
|
13
|
-
endFrame: () => void;
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=IShader.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IShader.d.ts","sourceRoot":"","sources":["../../src/shaders/IShader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAEhE;;;;;;OAMG;IACH,YAAY,EAAE,CACZ,UAAU,EAAE,oBAAoB,EAChC,KAAK,EAAE,SAAS,EAAE,KACf,MAAM,CAAC;IAEZ,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { SceneNode } from "../scene/SceneNode";
|
|
2
|
-
import type { AssetManager } from "../textures/AssetManager";
|
|
3
|
-
import type { EngineUniform } from "./EngineUniform";
|
|
4
|
-
import type { IShader } from "./IShader";
|
|
5
|
-
export type QuadShaderOpts = {
|
|
6
|
-
assetManager?: AssetManager;
|
|
7
|
-
blendMode?: GPUBlendState;
|
|
8
|
-
};
|
|
9
|
-
export declare class QuadShader implements IShader {
|
|
10
|
-
#private;
|
|
11
|
-
label: string;
|
|
12
|
-
code: string;
|
|
13
|
-
startFrame(device: GPUDevice, uniform: EngineUniform): void;
|
|
14
|
-
processBatch(renderPass: GPURenderPassEncoder, nodes: SceneNode[]): number;
|
|
15
|
-
endFrame(): void;
|
|
16
|
-
constructor(label: string, assetManager: AssetManager, device: GPUDevice, presentationFormat: GPUTextureFormat, userCode: string, instanceCount: number, blendMode?: GPUBlendState);
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=QuadShader.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QuadShader.d.ts","sourceRoot":"","sources":["../../src/shaders/QuadShader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAQ7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B,CAAC;AAEF,qBAAa,UAAW,YAAW,OAAO;;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IAYb,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa;IAiBpD,YAAY,CAAC,UAAU,EAAE,oBAAoB,EAAE,KAAK,EAAE,SAAS,EAAE;IA0DjE,QAAQ;gBAGN,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,SAAS,EACjB,kBAAkB,EAAE,gBAAgB,EACpC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,aAAa;CA4G5B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ShaderDescriptor.d.ts","sourceRoot":"","sources":["../../src/shaders/ShaderDescriptor.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC"}
|
package/dist/shaders/mod.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/shaders/mod.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/shaders/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,UAK/C;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,gBAAgB,CA4ClB;AAuED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,QAAQ,GAAE,iBAA8B,GACvC,qBAAqB,CAkDvB;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,QAaxD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAqB9D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blur.d.ts","sourceRoot":"","sources":["../../../src/shaders/postprocess/blur.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAInD,wBAAgB,IAAI,CAClB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,KAAK,EACjB,kBAAkB,EAAE,gBAAgB,EACpC,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,QA2InC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../src/shaders/postprocess/mod.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;OAMG;IACH,OAAO,CACL,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,EAClC,MAAM,EAAE,UAAU,GACjB,IAAI,CAAC;CACT,CAAC;AAEF,eAAO,MAAM,mBAAmB;+BACd,SAAS,KAAG,UAAU;0CAWX,SAAS,KAAG,qBAAqB;oCAOvC,SAAS,KAAG,eAAe;0CAuBrB,SAAS,KAAG,2BAA2B;CAY1D,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"samplers.d.ts","sourceRoot":"","sources":["../../src/shaders/samplers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,EAAE,oBAK7B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,oBAK3B,CAAC"}
|