@luma.gl/effects 9.1.9 → 9.2.0-alpha.2
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/dist.dev.js +1162 -851
- package/dist/dist.min.js +7 -6
- package/dist/index.cjs +560 -65
- package/dist/index.cjs.map +3 -3
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.d.ts +3 -3
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.js +9 -9
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.js.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/denoise.d.ts +2 -2
- package/dist/passes/postprocessing/image-adjust-filters/denoise.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/denoise.js +9 -5
- package/dist/passes/postprocessing/image-adjust-filters/denoise.js.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.d.ts +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.js +5 -4
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.js.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/noise.d.ts +3 -3
- package/dist/passes/postprocessing/image-adjust-filters/noise.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/noise.js +7 -7
- package/dist/passes/postprocessing/image-adjust-filters/noise.js.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/sepia.d.ts +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/sepia.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/sepia.js +25 -0
- package/dist/passes/postprocessing/image-adjust-filters/sepia.js.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.d.ts +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.js +20 -0
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.js.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/vignette.d.ts +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/vignette.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/vignette.js +19 -9
- package/dist/passes/postprocessing/image-adjust-filters/vignette.js.map +1 -1
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.d.ts +5 -3
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.js +52 -4
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.js.map +1 -1
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.d.ts +8 -6
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.js +41 -3
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.js.map +1 -1
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.d.ts +8 -6
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.js +42 -4
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.js.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.d.ts +3 -2
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.js +41 -2
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.js.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.d.ts +3 -2
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.js +29 -2
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.js.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/edgework.d.ts +4 -2
- package/dist/passes/postprocessing/image-fun-filters/edgework.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/edgework.js +36 -2
- package/dist/passes/postprocessing/image-fun-filters/edgework.js.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.d.ts +3 -2
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.js +49 -2
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.js.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/ink.d.ts +3 -2
- package/dist/passes/postprocessing/image-fun-filters/ink.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/ink.js +34 -2
- package/dist/passes/postprocessing/image-fun-filters/ink.js.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/magnify.d.ts +2 -1
- package/dist/passes/postprocessing/image-fun-filters/magnify.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/magnify.js +26 -1
- package/dist/passes/postprocessing/image-fun-filters/magnify.js.map +1 -1
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.d.ts +5 -3
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.js +33 -2
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.js.map +1 -1
- package/dist/passes/postprocessing/image-warp-filters/swirl.d.ts +5 -3
- package/dist/passes/postprocessing/image-warp-filters/swirl.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-warp-filters/swirl.js +35 -2
- package/dist/passes/postprocessing/image-warp-filters/swirl.js.map +1 -1
- package/dist/passes/postprocessing/image-warp-filters/warp.d.ts +2 -1
- package/dist/passes/postprocessing/image-warp-filters/warp.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-warp-filters/warp.js +14 -3
- package/dist/passes/postprocessing/image-warp-filters/warp.js.map +1 -1
- package/package.json +3 -3
- package/src/passes/postprocessing/image-adjust-filters/brightnesscontrast.ts +10 -10
- package/src/passes/postprocessing/image-adjust-filters/denoise.ts +9 -5
- package/src/passes/postprocessing/image-adjust-filters/huesaturation.ts +5 -4
- package/src/passes/postprocessing/image-adjust-filters/noise.ts +9 -8
- package/src/passes/postprocessing/image-adjust-filters/sepia.ts +26 -0
- package/src/passes/postprocessing/image-adjust-filters/vibrance.ts +21 -0
- package/src/passes/postprocessing/image-adjust-filters/vignette.ts +20 -10
- package/src/passes/postprocessing/image-blur-filters/tiltshift.ts +55 -5
- package/src/passes/postprocessing/image-blur-filters/triangleblur.ts +44 -4
- package/src/passes/postprocessing/image-blur-filters/zoomblur.ts +45 -5
- package/src/passes/postprocessing/image-fun-filters/colorhalftone.ts +44 -3
- package/src/passes/postprocessing/image-fun-filters/dotscreen.ts +32 -3
- package/src/passes/postprocessing/image-fun-filters/edgework.ts +38 -3
- package/src/passes/postprocessing/image-fun-filters/hexagonalpixelate.ts +52 -3
- package/src/passes/postprocessing/image-fun-filters/ink.ts +36 -3
- package/src/passes/postprocessing/image-fun-filters/magnify.ts +29 -1
- package/src/passes/postprocessing/image-warp-filters/bulgepinch.ts +36 -3
- package/src/passes/postprocessing/image-warp-filters/swirl.ts +36 -3
- package/src/passes/postprocessing/image-warp-filters/warp.ts +16 -3
package/dist/dist.dev.js
CHANGED
|
@@ -73,62 +73,33 @@ var __exports__ = (() => {
|
|
|
73
73
|
Sampler: () => Sampler,
|
|
74
74
|
Shader: () => Shader,
|
|
75
75
|
Texture: () => Texture,
|
|
76
|
+
TextureFormatDecoder: () => TextureFormatDecoder,
|
|
76
77
|
TextureView: () => TextureView,
|
|
77
78
|
TransformFeedback: () => TransformFeedback,
|
|
78
79
|
UniformBlock: () => UniformBlock,
|
|
79
80
|
UniformBufferLayout: () => UniformBufferLayout,
|
|
80
81
|
UniformStore: () => UniformStore,
|
|
81
82
|
VertexArray: () => VertexArray,
|
|
82
|
-
_BufferLayoutHelper: () => BufferLayoutHelper,
|
|
83
83
|
_getTextureFormatDefinition: () => getTextureFormatDefinition,
|
|
84
84
|
_getTextureFormatTable: () => getTextureFormatTable,
|
|
85
|
-
decodeShaderAttributeType: () => decodeShaderAttributeType,
|
|
86
|
-
decodeShaderUniformType: () => decodeShaderUniformType,
|
|
87
|
-
decodeTextureFormat: () => decodeTextureFormat,
|
|
88
|
-
decodeVertexFormat: () => decodeVertexFormat,
|
|
89
85
|
getAttributeInfosFromLayouts: () => getAttributeInfosFromLayouts,
|
|
90
|
-
|
|
86
|
+
getAttributeShaderTypeInfo: () => getAttributeShaderTypeInfo,
|
|
87
|
+
getDataType: () => getDataType,
|
|
88
|
+
getDataTypeInfo: () => getDataTypeInfo,
|
|
89
|
+
getNormalizedDataType: () => getNormalizedDataType,
|
|
91
90
|
getScratchArray: () => getScratchArray,
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
getTypedArrayConstructor: () => getTypedArrayConstructor,
|
|
92
|
+
getVariableShaderTypeInfo: () => getVariableShaderTypeInfo,
|
|
94
93
|
getVertexFormatFromAttribute: () => getVertexFormatFromAttribute,
|
|
94
|
+
getVertexFormatInfo: () => getVertexFormatInfo,
|
|
95
95
|
log: () => log,
|
|
96
96
|
luma: () => luma,
|
|
97
|
-
|
|
97
|
+
makeVertexFormat: () => makeVertexFormat,
|
|
98
|
+
readPixel: () => readPixel,
|
|
99
|
+
textureFormatDecoder: () => textureFormatDecoder,
|
|
100
|
+
writePixel: () => writePixel
|
|
98
101
|
});
|
|
99
102
|
|
|
100
|
-
// ../../node_modules/@probe.gl/env/dist/lib/globals.js
|
|
101
|
-
var window_ = globalThis;
|
|
102
|
-
var document_ = globalThis.document || {};
|
|
103
|
-
var process_ = globalThis.process || {};
|
|
104
|
-
var console_ = globalThis.console;
|
|
105
|
-
var navigator_ = globalThis.navigator || {};
|
|
106
|
-
|
|
107
|
-
// ../../node_modules/@probe.gl/env/dist/lib/is-electron.js
|
|
108
|
-
function isElectron(mockUserAgent) {
|
|
109
|
-
if (typeof window !== "undefined" && window.process?.type === "renderer") {
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
if (typeof process !== "undefined" && Boolean(process.versions?.["electron"])) {
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
const realUserAgent = typeof navigator !== "undefined" && navigator.userAgent;
|
|
116
|
-
const userAgent = mockUserAgent || realUserAgent;
|
|
117
|
-
return Boolean(userAgent && userAgent.indexOf("Electron") >= 0);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// ../../node_modules/@probe.gl/env/dist/lib/is-browser.js
|
|
121
|
-
function isBrowser() {
|
|
122
|
-
const isNode = (
|
|
123
|
-
// @ts-expect-error
|
|
124
|
-
typeof process === "object" && String(process) === "[object process]" && !process?.browser
|
|
125
|
-
);
|
|
126
|
-
return !isNode || isElectron();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// ../../node_modules/@probe.gl/env/dist/index.js
|
|
130
|
-
var VERSION = true ? "4.0.7" : "untranspiled source";
|
|
131
|
-
|
|
132
103
|
// ../../node_modules/@probe.gl/stats/dist/utils/hi-res-timestamp.js
|
|
133
104
|
function getHiResTimestamp() {
|
|
134
105
|
let timestamp;
|
|
@@ -337,6 +308,38 @@ var __exports__ = (() => {
|
|
|
337
308
|
};
|
|
338
309
|
var lumaStats = new StatsManager();
|
|
339
310
|
|
|
311
|
+
// ../../node_modules/@probe.gl/env/dist/lib/globals.js
|
|
312
|
+
var window_ = globalThis;
|
|
313
|
+
var document_ = globalThis.document || {};
|
|
314
|
+
var process_ = globalThis.process || {};
|
|
315
|
+
var console_ = globalThis.console;
|
|
316
|
+
var navigator_ = globalThis.navigator || {};
|
|
317
|
+
|
|
318
|
+
// ../../node_modules/@probe.gl/env/dist/lib/is-electron.js
|
|
319
|
+
function isElectron(mockUserAgent) {
|
|
320
|
+
if (typeof window !== "undefined" && window.process?.type === "renderer") {
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
if (typeof process !== "undefined" && Boolean(process.versions?.["electron"])) {
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
const realUserAgent = typeof navigator !== "undefined" && navigator.userAgent;
|
|
327
|
+
const userAgent = mockUserAgent || realUserAgent;
|
|
328
|
+
return Boolean(userAgent && userAgent.indexOf("Electron") >= 0);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ../../node_modules/@probe.gl/env/dist/lib/is-browser.js
|
|
332
|
+
function isBrowser() {
|
|
333
|
+
const isNode = (
|
|
334
|
+
// @ts-expect-error
|
|
335
|
+
typeof process === "object" && String(process) === "[object process]" && !process?.browser
|
|
336
|
+
);
|
|
337
|
+
return !isNode || isElectron();
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// ../../node_modules/@probe.gl/env/dist/index.js
|
|
341
|
+
var VERSION = true ? "4.1.0" : "untranspiled source";
|
|
342
|
+
|
|
340
343
|
// ../../node_modules/@probe.gl/log/dist/utils/local-storage.js
|
|
341
344
|
function getStorage(type) {
|
|
342
345
|
try {
|
|
@@ -910,10 +913,6 @@ var __exports__ = (() => {
|
|
|
910
913
|
clone(props) {
|
|
911
914
|
return this.device.createBuffer({ ...this.props, ...props });
|
|
912
915
|
}
|
|
913
|
-
/** Read data synchronously. @note WebGL2 only */
|
|
914
|
-
readSyncWebGL(byteOffset, byteLength) {
|
|
915
|
-
throw new Error("not implemented");
|
|
916
|
-
}
|
|
917
916
|
/** A partial CPU-side copy of the data in this buffer, for debugging purposes */
|
|
918
917
|
debugData = new ArrayBuffer(0);
|
|
919
918
|
/** This doesn't handle partial non-zero offset updates correctly */
|
|
@@ -933,21 +932,6 @@ var __exports__ = (() => {
|
|
|
933
932
|
}
|
|
934
933
|
};
|
|
935
934
|
var Buffer2 = _Buffer;
|
|
936
|
-
__publicField(Buffer2, "defaultProps", {
|
|
937
|
-
...Resource.defaultProps,
|
|
938
|
-
usage: 0,
|
|
939
|
-
// Buffer.COPY_DST | Buffer.COPY_SRC
|
|
940
|
-
byteLength: 0,
|
|
941
|
-
byteOffset: 0,
|
|
942
|
-
data: null,
|
|
943
|
-
indexType: "uint16",
|
|
944
|
-
mappedAtCreation: false
|
|
945
|
-
});
|
|
946
|
-
// Usage Flags
|
|
947
|
-
__publicField(Buffer2, "MAP_READ", 1);
|
|
948
|
-
__publicField(Buffer2, "MAP_WRITE", 2);
|
|
949
|
-
__publicField(Buffer2, "COPY_SRC", 4);
|
|
950
|
-
__publicField(Buffer2, "COPY_DST", 8);
|
|
951
935
|
/** Index buffer */
|
|
952
936
|
__publicField(Buffer2, "INDEX", 16);
|
|
953
937
|
/** Vertex buffer */
|
|
@@ -958,55 +942,176 @@ var __exports__ = (() => {
|
|
|
958
942
|
__publicField(Buffer2, "STORAGE", 128);
|
|
959
943
|
__publicField(Buffer2, "INDIRECT", 256);
|
|
960
944
|
__publicField(Buffer2, "QUERY_RESOLVE", 512);
|
|
945
|
+
// Usage Flags
|
|
946
|
+
__publicField(Buffer2, "MAP_READ", 1);
|
|
947
|
+
__publicField(Buffer2, "MAP_WRITE", 2);
|
|
948
|
+
__publicField(Buffer2, "COPY_SRC", 4);
|
|
949
|
+
__publicField(Buffer2, "COPY_DST", 8);
|
|
961
950
|
// PROTECTED METHODS (INTENDED FOR USE BY OTHER FRAMEWORK CODE ONLY)
|
|
962
951
|
/** Max amount of debug data saved. Two vec4's */
|
|
963
952
|
__publicField(Buffer2, "DEBUG_DATA_MAX_LENGTH", 32);
|
|
953
|
+
__publicField(Buffer2, "defaultProps", {
|
|
954
|
+
...Resource.defaultProps,
|
|
955
|
+
usage: 0,
|
|
956
|
+
// Buffer.COPY_DST | Buffer.COPY_SRC
|
|
957
|
+
byteLength: 0,
|
|
958
|
+
byteOffset: 0,
|
|
959
|
+
data: null,
|
|
960
|
+
indexType: "uint16",
|
|
961
|
+
onMapped: void 0
|
|
962
|
+
});
|
|
964
963
|
|
|
965
|
-
// ../core/src/
|
|
966
|
-
function
|
|
967
|
-
const
|
|
968
|
-
const bytes = getDataTypeBytes(dataType);
|
|
964
|
+
// ../core/src/shadertypes/data-types/decode-data-types.ts
|
|
965
|
+
function getDataTypeInfo(type) {
|
|
966
|
+
const [signedType, primitiveType, byteLength] = NORMALIZED_TYPE_MAP[type];
|
|
969
967
|
const normalized = type.includes("norm");
|
|
970
968
|
const integer = !normalized && !type.startsWith("float");
|
|
971
969
|
const signed = type.startsWith("s");
|
|
972
970
|
return {
|
|
973
|
-
|
|
974
|
-
|
|
971
|
+
signedType,
|
|
972
|
+
primitiveType,
|
|
973
|
+
byteLength,
|
|
974
|
+
normalized,
|
|
975
975
|
integer,
|
|
976
|
-
signed
|
|
977
|
-
normalized
|
|
976
|
+
signed
|
|
978
977
|
};
|
|
979
978
|
}
|
|
980
|
-
function
|
|
981
|
-
const
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
979
|
+
function getNormalizedDataType(signedDataType) {
|
|
980
|
+
const dataType = signedDataType;
|
|
981
|
+
switch (dataType) {
|
|
982
|
+
case "uint8":
|
|
983
|
+
return "unorm8";
|
|
984
|
+
case "sint8":
|
|
985
|
+
return "snorm8";
|
|
986
|
+
case "uint16":
|
|
987
|
+
return "unorm16";
|
|
988
|
+
case "sint16":
|
|
989
|
+
return "snorm16";
|
|
990
|
+
default:
|
|
991
|
+
return dataType;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
function alignTo(size, count) {
|
|
995
|
+
switch (count) {
|
|
996
|
+
case 1:
|
|
997
|
+
return size;
|
|
998
|
+
case 2:
|
|
999
|
+
return size + size % 2;
|
|
1000
|
+
default:
|
|
1001
|
+
return size + (4 - size % 4) % 4;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
function getDataType(arrayOrType) {
|
|
1005
|
+
const Constructor = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType;
|
|
1006
|
+
if (Constructor === Uint8ClampedArray) {
|
|
1007
|
+
return "uint8";
|
|
1008
|
+
}
|
|
1009
|
+
const info = Object.values(NORMALIZED_TYPE_MAP).find((entry) => Constructor === entry[4]);
|
|
1010
|
+
if (!info) {
|
|
1011
|
+
throw new Error(Constructor.name);
|
|
1012
|
+
}
|
|
1013
|
+
return info[0];
|
|
1014
|
+
}
|
|
1015
|
+
function getTypedArrayConstructor(type) {
|
|
1016
|
+
const [, , , , Constructor] = NORMALIZED_TYPE_MAP[type];
|
|
1017
|
+
return Constructor;
|
|
1018
|
+
}
|
|
1019
|
+
var NORMALIZED_TYPE_MAP = {
|
|
1020
|
+
uint8: ["uint8", "u32", 1, false, Uint8Array],
|
|
1021
|
+
sint8: ["sint8", "i32", 1, false, Int8Array],
|
|
1022
|
+
unorm8: ["uint8", "f32", 1, true, Uint8Array],
|
|
1023
|
+
snorm8: ["sint8", "f32", 1, true, Int8Array],
|
|
1024
|
+
uint16: ["uint16", "u32", 2, false, Uint16Array],
|
|
1025
|
+
sint16: ["sint16", "i32", 2, false, Int16Array],
|
|
1026
|
+
unorm16: ["uint16", "u32", 2, true, Uint16Array],
|
|
1027
|
+
snorm16: ["sint16", "i32", 2, true, Int16Array],
|
|
1028
|
+
float16: ["float16", "f16", 2, false, Uint16Array],
|
|
1029
|
+
float32: ["float32", "f32", 4, false, Float32Array],
|
|
1030
|
+
uint32: ["uint32", "u32", 4, false, Uint32Array],
|
|
1031
|
+
sint32: ["sint32", "i32", 4, false, Int32Array]
|
|
1007
1032
|
};
|
|
1008
1033
|
|
|
1009
|
-
// ../core/src/
|
|
1034
|
+
// ../core/src/shadertypes/vertex-arrays/decode-vertex-format.ts
|
|
1035
|
+
function getVertexFormatInfo(format) {
|
|
1036
|
+
let webglOnly;
|
|
1037
|
+
if (format.endsWith("-webgl")) {
|
|
1038
|
+
format.replace("-webgl", "");
|
|
1039
|
+
webglOnly = true;
|
|
1040
|
+
}
|
|
1041
|
+
const [type_, count] = format.split("x");
|
|
1042
|
+
const type = type_;
|
|
1043
|
+
const components = count ? parseInt(count) : 1;
|
|
1044
|
+
const decodedType = getDataTypeInfo(type);
|
|
1045
|
+
const result = {
|
|
1046
|
+
type,
|
|
1047
|
+
components,
|
|
1048
|
+
byteLength: decodedType.byteLength * components,
|
|
1049
|
+
integer: decodedType.integer,
|
|
1050
|
+
signed: decodedType.signed,
|
|
1051
|
+
normalized: decodedType.normalized
|
|
1052
|
+
};
|
|
1053
|
+
if (webglOnly) {
|
|
1054
|
+
result.webglOnly = true;
|
|
1055
|
+
}
|
|
1056
|
+
return result;
|
|
1057
|
+
}
|
|
1058
|
+
function makeVertexFormat(signedDataType, components, normalized) {
|
|
1059
|
+
const dataType = normalized ? getNormalizedDataType(signedDataType) : signedDataType;
|
|
1060
|
+
switch (dataType) {
|
|
1061
|
+
case "unorm8":
|
|
1062
|
+
if (components === 1) {
|
|
1063
|
+
return "unorm8";
|
|
1064
|
+
}
|
|
1065
|
+
if (components === 3) {
|
|
1066
|
+
return "unorm8x3-webgl";
|
|
1067
|
+
}
|
|
1068
|
+
return `${dataType}x${components}`;
|
|
1069
|
+
case "snorm8":
|
|
1070
|
+
case "uint8":
|
|
1071
|
+
case "sint8":
|
|
1072
|
+
case "uint16":
|
|
1073
|
+
case "sint16":
|
|
1074
|
+
case "unorm16":
|
|
1075
|
+
case "snorm16":
|
|
1076
|
+
case "float16":
|
|
1077
|
+
if (components === 1 || components === 3) {
|
|
1078
|
+
throw new Error(`size: ${components}`);
|
|
1079
|
+
}
|
|
1080
|
+
return `${dataType}x${components}`;
|
|
1081
|
+
default:
|
|
1082
|
+
return components === 1 ? dataType : `${dataType}x${components}`;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
function getVertexFormatFromAttribute(typedArray, size, normalized) {
|
|
1086
|
+
if (!size || size > 4) {
|
|
1087
|
+
throw new Error(`size ${size}`);
|
|
1088
|
+
}
|
|
1089
|
+
const components = size;
|
|
1090
|
+
const signedDataType = getDataType(typedArray);
|
|
1091
|
+
return makeVertexFormat(signedDataType, components, normalized);
|
|
1092
|
+
}
|
|
1093
|
+
function getCompatibleVertexFormat(opts) {
|
|
1094
|
+
let vertexType;
|
|
1095
|
+
switch (opts.primitiveType) {
|
|
1096
|
+
case "f32":
|
|
1097
|
+
vertexType = "float32";
|
|
1098
|
+
break;
|
|
1099
|
+
case "i32":
|
|
1100
|
+
vertexType = "sint32";
|
|
1101
|
+
break;
|
|
1102
|
+
case "u32":
|
|
1103
|
+
vertexType = "uint32";
|
|
1104
|
+
break;
|
|
1105
|
+
case "f16":
|
|
1106
|
+
return opts.components <= 2 ? "float16x2" : "float16x4";
|
|
1107
|
+
}
|
|
1108
|
+
if (opts.components === 1) {
|
|
1109
|
+
return vertexType;
|
|
1110
|
+
}
|
|
1111
|
+
return `${vertexType}x${opts.components}`;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
// ../core/src/shadertypes/textures/texture-format-table.ts
|
|
1010
1115
|
var texture_compression_bc = "texture-compression-bc";
|
|
1011
1116
|
var texture_compression_astc = "texture-compression-astc";
|
|
1012
1117
|
var texture_compression_etc2 = "texture-compression-etc2";
|
|
@@ -1031,73 +1136,65 @@ var __exports__ = (() => {
|
|
|
1031
1136
|
function getTextureFormatTable() {
|
|
1032
1137
|
return TEXTURE_FORMAT_TABLE;
|
|
1033
1138
|
}
|
|
1034
|
-
var
|
|
1139
|
+
var TEXTURE_FORMAT_COLOR_DEPTH_TABLE = {
|
|
1035
1140
|
// 8-bit formats
|
|
1036
1141
|
"r8unorm": {},
|
|
1037
|
-
"r8snorm": { render: snorm8_renderable },
|
|
1038
|
-
"r8uint": {},
|
|
1039
|
-
"r8sint": {},
|
|
1040
|
-
// 16-bit formats
|
|
1041
1142
|
"rg8unorm": {},
|
|
1042
|
-
"rg8snorm": { render: snorm8_renderable },
|
|
1043
|
-
"rg8uint": {},
|
|
1044
|
-
"rg8sint": {},
|
|
1045
|
-
"r16uint": {},
|
|
1046
|
-
"r16sint": {},
|
|
1047
|
-
"r16float": { render: float16_renderable, filter: "float16-filterable-webgl" },
|
|
1048
|
-
"r16unorm-webgl": { f: norm16_renderable },
|
|
1049
|
-
"r16snorm-webgl": { f: snorm16_renderable },
|
|
1050
|
-
// Packed 16-bit formats
|
|
1051
|
-
"rgba4unorm-webgl": { channels: "rgba", bitsPerChannel: [4, 4, 4, 4], packed: true },
|
|
1052
|
-
"rgb565unorm-webgl": { channels: "rgb", bitsPerChannel: [5, 6, 5, 0], packed: true },
|
|
1053
|
-
"rgb5a1unorm-webgl": { channels: "rgba", bitsPerChannel: [5, 5, 5, 1], packed: true },
|
|
1054
|
-
// 24-bit formats
|
|
1055
1143
|
"rgb8unorm-webgl": {},
|
|
1056
|
-
"rgb8snorm-webgl": {},
|
|
1057
|
-
// 32-bit formats
|
|
1058
1144
|
"rgba8unorm": {},
|
|
1059
1145
|
"rgba8unorm-srgb": {},
|
|
1146
|
+
"r8snorm": { render: snorm8_renderable },
|
|
1147
|
+
"rg8snorm": { render: snorm8_renderable },
|
|
1148
|
+
"rgb8snorm-webgl": {},
|
|
1060
1149
|
"rgba8snorm": { render: snorm8_renderable },
|
|
1150
|
+
"r8uint": {},
|
|
1151
|
+
"rg8uint": {},
|
|
1061
1152
|
"rgba8uint": {},
|
|
1153
|
+
"r8sint": {},
|
|
1154
|
+
"rg8sint": {},
|
|
1062
1155
|
"rgba8sint": {},
|
|
1063
|
-
// 32-bit, reverse colors, webgpu only
|
|
1064
1156
|
"bgra8unorm": {},
|
|
1065
1157
|
"bgra8unorm-srgb": {},
|
|
1158
|
+
"r16unorm": { f: norm16_renderable },
|
|
1159
|
+
"rg16unorm": { render: norm16_renderable },
|
|
1160
|
+
"rgb16unorm-webgl": { f: norm16_renderable },
|
|
1161
|
+
// rgb not renderable
|
|
1162
|
+
"rgba16unorm": { render: norm16_renderable },
|
|
1163
|
+
"r16snorm": { f: snorm16_renderable },
|
|
1164
|
+
"rg16snorm": { render: snorm16_renderable },
|
|
1165
|
+
"rgb16snorm-webgl": { f: norm16_renderable },
|
|
1166
|
+
// rgb not renderable
|
|
1167
|
+
"rgba16snorm": { render: snorm16_renderable },
|
|
1168
|
+
"r16uint": {},
|
|
1066
1169
|
"rg16uint": {},
|
|
1170
|
+
"rgba16uint": {},
|
|
1171
|
+
"r16sint": {},
|
|
1067
1172
|
"rg16sint": {},
|
|
1173
|
+
"rgba16sint": {},
|
|
1174
|
+
"r16float": { render: float16_renderable, filter: "float16-filterable-webgl" },
|
|
1068
1175
|
"rg16float": { render: float16_renderable, filter: float16_filterable },
|
|
1069
|
-
"
|
|
1070
|
-
"rg16snorm-webgl": { render: snorm16_renderable },
|
|
1176
|
+
"rgba16float": { render: float16_renderable, filter: float16_filterable },
|
|
1071
1177
|
"r32uint": {},
|
|
1178
|
+
"rg32uint": {},
|
|
1179
|
+
"rgba32uint": {},
|
|
1072
1180
|
"r32sint": {},
|
|
1181
|
+
"rg32sint": {},
|
|
1182
|
+
"rgba32sint": {},
|
|
1073
1183
|
"r32float": { render: float32_renderable, filter: float32_filterable },
|
|
1184
|
+
"rg32float": { render: false, filter: float32_filterable },
|
|
1185
|
+
"rgb32float-webgl": { render: float32_renderable, filter: float32_filterable },
|
|
1186
|
+
"rgba32float": { render: float32_renderable, filter: float32_filterable },
|
|
1187
|
+
// Packed 16-bit formats
|
|
1188
|
+
"rgba4unorm-webgl": { channels: "rgba", bitsPerChannel: [4, 4, 4, 4], packed: true },
|
|
1189
|
+
"rgb565unorm-webgl": { channels: "rgb", bitsPerChannel: [5, 6, 5, 0], packed: true },
|
|
1190
|
+
"rgb5a1unorm-webgl": { channels: "rgba", bitsPerChannel: [5, 5, 5, 1], packed: true },
|
|
1074
1191
|
// Packed 32 bit formats
|
|
1075
1192
|
"rgb9e5ufloat": { channels: "rgb", packed: true, render: rgb9e5ufloat_renderable },
|
|
1076
1193
|
// , filter: true},
|
|
1077
1194
|
"rg11b10ufloat": { channels: "rgb", bitsPerChannel: [11, 11, 10, 0], packed: true, p: 1, render: float32_renderable },
|
|
1078
1195
|
"rgb10a2unorm": { channels: "rgba", bitsPerChannel: [10, 10, 10, 2], packed: true, p: 1 },
|
|
1079
|
-
"rgb10a2uint
|
|
1080
|
-
//
|
|
1081
|
-
"rgb16unorm-webgl": { f: norm16_renderable },
|
|
1082
|
-
// rgb not renderable
|
|
1083
|
-
"rgb16snorm-webgl": { f: norm16_renderable },
|
|
1084
|
-
// rgb not renderable
|
|
1085
|
-
// 64-bit formats
|
|
1086
|
-
"rg32uint": {},
|
|
1087
|
-
"rg32sint": {},
|
|
1088
|
-
"rg32float": { render: false, filter: float32_filterable },
|
|
1089
|
-
"rgba16uint": {},
|
|
1090
|
-
"rgba16sint": {},
|
|
1091
|
-
"rgba16float": { render: float16_renderable, filter: float16_filterable },
|
|
1092
|
-
"rgba16unorm-webgl": { render: norm16_renderable },
|
|
1093
|
-
"rgba16snorm-webgl": { render: snorm16_renderable },
|
|
1094
|
-
// 96-bit formats (deprecated!)
|
|
1095
|
-
"rgb32float-webgl": { render: float32_renderable, filter: float32_filterable },
|
|
1096
|
-
// 128-bit formats
|
|
1097
|
-
"rgba32uint": {},
|
|
1098
|
-
"rgba32sint": {},
|
|
1099
|
-
"rgba32float": { render: float32_renderable, filter: float32_filterable },
|
|
1100
|
-
// Depth/stencil
|
|
1196
|
+
"rgb10a2uint": { channels: "rgba", bitsPerChannel: [10, 10, 10, 2], packed: true, p: 1 },
|
|
1197
|
+
// Depth/stencil Formats
|
|
1101
1198
|
// Depth and stencil formats
|
|
1102
1199
|
stencil8: { attachment: "stencil", bitsPerChannel: [8, 0, 0, 0], dataType: "uint8" },
|
|
1103
1200
|
"depth16unorm": { attachment: "depth", bitsPerChannel: [16, 0, 0, 0], dataType: "uint16" },
|
|
@@ -1106,7 +1203,9 @@ var __exports__ = (() => {
|
|
|
1106
1203
|
// The depth component of the "depth24plus" and "depth24plus-stencil8" formats may be implemented as either a 24-bit depth value or a "depth32float" value.
|
|
1107
1204
|
"depth24plus-stencil8": { attachment: "depth-stencil", bitsPerChannel: [24, 8, 0, 0], packed: true },
|
|
1108
1205
|
// "depth32float-stencil8" feature
|
|
1109
|
-
"depth32float-stencil8": { attachment: "depth-stencil", bitsPerChannel: [32, 8, 0, 0], packed: true }
|
|
1206
|
+
"depth32float-stencil8": { attachment: "depth-stencil", bitsPerChannel: [32, 8, 0, 0], packed: true }
|
|
1207
|
+
};
|
|
1208
|
+
var TEXTURE_FORMAT_COMPRESSED_TABLE = {
|
|
1110
1209
|
// BC compressed formats: check device.features.has("texture-compression-bc");
|
|
1111
1210
|
"bc1-rgb-unorm-webgl": { f: texture_compression_bc },
|
|
1112
1211
|
"bc1-rgb-unorm-srgb-webgl": { f: texture_compression_bc },
|
|
@@ -1177,8 +1276,12 @@ var __exports__ = (() => {
|
|
|
1177
1276
|
"atc-rgba-unorm-webgl": { f: texture_compression_atc_webgl },
|
|
1178
1277
|
"atc-rgbai-unorm-webgl": { f: texture_compression_atc_webgl }
|
|
1179
1278
|
};
|
|
1279
|
+
var TEXTURE_FORMAT_TABLE = {
|
|
1280
|
+
...TEXTURE_FORMAT_COLOR_DEPTH_TABLE,
|
|
1281
|
+
...TEXTURE_FORMAT_COMPRESSED_TABLE
|
|
1282
|
+
};
|
|
1180
1283
|
|
|
1181
|
-
// ../core/src/
|
|
1284
|
+
// ../core/src/shadertypes/textures/texture-format-decoder.ts
|
|
1182
1285
|
var COMPRESSED_TEXTURE_FORMAT_PREFIXES = [
|
|
1183
1286
|
"bc1",
|
|
1184
1287
|
"bc2",
|
|
@@ -1195,12 +1298,51 @@ var __exports__ = (() => {
|
|
|
1195
1298
|
"pvrtc"
|
|
1196
1299
|
];
|
|
1197
1300
|
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
if
|
|
1301
|
+
var TextureFormatDecoder = class {
|
|
1302
|
+
/** Returns information about a texture format, e.g. attatchment type, components, byte length and flags (integer, signed, normalized) */
|
|
1303
|
+
getInfo(format) {
|
|
1304
|
+
return getTextureFormatInfo(format);
|
|
1305
|
+
}
|
|
1306
|
+
/** Checks if a texture format is color */
|
|
1307
|
+
isColor(format) {
|
|
1308
|
+
return format.startsWith("rgba") || format.startsWith("bgra") || format.startsWith("rgb");
|
|
1309
|
+
}
|
|
1310
|
+
/** Checks if a texture format is depth or stencil */
|
|
1311
|
+
isDepthStencil(format) {
|
|
1312
|
+
return format.startsWith("depth") || format.startsWith("stencil");
|
|
1313
|
+
}
|
|
1314
|
+
/** Checks if a texture format is compressed */
|
|
1315
|
+
isCompressed(format) {
|
|
1316
|
+
return COMPRESSED_TEXTURE_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Returns the "static" capabilities of a texture format.
|
|
1320
|
+
* @note Needs to be checked against current device
|
|
1321
|
+
*/
|
|
1322
|
+
getCapabilities(format) {
|
|
1323
|
+
const info = getTextureFormatDefinition(format);
|
|
1324
|
+
const formatCapabilities = {
|
|
1325
|
+
format,
|
|
1326
|
+
create: info.f ?? true,
|
|
1327
|
+
render: info.render ?? true,
|
|
1328
|
+
filter: info.filter ?? true,
|
|
1329
|
+
blend: info.blend ?? true,
|
|
1330
|
+
store: info.store ?? true
|
|
1331
|
+
};
|
|
1332
|
+
const formatInfo = getTextureFormatInfo(format);
|
|
1333
|
+
const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
|
|
1334
|
+
const isSigned = formatInfo?.signed;
|
|
1335
|
+
const isInteger = formatInfo?.integer;
|
|
1336
|
+
const isWebGLSpecific = formatInfo?.webgl;
|
|
1337
|
+
formatCapabilities.render &&= !isSigned;
|
|
1338
|
+
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
1339
|
+
return formatCapabilities;
|
|
1340
|
+
}
|
|
1341
|
+
};
|
|
1342
|
+
var textureFormatDecoder = new TextureFormatDecoder();
|
|
1343
|
+
function getTextureFormatInfo(format) {
|
|
1344
|
+
let formatInfo = getTextureFormatInfoUsingTable(format);
|
|
1345
|
+
if (textureFormatDecoder.isCompressed(format)) {
|
|
1204
1346
|
formatInfo.channels = "rgb";
|
|
1205
1347
|
formatInfo.components = 3;
|
|
1206
1348
|
formatInfo.bytesPerPixel = 1;
|
|
@@ -1216,7 +1358,7 @@ var __exports__ = (() => {
|
|
|
1216
1358
|
if (matches) {
|
|
1217
1359
|
const [, channels, length, type, srgb, suffix] = matches;
|
|
1218
1360
|
const dataType = `${type}${length}`;
|
|
1219
|
-
const decodedType =
|
|
1361
|
+
const decodedType = getDataTypeInfo(dataType);
|
|
1220
1362
|
const bits = decodedType.byteLength * 8;
|
|
1221
1363
|
const components = channels.length;
|
|
1222
1364
|
const bitsPerChannel = [
|
|
@@ -1228,7 +1370,7 @@ var __exports__ = (() => {
|
|
|
1228
1370
|
formatInfo = {
|
|
1229
1371
|
format,
|
|
1230
1372
|
attachment: formatInfo.attachment,
|
|
1231
|
-
dataType: decodedType.
|
|
1373
|
+
dataType: decodedType.signedType,
|
|
1232
1374
|
components,
|
|
1233
1375
|
channels,
|
|
1234
1376
|
integer: decodedType.integer,
|
|
@@ -1254,7 +1396,7 @@ var __exports__ = (() => {
|
|
|
1254
1396
|
}
|
|
1255
1397
|
return formatInfo;
|
|
1256
1398
|
}
|
|
1257
|
-
function
|
|
1399
|
+
function getTextureFormatInfoUsingTable(format) {
|
|
1258
1400
|
const info = getTextureFormatDefinition(format);
|
|
1259
1401
|
const bytesPerPixel = info.bytesPerPixel || 1;
|
|
1260
1402
|
const bitsPerChannel = info.bitsPerChannel || [8, 8, 8, 8];
|
|
@@ -1294,25 +1436,24 @@ var __exports__ = (() => {
|
|
|
1294
1436
|
return null;
|
|
1295
1437
|
}
|
|
1296
1438
|
|
|
1297
|
-
// ../core/src/
|
|
1298
|
-
function
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
return formatCapabilities;
|
|
1439
|
+
// ../core/src/image-utils/image-types.ts
|
|
1440
|
+
function isExternalImage(data) {
|
|
1441
|
+
return typeof ImageData !== "undefined" && data instanceof ImageData || typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap || typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement || typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement || typeof VideoFrame !== "undefined" && data instanceof VideoFrame || typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement || typeof OffscreenCanvas !== "undefined" && data instanceof OffscreenCanvas;
|
|
1442
|
+
}
|
|
1443
|
+
function getExternalImageSize(data) {
|
|
1444
|
+
if (typeof ImageData !== "undefined" && data instanceof ImageData || typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap || typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement || typeof OffscreenCanvas !== "undefined" && data instanceof OffscreenCanvas) {
|
|
1445
|
+
return { width: data.width, height: data.height };
|
|
1446
|
+
}
|
|
1447
|
+
if (typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement) {
|
|
1448
|
+
return { width: data.naturalWidth, height: data.naturalHeight };
|
|
1449
|
+
}
|
|
1450
|
+
if (typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement) {
|
|
1451
|
+
return { width: data.videoWidth, height: data.videoHeight };
|
|
1452
|
+
}
|
|
1453
|
+
if (typeof VideoFrame !== "undefined" && data instanceof VideoFrame) {
|
|
1454
|
+
return { width: data.displayWidth, height: data.displayHeight };
|
|
1455
|
+
}
|
|
1456
|
+
throw new Error("Unknown image type");
|
|
1316
1457
|
}
|
|
1317
1458
|
|
|
1318
1459
|
// ../core/src/adapter/device.ts
|
|
@@ -1336,9 +1477,8 @@ var __exports__ = (() => {
|
|
|
1336
1477
|
get [Symbol.toStringTag]() {
|
|
1337
1478
|
return "Device";
|
|
1338
1479
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
|
|
1480
|
+
toString() {
|
|
1481
|
+
return `Device(${this.id})`;
|
|
1342
1482
|
}
|
|
1343
1483
|
/** id of this device, primarily for debugging */
|
|
1344
1484
|
id;
|
|
@@ -1354,23 +1494,46 @@ var __exports__ = (() => {
|
|
|
1354
1494
|
_reused = false;
|
|
1355
1495
|
/** Used by other luma.gl modules to store data on the device */
|
|
1356
1496
|
_lumaData = {};
|
|
1357
|
-
|
|
1497
|
+
_textureCaps = {};
|
|
1498
|
+
constructor(props) {
|
|
1499
|
+
this.props = { ..._Device.defaultProps, ...props };
|
|
1500
|
+
this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
|
|
1501
|
+
}
|
|
1502
|
+
getVertexFormatInfo(format) {
|
|
1503
|
+
return getVertexFormatInfo(format);
|
|
1504
|
+
}
|
|
1505
|
+
isVertexFormatSupported(format) {
|
|
1506
|
+
return true;
|
|
1507
|
+
}
|
|
1508
|
+
/** Returns information about a texture format, such as data type, channels, bits per channel, compression etc */
|
|
1509
|
+
getTextureFormatInfo(format) {
|
|
1510
|
+
return textureFormatDecoder.getInfo(format);
|
|
1511
|
+
}
|
|
1512
|
+
/** Determines what operations are supported on a texture format on this particular device (checks against supported device features) */
|
|
1358
1513
|
getTextureFormatCapabilities(format) {
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
format
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
return
|
|
1514
|
+
let textureCaps = this._textureCaps[format];
|
|
1515
|
+
if (!textureCaps) {
|
|
1516
|
+
const capabilities = this._getDeviceTextureFormatCapabilities(format);
|
|
1517
|
+
textureCaps = this._getDeviceSpecificTextureFormatCapabilities(capabilities);
|
|
1518
|
+
this._textureCaps[format] = textureCaps;
|
|
1519
|
+
}
|
|
1520
|
+
return textureCaps;
|
|
1521
|
+
}
|
|
1522
|
+
/** Calculates the number of mip levels for a texture of width, height and in case of 3d textures only, depth */
|
|
1523
|
+
getMipLevelCount(width, height, depth3d = 1) {
|
|
1524
|
+
const maxSize = Math.max(width, height, depth3d);
|
|
1525
|
+
return 1 + Math.floor(Math.log2(maxSize));
|
|
1526
|
+
}
|
|
1527
|
+
/** Check if data is an external image */
|
|
1528
|
+
isExternalImage(data) {
|
|
1529
|
+
return isExternalImage(data);
|
|
1530
|
+
}
|
|
1531
|
+
/** Get the size of an external image */
|
|
1532
|
+
getExternalImageSize(data) {
|
|
1533
|
+
return getExternalImageSize(data);
|
|
1371
1534
|
}
|
|
1372
1535
|
/** Check if device supports a specific texture format (creation and `nearest` sampling) */
|
|
1373
|
-
isTextureFormatSupported(format
|
|
1536
|
+
isTextureFormatSupported(format) {
|
|
1374
1537
|
return this.getTextureFormatCapabilities(format).create;
|
|
1375
1538
|
}
|
|
1376
1539
|
/** Check if linear filtering (sampler interpolation) is supported for a specific texture format */
|
|
@@ -1383,7 +1546,17 @@ var __exports__ = (() => {
|
|
|
1383
1546
|
}
|
|
1384
1547
|
/** Check if a specific texture format is GPU compressed */
|
|
1385
1548
|
isTextureFormatCompressed(format) {
|
|
1386
|
-
return
|
|
1549
|
+
return textureFormatDecoder.isCompressed(format);
|
|
1550
|
+
}
|
|
1551
|
+
// DEBUG METHODS
|
|
1552
|
+
pushDebugGroup(groupLabel) {
|
|
1553
|
+
this.commandEncoder.pushDebugGroup(groupLabel);
|
|
1554
|
+
}
|
|
1555
|
+
popDebugGroup() {
|
|
1556
|
+
this.commandEncoder?.popDebugGroup();
|
|
1557
|
+
}
|
|
1558
|
+
insertDebugMarker(markerLabel) {
|
|
1559
|
+
this.commandEncoder?.insertDebugMarker(markerLabel);
|
|
1387
1560
|
}
|
|
1388
1561
|
/**
|
|
1389
1562
|
* Trigger device loss.
|
|
@@ -1393,9 +1566,44 @@ var __exports__ = (() => {
|
|
|
1393
1566
|
loseDevice() {
|
|
1394
1567
|
return false;
|
|
1395
1568
|
}
|
|
1396
|
-
/**
|
|
1397
|
-
|
|
1398
|
-
this.
|
|
1569
|
+
/** A monotonic counter for tracking buffer and texture updates */
|
|
1570
|
+
incrementTimestamp() {
|
|
1571
|
+
return this.timestamp++;
|
|
1572
|
+
}
|
|
1573
|
+
/**
|
|
1574
|
+
* Reports Device errors in a way that optimizes for developer experience / debugging.
|
|
1575
|
+
* - Logs so that the console error links directly to the source code that generated the error.
|
|
1576
|
+
* - Includes the object that reported the error in the log message, even if the error is asynchronous.
|
|
1577
|
+
*
|
|
1578
|
+
* Conventions when calling reportError():
|
|
1579
|
+
* - Always call the returned function - to ensure error is logged, at the error site
|
|
1580
|
+
* - Follow with a call to device.debug() - to ensure that the debugger breaks at the error site
|
|
1581
|
+
*
|
|
1582
|
+
* @param error - the error to report. If needed, just create a new Error object with the appropriate message.
|
|
1583
|
+
* @param context - pass `this` as context, otherwise it may not be available in the debugger for async errors.
|
|
1584
|
+
* @returns the logger function returned by device.props.onError() so that it can be called from the error site.
|
|
1585
|
+
*
|
|
1586
|
+
* @example
|
|
1587
|
+
* device.reportError(new Error(...), this)();
|
|
1588
|
+
* device.debug();
|
|
1589
|
+
*/
|
|
1590
|
+
reportError(error, context, ...args) {
|
|
1591
|
+
const isHandled = this.props.onError(error, context);
|
|
1592
|
+
if (!isHandled) {
|
|
1593
|
+
return log.error(error.message, context, ...args);
|
|
1594
|
+
}
|
|
1595
|
+
return () => {
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
/** Break in the debugger - if device.props.debug is true */
|
|
1599
|
+
debug() {
|
|
1600
|
+
if (this.props.debug) {
|
|
1601
|
+
debugger;
|
|
1602
|
+
} else {
|
|
1603
|
+
const message = `'Type luma.log.set({debug: true}) in console to enable debug breakpoints',
|
|
1604
|
+
or create a device with the 'debug: true' prop.`;
|
|
1605
|
+
log.once(0, message)();
|
|
1606
|
+
}
|
|
1399
1607
|
}
|
|
1400
1608
|
/** Returns the default / primary canvas context. Throws an error if no canvas context is available (a WebGPU compute device) */
|
|
1401
1609
|
getDefaultCanvasContext() {
|
|
@@ -1404,17 +1612,13 @@ var __exports__ = (() => {
|
|
|
1404
1612
|
}
|
|
1405
1613
|
return this.canvasContext;
|
|
1406
1614
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
/** A monotonic counter for tracking buffer and texture updates */
|
|
1411
|
-
incrementTimestamp() {
|
|
1412
|
-
return this.timestamp++;
|
|
1615
|
+
/** Create a RenderPass using the default CommandEncoder */
|
|
1616
|
+
beginRenderPass(props) {
|
|
1617
|
+
return this.commandEncoder.beginRenderPass(props);
|
|
1413
1618
|
}
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
this.props.onError(error);
|
|
1619
|
+
/** Create a ComputePass using the default CommandEncoder*/
|
|
1620
|
+
beginComputePass(props) {
|
|
1621
|
+
return this.commandEncoder.beginComputePass(props);
|
|
1418
1622
|
}
|
|
1419
1623
|
// DEPRECATED METHODS
|
|
1420
1624
|
/** @deprecated Use getDefaultCanvasContext() */
|
|
@@ -1456,19 +1660,36 @@ var __exports__ = (() => {
|
|
|
1456
1660
|
static _getCanvasContextProps(props) {
|
|
1457
1661
|
return props.createCanvasContext === true ? {} : props.createCanvasContext;
|
|
1458
1662
|
}
|
|
1663
|
+
_getDeviceTextureFormatCapabilities(format) {
|
|
1664
|
+
const genericCapabilities = textureFormatDecoder.getCapabilities(format);
|
|
1665
|
+
const checkFeature = (feature) => (typeof feature === "string" ? this.features.has(feature) : feature) ?? true;
|
|
1666
|
+
const supported = checkFeature(genericCapabilities.create);
|
|
1667
|
+
return {
|
|
1668
|
+
format,
|
|
1669
|
+
create: supported,
|
|
1670
|
+
render: supported && checkFeature(genericCapabilities.render),
|
|
1671
|
+
filter: supported && checkFeature(genericCapabilities.filter),
|
|
1672
|
+
blend: supported && checkFeature(genericCapabilities.blend),
|
|
1673
|
+
store: supported && checkFeature(genericCapabilities.store)
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1459
1676
|
/** Subclasses use this to support .createBuffer() overloads */
|
|
1460
1677
|
_normalizeBufferProps(props) {
|
|
1461
1678
|
if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
|
|
1462
1679
|
props = { data: props };
|
|
1463
1680
|
}
|
|
1464
1681
|
const newProps = { ...props };
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1682
|
+
const usage = props.usage || 0;
|
|
1683
|
+
if (usage & Buffer2.INDEX) {
|
|
1684
|
+
if (!props.indexType) {
|
|
1685
|
+
if (props.data instanceof Uint32Array) {
|
|
1686
|
+
newProps.indexType = "uint32";
|
|
1687
|
+
} else if (props.data instanceof Uint16Array) {
|
|
1688
|
+
newProps.indexType = "uint16";
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
if (!newProps.indexType) {
|
|
1692
|
+
throw new Error("indices buffer content must be of type uint16 or uint32");
|
|
1472
1693
|
}
|
|
1473
1694
|
}
|
|
1474
1695
|
return newProps;
|
|
@@ -1480,34 +1701,47 @@ var __exports__ = (() => {
|
|
|
1480
1701
|
powerPreference: "high-performance",
|
|
1481
1702
|
failIfMajorPerformanceCaveat: false,
|
|
1482
1703
|
createCanvasContext: void 0,
|
|
1483
|
-
// Callbacks
|
|
1484
|
-
onError: (error) => log.error(error.message)(),
|
|
1485
|
-
// Experimental
|
|
1486
|
-
_reuseDevices: false,
|
|
1487
|
-
_requestMaxLimits: true,
|
|
1488
|
-
_factoryDestroyPolicy: "unused",
|
|
1489
|
-
// TODO - Change these after confirming things work as expected
|
|
1490
|
-
_initializeFeatures: true,
|
|
1491
|
-
_disabledFeatures: {
|
|
1492
|
-
"compilation-status-async-webgl": true
|
|
1493
|
-
},
|
|
1494
|
-
_resourceDefaults: {},
|
|
1495
1704
|
// WebGL specific
|
|
1496
1705
|
webgl: {},
|
|
1706
|
+
// Callbacks
|
|
1707
|
+
// eslint-disable-next-line handle-callback-err
|
|
1708
|
+
onError: (error, context) => {
|
|
1709
|
+
},
|
|
1710
|
+
onResize: (context, info) => {
|
|
1711
|
+
const [width, height] = context.getDevicePixelSize();
|
|
1712
|
+
log.log(1, `${context} resized => ${width}x${height}px`)();
|
|
1713
|
+
},
|
|
1714
|
+
onPositionChange: (context, info) => {
|
|
1715
|
+
const [left, top] = context.getPosition();
|
|
1716
|
+
log.log(1, `${context} repositioned => ${left},${top}`)();
|
|
1717
|
+
},
|
|
1718
|
+
onVisibilityChange: (context) => log.log(1, `${context} Visibility changed ${context.isVisible}`)(),
|
|
1719
|
+
onDevicePixelRatioChange: (context, info) => log.log(1, `${context} DPR changed ${info.oldRatio} => ${context.devicePixelRatio}`)(),
|
|
1720
|
+
// Debug flags
|
|
1497
1721
|
debug: log.get("debug") || void 0,
|
|
1498
1722
|
debugShaders: log.get("debug-shaders") || void 0,
|
|
1499
1723
|
debugFramebuffers: Boolean(log.get("debug-framebuffers")),
|
|
1724
|
+
debugFactories: Boolean(log.get("debug-factories")),
|
|
1500
1725
|
debugWebGL: Boolean(log.get("debug-webgl")),
|
|
1501
1726
|
debugSpectorJS: void 0,
|
|
1502
1727
|
// Note: log setting is queried by the spector.js code
|
|
1503
1728
|
debugSpectorJSUrl: void 0,
|
|
1729
|
+
// Experimental
|
|
1730
|
+
_reuseDevices: false,
|
|
1731
|
+
_requestMaxLimits: true,
|
|
1732
|
+
_cacheShaders: false,
|
|
1733
|
+
_cachePipelines: false,
|
|
1734
|
+
_cacheDestroyPolicy: "unused",
|
|
1735
|
+
// TODO - Change these after confirming things work as expected
|
|
1736
|
+
_initializeFeatures: true,
|
|
1737
|
+
_disabledFeatures: {
|
|
1738
|
+
"compilation-status-async-webgl": true
|
|
1739
|
+
},
|
|
1504
1740
|
// INTERNAL
|
|
1505
1741
|
_handle: void 0
|
|
1506
1742
|
});
|
|
1507
1743
|
|
|
1508
1744
|
// ../core/src/adapter/luma.ts
|
|
1509
|
-
var isPage = isBrowser() && typeof document !== "undefined";
|
|
1510
|
-
var isPageLoaded = () => isPage && document.readyState === "complete";
|
|
1511
1745
|
var STARTUP_MESSAGE = "set luma.log.level=1 (or higher) to trace rendering";
|
|
1512
1746
|
var ERROR_MESSAGE = "No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.";
|
|
1513
1747
|
var _Luma = class {
|
|
@@ -1541,6 +1775,34 @@ var __exports__ = (() => {
|
|
|
1541
1775
|
log.log(1, `${this.VERSION} - ${STARTUP_MESSAGE}`)();
|
|
1542
1776
|
globalThis.luma = this;
|
|
1543
1777
|
}
|
|
1778
|
+
/** Creates a device. Asynchronously. */
|
|
1779
|
+
async createDevice(props_ = {}) {
|
|
1780
|
+
const props = { ..._Luma.defaultProps, ...props_ };
|
|
1781
|
+
const adapter = this.selectAdapter(props.type, props.adapters);
|
|
1782
|
+
if (!adapter) {
|
|
1783
|
+
throw new Error(ERROR_MESSAGE);
|
|
1784
|
+
}
|
|
1785
|
+
if (props.waitForPageLoad) {
|
|
1786
|
+
await adapter.pageLoaded;
|
|
1787
|
+
}
|
|
1788
|
+
return await adapter.create(props);
|
|
1789
|
+
}
|
|
1790
|
+
/**
|
|
1791
|
+
* Attach to an existing GPU API handle (WebGL2RenderingContext or GPUDevice).
|
|
1792
|
+
* @param handle Externally created WebGL context or WebGPU device
|
|
1793
|
+
*/
|
|
1794
|
+
async attachDevice(handle, props) {
|
|
1795
|
+
const type = this._getTypeFromHandle(handle, props.adapters);
|
|
1796
|
+
const adapter = type && this.selectAdapter(type, props.adapters);
|
|
1797
|
+
if (!adapter) {
|
|
1798
|
+
throw new Error(ERROR_MESSAGE);
|
|
1799
|
+
}
|
|
1800
|
+
return await adapter?.attach?.(handle, props);
|
|
1801
|
+
}
|
|
1802
|
+
/**
|
|
1803
|
+
* Global adapter registration.
|
|
1804
|
+
* @deprecated Use props.adapters instead
|
|
1805
|
+
*/
|
|
1544
1806
|
registerAdapters(adapters) {
|
|
1545
1807
|
for (const deviceClass of adapters) {
|
|
1546
1808
|
this.preregisteredAdapters.set(deviceClass.type, deviceClass);
|
|
@@ -1548,92 +1810,75 @@ var __exports__ = (() => {
|
|
|
1548
1810
|
}
|
|
1549
1811
|
/** Get type strings for supported Devices */
|
|
1550
1812
|
getSupportedAdapters(adapters = []) {
|
|
1551
|
-
const adapterMap = this.
|
|
1813
|
+
const adapterMap = this._getAdapterMap(adapters);
|
|
1552
1814
|
return Array.from(adapterMap).map(([, adapter]) => adapter).filter((adapter) => adapter.isSupported?.()).map((adapter) => adapter.type);
|
|
1553
1815
|
}
|
|
1554
1816
|
/** Get type strings for best available Device */
|
|
1555
|
-
|
|
1556
|
-
const
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1817
|
+
getBestAvailableAdapterType(adapters = []) {
|
|
1818
|
+
const KNOWN_ADAPTERS = ["webgpu", "webgl", "null"];
|
|
1819
|
+
const adapterMap = this._getAdapterMap(adapters);
|
|
1820
|
+
for (const type of KNOWN_ADAPTERS) {
|
|
1821
|
+
if (adapterMap.get(type)?.isSupported?.()) {
|
|
1822
|
+
return type;
|
|
1823
|
+
}
|
|
1562
1824
|
}
|
|
1563
1825
|
return null;
|
|
1564
1826
|
}
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
/** Creates a device. Asynchronously. */
|
|
1569
|
-
async createDevice(props = {}) {
|
|
1570
|
-
props = { ..._Luma.defaultProps, ...props };
|
|
1571
|
-
if (props.waitForPageLoad) {
|
|
1572
|
-
await _Luma.pageLoaded;
|
|
1573
|
-
}
|
|
1574
|
-
const adapterMap = this.getAdapterMap(props.adapters);
|
|
1575
|
-
let type = props.type || "";
|
|
1827
|
+
/** Select adapter of type from registered adapters */
|
|
1828
|
+
selectAdapter(type, adapters = []) {
|
|
1829
|
+
let selectedType = type;
|
|
1576
1830
|
if (type === "best-available") {
|
|
1577
|
-
|
|
1578
|
-
}
|
|
1579
|
-
const adapters = this.getAdapterMap(props.adapters) || adapterMap;
|
|
1580
|
-
const adapter = adapters.get(type);
|
|
1581
|
-
const device = await adapter?.create?.(props);
|
|
1582
|
-
if (device) {
|
|
1583
|
-
return device;
|
|
1584
|
-
}
|
|
1585
|
-
throw new Error(ERROR_MESSAGE);
|
|
1586
|
-
}
|
|
1587
|
-
/** Attach to an existing GPU API handle (WebGL2RenderingContext or GPUDevice). */
|
|
1588
|
-
async attachDevice(props) {
|
|
1589
|
-
const adapters = this.getAdapterMap(props.adapters);
|
|
1590
|
-
let type = "";
|
|
1591
|
-
if (props.handle instanceof WebGL2RenderingContext) {
|
|
1592
|
-
type = "webgl";
|
|
1593
|
-
}
|
|
1594
|
-
if (props.createCanvasContext) {
|
|
1595
|
-
await _Luma.pageLoaded;
|
|
1596
|
-
}
|
|
1597
|
-
if (props.handle === null) {
|
|
1598
|
-
type = "unknown";
|
|
1599
|
-
}
|
|
1600
|
-
const adapter = adapters.get(type);
|
|
1601
|
-
const device = await adapter?.attach?.(null);
|
|
1602
|
-
if (device) {
|
|
1603
|
-
return device;
|
|
1831
|
+
selectedType = this.getBestAvailableAdapterType(adapters);
|
|
1604
1832
|
}
|
|
1605
|
-
|
|
1833
|
+
const adapterMap = this._getAdapterMap(adapters);
|
|
1834
|
+
return selectedType && adapterMap.get(selectedType) || null;
|
|
1606
1835
|
}
|
|
1607
1836
|
/**
|
|
1608
1837
|
* Override `HTMLCanvasContext.getCanvas()` to always create WebGL2 contexts with additional WebGL1 compatibility.
|
|
1609
1838
|
* Useful when attaching luma to a context from an external library does not support creating WebGL2 contexts.
|
|
1610
1839
|
*/
|
|
1611
1840
|
enforceWebGL2(enforce = true, adapters = []) {
|
|
1612
|
-
const adapterMap = this.
|
|
1841
|
+
const adapterMap = this._getAdapterMap(adapters);
|
|
1613
1842
|
const webgl2Adapter = adapterMap.get("webgl");
|
|
1614
1843
|
if (!webgl2Adapter) {
|
|
1615
1844
|
log.warn("enforceWebGL2: webgl adapter not found")();
|
|
1616
1845
|
}
|
|
1617
1846
|
webgl2Adapter?.enforceWebGL2?.(enforce);
|
|
1618
1847
|
}
|
|
1848
|
+
// DEPRECATED
|
|
1849
|
+
/** @deprecated */
|
|
1850
|
+
setDefaultDeviceProps(props) {
|
|
1851
|
+
Object.assign(_Luma.defaultProps, props);
|
|
1852
|
+
}
|
|
1853
|
+
// HELPERS
|
|
1619
1854
|
/** Convert a list of adapters to a map */
|
|
1620
|
-
|
|
1855
|
+
_getAdapterMap(adapters = []) {
|
|
1621
1856
|
const map = new Map(this.preregisteredAdapters);
|
|
1622
1857
|
for (const adapter of adapters) {
|
|
1623
1858
|
map.set(adapter.type, adapter);
|
|
1624
1859
|
}
|
|
1625
1860
|
return map;
|
|
1626
1861
|
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1862
|
+
/** Get type of a handle (for attachDevice) */
|
|
1863
|
+
_getTypeFromHandle(handle, adapters = []) {
|
|
1864
|
+
if (handle instanceof WebGL2RenderingContext) {
|
|
1865
|
+
return "webgl";
|
|
1866
|
+
}
|
|
1867
|
+
if (typeof GPUDevice !== "undefined" && handle instanceof GPUDevice) {
|
|
1868
|
+
return "webgpu";
|
|
1869
|
+
}
|
|
1870
|
+
if (handle?.queue) {
|
|
1871
|
+
return "webgpu";
|
|
1872
|
+
}
|
|
1873
|
+
if (handle === null) {
|
|
1874
|
+
return "null";
|
|
1636
1875
|
}
|
|
1876
|
+
if (handle instanceof WebGLRenderingContext) {
|
|
1877
|
+
log.warn("WebGL1 is not supported", handle)();
|
|
1878
|
+
} else {
|
|
1879
|
+
log.warn("Unknown handle type", handle)();
|
|
1880
|
+
}
|
|
1881
|
+
return null;
|
|
1637
1882
|
}
|
|
1638
1883
|
};
|
|
1639
1884
|
var Luma = _Luma;
|
|
@@ -1643,224 +1888,326 @@ var __exports__ = (() => {
|
|
|
1643
1888
|
adapters: void 0,
|
|
1644
1889
|
waitForPageLoad: true
|
|
1645
1890
|
});
|
|
1646
|
-
/**
|
|
1647
|
-
* Page load promise
|
|
1648
|
-
* Get a 'lazy' promise that resolves when the DOM is loaded.
|
|
1649
|
-
* @note Since there may be limitations on number of `load` event listeners,
|
|
1650
|
-
* it is recommended avoid calling this function until actually needed.
|
|
1651
|
-
* I.e. don't call it until you know that you will be looking up a string in the DOM.
|
|
1652
|
-
*/
|
|
1653
|
-
__publicField(Luma, "pageLoaded", getPageLoadPromise().then(() => {
|
|
1654
|
-
log.probe(2, "DOM is loaded")();
|
|
1655
|
-
}));
|
|
1656
1891
|
var luma = new Luma();
|
|
1657
|
-
function getPageLoadPromise() {
|
|
1658
|
-
if (isPageLoaded() || typeof window === "undefined") {
|
|
1659
|
-
return Promise.resolve();
|
|
1660
|
-
}
|
|
1661
|
-
return new Promise((resolve) => {
|
|
1662
|
-
window.addEventListener("load", () => resolve());
|
|
1663
|
-
});
|
|
1664
|
-
}
|
|
1665
1892
|
|
|
1666
1893
|
// ../core/src/adapter/adapter.ts
|
|
1667
1894
|
var Adapter = class {
|
|
1895
|
+
/**
|
|
1896
|
+
* Page load promise
|
|
1897
|
+
* Resolves when the DOM is loaded.
|
|
1898
|
+
* @note Since are be limitations on number of `load` event listeners,
|
|
1899
|
+
* it is recommended avoid calling this accessor until actually needed.
|
|
1900
|
+
* I.e. we don't call it unless you know that you will be looking up a string in the DOM.
|
|
1901
|
+
*/
|
|
1902
|
+
get pageLoaded() {
|
|
1903
|
+
return getPageLoadPromise();
|
|
1904
|
+
}
|
|
1668
1905
|
};
|
|
1906
|
+
var isPage = isBrowser() && typeof document !== "undefined";
|
|
1907
|
+
var isPageLoaded = () => isPage && document.readyState === "complete";
|
|
1908
|
+
var pageLoadPromise = null;
|
|
1909
|
+
function getPageLoadPromise() {
|
|
1910
|
+
if (!pageLoadPromise) {
|
|
1911
|
+
if (isPageLoaded() || typeof window === "undefined") {
|
|
1912
|
+
pageLoadPromise = Promise.resolve();
|
|
1913
|
+
} else {
|
|
1914
|
+
pageLoadPromise = new Promise((resolve) => window.addEventListener("load", () => resolve()));
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
return pageLoadPromise;
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
// ../core/src/utils/promise-utils.ts
|
|
1921
|
+
function withResolvers() {
|
|
1922
|
+
let resolve;
|
|
1923
|
+
let reject;
|
|
1924
|
+
const promise = new Promise((_resolve, _reject) => {
|
|
1925
|
+
resolve = _resolve;
|
|
1926
|
+
reject = _reject;
|
|
1927
|
+
});
|
|
1928
|
+
return { promise, resolve, reject };
|
|
1929
|
+
}
|
|
1669
1930
|
|
|
1670
1931
|
// ../core/src/adapter/canvas-context.ts
|
|
1671
1932
|
var _CanvasContext = class {
|
|
1933
|
+
static isHTMLCanvas(canvas) {
|
|
1934
|
+
return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
|
|
1935
|
+
}
|
|
1936
|
+
static isOffscreenCanvas(canvas) {
|
|
1937
|
+
return typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas;
|
|
1938
|
+
}
|
|
1672
1939
|
id;
|
|
1673
1940
|
props;
|
|
1674
1941
|
canvas;
|
|
1942
|
+
/** Handle to HTML canvas */
|
|
1675
1943
|
htmlCanvas;
|
|
1944
|
+
/** Handle to wrapped OffScreenCanvas */
|
|
1676
1945
|
offscreenCanvas;
|
|
1677
1946
|
type;
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
/**
|
|
1682
|
-
|
|
1947
|
+
/** Promise that resolved once the resize observer has updated the pixel size */
|
|
1948
|
+
initialized;
|
|
1949
|
+
isInitialized = false;
|
|
1950
|
+
/** Visibility is automatically updated (via an IntersectionObserver) */
|
|
1951
|
+
isVisible = true;
|
|
1952
|
+
/** Width of canvas in CSS units (tracked by a ResizeObserver) */
|
|
1953
|
+
cssWidth;
|
|
1954
|
+
/** Height of canvas in CSS units (tracked by a ResizeObserver) */
|
|
1955
|
+
cssHeight;
|
|
1956
|
+
/** Device pixel ratio. Automatically updated via media queries */
|
|
1957
|
+
devicePixelRatio;
|
|
1958
|
+
/** Exact width of canvas in physical pixels (tracked by a ResizeObserver) */
|
|
1959
|
+
devicePixelWidth;
|
|
1960
|
+
/** Exact height of canvas in physical pixels (tracked by a ResizeObserver) */
|
|
1961
|
+
devicePixelHeight;
|
|
1962
|
+
/** Width of drawing buffer: automatically tracks this.pixelWidth if props.autoResize is true */
|
|
1963
|
+
drawingBufferWidth;
|
|
1964
|
+
/** Height of drawing buffer: automatically tracks this.pixelHeight if props.autoResize is true */
|
|
1965
|
+
drawingBufferHeight;
|
|
1966
|
+
_initializedResolvers = withResolvers();
|
|
1967
|
+
_resizeObserver;
|
|
1968
|
+
_intersectionObserver;
|
|
1969
|
+
_position;
|
|
1970
|
+
destroyed = false;
|
|
1683
1971
|
toString() {
|
|
1684
1972
|
return `${this[Symbol.toStringTag]}(${this.id})`;
|
|
1685
1973
|
}
|
|
1686
1974
|
constructor(props) {
|
|
1687
1975
|
this.props = { ..._CanvasContext.defaultProps, ...props };
|
|
1688
1976
|
props = this.props;
|
|
1977
|
+
this.initialized = this._initializedResolvers.promise;
|
|
1689
1978
|
if (!isBrowser()) {
|
|
1690
|
-
this.
|
|
1691
|
-
|
|
1692
|
-
this.
|
|
1693
|
-
this.height = this.props.height;
|
|
1694
|
-
this.canvas = null;
|
|
1695
|
-
return;
|
|
1696
|
-
}
|
|
1697
|
-
if (!props.canvas) {
|
|
1698
|
-
const canvas = createCanvas(props);
|
|
1699
|
-
const container = getContainer(props?.container || null);
|
|
1700
|
-
container.insertBefore(canvas, container.firstChild);
|
|
1701
|
-
this.canvas = canvas;
|
|
1702
|
-
if (!props?.visible) {
|
|
1703
|
-
this.canvas.style.visibility = "hidden";
|
|
1704
|
-
}
|
|
1979
|
+
this.canvas = { width: props.width || 1, height: props.height || 1 };
|
|
1980
|
+
} else if (!props.canvas) {
|
|
1981
|
+
this.canvas = createCanvasElement(props);
|
|
1705
1982
|
} else if (typeof props.canvas === "string") {
|
|
1706
1983
|
this.canvas = getCanvasFromDOM(props.canvas);
|
|
1707
1984
|
} else {
|
|
1708
1985
|
this.canvas = props.canvas;
|
|
1709
1986
|
}
|
|
1710
|
-
if (this.canvas
|
|
1711
|
-
this.id = this.canvas.id;
|
|
1987
|
+
if (_CanvasContext.isHTMLCanvas(this.canvas)) {
|
|
1988
|
+
this.id = props.id || this.canvas.id;
|
|
1712
1989
|
this.type = "html-canvas";
|
|
1713
1990
|
this.htmlCanvas = this.canvas;
|
|
1714
|
-
} else {
|
|
1715
|
-
this.id = "offscreen-canvas";
|
|
1991
|
+
} else if (_CanvasContext.isOffscreenCanvas(this.canvas)) {
|
|
1992
|
+
this.id = props.id || "offscreen-canvas";
|
|
1716
1993
|
this.type = "offscreen-canvas";
|
|
1717
1994
|
this.offscreenCanvas = this.canvas;
|
|
1995
|
+
} else {
|
|
1996
|
+
this.id = props.id || "node-canvas-context";
|
|
1997
|
+
this.type = "node";
|
|
1718
1998
|
}
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1999
|
+
this.cssWidth = this.htmlCanvas?.clientWidth || this.canvas.width;
|
|
2000
|
+
this.cssHeight = this.htmlCanvas?.clientHeight || this.canvas.height;
|
|
2001
|
+
this.devicePixelWidth = this.canvas.width;
|
|
2002
|
+
this.devicePixelHeight = this.canvas.height;
|
|
2003
|
+
this.drawingBufferWidth = this.canvas.width;
|
|
2004
|
+
this.drawingBufferHeight = this.canvas.height;
|
|
2005
|
+
this.devicePixelRatio = globalThis.devicePixelRatio || 1;
|
|
2006
|
+
this._position = [0, 0];
|
|
2007
|
+
if (_CanvasContext.isHTMLCanvas(this.canvas)) {
|
|
2008
|
+
this._intersectionObserver = new IntersectionObserver(
|
|
2009
|
+
(entries) => this._handleIntersection(entries)
|
|
2010
|
+
);
|
|
2011
|
+
this._intersectionObserver.observe(this.canvas);
|
|
2012
|
+
this._resizeObserver = new ResizeObserver((entries) => this._handleResize(entries));
|
|
2013
|
+
try {
|
|
2014
|
+
this._resizeObserver.observe(this.canvas, { box: "device-pixel-content-box" });
|
|
2015
|
+
} catch {
|
|
2016
|
+
this._resizeObserver.observe(this.canvas, { box: "content-box" });
|
|
2017
|
+
}
|
|
2018
|
+
setTimeout(() => this._observeDevicePixelRatio(), 0);
|
|
2019
|
+
if (this.props.trackPosition) {
|
|
2020
|
+
this._trackPosition();
|
|
2021
|
+
}
|
|
1728
2022
|
}
|
|
1729
2023
|
}
|
|
2024
|
+
destroy() {
|
|
2025
|
+
this.destroyed = true;
|
|
2026
|
+
}
|
|
2027
|
+
// SIZE METHODS
|
|
1730
2028
|
/**
|
|
1731
|
-
* Returns the
|
|
1732
|
-
*
|
|
2029
|
+
* Returns the size covered by the canvas in CSS pixels
|
|
2030
|
+
* @note This can be different from the actual device pixel size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
2031
|
+
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
1733
2032
|
*/
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
return
|
|
2033
|
+
getCSSSize() {
|
|
2034
|
+
return [this.cssWidth, this.cssHeight];
|
|
2035
|
+
}
|
|
2036
|
+
getPosition() {
|
|
2037
|
+
return this._position;
|
|
2038
|
+
}
|
|
2039
|
+
/**
|
|
2040
|
+
* Returns the size covered by the canvas in actual device pixels.
|
|
2041
|
+
* @note This can be different from the 'CSS' size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
2042
|
+
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
2043
|
+
*/
|
|
2044
|
+
getDevicePixelSize() {
|
|
2045
|
+
return [this.devicePixelWidth, this.devicePixelHeight];
|
|
2046
|
+
}
|
|
2047
|
+
/** Get the drawing buffer size (number of pixels GPU is rendering into, can be different from CSS size) */
|
|
2048
|
+
getDrawingBufferSize() {
|
|
2049
|
+
return [this.drawingBufferWidth, this.drawingBufferHeight];
|
|
2050
|
+
}
|
|
2051
|
+
/** Returns the biggest allowed framebuffer size. @todo Allow the application to limit this? */
|
|
2052
|
+
getMaxDrawingBufferSize() {
|
|
2053
|
+
const maxTextureDimension = this.device.limits.maxTextureDimension2D;
|
|
2054
|
+
return [maxTextureDimension, maxTextureDimension];
|
|
2055
|
+
}
|
|
2056
|
+
/** Update the canvas drawing buffer size. Called automatically if props.autoResize is true. */
|
|
2057
|
+
setDrawingBufferSize(width, height) {
|
|
2058
|
+
this.canvas.width = width;
|
|
2059
|
+
this.canvas.height = height;
|
|
2060
|
+
this.drawingBufferWidth = width;
|
|
2061
|
+
this.drawingBufferHeight = height;
|
|
1747
2062
|
}
|
|
1748
2063
|
/**
|
|
1749
|
-
* Returns the
|
|
1750
|
-
* @note This can be
|
|
1751
|
-
*
|
|
1752
|
-
* This is the size required to cover the canvas, adjusted for DPR
|
|
2064
|
+
* Returns the current DPR (number of physical pixels per CSS pixel), if props.useDevicePixels is true
|
|
2065
|
+
* @note This can be a fractional (non-integer) number, e.g. when the user zooms in the browser.
|
|
2066
|
+
* @note This function handles the non-HTML canvas cases
|
|
1753
2067
|
*/
|
|
2068
|
+
getDevicePixelRatio() {
|
|
2069
|
+
const dpr = typeof window !== "undefined" && window.devicePixelRatio;
|
|
2070
|
+
return dpr || 1;
|
|
2071
|
+
}
|
|
2072
|
+
// DEPRECATED METHODS
|
|
2073
|
+
/**
|
|
2074
|
+
* Maps CSS pixel position to device pixel position
|
|
2075
|
+
*/
|
|
2076
|
+
cssToDevicePixels(cssPixel, yInvert = true) {
|
|
2077
|
+
const ratio = this.cssToDeviceRatio();
|
|
2078
|
+
const [width, height] = this.getDrawingBufferSize();
|
|
2079
|
+
return scalePixels(cssPixel, ratio, width, height, yInvert);
|
|
2080
|
+
}
|
|
2081
|
+
/** @deprecated - use .getDevicePixelSize() */
|
|
1754
2082
|
getPixelSize() {
|
|
1755
|
-
|
|
1756
|
-
case "node":
|
|
1757
|
-
return [this.width, this.height];
|
|
1758
|
-
case "offscreen-canvas":
|
|
1759
|
-
return [this.canvas.width, this.canvas.height];
|
|
1760
|
-
case "html-canvas":
|
|
1761
|
-
const dpr = this.getDevicePixelRatio();
|
|
1762
|
-
const canvas = this.canvas;
|
|
1763
|
-
return canvas.parentElement ? [canvas.clientWidth * dpr, canvas.clientHeight * dpr] : [this.canvas.width, this.canvas.height];
|
|
1764
|
-
default:
|
|
1765
|
-
throw new Error(this.type);
|
|
1766
|
-
}
|
|
2083
|
+
return this.getDevicePixelSize();
|
|
1767
2084
|
}
|
|
2085
|
+
/** @deprecated - TODO which values should we use for aspect */
|
|
1768
2086
|
getAspect() {
|
|
1769
|
-
const [width, height] = this.
|
|
2087
|
+
const [width, height] = this.getDevicePixelSize();
|
|
1770
2088
|
return width / height;
|
|
1771
2089
|
}
|
|
1772
|
-
/**
|
|
1773
|
-
* Returns multiplier need to convert CSS size to Device size
|
|
1774
|
-
*/
|
|
2090
|
+
/** @deprecated Returns multiplier need to convert CSS size to Device size */
|
|
1775
2091
|
cssToDeviceRatio() {
|
|
1776
2092
|
try {
|
|
1777
2093
|
const [drawingBufferWidth] = this.getDrawingBufferSize();
|
|
1778
|
-
const
|
|
1779
|
-
return
|
|
2094
|
+
const [cssWidth] = this.getCSSSize();
|
|
2095
|
+
return cssWidth ? drawingBufferWidth / cssWidth : 1;
|
|
1780
2096
|
} catch {
|
|
1781
2097
|
return 1;
|
|
1782
2098
|
}
|
|
1783
2099
|
}
|
|
2100
|
+
/** @deprecated Use canvasContext.setDrawingBufferSize() */
|
|
2101
|
+
resize(size) {
|
|
2102
|
+
this.setDrawingBufferSize(size.width, size.height);
|
|
2103
|
+
}
|
|
2104
|
+
// IMPLEMENTATION
|
|
1784
2105
|
/**
|
|
1785
|
-
*
|
|
2106
|
+
* Allows subclass constructor to override the canvas id for auto created canvases.
|
|
2107
|
+
* This can really help when debugging DOM in apps that create multiple devices
|
|
1786
2108
|
*/
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
2109
|
+
_setAutoCreatedCanvasId(id) {
|
|
2110
|
+
if (this.htmlCanvas?.id === "lumagl-auto-created-canvas") {
|
|
2111
|
+
this.htmlCanvas.id = id;
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
/** reacts to an observed intersection */
|
|
2115
|
+
_handleIntersection(entries) {
|
|
2116
|
+
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
2117
|
+
if (!entry) {
|
|
2118
|
+
return;
|
|
2119
|
+
}
|
|
2120
|
+
const isVisible = entry.isIntersecting;
|
|
2121
|
+
if (this.isVisible !== isVisible) {
|
|
2122
|
+
this.isVisible = isVisible;
|
|
2123
|
+
this.device.props.onVisibilityChange(this);
|
|
2124
|
+
}
|
|
1791
2125
|
}
|
|
1792
2126
|
/**
|
|
1793
|
-
*
|
|
1794
|
-
* @
|
|
2127
|
+
* Reacts to an observed resize by using the most accurate pixel size information the browser can provide
|
|
2128
|
+
* @see https://web.dev/articles/device-pixel-content-box
|
|
2129
|
+
* @see https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html
|
|
1795
2130
|
*/
|
|
1796
|
-
|
|
1797
|
-
|
|
2131
|
+
_handleResize(entries) {
|
|
2132
|
+
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
2133
|
+
if (!entry) {
|
|
1798
2134
|
return;
|
|
1799
2135
|
}
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
this.htmlCanvas.width = canvasWidth;
|
|
1814
|
-
this.htmlCanvas.height = canvasHeight;
|
|
1815
|
-
const gl = this.device.gl;
|
|
1816
|
-
if (gl) {
|
|
1817
|
-
const [drawingBufferWidth, drawingBufferHeight] = this.getDrawingBufferSize();
|
|
1818
|
-
if (drawingBufferWidth !== canvasWidth || drawingBufferHeight !== canvasHeight) {
|
|
1819
|
-
clampedPixelRatio = Math.min(
|
|
1820
|
-
drawingBufferWidth / clientWidth,
|
|
1821
|
-
drawingBufferHeight / clientHeight
|
|
1822
|
-
);
|
|
1823
|
-
this.htmlCanvas.width = Math.floor(clientWidth * clampedPixelRatio);
|
|
1824
|
-
this.htmlCanvas.height = Math.floor(clientHeight * clampedPixelRatio);
|
|
1825
|
-
log.warn("Device pixel ratio clamped")();
|
|
1826
|
-
}
|
|
1827
|
-
this._canvasSizeInfo.clientWidth = clientWidth;
|
|
1828
|
-
this._canvasSizeInfo.clientHeight = clientHeight;
|
|
1829
|
-
this._canvasSizeInfo.devicePixelRatio = devicePixelRatio;
|
|
2136
|
+
this.cssWidth = entry.contentBoxSize[0].inlineSize;
|
|
2137
|
+
this.cssHeight = entry.contentBoxSize[0].blockSize;
|
|
2138
|
+
const oldPixelSize = this.getDevicePixelSize();
|
|
2139
|
+
const devicePixelWidth = entry.devicePixelContentBoxSize?.[0].inlineSize || entry.contentBoxSize[0].inlineSize * devicePixelRatio;
|
|
2140
|
+
const devicePixelHeight = entry.devicePixelContentBoxSize?.[0].blockSize || entry.contentBoxSize[0].blockSize * devicePixelRatio;
|
|
2141
|
+
const [maxDevicePixelWidth, maxDevicePixelHeight] = this.getMaxDrawingBufferSize();
|
|
2142
|
+
this.devicePixelWidth = Math.max(1, Math.min(devicePixelWidth, maxDevicePixelWidth));
|
|
2143
|
+
this.devicePixelHeight = Math.max(1, Math.min(devicePixelHeight, maxDevicePixelHeight));
|
|
2144
|
+
if (this.props.autoResize) {
|
|
2145
|
+
if (this.props.useDevicePixels) {
|
|
2146
|
+
this.setDrawingBufferSize(this.devicePixelWidth, this.devicePixelHeight);
|
|
2147
|
+
} else {
|
|
2148
|
+
this.setDrawingBufferSize(this.cssWidth, this.cssHeight);
|
|
1830
2149
|
}
|
|
1831
|
-
|
|
2150
|
+
this._updateDevice();
|
|
2151
|
+
}
|
|
2152
|
+
this._initializedResolvers.resolve();
|
|
2153
|
+
this.isInitialized = true;
|
|
2154
|
+
this.updatePosition();
|
|
2155
|
+
this.device.props.onResize(this, { oldPixelSize });
|
|
2156
|
+
}
|
|
2157
|
+
/** Monitor DPR changes */
|
|
2158
|
+
_observeDevicePixelRatio() {
|
|
2159
|
+
const oldRatio = this.devicePixelRatio;
|
|
2160
|
+
this.devicePixelRatio = window.devicePixelRatio;
|
|
2161
|
+
this.updatePosition();
|
|
2162
|
+
this.device.props.onDevicePixelRatioChange(this, { oldRatio });
|
|
2163
|
+
matchMedia(`(resolution: ${this.devicePixelRatio}dppx)`).addEventListener(
|
|
2164
|
+
"change",
|
|
2165
|
+
() => this._observeDevicePixelRatio(),
|
|
2166
|
+
{ once: true }
|
|
2167
|
+
);
|
|
1832
2168
|
}
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
2169
|
+
/** Start tracking positions with a timer */
|
|
2170
|
+
_trackPosition(intervalMs = 100) {
|
|
2171
|
+
const intervalId = setInterval(() => {
|
|
2172
|
+
if (this.destroyed) {
|
|
2173
|
+
clearInterval(intervalId);
|
|
2174
|
+
} else {
|
|
2175
|
+
this.updatePosition();
|
|
2176
|
+
}
|
|
2177
|
+
}, intervalMs);
|
|
1841
2178
|
}
|
|
1842
2179
|
/**
|
|
1843
|
-
*
|
|
1844
|
-
*
|
|
2180
|
+
* Calculated the absolute position of the canvas
|
|
2181
|
+
* @note - getBoundingClientRect() is normally cheap but can be expensive
|
|
2182
|
+
* if called before browser has finished a reflow. Should not be the case here.
|
|
1845
2183
|
*/
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
2184
|
+
updatePosition() {
|
|
2185
|
+
const newRect = this.htmlCanvas?.getBoundingClientRect();
|
|
2186
|
+
if (newRect) {
|
|
2187
|
+
const position = [newRect.left, newRect.top];
|
|
2188
|
+
this._position ??= position;
|
|
2189
|
+
const positionChanged = position[0] !== this._position[0] || position[1] !== this._position[1];
|
|
2190
|
+
if (positionChanged) {
|
|
2191
|
+
const oldPosition = this._position;
|
|
2192
|
+
this._position = position;
|
|
2193
|
+
this.device.props.onPositionChange?.(this, { oldPosition });
|
|
2194
|
+
}
|
|
1849
2195
|
}
|
|
1850
2196
|
}
|
|
1851
2197
|
};
|
|
1852
2198
|
var CanvasContext = _CanvasContext;
|
|
1853
2199
|
__publicField(CanvasContext, "defaultProps", {
|
|
2200
|
+
id: void 0,
|
|
1854
2201
|
canvas: null,
|
|
1855
2202
|
width: 800,
|
|
1856
|
-
// width are height are only used by headless gl
|
|
1857
2203
|
height: 600,
|
|
1858
2204
|
useDevicePixels: true,
|
|
1859
2205
|
autoResize: true,
|
|
1860
2206
|
container: null,
|
|
1861
2207
|
visible: true,
|
|
1862
2208
|
alphaMode: "opaque",
|
|
1863
|
-
colorSpace: "srgb"
|
|
2209
|
+
colorSpace: "srgb",
|
|
2210
|
+
trackPosition: false
|
|
1864
2211
|
});
|
|
1865
2212
|
function getContainer(container) {
|
|
1866
2213
|
if (typeof container === "string") {
|
|
@@ -1869,27 +2216,33 @@ var __exports__ = (() => {
|
|
|
1869
2216
|
throw new Error(`${container} is not an HTML element`);
|
|
1870
2217
|
}
|
|
1871
2218
|
return element;
|
|
1872
|
-
}
|
|
2219
|
+
}
|
|
2220
|
+
if (container) {
|
|
1873
2221
|
return container;
|
|
1874
2222
|
}
|
|
1875
2223
|
return document.body;
|
|
1876
2224
|
}
|
|
1877
2225
|
function getCanvasFromDOM(canvasId) {
|
|
1878
2226
|
const canvas = document.getElementById(canvasId);
|
|
1879
|
-
if (!(canvas
|
|
2227
|
+
if (!CanvasContext.isHTMLCanvas(canvas)) {
|
|
1880
2228
|
throw new Error("Object is not a canvas element");
|
|
1881
2229
|
}
|
|
1882
2230
|
return canvas;
|
|
1883
2231
|
}
|
|
1884
|
-
function
|
|
2232
|
+
function createCanvasElement(props) {
|
|
1885
2233
|
const { width, height } = props;
|
|
1886
|
-
const
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
2234
|
+
const newCanvas = document.createElement("canvas");
|
|
2235
|
+
newCanvas.id = uid("lumagl-auto-created-canvas");
|
|
2236
|
+
newCanvas.width = width || 1;
|
|
2237
|
+
newCanvas.height = height || 1;
|
|
2238
|
+
newCanvas.style.width = Number.isFinite(width) ? `${width}px` : "100%";
|
|
2239
|
+
newCanvas.style.height = Number.isFinite(height) ? `${height}px` : "100%";
|
|
2240
|
+
if (!props?.visible) {
|
|
2241
|
+
newCanvas.style.visibility = "hidden";
|
|
2242
|
+
}
|
|
2243
|
+
const container = getContainer(props?.container || null);
|
|
2244
|
+
container.insertBefore(newCanvas, container.firstChild);
|
|
2245
|
+
return newCanvas;
|
|
1893
2246
|
}
|
|
1894
2247
|
function scalePixels(pixel, ratio, width, height, yInvert) {
|
|
1895
2248
|
const point = pixel;
|
|
@@ -1922,16 +2275,50 @@ var __exports__ = (() => {
|
|
|
1922
2275
|
return yInvert ? Math.max(0, height - 1 - Math.round(y * ratio)) : Math.min(Math.round(y * ratio), height - 1);
|
|
1923
2276
|
}
|
|
1924
2277
|
|
|
1925
|
-
// ../core/src/adapter/resources/
|
|
1926
|
-
var
|
|
2278
|
+
// ../core/src/adapter/resources/sampler.ts
|
|
2279
|
+
var _Sampler = class extends Resource {
|
|
1927
2280
|
get [Symbol.toStringTag]() {
|
|
1928
|
-
return "
|
|
2281
|
+
return "Sampler";
|
|
1929
2282
|
}
|
|
1930
|
-
|
|
1931
|
-
|
|
2283
|
+
constructor(device, props) {
|
|
2284
|
+
props = _Sampler.normalizeProps(device, props);
|
|
2285
|
+
super(device, props, _Sampler.defaultProps);
|
|
2286
|
+
}
|
|
2287
|
+
static normalizeProps(device, props) {
|
|
2288
|
+
return props;
|
|
1932
2289
|
}
|
|
2290
|
+
};
|
|
2291
|
+
var Sampler = _Sampler;
|
|
2292
|
+
__publicField(Sampler, "defaultProps", {
|
|
2293
|
+
...Resource.defaultProps,
|
|
2294
|
+
type: "color-sampler",
|
|
2295
|
+
addressModeU: "clamp-to-edge",
|
|
2296
|
+
addressModeV: "clamp-to-edge",
|
|
2297
|
+
addressModeW: "clamp-to-edge",
|
|
2298
|
+
magFilter: "nearest",
|
|
2299
|
+
minFilter: "nearest",
|
|
2300
|
+
mipmapFilter: "none",
|
|
2301
|
+
lodMinClamp: 0,
|
|
2302
|
+
lodMaxClamp: 32,
|
|
2303
|
+
// Per WebGPU spec
|
|
2304
|
+
compare: "less-equal",
|
|
2305
|
+
maxAnisotropy: 1
|
|
2306
|
+
});
|
|
2307
|
+
|
|
2308
|
+
// ../core/src/adapter/resources/texture.ts
|
|
2309
|
+
var BASE_DIMENSIONS = {
|
|
2310
|
+
"1d": "1d",
|
|
2311
|
+
"2d": "2d",
|
|
2312
|
+
"2d-array": "2d",
|
|
2313
|
+
cube: "2d",
|
|
2314
|
+
"cube-array": "2d",
|
|
2315
|
+
"3d": "3d"
|
|
2316
|
+
};
|
|
2317
|
+
var _Texture = class extends Resource {
|
|
1933
2318
|
/** dimension of this texture */
|
|
1934
2319
|
dimension;
|
|
2320
|
+
/** base dimension of this texture */
|
|
2321
|
+
baseDimension;
|
|
1935
2322
|
/** format of this texture */
|
|
1936
2323
|
format;
|
|
1937
2324
|
/** width in pixels of this texture */
|
|
@@ -1944,133 +2331,55 @@ var __exports__ = (() => {
|
|
|
1944
2331
|
mipLevels;
|
|
1945
2332
|
/** "Time" of last update. Monotonically increasing timestamp. TODO move to AsyncTexture? */
|
|
1946
2333
|
updateTimestamp;
|
|
2334
|
+
get [Symbol.toStringTag]() {
|
|
2335
|
+
return "Texture";
|
|
2336
|
+
}
|
|
2337
|
+
toString() {
|
|
2338
|
+
return `Texture(${this.id},${this.format},${this.width}x${this.height})`;
|
|
2339
|
+
}
|
|
1947
2340
|
/** Do not use directly. Create with device.createTexture() */
|
|
1948
2341
|
constructor(device, props) {
|
|
1949
2342
|
props = _Texture.normalizeProps(device, props);
|
|
1950
2343
|
super(device, props, _Texture.defaultProps);
|
|
1951
2344
|
this.dimension = this.props.dimension;
|
|
2345
|
+
this.baseDimension = BASE_DIMENSIONS[this.dimension];
|
|
1952
2346
|
this.format = this.props.format;
|
|
1953
2347
|
this.width = this.props.width;
|
|
1954
2348
|
this.height = this.props.height;
|
|
1955
2349
|
this.depth = this.props.depth;
|
|
2350
|
+
this.mipLevels = this.props.mipLevels;
|
|
1956
2351
|
if (this.props.width === void 0 || this.props.height === void 0) {
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
2352
|
+
if (device.isExternalImage(props.data)) {
|
|
2353
|
+
const size = device.getExternalImageSize(props.data);
|
|
2354
|
+
this.width = size?.width || 1;
|
|
2355
|
+
this.height = size?.height || 1;
|
|
2356
|
+
} else {
|
|
2357
|
+
this.width = 1;
|
|
2358
|
+
this.height = 1;
|
|
2359
|
+
if (this.props.width === void 0 || this.props.height === void 0) {
|
|
2360
|
+
log.warn(
|
|
2361
|
+
`${this} created with undefined width or height. This is deprecated. Use AsyncTexture instead.`
|
|
2362
|
+
)();
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
1963
2365
|
}
|
|
1964
|
-
this.mipLevels = this.props.mipLevels === "pyramid" ? _Texture.getMipLevelCount(this.width, this.height) : this.props.mipLevels || 1;
|
|
1965
2366
|
this.updateTimestamp = device.incrementTimestamp();
|
|
1966
2367
|
}
|
|
2368
|
+
/** Set sampler props associated with this texture */
|
|
2369
|
+
setSampler(sampler) {
|
|
2370
|
+
this.sampler = sampler instanceof Sampler ? sampler : this.device.createSampler(sampler);
|
|
2371
|
+
}
|
|
1967
2372
|
/**
|
|
1968
|
-
* Create a new texture with the same parameters and optionally
|
|
2373
|
+
* Create a new texture with the same parameters and optionally a different size
|
|
1969
2374
|
* @note Textures are immutable and cannot be resized after creation, but we can create a similar texture with the same parameters but a new size.
|
|
1970
2375
|
* @note Does not copy contents of the texture
|
|
1971
2376
|
*/
|
|
1972
2377
|
clone(size) {
|
|
1973
2378
|
return this.device.createTexture({ ...this.props, ...size });
|
|
1974
2379
|
}
|
|
1975
|
-
/** Check if data is an external image */
|
|
1976
|
-
static isExternalImage(data) {
|
|
1977
|
-
return typeof ImageData !== "undefined" && data instanceof ImageData || typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap || typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement || typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement || typeof VideoFrame !== "undefined" && data instanceof VideoFrame || typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement || typeof OffscreenCanvas !== "undefined" && data instanceof OffscreenCanvas;
|
|
1978
|
-
}
|
|
1979
|
-
/** Determine size (width and height) of provided image data */
|
|
1980
|
-
static getExternalImageSize(data) {
|
|
1981
|
-
if (typeof ImageData !== "undefined" && data instanceof ImageData || typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap || typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement || typeof OffscreenCanvas !== "undefined" && data instanceof OffscreenCanvas) {
|
|
1982
|
-
return { width: data.width, height: data.height };
|
|
1983
|
-
}
|
|
1984
|
-
if (typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement) {
|
|
1985
|
-
return { width: data.naturalWidth, height: data.naturalHeight };
|
|
1986
|
-
}
|
|
1987
|
-
if (typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement) {
|
|
1988
|
-
return { width: data.videoWidth, height: data.videoHeight };
|
|
1989
|
-
}
|
|
1990
|
-
if (typeof VideoFrame !== "undefined" && data instanceof VideoFrame) {
|
|
1991
|
-
return { width: data.displayWidth, height: data.displayHeight };
|
|
1992
|
-
}
|
|
1993
|
-
throw new Error("Unknown image type");
|
|
1994
|
-
}
|
|
1995
|
-
/** Check if texture data is a typed array */
|
|
1996
|
-
static isTextureLevelData(data) {
|
|
1997
|
-
const typedArray = data?.data;
|
|
1998
|
-
return ArrayBuffer.isView(typedArray);
|
|
1999
|
-
}
|
|
2000
|
-
/** Get the size of the texture described by the provided TextureData */
|
|
2001
|
-
static getTextureDataSize(data) {
|
|
2002
|
-
if (!data) {
|
|
2003
|
-
return null;
|
|
2004
|
-
}
|
|
2005
|
-
if (ArrayBuffer.isView(data)) {
|
|
2006
|
-
return null;
|
|
2007
|
-
}
|
|
2008
|
-
if (Array.isArray(data)) {
|
|
2009
|
-
return _Texture.getTextureDataSize(data[0]);
|
|
2010
|
-
}
|
|
2011
|
-
if (_Texture.isExternalImage(data)) {
|
|
2012
|
-
return _Texture.getExternalImageSize(data);
|
|
2013
|
-
}
|
|
2014
|
-
if (data && typeof data === "object" && data.constructor === Object) {
|
|
2015
|
-
const textureDataArray = Object.values(data);
|
|
2016
|
-
const untypedData = textureDataArray[0];
|
|
2017
|
-
return { width: untypedData.width, height: untypedData.height };
|
|
2018
|
-
}
|
|
2019
|
-
throw new Error("texture size deduction failed");
|
|
2020
|
-
}
|
|
2021
|
-
/**
|
|
2022
|
-
* Normalize TextureData to an array of TextureLevelData / ExternalImages
|
|
2023
|
-
* @param data
|
|
2024
|
-
* @param options
|
|
2025
|
-
* @returns array of TextureLevelData / ExternalImages
|
|
2026
|
-
*/
|
|
2027
|
-
static normalizeTextureData(data, options) {
|
|
2028
|
-
let lodArray;
|
|
2029
|
-
if (ArrayBuffer.isView(data)) {
|
|
2030
|
-
lodArray = [
|
|
2031
|
-
{
|
|
2032
|
-
// ts-expect-error does data really need to be Uint8ClampedArray?
|
|
2033
|
-
data,
|
|
2034
|
-
width: options.width,
|
|
2035
|
-
height: options.height
|
|
2036
|
-
// depth: options.depth
|
|
2037
|
-
}
|
|
2038
|
-
];
|
|
2039
|
-
} else if (!Array.isArray(data)) {
|
|
2040
|
-
lodArray = [data];
|
|
2041
|
-
} else {
|
|
2042
|
-
lodArray = data;
|
|
2043
|
-
}
|
|
2044
|
-
return lodArray;
|
|
2045
|
-
}
|
|
2046
|
-
/** Calculate the number of mip levels for a texture of width and height */
|
|
2047
|
-
static getMipLevelCount(width, height) {
|
|
2048
|
-
return Math.floor(Math.log2(Math.max(width, height))) + 1;
|
|
2049
|
-
}
|
|
2050
|
-
/** Convert luma.gl cubemap face constants to depth index */
|
|
2051
|
-
static getCubeFaceDepth(face) {
|
|
2052
|
-
switch (face) {
|
|
2053
|
-
case "+X":
|
|
2054
|
-
return 0;
|
|
2055
|
-
case "-X":
|
|
2056
|
-
return 1;
|
|
2057
|
-
case "+Y":
|
|
2058
|
-
return 2;
|
|
2059
|
-
case "-Y":
|
|
2060
|
-
return 3;
|
|
2061
|
-
case "+Z":
|
|
2062
|
-
return 4;
|
|
2063
|
-
case "-Z":
|
|
2064
|
-
return 5;
|
|
2065
|
-
default:
|
|
2066
|
-
throw new Error(face);
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
2380
|
/** Ensure we have integer coordinates */
|
|
2070
2381
|
static normalizeProps(device, props) {
|
|
2071
2382
|
const newProps = { ...props };
|
|
2072
|
-
const overriddenDefaultProps = device?.props?._resourceDefaults?.texture || {};
|
|
2073
|
-
Object.assign(newProps, overriddenDefaultProps);
|
|
2074
2383
|
const { width, height } = newProps;
|
|
2075
2384
|
if (typeof width === "number") {
|
|
2076
2385
|
newProps.width = Math.max(1, Math.ceil(width));
|
|
@@ -2080,30 +2389,98 @@ var __exports__ = (() => {
|
|
|
2080
2389
|
}
|
|
2081
2390
|
return newProps;
|
|
2082
2391
|
}
|
|
2392
|
+
// HELPERS
|
|
2393
|
+
/** Initialize texture with supplied props */
|
|
2394
|
+
// eslint-disable-next-line max-statements
|
|
2395
|
+
_initializeData(data) {
|
|
2396
|
+
if (this.device.isExternalImage(data)) {
|
|
2397
|
+
this.copyExternalImage({
|
|
2398
|
+
image: data,
|
|
2399
|
+
width: this.width,
|
|
2400
|
+
height: this.height,
|
|
2401
|
+
depth: this.depth,
|
|
2402
|
+
mipLevel: 0,
|
|
2403
|
+
x: 0,
|
|
2404
|
+
y: 0,
|
|
2405
|
+
z: 0,
|
|
2406
|
+
aspect: "all",
|
|
2407
|
+
colorSpace: "srgb",
|
|
2408
|
+
premultipliedAlpha: false,
|
|
2409
|
+
flipY: false
|
|
2410
|
+
});
|
|
2411
|
+
} else if (data) {
|
|
2412
|
+
this.copyImageData({
|
|
2413
|
+
data,
|
|
2414
|
+
// width: this.width,
|
|
2415
|
+
// height: this.height,
|
|
2416
|
+
// depth: this.depth,
|
|
2417
|
+
mipLevel: 0,
|
|
2418
|
+
x: 0,
|
|
2419
|
+
y: 0,
|
|
2420
|
+
z: 0,
|
|
2421
|
+
aspect: "all"
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
_normalizeCopyImageDataOptions(options_) {
|
|
2426
|
+
const { width, height, depth } = this;
|
|
2427
|
+
const options = { ..._Texture.defaultCopyDataOptions, width, height, depth, ...options_ };
|
|
2428
|
+
const info = this.device.getTextureFormatInfo(this.format);
|
|
2429
|
+
if (!options_.bytesPerRow && !info.bytesPerPixel) {
|
|
2430
|
+
throw new Error(`bytesPerRow must be provided for texture format ${this.format}`);
|
|
2431
|
+
}
|
|
2432
|
+
options.bytesPerRow = options_.bytesPerRow || width * (info.bytesPerPixel || 4);
|
|
2433
|
+
options.rowsPerImage = options_.rowsPerImage || height;
|
|
2434
|
+
return options;
|
|
2435
|
+
}
|
|
2436
|
+
_normalizeCopyExternalImageOptions(options_) {
|
|
2437
|
+
const size = this.device.getExternalImageSize(options_.image);
|
|
2438
|
+
const options = { ..._Texture.defaultCopyExternalImageOptions, ...size, ...options_ };
|
|
2439
|
+
options.width = Math.min(options.width, this.width - options.x);
|
|
2440
|
+
options.height = Math.min(options.height, this.height - options.y);
|
|
2441
|
+
return options;
|
|
2442
|
+
}
|
|
2083
2443
|
};
|
|
2084
2444
|
var Texture = _Texture;
|
|
2445
|
+
/** The texture can be bound for use as a sampled texture in a shader */
|
|
2446
|
+
__publicField(Texture, "SAMPLE", 4);
|
|
2447
|
+
/** The texture can be bound for use as a storage texture in a shader */
|
|
2448
|
+
__publicField(Texture, "STORAGE", 8);
|
|
2449
|
+
/** The texture can be used as a color or depth/stencil attachment in a render pass */
|
|
2450
|
+
__publicField(Texture, "RENDER", 16);
|
|
2451
|
+
/** The texture can be used as the source of a copy operation */
|
|
2085
2452
|
__publicField(Texture, "COPY_SRC", 1);
|
|
2453
|
+
/** he texture can be used as the destination of a copy or write operation */
|
|
2086
2454
|
__publicField(Texture, "COPY_DST", 2);
|
|
2455
|
+
/** @deprecated Use Texture.SAMPLE */
|
|
2087
2456
|
__publicField(Texture, "TEXTURE", 4);
|
|
2088
|
-
|
|
2457
|
+
/** @deprecated Use Texture.RENDER */
|
|
2089
2458
|
__publicField(Texture, "RENDER_ATTACHMENT", 16);
|
|
2090
|
-
|
|
2459
|
+
/** Default options */
|
|
2091
2460
|
__publicField(Texture, "defaultProps", {
|
|
2092
2461
|
...Resource.defaultProps,
|
|
2093
2462
|
data: null,
|
|
2094
2463
|
dimension: "2d",
|
|
2095
2464
|
format: "rgba8unorm",
|
|
2465
|
+
usage: _Texture.TEXTURE | _Texture.RENDER_ATTACHMENT | _Texture.COPY_DST,
|
|
2096
2466
|
width: void 0,
|
|
2097
2467
|
height: void 0,
|
|
2098
2468
|
depth: 1,
|
|
2099
|
-
|
|
2100
|
-
compressed: false,
|
|
2101
|
-
usage: 0,
|
|
2102
|
-
mipLevels: void 0,
|
|
2469
|
+
mipLevels: 1,
|
|
2103
2470
|
samples: void 0,
|
|
2104
2471
|
sampler: {},
|
|
2105
|
-
view: void 0
|
|
2106
|
-
|
|
2472
|
+
view: void 0
|
|
2473
|
+
});
|
|
2474
|
+
__publicField(Texture, "defaultCopyDataOptions", {
|
|
2475
|
+
data: void 0,
|
|
2476
|
+
byteOffset: 0,
|
|
2477
|
+
bytesPerRow: void 0,
|
|
2478
|
+
rowsPerImage: void 0,
|
|
2479
|
+
mipLevel: 0,
|
|
2480
|
+
x: 0,
|
|
2481
|
+
y: 0,
|
|
2482
|
+
z: 0,
|
|
2483
|
+
aspect: "all"
|
|
2107
2484
|
});
|
|
2108
2485
|
/** Default options */
|
|
2109
2486
|
__publicField(Texture, "defaultCopyExternalImageOptions", {
|
|
@@ -2179,6 +2556,13 @@ var __exports__ = (() => {
|
|
|
2179
2556
|
});
|
|
2180
2557
|
}
|
|
2181
2558
|
}
|
|
2559
|
+
while (log2.length > currentMessage) {
|
|
2560
|
+
const message = log2[currentMessage++];
|
|
2561
|
+
formattedLog += formatCompilerMessage(message, [], 0, {
|
|
2562
|
+
...options,
|
|
2563
|
+
inlineSource: false
|
|
2564
|
+
});
|
|
2565
|
+
}
|
|
2182
2566
|
return formattedLog;
|
|
2183
2567
|
case "issues":
|
|
2184
2568
|
case "no":
|
|
@@ -2274,19 +2658,19 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
|
|
|
2274
2658
|
if (trigger === "warnings" && messages?.length === 0) {
|
|
2275
2659
|
return;
|
|
2276
2660
|
}
|
|
2277
|
-
this._displayShaderLog(messages);
|
|
2661
|
+
this._displayShaderLog(messages, this.id);
|
|
2278
2662
|
}
|
|
2279
2663
|
// PRIVATE
|
|
2280
2664
|
/**
|
|
2281
2665
|
* In-browser UI logging of errors
|
|
2282
2666
|
* TODO - this HTML formatting code should not be in Device, should be pluggable
|
|
2283
2667
|
*/
|
|
2284
|
-
_displayShaderLog(messages) {
|
|
2668
|
+
_displayShaderLog(messages, shaderId) {
|
|
2285
2669
|
if (typeof document === "undefined" || !document?.createElement) {
|
|
2286
2670
|
return;
|
|
2287
2671
|
}
|
|
2288
|
-
const shaderName =
|
|
2289
|
-
const shaderTitle = `${this.stage} ${shaderName}`;
|
|
2672
|
+
const shaderName = shaderId;
|
|
2673
|
+
const shaderTitle = `${this.stage} shader "${shaderName}"`;
|
|
2290
2674
|
let htmlLog = formatCompilerLog(messages, this.source, { showSourceCode: "all", html: true });
|
|
2291
2675
|
const translatedSource = this.getTranslatedSource();
|
|
2292
2676
|
if (translatedSource) {
|
|
@@ -2294,7 +2678,7 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
|
|
|
2294
2678
|
}
|
|
2295
2679
|
const button = document.createElement("Button");
|
|
2296
2680
|
button.innerHTML = `
|
|
2297
|
-
<h1>
|
|
2681
|
+
<h1>Compilation error in ${shaderTitle}</h1><br /><br />
|
|
2298
2682
|
<code style="user-select:text;"><pre>
|
|
2299
2683
|
${htmlLog}
|
|
2300
2684
|
</pre></code>`;
|
|
@@ -2332,38 +2716,6 @@ ${htmlLog}
|
|
|
2332
2716
|
return match ? match[1] : defaultName;
|
|
2333
2717
|
}
|
|
2334
2718
|
|
|
2335
|
-
// ../core/src/adapter/resources/sampler.ts
|
|
2336
|
-
var _Sampler = class extends Resource {
|
|
2337
|
-
get [Symbol.toStringTag]() {
|
|
2338
|
-
return "Sampler";
|
|
2339
|
-
}
|
|
2340
|
-
constructor(device, props) {
|
|
2341
|
-
props = _Sampler.normalizeProps(device, props);
|
|
2342
|
-
super(device, props, _Sampler.defaultProps);
|
|
2343
|
-
}
|
|
2344
|
-
static normalizeProps(device, props) {
|
|
2345
|
-
const overriddenDefaultProps = device?.props?._resourceDefaults?.sampler || {};
|
|
2346
|
-
const newProps = { ...props, ...overriddenDefaultProps };
|
|
2347
|
-
return newProps;
|
|
2348
|
-
}
|
|
2349
|
-
};
|
|
2350
|
-
var Sampler = _Sampler;
|
|
2351
|
-
__publicField(Sampler, "defaultProps", {
|
|
2352
|
-
...Resource.defaultProps,
|
|
2353
|
-
type: "color-sampler",
|
|
2354
|
-
addressModeU: "clamp-to-edge",
|
|
2355
|
-
addressModeV: "clamp-to-edge",
|
|
2356
|
-
addressModeW: "clamp-to-edge",
|
|
2357
|
-
magFilter: "nearest",
|
|
2358
|
-
minFilter: "nearest",
|
|
2359
|
-
mipmapFilter: "none",
|
|
2360
|
-
lodMinClamp: 0,
|
|
2361
|
-
lodMaxClamp: 32,
|
|
2362
|
-
// Per WebGPU spec
|
|
2363
|
-
compare: "less-equal",
|
|
2364
|
-
maxAnisotropy: 1
|
|
2365
|
-
});
|
|
2366
|
-
|
|
2367
2719
|
// ../core/src/adapter/resources/framebuffer.ts
|
|
2368
2720
|
var _Framebuffer = class extends Resource {
|
|
2369
2721
|
get [Symbol.toStringTag]() {
|
|
@@ -2453,8 +2805,7 @@ ${htmlLog}
|
|
|
2453
2805
|
usage: Texture.RENDER_ATTACHMENT,
|
|
2454
2806
|
format,
|
|
2455
2807
|
width: this.width,
|
|
2456
|
-
height: this.height
|
|
2457
|
-
mipmaps: false
|
|
2808
|
+
height: this.height
|
|
2458
2809
|
});
|
|
2459
2810
|
}
|
|
2460
2811
|
/**
|
|
@@ -2515,16 +2866,6 @@ ${htmlLog}
|
|
|
2515
2866
|
this.shaderLayout = this.props.shaderLayout;
|
|
2516
2867
|
this.bufferLayout = this.props.bufferLayout || [];
|
|
2517
2868
|
}
|
|
2518
|
-
// DEPRECATED METHODS
|
|
2519
|
-
/**
|
|
2520
|
-
* Uniforms
|
|
2521
|
-
* @deprecated Use uniforms buffers
|
|
2522
|
-
* @note textures, samplers and uniform buffers should be set via `setBindings()`, these are not considered uniforms.
|
|
2523
|
-
* @note In WebGL uniforms have a performance penalty, they are reset before each call to enable pipeline sharing.
|
|
2524
|
-
*/
|
|
2525
|
-
setUniformsWebGL(uniforms) {
|
|
2526
|
-
throw new Error("Use uniform blocks");
|
|
2527
|
-
}
|
|
2528
2869
|
};
|
|
2529
2870
|
var RenderPipeline = _RenderPipeline;
|
|
2530
2871
|
__publicField(RenderPipeline, "defaultProps", {
|
|
@@ -2538,10 +2879,9 @@ ${htmlLog}
|
|
|
2538
2879
|
shaderLayout: null,
|
|
2539
2880
|
bufferLayout: [],
|
|
2540
2881
|
topology: "triangle-list",
|
|
2882
|
+
colorAttachmentFormats: void 0,
|
|
2883
|
+
depthStencilAttachmentFormat: void 0,
|
|
2541
2884
|
parameters: {},
|
|
2542
|
-
// isInstanced: false,
|
|
2543
|
-
// instanceCount: 0,
|
|
2544
|
-
// vertexCount: 0,
|
|
2545
2885
|
bindings: {},
|
|
2546
2886
|
uniforms: {}
|
|
2547
2887
|
});
|
|
@@ -2556,9 +2896,7 @@ ${htmlLog}
|
|
|
2556
2896
|
super(device, props, _RenderPass.defaultProps);
|
|
2557
2897
|
}
|
|
2558
2898
|
static normalizeProps(device, props) {
|
|
2559
|
-
|
|
2560
|
-
const newProps = { ...overriddenDefaultProps, ...props };
|
|
2561
|
-
return newProps;
|
|
2899
|
+
return props;
|
|
2562
2900
|
}
|
|
2563
2901
|
};
|
|
2564
2902
|
var RenderPass = _RenderPass;
|
|
@@ -2610,12 +2948,12 @@ ${htmlLog}
|
|
|
2610
2948
|
|
|
2611
2949
|
// ../core/src/adapter/resources/compute-pass.ts
|
|
2612
2950
|
var _ComputePass = class extends Resource {
|
|
2613
|
-
get [Symbol.toStringTag]() {
|
|
2614
|
-
return "ComputePass";
|
|
2615
|
-
}
|
|
2616
2951
|
constructor(device, props) {
|
|
2617
2952
|
super(device, props, _ComputePass.defaultProps);
|
|
2618
2953
|
}
|
|
2954
|
+
get [Symbol.toStringTag]() {
|
|
2955
|
+
return "ComputePass";
|
|
2956
|
+
}
|
|
2619
2957
|
};
|
|
2620
2958
|
var ComputePass = _ComputePass;
|
|
2621
2959
|
__publicField(ComputePass, "defaultProps", {
|
|
@@ -2633,11 +2971,11 @@ ${htmlLog}
|
|
|
2633
2971
|
constructor(device, props) {
|
|
2634
2972
|
super(device, props, _CommandEncoder.defaultProps);
|
|
2635
2973
|
}
|
|
2636
|
-
// TODO - luma.gl has these on the device, should we align with WebGPU API?
|
|
2637
|
-
// beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
|
|
2638
|
-
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
2639
2974
|
};
|
|
2640
2975
|
var CommandEncoder = _CommandEncoder;
|
|
2976
|
+
// TODO - luma.gl has these on the device, should we align with WebGPU API?
|
|
2977
|
+
// beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
|
|
2978
|
+
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
2641
2979
|
__publicField(CommandEncoder, "defaultProps", {
|
|
2642
2980
|
...Resource.defaultProps,
|
|
2643
2981
|
measureExecutionTime: void 0
|
|
@@ -2657,42 +2995,31 @@ ${htmlLog}
|
|
|
2657
2995
|
...Resource.defaultProps
|
|
2658
2996
|
});
|
|
2659
2997
|
|
|
2660
|
-
// ../core/src/
|
|
2661
|
-
function
|
|
2662
|
-
const
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
const
|
|
2998
|
+
// ../core/src/shadertypes/data-types/decode-shader-types.ts
|
|
2999
|
+
function getVariableShaderTypeInfo(format) {
|
|
3000
|
+
const decoded = UNIFORM_FORMATS[format];
|
|
3001
|
+
return decoded;
|
|
3002
|
+
}
|
|
3003
|
+
function getAttributeShaderTypeInfo(attributeType) {
|
|
3004
|
+
const [primitiveType, components] = TYPE_INFO[attributeType];
|
|
3005
|
+
const integer = primitiveType === "i32" || primitiveType === "u32";
|
|
3006
|
+
const signed = primitiveType !== "u32";
|
|
3007
|
+
const byteLength = PRIMITIVE_TYPE_SIZES[primitiveType] * components;
|
|
2667
3008
|
return {
|
|
2668
|
-
|
|
3009
|
+
primitiveType,
|
|
2669
3010
|
components,
|
|
2670
|
-
defaultVertexFormat,
|
|
2671
3011
|
byteLength,
|
|
2672
3012
|
integer,
|
|
2673
3013
|
signed
|
|
2674
3014
|
};
|
|
2675
3015
|
}
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
vertexType = "sint32";
|
|
2684
|
-
break;
|
|
2685
|
-
case "u32":
|
|
2686
|
-
vertexType = "uint32";
|
|
2687
|
-
break;
|
|
2688
|
-
case "f16":
|
|
2689
|
-
return components <= 2 ? "float16x2" : "float16x4";
|
|
2690
|
-
}
|
|
2691
|
-
if (components === 1) {
|
|
2692
|
-
return vertexType;
|
|
2693
|
-
}
|
|
2694
|
-
return `${vertexType}x${components}`;
|
|
2695
|
-
}
|
|
3016
|
+
var PRIMITIVE_TYPE_SIZES = {
|
|
3017
|
+
f32: 4,
|
|
3018
|
+
f16: 2,
|
|
3019
|
+
i32: 4,
|
|
3020
|
+
u32: 4
|
|
3021
|
+
// 'bool-webgl': 4,
|
|
3022
|
+
};
|
|
2696
3023
|
var TYPE_INFO = {
|
|
2697
3024
|
f32: ["f32", 1],
|
|
2698
3025
|
"vec2<f32>": ["f32", 2],
|
|
@@ -2711,38 +3038,115 @@ ${htmlLog}
|
|
|
2711
3038
|
"vec3<u32>": ["u32", 3],
|
|
2712
3039
|
"vec4<u32>": ["u32", 4]
|
|
2713
3040
|
};
|
|
2714
|
-
var
|
|
2715
|
-
f32:
|
|
2716
|
-
f16:
|
|
2717
|
-
i32:
|
|
2718
|
-
u32:
|
|
2719
|
-
// 'bool-webgl':
|
|
3041
|
+
var UNIFORM_FORMATS = {
|
|
3042
|
+
f32: { type: "f32", components: 1 },
|
|
3043
|
+
f16: { type: "f16", components: 1 },
|
|
3044
|
+
i32: { type: "i32", components: 1 },
|
|
3045
|
+
u32: { type: "u32", components: 1 },
|
|
3046
|
+
// 'bool-webgl': {type: 'bool-webgl', components: 1},
|
|
3047
|
+
"vec2<f32>": { type: "f32", components: 2 },
|
|
3048
|
+
"vec3<f32>": { type: "f32", components: 3 },
|
|
3049
|
+
"vec4<f32>": { type: "f32", components: 4 },
|
|
3050
|
+
"vec2<f16>": { type: "f16", components: 2 },
|
|
3051
|
+
"vec3<f16>": { type: "f16", components: 3 },
|
|
3052
|
+
"vec4<f16>": { type: "f16", components: 4 },
|
|
3053
|
+
"vec2<i32>": { type: "i32", components: 2 },
|
|
3054
|
+
"vec3<i32>": { type: "i32", components: 3 },
|
|
3055
|
+
"vec4<i32>": { type: "i32", components: 4 },
|
|
3056
|
+
"vec2<u32>": { type: "u32", components: 2 },
|
|
3057
|
+
"vec3<u32>": { type: "u32", components: 3 },
|
|
3058
|
+
"vec4<u32>": { type: "u32", components: 4 },
|
|
3059
|
+
"mat2x2<f32>": { type: "f32", components: 4 },
|
|
3060
|
+
"mat2x3<f32>": { type: "f32", components: 6 },
|
|
3061
|
+
"mat2x4<f32>": { type: "f32", components: 8 },
|
|
3062
|
+
"mat3x2<f32>": { type: "f32", components: 6 },
|
|
3063
|
+
"mat3x3<f32>": { type: "f32", components: 9 },
|
|
3064
|
+
"mat3x4<f32>": { type: "f32", components: 12 },
|
|
3065
|
+
"mat4x2<f32>": { type: "f32", components: 8 },
|
|
3066
|
+
"mat4x3<f32>": { type: "f32", components: 12 },
|
|
3067
|
+
"mat4x4<f32>": { type: "f32", components: 16 },
|
|
3068
|
+
"mat2x2<f16>": { type: "f16", components: 4 },
|
|
3069
|
+
"mat2x3<f16>": { type: "f16", components: 6 },
|
|
3070
|
+
"mat2x4<f16>": { type: "f16", components: 8 },
|
|
3071
|
+
"mat3x2<f16>": { type: "f16", components: 6 },
|
|
3072
|
+
"mat3x3<f16>": { type: "f16", components: 9 },
|
|
3073
|
+
"mat3x4<f16>": { type: "f16", components: 12 },
|
|
3074
|
+
"mat4x2<f16>": { type: "f16", components: 8 },
|
|
3075
|
+
"mat4x3<f16>": { type: "f16", components: 12 },
|
|
3076
|
+
"mat4x4<f16>": { type: "f16", components: 16 },
|
|
3077
|
+
"mat2x2<i32>": { type: "i32", components: 4 },
|
|
3078
|
+
"mat2x3<i32>": { type: "i32", components: 6 },
|
|
3079
|
+
"mat2x4<i32>": { type: "i32", components: 8 },
|
|
3080
|
+
"mat3x2<i32>": { type: "i32", components: 6 },
|
|
3081
|
+
"mat3x3<i32>": { type: "i32", components: 9 },
|
|
3082
|
+
"mat3x4<i32>": { type: "i32", components: 12 },
|
|
3083
|
+
"mat4x2<i32>": { type: "i32", components: 8 },
|
|
3084
|
+
"mat4x3<i32>": { type: "i32", components: 12 },
|
|
3085
|
+
"mat4x4<i32>": { type: "i32", components: 16 },
|
|
3086
|
+
"mat2x2<u32>": { type: "u32", components: 4 },
|
|
3087
|
+
"mat2x3<u32>": { type: "u32", components: 6 },
|
|
3088
|
+
"mat2x4<u32>": { type: "u32", components: 8 },
|
|
3089
|
+
"mat3x2<u32>": { type: "u32", components: 6 },
|
|
3090
|
+
"mat3x3<u32>": { type: "u32", components: 9 },
|
|
3091
|
+
"mat3x4<u32>": { type: "u32", components: 12 },
|
|
3092
|
+
"mat4x2<u32>": { type: "u32", components: 8 },
|
|
3093
|
+
"mat4x3<u32>": { type: "u32", components: 12 },
|
|
3094
|
+
"mat4x4<u32>": { type: "u32", components: 16 }
|
|
3095
|
+
};
|
|
3096
|
+
var WGSL_ATTRIBUTE_TYPE_ALIAS_MAP = {
|
|
3097
|
+
vec2i: "vec2<i32>",
|
|
3098
|
+
vec3i: "vec3<i32>",
|
|
3099
|
+
vec4i: "vec4<i32>",
|
|
3100
|
+
vec2u: "vec2<u32>",
|
|
3101
|
+
vec3u: "vec3<u32>",
|
|
3102
|
+
vec4u: "vec4<u32>",
|
|
3103
|
+
vec2f: "vec2<f32>",
|
|
3104
|
+
vec3f: "vec3<f32>",
|
|
3105
|
+
vec4f: "vec4<f32>",
|
|
3106
|
+
// Requires the f16 extension.
|
|
3107
|
+
vec2h: "vec2<f16>",
|
|
3108
|
+
vec3h: "vec3<f16>",
|
|
3109
|
+
vec4h: "vec4<f16>"
|
|
3110
|
+
};
|
|
3111
|
+
var WGSL_VARIABLE_TYPE_ALIAS_MAP = {
|
|
3112
|
+
...WGSL_ATTRIBUTE_TYPE_ALIAS_MAP,
|
|
3113
|
+
mat2x2f: "mat2x2<f32>",
|
|
3114
|
+
mat2x3f: "mat2x3<f32>",
|
|
3115
|
+
mat2x4f: "mat2x4<f32>",
|
|
3116
|
+
mat3x2f: "mat3x2<f32>",
|
|
3117
|
+
mat3x3f: "mat3x3<f32>",
|
|
3118
|
+
mat3x4f: "mat3x4<f32>",
|
|
3119
|
+
mat4x2f: "mat4x2<f32>",
|
|
3120
|
+
mat4x3f: "mat4x3<f32>",
|
|
3121
|
+
mat4x4f: "mat4x4<f32>",
|
|
3122
|
+
mat2x2i: "mat2x2<i32>",
|
|
3123
|
+
mat2x3i: "mat2x3<i32>",
|
|
3124
|
+
mat2x4i: "mat2x4<i32>",
|
|
3125
|
+
mat3x2i: "mat3x2<i32>",
|
|
3126
|
+
mat3x3i: "mat3x3<i32>",
|
|
3127
|
+
mat3x4i: "mat3x4<i32>",
|
|
3128
|
+
mat4x2i: "mat4x2<i32>",
|
|
3129
|
+
mat4x3i: "mat4x3<i32>",
|
|
3130
|
+
mat4x4i: "mat4x4<i32>",
|
|
3131
|
+
mat2x2u: "mat2x2<u32>",
|
|
3132
|
+
mat2x3u: "mat2x3<u32>",
|
|
3133
|
+
mat2x4u: "mat2x4<u32>",
|
|
3134
|
+
mat3x2u: "mat3x2<u32>",
|
|
3135
|
+
mat3x3u: "mat3x3<u32>",
|
|
3136
|
+
mat3x4u: "mat3x4<u32>",
|
|
3137
|
+
mat4x2u: "mat4x2<u32>",
|
|
3138
|
+
mat4x3u: "mat4x3<u32>",
|
|
3139
|
+
mat4x4u: "mat4x4<u32>",
|
|
3140
|
+
mat2x2h: "mat2x2<f16>",
|
|
3141
|
+
mat2x3h: "mat2x3<f16>",
|
|
3142
|
+
mat2x4h: "mat2x4<f16>",
|
|
3143
|
+
mat3x2h: "mat3x2<f16>",
|
|
3144
|
+
mat3x3h: "mat3x3<f16>",
|
|
3145
|
+
mat3x4h: "mat3x4<f16>",
|
|
3146
|
+
mat4x2h: "mat4x2<f16>",
|
|
3147
|
+
mat4x3h: "mat4x3<f16>",
|
|
3148
|
+
mat4x4h: "mat4x4<f16>"
|
|
2720
3149
|
};
|
|
2721
|
-
|
|
2722
|
-
// ../core/src/gpu-type-utils/decode-vertex-format.ts
|
|
2723
|
-
function decodeVertexFormat(format) {
|
|
2724
|
-
let webglOnly;
|
|
2725
|
-
if (format.endsWith("-webgl")) {
|
|
2726
|
-
format.replace("-webgl", "");
|
|
2727
|
-
webglOnly = true;
|
|
2728
|
-
}
|
|
2729
|
-
const [type_, count] = format.split("x");
|
|
2730
|
-
const type = type_;
|
|
2731
|
-
const components = count ? parseInt(count) : 1;
|
|
2732
|
-
const decodedType = decodeVertexType(type);
|
|
2733
|
-
const result = {
|
|
2734
|
-
type,
|
|
2735
|
-
components,
|
|
2736
|
-
byteLength: decodedType.byteLength * components,
|
|
2737
|
-
integer: decodedType.integer,
|
|
2738
|
-
signed: decodedType.signed,
|
|
2739
|
-
normalized: decodedType.normalized
|
|
2740
|
-
};
|
|
2741
|
-
if (webglOnly) {
|
|
2742
|
-
result.webglOnly = true;
|
|
2743
|
-
}
|
|
2744
|
-
return result;
|
|
2745
|
-
}
|
|
2746
3150
|
|
|
2747
3151
|
// ../core/src/adapter-utils/get-attribute-from-layouts.ts
|
|
2748
3152
|
function getAttributeInfosFromLayouts(shaderLayout, bufferLayout) {
|
|
@@ -2772,15 +3176,16 @@ ${htmlLog}
|
|
|
2772
3176
|
if (!shaderDeclaration) {
|
|
2773
3177
|
return null;
|
|
2774
3178
|
}
|
|
2775
|
-
const attributeTypeInfo =
|
|
2776
|
-
const
|
|
2777
|
-
const
|
|
3179
|
+
const attributeTypeInfo = getAttributeShaderTypeInfo(shaderDeclaration.type);
|
|
3180
|
+
const defaultVertexFormat = getCompatibleVertexFormat(attributeTypeInfo);
|
|
3181
|
+
const vertexFormat = bufferMapping?.vertexFormat || defaultVertexFormat;
|
|
3182
|
+
const vertexFormatInfo = getVertexFormatInfo(vertexFormat);
|
|
2778
3183
|
return {
|
|
2779
3184
|
attributeName: bufferMapping?.attributeName || shaderDeclaration.name,
|
|
2780
3185
|
bufferName: bufferMapping?.bufferName || shaderDeclaration.name,
|
|
2781
3186
|
location: shaderDeclaration.location,
|
|
2782
3187
|
shaderType: shaderDeclaration.type,
|
|
2783
|
-
|
|
3188
|
+
primitiveType: attributeTypeInfo.primitiveType,
|
|
2784
3189
|
shaderComponents: attributeTypeInfo.components,
|
|
2785
3190
|
vertexFormat,
|
|
2786
3191
|
bufferDataType: vertexFormatInfo.type,
|
|
@@ -2842,7 +3247,7 @@ ${htmlLog}
|
|
|
2842
3247
|
let byteStride = bufferLayout.byteStride;
|
|
2843
3248
|
if (typeof bufferLayout.byteStride !== "number") {
|
|
2844
3249
|
for (const attributeMapping2 of bufferLayout.attributes || []) {
|
|
2845
|
-
const info =
|
|
3250
|
+
const info = getVertexFormatInfo(attributeMapping2.format);
|
|
2846
3251
|
byteStride += info.byteLength;
|
|
2847
3252
|
}
|
|
2848
3253
|
}
|
|
@@ -2879,26 +3284,23 @@ ${htmlLog}
|
|
|
2879
3284
|
super(device, props, _VertexArray.defaultProps);
|
|
2880
3285
|
this.maxVertexAttributes = device.limits.maxVertexAttributes;
|
|
2881
3286
|
this.attributes = new Array(this.maxVertexAttributes).fill(null);
|
|
2882
|
-
const { shaderLayout, bufferLayout } = props.renderPipeline || {};
|
|
2883
|
-
if (!shaderLayout || !bufferLayout) {
|
|
2884
|
-
throw new Error("VertexArray");
|
|
2885
|
-
}
|
|
2886
3287
|
this.attributeInfos = getAttributeInfosByLocation(
|
|
2887
|
-
shaderLayout,
|
|
2888
|
-
bufferLayout,
|
|
3288
|
+
props.shaderLayout,
|
|
3289
|
+
props.bufferLayout,
|
|
2889
3290
|
this.maxVertexAttributes
|
|
2890
3291
|
);
|
|
2891
3292
|
}
|
|
2892
3293
|
// DEPRECATED METHODS
|
|
2893
3294
|
/** @deprecated Set constant attributes (WebGL only) */
|
|
2894
3295
|
setConstantWebGL(location, value) {
|
|
2895
|
-
this.device.reportError(new Error("constant attributes not supported"));
|
|
3296
|
+
this.device.reportError(new Error("constant attributes not supported"), this)();
|
|
2896
3297
|
}
|
|
2897
3298
|
};
|
|
2898
3299
|
var VertexArray = _VertexArray;
|
|
2899
3300
|
__publicField(VertexArray, "defaultProps", {
|
|
2900
3301
|
...Resource.defaultProps,
|
|
2901
|
-
|
|
3302
|
+
shaderLayout: void 0,
|
|
3303
|
+
bufferLayout: []
|
|
2902
3304
|
});
|
|
2903
3305
|
|
|
2904
3306
|
// ../core/src/adapter/resources/transform-feedback.ts
|
|
@@ -2951,46 +3353,6 @@ ${htmlLog}
|
|
|
2951
3353
|
}
|
|
2952
3354
|
});
|
|
2953
3355
|
|
|
2954
|
-
// ../core/src/gpu-type-utils/decode-shader-types.ts
|
|
2955
|
-
var UNIFORM_FORMATS = {
|
|
2956
|
-
f32: { type: "f32", components: 1 },
|
|
2957
|
-
i32: { type: "i32", components: 1 },
|
|
2958
|
-
u32: { type: "u32", components: 1 },
|
|
2959
|
-
// 'bool-webgl': {type: 'bool-webgl', components: 1},
|
|
2960
|
-
"vec2<f32>": { type: "f32", components: 2 },
|
|
2961
|
-
"vec3<f32>": { type: "f32", components: 3 },
|
|
2962
|
-
"vec4<f32>": { type: "f32", components: 4 },
|
|
2963
|
-
"vec2<i32>": { type: "i32", components: 2 },
|
|
2964
|
-
"vec3<i32>": { type: "i32", components: 3 },
|
|
2965
|
-
"vec4<i32>": { type: "i32", components: 4 },
|
|
2966
|
-
"vec2<u32>": { type: "u32", components: 2 },
|
|
2967
|
-
"vec3<u32>": { type: "u32", components: 3 },
|
|
2968
|
-
"vec4<u32>": { type: "u32", components: 4 },
|
|
2969
|
-
"mat2x2<f32>": { type: "f32", components: 4 },
|
|
2970
|
-
"mat2x3<f32>": { type: "f32", components: 6 },
|
|
2971
|
-
"mat2x4<f32>": { type: "f32", components: 8 },
|
|
2972
|
-
"mat3x2<f32>": { type: "f32", components: 6 },
|
|
2973
|
-
"mat3x3<f32>": { type: "f32", components: 9 },
|
|
2974
|
-
"mat3x4<f32>": { type: "f32", components: 12 },
|
|
2975
|
-
"mat4x2<f32>": { type: "f32", components: 8 },
|
|
2976
|
-
"mat4x3<f32>": { type: "f32", components: 12 },
|
|
2977
|
-
"mat4x4<f32>": { type: "f32", components: 16 }
|
|
2978
|
-
};
|
|
2979
|
-
function decodeShaderUniformType(format) {
|
|
2980
|
-
const decoded = UNIFORM_FORMATS[format];
|
|
2981
|
-
return decoded;
|
|
2982
|
-
}
|
|
2983
|
-
function alignTo(size, count) {
|
|
2984
|
-
switch (count) {
|
|
2985
|
-
case 1:
|
|
2986
|
-
return size;
|
|
2987
|
-
case 2:
|
|
2988
|
-
return size + size % 2;
|
|
2989
|
-
default:
|
|
2990
|
-
return size + (4 - size % 4) % 4;
|
|
2991
|
-
}
|
|
2992
|
-
}
|
|
2993
|
-
|
|
2994
3356
|
// ../core/src/utils/array-utils-flat.ts
|
|
2995
3357
|
var arrayBuffer;
|
|
2996
3358
|
function getScratchArrayBuffer(byteLength) {
|
|
@@ -3025,7 +3387,7 @@ ${htmlLog}
|
|
|
3025
3387
|
constructor(uniformTypes) {
|
|
3026
3388
|
let size = 0;
|
|
3027
3389
|
for (const [key, uniformType] of Object.entries(uniformTypes)) {
|
|
3028
|
-
const typeAndComponents =
|
|
3390
|
+
const typeAndComponents = getVariableShaderTypeInfo(uniformType);
|
|
3029
3391
|
const { type, components: count } = typeAndComponents;
|
|
3030
3392
|
size = alignTo(size, count);
|
|
3031
3393
|
const offset = size;
|
|
@@ -3274,137 +3636,86 @@ ${htmlLog}
|
|
|
3274
3636
|
}
|
|
3275
3637
|
};
|
|
3276
3638
|
|
|
3277
|
-
// ../core/src/
|
|
3278
|
-
function
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
return
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
}
|
|
3328
|
-
const components = size;
|
|
3329
|
-
let dataType = getDataTypeFromTypedArray(typedArray);
|
|
3330
|
-
if (dataType === "uint8" && normalized && components === 1) {
|
|
3331
|
-
return "unorm8-webgl";
|
|
3332
|
-
}
|
|
3333
|
-
if (dataType === "uint8" && normalized && components === 3) {
|
|
3334
|
-
return "unorm8x3-webgl";
|
|
3335
|
-
}
|
|
3336
|
-
if (dataType === "uint8" || dataType === "sint8") {
|
|
3337
|
-
if (components === 1 || components === 3) {
|
|
3338
|
-
throw new Error(`size: ${size}`);
|
|
3339
|
-
}
|
|
3340
|
-
if (normalized) {
|
|
3341
|
-
dataType = dataType.replace("int", "norm");
|
|
3342
|
-
}
|
|
3343
|
-
return `${dataType}x${components}`;
|
|
3344
|
-
}
|
|
3345
|
-
if (dataType === "uint16" || dataType === "sint16") {
|
|
3346
|
-
if (components === 1 || components === 3) {
|
|
3347
|
-
throw new Error(`size: ${size}`);
|
|
3348
|
-
}
|
|
3349
|
-
if (normalized) {
|
|
3350
|
-
dataType = dataType.replace("int", "norm");
|
|
3351
|
-
}
|
|
3352
|
-
return `${dataType}x${components}`;
|
|
3353
|
-
}
|
|
3354
|
-
if (components === 1) {
|
|
3355
|
-
return dataType;
|
|
3639
|
+
// ../core/src/shadertypes/textures/pixel-utils.ts
|
|
3640
|
+
function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
3641
|
+
if (x < 0 || x >= pixelData.width || y < 0 || y >= pixelData.height) {
|
|
3642
|
+
throw new Error("Coordinates out of bounds.");
|
|
3643
|
+
}
|
|
3644
|
+
const byteOffset = y * pixelData.bytesPerRow + x * pixelData.bytesPerPixel;
|
|
3645
|
+
const pixelDataView = new DataView(pixelData.arrayBuffer, byteOffset, pixelData.bytesPerPixel);
|
|
3646
|
+
let bitOffsetWithinPixel = 0;
|
|
3647
|
+
const channels = [];
|
|
3648
|
+
for (let i = 0; i < 4; i++) {
|
|
3649
|
+
const bits = bitsPerChannel[i];
|
|
3650
|
+
if (bits <= 0) {
|
|
3651
|
+
channels.push(0);
|
|
3652
|
+
} else {
|
|
3653
|
+
const channelValue = readBitsFromDataView(pixelDataView, bitOffsetWithinPixel, bits);
|
|
3654
|
+
channels.push(channelValue);
|
|
3655
|
+
bitOffsetWithinPixel += bits;
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
return [channels[0], channels[1], channels[2], channels[3]];
|
|
3659
|
+
}
|
|
3660
|
+
function writePixel(dataView, bitOffset, bitsPerChannel, pixel) {
|
|
3661
|
+
let currentBitOffset = bitOffset;
|
|
3662
|
+
for (let channel = 0; channel < 4; channel++) {
|
|
3663
|
+
const bits = bitsPerChannel[channel];
|
|
3664
|
+
const maxValue = (1 << bits) - 1;
|
|
3665
|
+
const channelValue = pixel[channel] & maxValue;
|
|
3666
|
+
writeBitsToDataView(dataView, currentBitOffset, bits, channelValue);
|
|
3667
|
+
currentBitOffset += bits;
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3670
|
+
function readBitsFromDataView(dataView, bitOffset, bitCount) {
|
|
3671
|
+
if (bitOffset % 8 === 0) {
|
|
3672
|
+
const byteOffset = bitOffset / 8;
|
|
3673
|
+
if (bitCount === 8 && byteOffset + 1 <= dataView.byteLength) {
|
|
3674
|
+
return dataView.getUint8(byteOffset);
|
|
3675
|
+
} else if (bitCount === 16 && byteOffset + 2 <= dataView.byteLength) {
|
|
3676
|
+
return dataView.getUint16(byteOffset, false);
|
|
3677
|
+
} else if (bitCount === 32 && byteOffset + 4 <= dataView.byteLength) {
|
|
3678
|
+
return dataView.getUint32(byteOffset, false);
|
|
3679
|
+
}
|
|
3680
|
+
}
|
|
3681
|
+
let value = 0;
|
|
3682
|
+
for (let i = 0; i < bitCount; i++) {
|
|
3683
|
+
const overallBitIndex = bitOffset + i;
|
|
3684
|
+
const byteIndex = Math.floor(overallBitIndex / 8);
|
|
3685
|
+
const bitIndex = overallBitIndex % 8;
|
|
3686
|
+
const byteValue = dataView.getUint8(byteIndex);
|
|
3687
|
+
const bit = byteValue >> 7 - bitIndex & 1;
|
|
3688
|
+
value = value << 1 | bit;
|
|
3356
3689
|
}
|
|
3357
|
-
return
|
|
3690
|
+
return value;
|
|
3358
3691
|
}
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
return bufferLayout.attributes ? bufferLayout.attributes?.map((layout) => layout.attribute) : [bufferLayout.name];
|
|
3372
|
-
}
|
|
3373
|
-
mergeBufferLayouts(bufferLayouts1, bufferLayouts2) {
|
|
3374
|
-
const mergedLayouts = [...bufferLayouts1];
|
|
3375
|
-
for (const attribute of bufferLayouts2) {
|
|
3376
|
-
const index = mergedLayouts.findIndex((attribute2) => attribute2.name === attribute.name);
|
|
3377
|
-
if (index < 0) {
|
|
3378
|
-
mergedLayouts.push(attribute);
|
|
3379
|
-
} else {
|
|
3380
|
-
mergedLayouts[index] = attribute;
|
|
3381
|
-
}
|
|
3692
|
+
function writeBitsToDataView(dataView, bitOffset, bitCount, value) {
|
|
3693
|
+
if (bitOffset % 8 === 0) {
|
|
3694
|
+
const byteOffset = bitOffset / 8;
|
|
3695
|
+
if (bitCount === 8 && byteOffset + 1 <= dataView.byteLength) {
|
|
3696
|
+
dataView.setUint8(byteOffset, value & 255);
|
|
3697
|
+
return;
|
|
3698
|
+
} else if (bitCount === 16 && byteOffset + 2 <= dataView.byteLength) {
|
|
3699
|
+
dataView.setUint16(byteOffset, value & 65535, false);
|
|
3700
|
+
return;
|
|
3701
|
+
} else if (bitCount === 32 && byteOffset + 4 <= dataView.byteLength) {
|
|
3702
|
+
dataView.setUint32(byteOffset, value, false);
|
|
3703
|
+
return;
|
|
3382
3704
|
}
|
|
3383
|
-
return mergedLayouts;
|
|
3384
3705
|
}
|
|
3385
|
-
|
|
3386
|
-
const
|
|
3387
|
-
|
|
3388
|
-
|
|
3706
|
+
for (let i = 0; i < bitCount; i++) {
|
|
3707
|
+
const overallBitIndex = bitOffset + i;
|
|
3708
|
+
const byteIndex = Math.floor(overallBitIndex / 8);
|
|
3709
|
+
const bitIndex = overallBitIndex % 8;
|
|
3710
|
+
const mask = 1 << 7 - bitIndex;
|
|
3711
|
+
const bitValue = value >> bitCount - 1 - i & 1;
|
|
3712
|
+
let currentByte = dataView.getUint8(byteIndex);
|
|
3713
|
+
currentByte &= ~mask;
|
|
3714
|
+
if (bitValue) {
|
|
3715
|
+
currentByte |= mask;
|
|
3389
3716
|
}
|
|
3390
|
-
|
|
3717
|
+
dataView.setUint8(byteIndex, currentByte);
|
|
3391
3718
|
}
|
|
3392
|
-
};
|
|
3393
|
-
|
|
3394
|
-
// ../core/src/adapter-utils/buffer-layout-order.ts
|
|
3395
|
-
function sortedBufferLayoutByShaderSourceLocations(shaderLayout, bufferLayout) {
|
|
3396
|
-
const shaderLayoutMap = Object.fromEntries(
|
|
3397
|
-
shaderLayout.attributes.map((attr) => [attr.name, attr.location])
|
|
3398
|
-
);
|
|
3399
|
-
const sortedLayout = bufferLayout.slice();
|
|
3400
|
-
sortedLayout.sort((a, b) => {
|
|
3401
|
-
const attributeNamesA = a.attributes ? a.attributes.map((attr) => attr.attribute) : [a.name];
|
|
3402
|
-
const attributeNamesB = b.attributes ? b.attributes.map((attr) => attr.attribute) : [b.name];
|
|
3403
|
-
const minLocationA = Math.min(...attributeNamesA.map((name2) => shaderLayoutMap[name2]));
|
|
3404
|
-
const minLocationB = Math.min(...attributeNamesB.map((name2) => shaderLayoutMap[name2]));
|
|
3405
|
-
return minLocationA - minLocationB;
|
|
3406
|
-
});
|
|
3407
|
-
return sortedLayout;
|
|
3408
3719
|
}
|
|
3409
3720
|
|
|
3410
3721
|
// bundle.ts
|