@luma.gl/engine 9.1.0-beta.8 → 9.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +5 -0
  2. package/dist/animation-loop/animation-loop.d.ts +11 -11
  3. package/dist/animation-loop/animation-loop.d.ts.map +1 -1
  4. package/dist/animation-loop/animation-loop.js +25 -49
  5. package/dist/animation-loop/animation-loop.js.map +1 -1
  6. package/dist/animation-loop/animation-props.d.ts +3 -4
  7. package/dist/animation-loop/animation-props.d.ts.map +1 -1
  8. package/dist/async-texture/async-texture.d.ts +106 -2
  9. package/dist/async-texture/async-texture.d.ts.map +1 -1
  10. package/dist/async-texture/async-texture.js +278 -5
  11. package/dist/async-texture/async-texture.js.map +1 -1
  12. package/dist/compute/computation.d.ts +1 -1
  13. package/dist/compute/computation.d.ts.map +1 -1
  14. package/dist/compute/swap.d.ts.map +1 -1
  15. package/dist/compute/swap.js +6 -2
  16. package/dist/compute/swap.js.map +1 -1
  17. package/dist/compute/texture-transform.d.ts.map +1 -1
  18. package/dist/compute/texture-transform.js +1 -0
  19. package/dist/compute/texture-transform.js.map +1 -1
  20. package/dist/debug/copy-texture-to-image.d.ts +23 -1
  21. package/dist/debug/copy-texture-to-image.d.ts.map +1 -1
  22. package/dist/debug/copy-texture-to-image.js +37 -1
  23. package/dist/debug/copy-texture-to-image.js.map +1 -1
  24. package/dist/dist.dev.js +316 -153
  25. package/dist/dist.min.js +23 -23
  26. package/dist/index.cjs +334 -172
  27. package/dist/index.cjs.map +4 -4
  28. package/dist/index.d.ts +1 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/model/model.d.ts +4 -19
  32. package/dist/model/model.d.ts.map +1 -1
  33. package/dist/model/model.js +1 -44
  34. package/dist/model/model.js.map +1 -1
  35. package/dist/models/billboard-texture-model.d.ts.map +1 -1
  36. package/dist/models/billboard-texture-model.js +6 -4
  37. package/dist/models/billboard-texture-model.js.map +1 -1
  38. package/dist/modules/picking/legacy-picking-manager.d.ts +1 -1
  39. package/dist/modules/picking/legacy-picking-manager.d.ts.map +1 -1
  40. package/dist/modules/picking/legacy-picking-manager.js +1 -1
  41. package/dist/modules/picking/legacy-picking-manager.js.map +1 -1
  42. package/dist/modules/picking/picking-manager.d.ts +1 -1
  43. package/dist/modules/picking/picking-manager.d.ts.map +1 -1
  44. package/dist/modules/picking/picking-manager.js +1 -1
  45. package/dist/modules/picking/picking-manager.js.map +1 -1
  46. package/dist/passes/get-fragment-shader.js +2 -2
  47. package/dist/passes/shader-pass-renderer.d.ts +4 -4
  48. package/dist/passes/shader-pass-renderer.d.ts.map +1 -1
  49. package/dist/passes/shader-pass-renderer.js +15 -5
  50. package/dist/passes/shader-pass-renderer.js.map +1 -1
  51. package/dist/shader-inputs.js +1 -1
  52. package/dist/shader-inputs.js.map +1 -1
  53. package/package.json +4 -4
  54. package/src/animation-loop/animation-loop.ts +30 -58
  55. package/src/animation-loop/animation-props.ts +3 -5
  56. package/src/async-texture/async-texture.ts +382 -16
  57. package/src/async-texture/texture-setters.ts.disabled +296 -0
  58. package/src/compute/computation.ts +1 -1
  59. package/src/compute/swap.ts +7 -2
  60. package/src/compute/texture-transform.ts +1 -0
  61. package/src/debug/copy-texture-to-image.ts +52 -2
  62. package/src/index.ts +12 -0
  63. package/src/model/model.ts +4 -55
  64. package/src/models/billboard-texture-model.ts +6 -4
  65. package/src/modules/picking/legacy-picking-manager.ts +2 -2
  66. package/src/modules/picking/picking-manager.ts +2 -2
  67. package/src/passes/get-fragment-shader.ts +2 -2
  68. package/src/passes/shader-pass-renderer.ts +18 -8
  69. package/src/shader-inputs.ts +1 -1
@@ -0,0 +1,296 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {Texture, TypedArray, TextureFormat, ExternalImage} from '@luma.gl/core';
6
+ import {isExternalImage, getExternalImageSize} from '@luma.gl/core';
7
+
8
+ /** Names of cube texture faces */
9
+ export type TextureCubeFace = '+X' | '-X' | '+Y' | '-Y' | '+Z' | '-Z';
10
+
11
+ /**
12
+ * One mip level
13
+ * Basic data structure is similar to `ImageData`
14
+ * additional optional fields can describe compressed texture data.
15
+ */
16
+ export type TextureLevelData = {
17
+ /** WebGPU style format string. Defaults to 'rgba8unorm' */
18
+ format?: TextureFormat;
19
+ data: TypedArray;
20
+ width: number;
21
+ height: number;
22
+
23
+ compressed?: boolean;
24
+ byteLength?: number;
25
+ hasAlpha?: boolean;
26
+ };
27
+
28
+ export type TextureLevelSource = TextureLevelData | ExternalImage;
29
+
30
+ /** Texture data can be one or more mip levels */
31
+ export type TextureData = TextureLevelData | ExternalImage | (TextureLevelData | ExternalImage)[];
32
+
33
+ /** @todo - define what data type is supported for 1D textures */
34
+ export type Texture1DData = TypedArray | TextureLevelData;
35
+
36
+ /** Texture data can be one or more mip levels */
37
+ export type Texture2DData =
38
+ | TypedArray
39
+ | TextureLevelData
40
+ | ExternalImage
41
+ | (TextureLevelData | ExternalImage)[];
42
+
43
+ /** Array of textures */
44
+ export type Texture3DData = TypedArray | TextureData[];
45
+
46
+ /** 6 face textures */
47
+ export type TextureCubeData = Record<TextureCubeFace, Texture2DData>;
48
+
49
+ /** Array of textures */
50
+ export type TextureArrayData = TextureData[];
51
+
52
+ /** Array of 6 face textures */
53
+ export type TextureCubeArrayData = Record<TextureCubeFace, TextureData>[];
54
+
55
+ export type TextureDataProps =
56
+ | Texture1DProps
57
+ | Texture2DProps
58
+ | Texture3DProps
59
+ | TextureArrayProps
60
+ | TextureCubeProps
61
+ | TextureCubeArrayProps;
62
+
63
+ export type Texture1DProps = {dimension: '1d'; data?: Texture1DData | null};
64
+ export type Texture2DProps = {dimension?: '2d'; data?: Texture2DData | null};
65
+ export type Texture3DProps = {dimension: '3d'; data?: Texture3DData | null};
66
+ export type TextureArrayProps = {dimension: '2d-array'; data?: TextureArrayData | null};
67
+ export type TextureCubeProps = {dimension: 'cube'; data?: TextureCubeData | null};
68
+ export type TextureCubeArrayProps = {dimension: 'cube-array'; data: TextureCubeArrayData | null};
69
+
70
+ export const CubeFaces: TextureCubeFace[] = ['+X', '-X', '+Y', '-Y', '+Z', '-Z'];
71
+
72
+ /** Check if texture data is a typed array */
73
+ export function isTextureLevelData(data: TextureData): data is TextureLevelData {
74
+ const typedArray = (data as TextureLevelData)?.data;
75
+ return ArrayBuffer.isView(typedArray);
76
+ }
77
+
78
+ /** Get the size of the texture described by the provided TextureData */
79
+ export function getTextureDataSize(
80
+ data: TextureData | TextureCubeData | TextureArrayData | TextureCubeArrayData | TypedArray
81
+ ): {width: number; height: number} | null {
82
+ if (!data) {
83
+ return null;
84
+ }
85
+ if (ArrayBuffer.isView(data)) {
86
+ return null;
87
+ }
88
+ // Recurse into arrays (array of miplevels)
89
+ if (Array.isArray(data)) {
90
+ return getTextureDataSize(data[0]);
91
+ }
92
+ if (isExternalImage(data)) {
93
+ return getExternalImageSize(data);
94
+ }
95
+ if (data && typeof data === 'object' && data.constructor === Object) {
96
+ const textureDataArray = Object.values(data) as Texture2DData[];
97
+ const untypedData = textureDataArray[0] as any;
98
+ return {width: untypedData.width, height: untypedData.height};
99
+ }
100
+ throw new Error('texture size deduction failed');
101
+ }
102
+
103
+ /**
104
+ * Normalize TextureData to an array of TextureLevelData / ExternalImages
105
+ * @param data
106
+ * @param options
107
+ * @returns array of TextureLevelData / ExternalImages
108
+ */
109
+ export function normalizeTextureData(
110
+ data: Texture2DData,
111
+ options: {width: number; height: number; depth: number}
112
+ ): (TextureLevelData | ExternalImage)[] {
113
+ let lodArray: (TextureLevelData | ExternalImage)[];
114
+ if (ArrayBuffer.isView(data)) {
115
+ lodArray = [
116
+ {
117
+ // ts-expect-error does data really need to be Uint8ClampedArray?
118
+ data,
119
+ width: options.width,
120
+ height: options.height
121
+ // depth: options.depth
122
+ }
123
+ ];
124
+ } else if (!Array.isArray(data)) {
125
+ lodArray = [data];
126
+ } else {
127
+ lodArray = data;
128
+ }
129
+ return lodArray;
130
+ }
131
+
132
+ /** Convert luma.gl cubemap face constants to depth index */
133
+ export function getCubeFaceDepth(face: TextureCubeFace): number {
134
+ // prettier-ignore
135
+ switch (face) {
136
+ case '+X': return 0;
137
+ case '-X': return 1;
138
+ case '+Y': return 2;
139
+ case '-Y': return 3;
140
+ case '+Z': return 4;
141
+ case '-Z': return 5;
142
+ default: throw new Error(face);
143
+ }
144
+ }
145
+
146
+ // EXPERIMENTAL
147
+
148
+ /** Set multiple mip levels */
149
+ export function setTexture1DData(texture: Texture, data: Texture1DData): void {
150
+ throw new Error('setTexture1DData not supported in WebGL.');
151
+ }
152
+
153
+ /** Set multiple mip levels */
154
+ export function setTexture2DData(texture: Texture, lodData: Texture2DData, depth = 0): void {
155
+ this.bind();
156
+
157
+ const lodArray = Texture.normalizeTextureData(lodData, this);
158
+
159
+ // If the user provides multiple LODs, then automatic mipmap
160
+ // generation generateMipmap() should be disabled to avoid overwriting them.
161
+ if (lodArray.length > 1 && this.props.mipmaps !== false) {
162
+ log.warn(`Texture ${this.id} mipmap and multiple LODs.`)();
163
+ }
164
+
165
+ for (let lodLevel = 0; lodLevel < lodArray.length; lodLevel++) {
166
+ const imageData = lodArray[lodLevel];
167
+ this._setMipLevel(depth, lodLevel, imageData);
168
+ }
169
+
170
+ this.unbind();
171
+ }
172
+
173
+ /**
174
+ * Sets 3D texture data: multiple depth slices, multiple mip levels
175
+ * @param data
176
+ */
177
+ export function setTexture3DData(texture: Texture, data: Texture3DData): void {
178
+ if (this.props.dimension !== '3d') {
179
+ throw new Error(this.id);
180
+ }
181
+ if (ArrayBuffer.isView(data)) {
182
+ this.bind();
183
+ copyCPUDataToMipLevel(this.device.gl, data, this);
184
+ this.unbind();
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Set Cube texture data, multiple faces, multiple mip levels
190
+ * @todo - could support TextureCubeArray with depth
191
+ * @param data
192
+ * @param index
193
+ */
194
+ export function setTextureCubeData(texture: Texture, data: TextureCubeData): void {
195
+ if (this.props.dimension !== 'cube') {
196
+ throw new Error(this.id);
197
+ }
198
+ for (const face of Texture.CubeFaces) {
199
+ this.setTextureCubeFaceData(data[face], face);
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Sets texture array data, multiple levels, multiple depth slices
205
+ * @param data
206
+ */
207
+ export function setTextureArrayData(texture: Texture, data: TextureArrayData): void {
208
+ if (this.props.dimension !== '2d-array') {
209
+ throw new Error(this.id);
210
+ }
211
+ throw new Error('setTextureArrayData not implemented.');
212
+ }
213
+
214
+ /**
215
+ * Sets texture cube array, multiple faces, multiple levels, multiple mip levels
216
+ * @param data
217
+ */
218
+ export function setTextureCubeArrayData(texture: Texture, data: TextureCubeArrayData): void {
219
+ throw new Error('setTextureCubeArrayData not supported in WebGL2.');
220
+ }
221
+
222
+ export function setTextureCubeFaceData(
223
+ texture: Texture,
224
+ lodData: Texture2DData,
225
+ face: TextureCubeFace,
226
+ depth: number = 0
227
+ ): void {
228
+ // assert(this.props.dimension === 'cube');
229
+
230
+ // If the user provides multiple LODs, then automatic mipmap
231
+ // generation generateMipmap() should be disabled to avoid overwriting them.
232
+ if (Array.isArray(lodData) && lodData.length > 1 && this.props.mipmaps !== false) {
233
+ log.warn(`${this.id} has mipmap and multiple LODs.`)();
234
+ }
235
+
236
+ const faceDepth = Texture.CubeFaces.indexOf(face);
237
+
238
+ this.setTexture2DData(lodData, faceDepth);
239
+ }
240
+
241
+ // TODO - Remove when texture refactor is complete
242
+
243
+ /*
244
+ setCubeMapData(options: {
245
+ width: number;
246
+ height: number;
247
+ data: Record<GL, Texture2DData> | Record<TextureCubeFace, Texture2DData>;
248
+ format?: any;
249
+ type?: any;
250
+ /** @deprecated Use .data *
251
+ pixels: any;
252
+ }): void {
253
+ const {gl} = this;
254
+
255
+ const {width, height, pixels, data, format = GL.RGBA, type = GL.UNSIGNED_BYTE} = options;
256
+
257
+ // pixel data (imageDataMap) is an Object from Face to Image or Promise.
258
+ // For example:
259
+ // {
260
+ // GL.TEXTURE_CUBE_MAP_POSITIVE_X : Image-or-Promise,
261
+ // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : Image-or-Promise,
262
+ // ... }
263
+ // To provide multiple level-of-details (LODs) this can be Face to Array
264
+ // of Image or Promise, like this
265
+ // {
266
+ // GL.TEXTURE_CUBE_MAP_POSITIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
267
+ // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
268
+ // ... }
269
+
270
+ const imageDataMap = this._getImageDataMap(pixels || data);
271
+
272
+ const resolvedFaces = WEBGLTexture.FACES.map(face => {
273
+ const facePixels = imageDataMap[face];
274
+ return Array.isArray(facePixels) ? facePixels : [facePixels];
275
+ });
276
+ this.bind();
277
+
278
+ WEBGLTexture.FACES.forEach((face, index) => {
279
+ if (resolvedFaces[index].length > 1 && this.props.mipmaps !== false) {
280
+ // If the user provides multiple LODs, then automatic mipmap
281
+ // generation generateMipmaps() should be disabled to avoid overwritting them.
282
+ log.warn(`${this.id} has mipmap and multiple LODs.`)();
283
+ }
284
+ resolvedFaces[index].forEach((image, lodLevel) => {
285
+ // TODO: adjust width & height for LOD!
286
+ if (width && height) {
287
+ gl.texImage2D(face, lodLevel, format, width, height, 0 /* border*, format, type, image);
288
+ } else {
289
+ gl.texImage2D(face, lodLevel, format, format, type, image);
290
+ }
291
+ });
292
+ });
293
+
294
+ this.unbind();
295
+ }
296
+ */
@@ -30,7 +30,7 @@ export type ComputationProps = Omit<ComputePipelineProps, 'shader'> & {
30
30
  /** shadertool shader modules (added to shader code) */
31
31
  modules?: ShaderModule[];
32
32
  /** Shadertool module defines (configures shader code)*/
33
- defines?: Record<string, string | number | boolean>;
33
+ defines?: Record<string, boolean>;
34
34
  // TODO - injections, hooks etc?
35
35
 
36
36
  /** Shader inputs, used to generated uniform buffers and bindings */
@@ -46,7 +46,9 @@ export class SwapFramebuffers extends Swap<Framebuffer> {
46
46
  ? colorAttachment
47
47
  : device.createTexture({
48
48
  format: colorAttachment,
49
- usage: Texture.COPY_DST | Texture.RENDER_ATTACHMENT
49
+ usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_SRC | Texture.COPY_DST,
50
+ width: 1,
51
+ height: 1
50
52
  })
51
53
  );
52
54
 
@@ -57,7 +59,10 @@ export class SwapFramebuffers extends Swap<Framebuffer> {
57
59
  ? colorAttachment
58
60
  : device.createTexture({
59
61
  format: colorAttachment,
60
- usage: Texture.COPY_DST | Texture.RENDER_ATTACHMENT
62
+ usage:
63
+ Texture.TEXTURE | Texture.COPY_SRC | Texture.COPY_DST | Texture.RENDER_ATTACHMENT,
64
+ width: 1,
65
+ height: 1
61
66
  })
62
67
  );
63
68
 
@@ -95,6 +95,7 @@ export class TextureTransform {
95
95
  const renderPass = this.device.beginRenderPass({framebuffer, ...options});
96
96
  this.model.draw(renderPass);
97
97
  renderPass.end();
98
+ this.device.submit();
98
99
  }
99
100
 
100
101
  getTargetTexture(): Texture {
@@ -2,8 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {Texture, Framebuffer} from '@luma.gl/core';
6
- import {flipRows, scalePixels} from './pixel-data-utils';
5
+ import {Texture, Framebuffer, TypedArray} from '@luma.gl/core';
7
6
 
8
7
  /**
9
8
  * Options for copying texture pixels to image
@@ -71,3 +70,54 @@ export function copyTextureToDataUrl(
71
70
 
72
71
  return canvas.toDataURL('image/png');
73
72
  }
73
+
74
+ // HELPERS
75
+
76
+ /**
77
+ * Flip rows (can be used on arrays returned from `Framebuffer.readPixels`)
78
+ * https: *stackoverflow.com/questions/41969562/
79
+ * how-can-i-flip-the-result-of-webglrenderingcontext-readpixels
80
+ * @param param0
81
+ */
82
+ export function flipRows(options: {
83
+ data: TypedArray;
84
+ width: number;
85
+ height: number;
86
+ bytesPerPixel?: number;
87
+ temp?: Uint8Array;
88
+ }): void {
89
+ const {data, width, height, bytesPerPixel = 4, temp} = options;
90
+ const bytesPerRow = width * bytesPerPixel;
91
+
92
+ // make a temp buffer to hold one row
93
+ const tempBuffer = temp || new Uint8Array(bytesPerRow);
94
+ for (let y = 0; y < height / 2; ++y) {
95
+ const topOffset = y * bytesPerRow;
96
+ const bottomOffset = (height - y - 1) * bytesPerRow;
97
+ // make copy of a row on the top half
98
+ tempBuffer.set(data.subarray(topOffset, topOffset + bytesPerRow));
99
+ // copy a row from the bottom half to the top
100
+ data.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
101
+ // copy the copy of the top half row to the bottom half
102
+ data.set(tempBuffer, bottomOffset);
103
+ }
104
+ }
105
+
106
+ export function scalePixels(options: {data: TypedArray; width: number; height: number}): {
107
+ data: Uint8Array;
108
+ width: number;
109
+ height: number;
110
+ } {
111
+ const {data, width, height} = options;
112
+ const newWidth = Math.round(width / 2);
113
+ const newHeight = Math.round(height / 2);
114
+ const newData = new Uint8Array(newWidth * newHeight * 4);
115
+ for (let y = 0; y < newHeight; y++) {
116
+ for (let x = 0; x < newWidth; x++) {
117
+ for (let c = 0; c < 4; c++) {
118
+ newData[(y * newWidth + x) * 4 + c] = data[(y * 2 * width + x * 2) * 4 + c];
119
+ }
120
+ }
121
+ }
122
+ return {data: newData, width: newWidth, height: newHeight};
123
+ }
package/src/index.ts CHANGED
@@ -80,6 +80,18 @@ export {SwapFramebuffers} from './compute/swap';
80
80
  export type {ComputationProps} from './compute/computation';
81
81
  export {Computation} from './compute/computation';
82
82
 
83
+ export type {
84
+ TextureCubeFace,
85
+ TextureImageData,
86
+ TextureData,
87
+ Texture1DData,
88
+ Texture2DData,
89
+ Texture3DData,
90
+ TextureCubeData,
91
+ TextureArrayData,
92
+ TextureCubeArrayData
93
+ } from './async-texture/async-texture';
94
+
83
95
  export type {AsyncTextureProps} from './async-texture/async-texture';
84
96
  export {AsyncTexture} from './async-texture/async-texture';
85
97
 
@@ -13,7 +13,6 @@ import type {
13
13
  TransformFeedback,
14
14
  AttributeInfo,
15
15
  Binding,
16
- UniformValue,
17
16
  PrimitiveTopology
18
17
  } from '@luma.gl/core';
19
18
  import {
@@ -44,23 +43,20 @@ import {debugFramebuffer} from '../debug/debug-framebuffer';
44
43
  import {deepEqual} from '../utils/deep-equal';
45
44
  import {uid} from '../utils/uid';
46
45
  import {ShaderInputs} from '../shader-inputs';
47
- // import type {AsyncTextureProps} from '../async-texture/async-texture';
48
46
  import {AsyncTexture} from '../async-texture/async-texture';
49
47
 
50
- import {splitUniformsAndBindings} from './split-uniforms-and-bindings';
51
-
52
48
  const LOG_DRAW_PRIORITY = 2;
53
49
  const LOG_DRAW_TIMEOUT = 10000;
54
50
 
55
51
  export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs' | 'bindings'> & {
56
52
  source?: string;
57
- vs: string | null;
58
- fs: string | null;
53
+ vs?: string | null;
54
+ fs?: string | null;
59
55
 
60
56
  /** shadertool shader modules (added to shader code) */
61
57
  modules?: ShaderModule[];
62
58
  /** Shadertool module defines (configures shader code)*/
63
- defines?: Record<string, string | number | boolean>;
59
+ defines?: Record<string, boolean>;
64
60
  // TODO - injections, hooks etc?
65
61
 
66
62
  /** Shader inputs, used to generated uniform buffers and bindings */
@@ -94,9 +90,6 @@ export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs' | 'bindings'> & {
94
90
 
95
91
  transformFeedback?: TransformFeedback;
96
92
 
97
- /** Mapped uniforms for shadertool modules */
98
- moduleSettings?: Record<string, Record<string, any>>;
99
-
100
93
  /** Show shader source in browser? */
101
94
  debugShaders?: 'never' | 'errors' | 'warnings' | 'always';
102
95
 
@@ -127,7 +120,6 @@ export class Model {
127
120
  userData: {},
128
121
  defines: {},
129
122
  modules: [],
130
- moduleSettings: undefined!,
131
123
  geometry: null,
132
124
  indexBuffer: null,
133
125
  attributes: {},
@@ -187,8 +179,6 @@ export class Model {
187
179
  constantAttributes: Record<string, TypedArray> = {};
188
180
  /** Bindings (textures, samplers, uniform buffers) */
189
181
  bindings: Record<string, Binding | AsyncTexture> = {};
190
- /** Sets uniforms @deprecated Use uniform buffers and setBindings() for portability*/
191
- uniforms: Record<string, UniformValue> = {};
192
182
 
193
183
  /**
194
184
  * VertexArray
@@ -211,7 +201,6 @@ export class Model {
211
201
 
212
202
  _attributeInfos: Record<string, AttributeInfo> = {};
213
203
  _gpuGeometry: GPUGeometry | null = null;
214
- private _getModuleUniforms: (props?: Record<string, Record<string, any>>) => Record<string, any>;
215
204
  private props: Required<ModelProps>;
216
205
 
217
206
  _pipelineNeedsUpdate: string | false = 'newly created';
@@ -335,13 +324,6 @@ export class Model {
335
324
  if (props.bindings) {
336
325
  this.setBindings(props.bindings);
337
326
  }
338
- if (props.uniforms) {
339
- this.setUniformsWebGL(props.uniforms);
340
- }
341
- if (props.moduleSettings) {
342
- // log.warn('Model.props.moduleSettings is deprecated. Use Model.shaderInputs.setProps()')();
343
- this.updateModuleSettingsWebGL(props.moduleSettings);
344
- }
345
327
  if (props.transformFeedback) {
346
328
  this.transformFeedback = props.transformFeedback;
347
329
  }
@@ -423,9 +405,6 @@ export class Model {
423
405
  this.pipeline.setBindings(syncBindings, {
424
406
  disableWarnings: this.props.disableWarnings
425
407
  });
426
- if (!isObjectEmpty(this.uniforms)) {
427
- this.pipeline.setUniformsWebGL(this.uniforms);
428
- }
429
408
 
430
409
  const {indexBuffer} = this.vertexArray;
431
410
  const indexCount = indexBuffer
@@ -676,33 +655,7 @@ export class Model {
676
655
  this.setNeedsRedraw('constants');
677
656
  }
678
657
 
679
- // DEPRECATED METHODS
680
-
681
- /**
682
- * Sets individual uniforms
683
- * @deprecated WebGL only, use uniform buffers for portability
684
- * @param uniforms
685
- */
686
- setUniformsWebGL(uniforms: Record<string, UniformValue>): void {
687
- if (!isObjectEmpty(uniforms)) {
688
- this.pipeline.setUniformsWebGL(uniforms);
689
- Object.assign(this.uniforms, uniforms);
690
- }
691
- this.setNeedsRedraw('uniforms');
692
- }
693
-
694
- /**
695
- * @deprecated Updates shader module settings (which results in uniforms being set)
696
- */
697
- updateModuleSettingsWebGL(props: Record<string, any>): void {
698
- // log.warn('Model.updateModuleSettings is deprecated. Use Model.shaderInputs.setProps()')();
699
- const {bindings, uniforms} = splitUniformsAndBindings(this._getModuleUniforms(props));
700
- Object.assign(this.bindings, bindings);
701
- Object.assign(this.uniforms, uniforms);
702
- this.setNeedsRedraw('moduleSettings');
703
- }
704
-
705
- // Internal methods
658
+ // INTERNAL METHODS
706
659
 
707
660
  /** Check that bindings are loaded. Returns id of first binding that is still loading. */
708
661
  _areBindingsLoading(): string | false {
@@ -868,10 +821,6 @@ export class Model {
868
821
  log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
869
822
 
870
823
  const uniformTable = this.shaderInputs.getDebugTable();
871
- // Add any global uniforms
872
- for (const [name, value] of Object.entries(this.uniforms)) {
873
- uniformTable[name] = {value};
874
- }
875
824
  log.table(LOG_DRAW_PRIORITY, uniformTable)();
876
825
 
877
826
  const attributeTable = this._getAttributeDebugTable();
@@ -11,7 +11,7 @@ const BACKGROUND_FS_WGSL = /* wgsl */ `\
11
11
  @group(0) @binding(1) var backgroundTextureSampler: sampler;
12
12
 
13
13
  fn billboardTexture_getTextureUV(coordinates: vec2<f32>) -> vec2<f32> {
14
- let iTexSize: vec2<u32> = textureDimensions(backgroundTexture, 0) * 2;
14
+ let iTexSize: vec2<u32> = textureDimensions(backgroundTexture, 0);
15
15
  let texSize: vec2<f32> = vec2<f32>(f32(iTexSize.x), f32(iTexSize.y));
16
16
  var position: vec2<f32> = coordinates.xy / texSize;
17
17
  return position;
@@ -32,7 +32,7 @@ uniform sampler2D backgroundTexture;
32
32
  out vec4 fragColor;
33
33
 
34
34
  vec2 billboardTexture_getTextureUV() {
35
- ivec2 iTexSize = textureDimensions(backgroundTexture, 0) * 2;
35
+ ivec2 iTexSize = textureSize(backgroundTexture, 0);
36
36
  vec2 texSize = vec2(float(iTexSize.x), float(iTexSize.y));
37
37
  vec2 position = gl_FragCoord.xy / texSize;
38
38
  return position;
@@ -67,14 +67,13 @@ export class BackgroundTextureModel extends ClipSpace {
67
67
  fs: BACKGROUND_FS,
68
68
  parameters: {
69
69
  depthWriteEnabled: false,
70
- depthCompare: 'always',
71
70
  ...(props.blend
72
71
  ? {
73
72
  blend: true,
74
73
  blendColorOperation: 'add',
75
74
  blendAlphaOperation: 'add',
76
75
  blendColorSrcFactor: 'one',
77
- blendColorDstFactor: 'one-minus-src-color',
76
+ blendColorDstFactor: 'one-minus-src',
78
77
  blendAlphaSrcFactor: 'one',
79
78
  blendAlphaDstFactor: 'one-minus-src-alpha'
80
79
  }
@@ -82,6 +81,9 @@ export class BackgroundTextureModel extends ClipSpace {
82
81
  }
83
82
  });
84
83
 
84
+ if (!props.backgroundTexture) {
85
+ throw new Error('BackgroundTextureModel requires a backgroundTexture prop');
86
+ }
85
87
  this.setTexture(props.backgroundTexture);
86
88
  }
87
89
 
@@ -42,7 +42,7 @@ export class LegacyPickingManager {
42
42
  /** Prepare for rendering picking colors */
43
43
  beginRenderPass() {
44
44
  const framebuffer = this.getFramebuffer();
45
- framebuffer.resize(this.device.getCanvasContext().getPixelSize());
45
+ framebuffer.resize(this.device.getCanvasContext().getDevicePixelSize());
46
46
 
47
47
  this.shaderInputs.setProps({picking: {isActive: true}});
48
48
 
@@ -90,7 +90,7 @@ export class LegacyPickingManager {
90
90
  * Get pick position in device pixel range
91
91
  * use the center pixel location in device pixel range
92
92
  */
93
- getPickPosition(mousePosition: number[]): [number, number] {
93
+ getPickPosition(mousePosition: [number, number]): [number, number] {
94
94
  const devicePixels = this.device.getCanvasContext().cssToDevicePixels(mousePosition);
95
95
  const pickX = devicePixels.x + Math.floor(devicePixels.width / 2);
96
96
  const pickY = devicePixels.y + Math.floor(devicePixels.height / 2);
@@ -67,7 +67,7 @@ export class PickingManager {
67
67
  /** Prepare for rendering picking colors */
68
68
  beginRenderPass() {
69
69
  const framebuffer = this.getFramebuffer();
70
- framebuffer.resize(this.device.getDefaultCanvasContext().getPixelSize());
70
+ framebuffer.resize(this.device.getDefaultCanvasContext().getDevicePixelSize());
71
71
 
72
72
  this.props.shaderInputs?.setProps({picking: {isActive: true}});
73
73
 
@@ -128,7 +128,7 @@ export class PickingManager {
128
128
  * Get pick position in device pixel range
129
129
  * use the center pixel location in device pixel range
130
130
  */
131
- getPickPosition(mousePosition: number[]): [number, number] {
131
+ getPickPosition(mousePosition: [number, number]): [number, number] {
132
132
  const devicePixels = this.device.getDefaultCanvasContext().cssToDevicePixels(mousePosition);
133
133
  const pickX = devicePixels.x + Math.floor(devicePixels.width / 2);
134
134
  const pickY = devicePixels.y + Math.floor(devicePixels.height / 2);
@@ -37,11 +37,11 @@ export function getFragmentShaderForRenderPass(options: {
37
37
  function getFilterShaderWGSL(func: string) {
38
38
  return /* wgsl */ `\
39
39
  // Binding 0:1 is reserved for shader passes
40
- @group(0) @binding(0) var<uniform> brightnessContrast : brightnessContrastUniforms;
40
+ // @group(0) @binding(0) var<uniform> brightnessContrast : brightnessContrastUniforms;
41
41
  @group(0) @binding(1) var texture: texture_2d<f32>;
42
42
  @group(0) @binding(2) var sampler: sampler;
43
43
 
44
- struct FragmentInputs = {
44
+ struct FragmentInputs {
45
45
  @location(0) fragUV: vec2f,
46
46
  @location(1) fragPosition: vec4f,
47
47
  @location(2) fragCoordinate: vec4f