@luma.gl/engine 9.0.0-alpha.27 → 9.0.0-alpha.29

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 CHANGED
@@ -2147,8 +2147,8 @@ var __exports__ = (() => {
2147
2147
  function decodeVertexType(type) {
2148
2148
  const dataType = TYPE_MAP[type];
2149
2149
  const bytes = getDataTypeBytes(dataType);
2150
- const integer = !type.startsWith("float");
2151
2150
  const normalized = type.includes("norm");
2151
+ const integer = !normalized && !type.startsWith("float");
2152
2152
  const signed = type.startsWith("s");
2153
2153
  return {
2154
2154
  dataType: TYPE_MAP[type],
@@ -5872,16 +5872,28 @@ void main() {
5872
5872
  };
5873
5873
  var Model = class {
5874
5874
  fs = null;
5875
+ /** The underlying GPU "program". @note May be recreated if parameters change */
5875
5876
  userData = {};
5877
+ // readonly props: Required<ModelProps>;
5878
+ /** Vertex count */
5879
+ /** instance count */
5880
+ instanceCount = 0;
5881
+ /** Buffer-valued attributes */
5882
+ bufferAttributes = {};
5883
+ /** Constant-valued attributes */
5884
+ constantAttributes = {};
5885
+ /** Bindings (textures, samplers, uniform buffers) */
5886
+ bindings = {};
5887
+ /** Uniforms */
5888
+ uniforms = {};
5876
5889
  constructor(device, props) {
5877
- this.props = {
5890
+ props = {
5878
5891
  ...DEFAULT_MODEL_PROPS,
5879
5892
  ...props
5880
5893
  };
5881
- props = this.props;
5882
- this.id = this.props.id;
5894
+ this.id = props.id;
5883
5895
  this.device = device;
5884
- Object.assign(this.userData, this.props.userData);
5896
+ Object.assign(this.userData, props.userData);
5885
5897
  if (!props.vs) {
5886
5898
  throw new Error("no vertex shader");
5887
5899
  }
@@ -5889,18 +5901,19 @@ void main() {
5889
5901
  if (props.fs) {
5890
5902
  this.fs = getShaderSource(this.device, props.fs);
5891
5903
  }
5892
- this.vertexCount = this.props.vertexCount;
5893
- this.topology = this.props.topology;
5894
- if (this.props.geometry) {
5895
- this.vertexCount = this.props.geometry.vertexCount;
5896
- this.topology = this.props.geometry.topology || "triangle-list";
5904
+ this.vertexCount = props.vertexCount;
5905
+ this.instanceCount = props.instanceCount;
5906
+ this.topology = props.topology;
5907
+ if (props.geometry) {
5908
+ this.vertexCount = props.geometry.vertexCount;
5909
+ this.topology = props.geometry.topology || "triangle-list";
5897
5910
  }
5898
- this.pipelineFactory = this.props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
5911
+ this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
5899
5912
  const {
5900
5913
  pipeline,
5901
5914
  getUniforms
5902
5915
  } = this.pipelineFactory.createRenderPipeline({
5903
- ...this.props,
5916
+ ...props,
5904
5917
  vs: this.vs,
5905
5918
  fs: this.fs,
5906
5919
  topology: this.topology,
@@ -5910,11 +5923,11 @@ void main() {
5910
5923
  });
5911
5924
  this.pipeline = pipeline;
5912
5925
  this._getModuleUniforms = getUniforms;
5913
- if (this.props.geometry) {
5914
- this._setGeometry(this.props.geometry);
5926
+ if (props.geometry) {
5927
+ this._setGeometry(props.geometry);
5915
5928
  }
5916
5929
  this.setUniforms(this._getModuleUniforms());
5917
- this.setProps(this.props);
5930
+ this.setProps(props);
5918
5931
  }
5919
5932
  destroy() {
5920
5933
  this.pipelineFactory.release(this.pipeline);
@@ -5923,9 +5936,8 @@ void main() {
5923
5936
  this.pipeline.draw({
5924
5937
  renderPass,
5925
5938
  vertexCount: this.vertexCount,
5926
- instanceCount: this.props.instanceCount
5939
+ instanceCount: this.instanceCount
5927
5940
  });
5928
- return this;
5929
5941
  }
5930
5942
  setProps(props) {
5931
5943
  if (props.indices) {
@@ -5943,71 +5955,33 @@ void main() {
5943
5955
  if (props.moduleSettings) {
5944
5956
  this.updateModuleSettings(props.moduleSettings);
5945
5957
  }
5946
- return this;
5947
5958
  }
5948
5959
  updateModuleSettings(props) {
5949
5960
  const uniforms = this._getModuleUniforms(props);
5950
5961
  this.setUniforms(uniforms);
5951
- return this;
5952
5962
  }
5953
5963
  setIndexBuffer(indices) {
5954
5964
  this.pipeline.setIndexBuffer(indices);
5955
- return this;
5956
- }
5957
- // Temporary hack to support deck.gl's dependency on luma.gl v8 Model attribute API.
5958
- _splitAttributes(attributes, filterBuffers) {
5959
- const bufferAttributes = {};
5960
- const constantAttributes = {};
5961
- const indices = attributes.indices;
5962
- delete attributes.indices;
5963
- for (const name in attributes) {
5964
- let attribute = attributes[name];
5965
- if (attribute instanceof Buffer2) {
5966
- bufferAttributes[name] = attribute;
5967
- continue;
5968
- }
5969
- if (attribute.getValue) {
5970
- attribute = attribute.getValue();
5971
- console.warn(`attribute ${name}: getValue() will be removed`);
5972
- }
5973
- if (ArrayBuffer.isView(attribute) && !attribute) {
5974
- constantAttributes[name] = attribute;
5975
- continue;
5976
- }
5977
- if (filterBuffers && attribute[name]._buffer) {
5978
- buffer[name] = attribute[name]._buffer;
5979
- }
5980
- }
5981
- return {
5982
- bufferAttributes,
5983
- constantAttributes,
5984
- indices
5985
- };
5986
5965
  }
5987
- setAttributes(attributes, filterBuffers) {
5988
- const {
5989
- bufferAttributes,
5990
- constantAttributes,
5991
- indices
5992
- } = this._splitAttributes(attributes, filterBuffers);
5993
- if (indices) {
5994
- this.setIndexBuffer(indices);
5995
- console.warn("luma.gl: indices should not be part of attributes");
5966
+ setAttributes(bufferAttributes) {
5967
+ if (bufferAttributes.indices) {
5968
+ log.warn(`Model:${this.id} setAttributes() - indices should be set using setIndexBuffer()`);
5996
5969
  }
5997
5970
  this.pipeline.setAttributes(bufferAttributes);
5971
+ Object.assign(this.bufferAttributes, bufferAttributes);
5972
+ }
5973
+ setConstantAttributes(constantAttributes) {
5998
5974
  this.pipeline.setConstantAttributes(constantAttributes);
5999
- Object.assign(this.props.attributes, bufferAttributes, constantAttributes);
5975
+ Object.assign(this.constantAttributes, constantAttributes);
6000
5976
  }
6001
5977
  /** Set the bindings */
6002
5978
  setBindings(bindings) {
6003
5979
  this.pipeline.setBindings(bindings);
6004
- Object.assign(this.props.bindings, bindings);
6005
- return this;
5980
+ Object.assign(this.bindings, bindings);
6006
5981
  }
6007
5982
  setUniforms(uniforms) {
6008
5983
  this.pipeline.setUniforms(uniforms);
6009
- Object.assign(this.props.uniforms, uniforms);
6010
- return this;
5984
+ Object.assign(this.uniforms, uniforms);
6011
5985
  }
6012
5986
  _setGeometry(geometry) {
6013
5987
  const geometryBuffers = getAttributeBuffersFromGeometry(this.device, geometry);
@@ -6839,13 +6813,13 @@ void main() {
6839
6813
  attrib.enabled = false;
6840
6814
  return original.disableVertexAttribArray.apply(this, arguments);
6841
6815
  };
6842
- gl.bindBuffer = function bindBuffer2(target, buffer2) {
6816
+ gl.bindBuffer = function bindBuffer2(target, buffer) {
6843
6817
  switch (target) {
6844
6818
  case gl.ARRAY_BUFFER:
6845
- self.currentArrayBuffer = buffer2;
6819
+ self.currentArrayBuffer = buffer;
6846
6820
  break;
6847
6821
  case gl.ELEMENT_ARRAY_BUFFER:
6848
- self.currentVertexArrayObject.elementArrayBuffer = buffer2;
6822
+ self.currentVertexArrayObject.elementArrayBuffer = buffer;
6849
6823
  break;
6850
6824
  default:
6851
6825
  }
@@ -7482,8 +7456,8 @@ void main() {
7482
7456
  [GL.PIXEL_PACK_BUFFER_BINDING]: GL.PIXEL_PACK_BUFFER,
7483
7457
  [GL.PIXEL_UNPACK_BUFFER_BINDING]: GL.PIXEL_UNPACK_BUFFER
7484
7458
  };
7485
- const target = bindingMap[key];
7486
- gl.bindBuffer(target, value);
7459
+ const glTarget = bindingMap[key];
7460
+ gl.bindBuffer(glTarget, value);
7487
7461
  };
7488
7462
  function isArray2(array) {
7489
7463
  return Array.isArray(array) || ArrayBuffer.isView(array) && !(array instanceof DataView);
@@ -7684,7 +7658,7 @@ void main() {
7684
7658
  return null;
7685
7659
  }
7686
7660
  },
7687
- bindBuffer: (update, target, buffer2) => {
7661
+ bindBuffer: (update, target, buffer) => {
7688
7662
  const pname = {
7689
7663
  [GL.ARRAY_BUFFER]: [GL.ARRAY_BUFFER_BINDING],
7690
7664
  [GL.COPY_READ_BUFFER]: [GL.COPY_READ_BUFFER_BINDING],
@@ -7694,7 +7668,7 @@ void main() {
7694
7668
  }[target];
7695
7669
  if (pname) {
7696
7670
  return update({
7697
- [pname]: buffer2
7671
+ [pname]: buffer
7698
7672
  });
7699
7673
  }
7700
7674
  return {
@@ -9604,8 +9578,14 @@ void main(void) {}`;
9604
9578
  // ../webgl/src/adapter/resources/webgl-buffer.ts
9605
9579
  var DEBUG_DATA_LENGTH = 10;
9606
9580
  var WEBGLBuffer = class extends Buffer2 {
9581
+ /** Target in OpenGL defines the type of buffer */
9582
+ /** Usage is a hint on how frequently the buffer will be updates */
9583
+ /** Index type is needed when issuing draw calls, so we pre-compute it */
9584
+ glIndexType = GL.UNSIGNED_SHORT;
9585
+ /** Number of bytes allocated on the GPU for this buffer */
9586
+ /** Number of bytes used */
9587
+ /** A partial CPU-side copy of the data in this buffer, for debugging purposes */
9607
9588
  debugData = null;
9608
- // accessor: {};
9609
9589
  constructor(device, props = {}) {
9610
9590
  super(device, props);
9611
9591
  this.device = device;
@@ -9617,8 +9597,9 @@ void main(void) {}`;
9617
9597
  ...this.props,
9618
9598
  data: typeof this.props.data
9619
9599
  });
9620
- this.target = this.props.target || getWebGLTarget(this.props.usage);
9621
- this.webglUsage = this.props.webglUsage || getWebGLUsage(this.props.usage);
9600
+ this.glTarget = getWebGLTarget(this.props.usage);
9601
+ this.glUsage = getWebGLUsage(this.props.usage);
9602
+ this.glIndexType = this.props.indexType === "uint32" ? GL.UNSIGNED_INT : GL.UNSIGNED_SHORT;
9622
9603
  this.debugData = null;
9623
9604
  if (props.data) {
9624
9605
  this._initWithData(props.data, props.byteOffset, props.byteLength);
@@ -9627,14 +9608,14 @@ void main(void) {}`;
9627
9608
  }
9628
9609
  }
9629
9610
  // PRIVATE METHODS
9630
- // Allocate a new buffer and initialize to contents of typed array
9611
+ /** Allocate a new buffer and initialize to contents of typed array */
9631
9612
  _initWithData(data, byteOffset = 0, byteLength = data.byteLength + byteOffset) {
9632
9613
  assert2(ArrayBuffer.isView(data));
9633
- const target = this._getWriteTarget();
9634
- this.gl.bindBuffer(target, this.handle);
9635
- this.gl.bufferData(target, byteLength, this.webglUsage);
9636
- this.gl.bufferSubData(target, byteOffset, data);
9637
- this.gl.bindBuffer(target, null);
9614
+ const glTarget = this._getWriteTarget();
9615
+ this.gl.bindBuffer(glTarget, this.handle);
9616
+ this.gl.bufferData(glTarget, byteLength, this.glUsage);
9617
+ this.gl.bufferSubData(glTarget, byteOffset, data);
9618
+ this.gl.bindBuffer(glTarget, null);
9638
9619
  this.debugData = data.slice(0, DEBUG_DATA_LENGTH);
9639
9620
  this.bytesUsed = byteLength;
9640
9621
  this.byteLength = byteLength;
@@ -9648,10 +9629,10 @@ void main(void) {}`;
9648
9629
  if (byteLength === 0) {
9649
9630
  data = new Float32Array(0);
9650
9631
  }
9651
- const target = this._getWriteTarget();
9652
- this.gl.bindBuffer(target, this.handle);
9653
- this.gl.bufferData(target, data, this.webglUsage);
9654
- this.gl.bindBuffer(target, null);
9632
+ const glTarget = this._getWriteTarget();
9633
+ this.gl.bindBuffer(glTarget, this.handle);
9634
+ this.gl.bufferData(glTarget, data, this.glUsage);
9635
+ this.gl.bindBuffer(glTarget, null);
9655
9636
  this.debugData = null;
9656
9637
  this.bytesUsed = byteLength;
9657
9638
  this.byteLength = byteLength;
@@ -9669,15 +9650,15 @@ void main(void) {}`;
9669
9650
  write(data, byteOffset = 0) {
9670
9651
  const srcOffset = 0;
9671
9652
  const byteLength = void 0;
9672
- const target = this.device.isWebGL2 ? GL.COPY_WRITE_BUFFER : this.target;
9673
- this.gl.bindBuffer(target, this.handle);
9653
+ const glTarget = this.device.isWebGL2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
9654
+ this.gl.bindBuffer(glTarget, this.handle);
9674
9655
  if (srcOffset !== 0 || byteLength !== void 0) {
9675
9656
  this.device.assertWebGL2();
9676
- this.gl2.bufferSubData(target, byteOffset, data, srcOffset, byteLength);
9657
+ this.gl2.bufferSubData(glTarget, byteOffset, data, srcOffset, byteLength);
9677
9658
  } else {
9678
- this.gl.bufferSubData(target, byteOffset, data);
9659
+ this.gl.bufferSubData(glTarget, byteOffset, data);
9679
9660
  }
9680
- this.gl.bindBuffer(target, null);
9661
+ this.gl.bindBuffer(glTarget, null);
9681
9662
  }
9682
9663
  /** Read data from the buffer */
9683
9664
  async readAsync(byteOffset = 0, byteLength) {
@@ -9694,10 +9675,10 @@ void main(void) {}`;
9694
9675
  this.debugData = null;
9695
9676
  }
9696
9677
  _getWriteTarget() {
9697
- return this.target;
9678
+ return this.glTarget;
9698
9679
  }
9699
9680
  _getReadTarget() {
9700
- return this.target;
9681
+ return this.glTarget;
9701
9682
  }
9702
9683
  };
9703
9684
  function getWebGLTarget(usage) {
@@ -9722,7 +9703,7 @@ void main(void) {}`;
9722
9703
  if (usage & Buffer2.UNIFORM) {
9723
9704
  return GL.DYNAMIC_DRAW;
9724
9705
  }
9725
- return GL.DYNAMIC_DRAW;
9706
+ return GL.STATIC_DRAW;
9726
9707
  }
9727
9708
 
9728
9709
  // ../webgl/src/adapter/resources/webgl-sampler.ts
@@ -11143,7 +11124,7 @@ void main(void) {}`;
11143
11124
  return gl.luma;
11144
11125
  }
11145
11126
  async function loadWebGLDeveloperTools() {
11146
- if (!globalThis.WebGLDebugUtils) {
11127
+ if (isBrowser() && !globalThis.WebGLDebugUtils) {
11147
11128
  globalThis.global = globalThis.global || globalThis;
11148
11129
  globalThis.global.module = {};
11149
11130
  await loadScript(WEBGL_DEBUG_CDN_URL);
@@ -11440,9 +11421,6 @@ void main(void) {}`;
11440
11421
  const bufferProps = {
11441
11422
  ...props
11442
11423
  };
11443
- if (bufferProps.offset) {
11444
- bufferProps.byteOffset = bufferProps.offset;
11445
- }
11446
11424
  return bufferProps;
11447
11425
  }
11448
11426
  var BufferWithAccessor = class extends WEBGLBuffer {
@@ -11485,11 +11463,11 @@ void main(void) {}`;
11485
11463
  };
11486
11464
  }
11487
11465
  props = checkProps("Buffer", props, PROP_CHECKS_INITIALIZE);
11488
- this.webglUsage = props.webglUsage || GL.STATIC_DRAW;
11466
+ this.glUsage = props.glUsage || GL.STATIC_DRAW;
11489
11467
  this.debugData = null;
11490
11468
  this.setAccessor(Object.assign({}, props, props.accessor));
11491
11469
  if (props.data) {
11492
- this._setData(props.data, props.offset, props.byteLength);
11470
+ this._setData(props.data, props.byteOffset, props.byteLength);
11493
11471
  } else {
11494
11472
  this._setByteLength(props.byteLength || 0);
11495
11473
  }
@@ -11545,15 +11523,15 @@ void main(void) {}`;
11545
11523
  } = options;
11546
11524
  const byteLength = options.byteLength || options.length;
11547
11525
  assert2(data);
11548
- const target = this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.target;
11549
- this.gl.bindBuffer(target, this.handle);
11526
+ const glTarget = this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
11527
+ this.gl.bindBuffer(glTarget, this.handle);
11550
11528
  if (srcOffset !== 0 || byteLength !== void 0) {
11551
11529
  assertWebGL2Context(this.gl);
11552
- this.gl.bufferSubData(this.target, offset, data, srcOffset, byteLength);
11530
+ this.gl.bufferSubData(this.glTarget, offset, data, srcOffset, byteLength);
11553
11531
  } else {
11554
- this.gl.bufferSubData(target, offset, data);
11532
+ this.gl.bufferSubData(glTarget, offset, data);
11555
11533
  }
11556
- this.gl.bindBuffer(target, null);
11534
+ this.gl.bindBuffer(glTarget, null);
11557
11535
  this.debugData = null;
11558
11536
  this._inferType(data);
11559
11537
  return this;
@@ -11628,35 +11606,35 @@ void main(void) {}`;
11628
11606
  */
11629
11607
  bind(options) {
11630
11608
  const {
11631
- target = this.target,
11609
+ glTarget = this.glTarget,
11632
11610
  // target for the bind operation
11633
11611
  index = this.accessor && this.accessor.index,
11634
11612
  // index = index of target (indexed bind point)
11635
11613
  offset = 0,
11636
11614
  size
11637
11615
  } = options || {};
11638
- if (target === GL.UNIFORM_BUFFER || target === GL.TRANSFORM_FEEDBACK_BUFFER) {
11616
+ if (glTarget === GL.UNIFORM_BUFFER || glTarget === GL.TRANSFORM_FEEDBACK_BUFFER) {
11639
11617
  if (size !== void 0) {
11640
- this.gl2?.bindBufferRange(target, index, this.handle, offset, size);
11618
+ this.gl2?.bindBufferRange(glTarget, index, this.handle, offset, size);
11641
11619
  } else {
11642
11620
  assert2(offset === 0);
11643
- this.gl2?.bindBufferBase(target, index, this.handle);
11621
+ this.gl2?.bindBufferBase(glTarget, index, this.handle);
11644
11622
  }
11645
11623
  } else {
11646
- this.gl.bindBuffer(target, this.handle);
11624
+ this.gl.bindBuffer(glTarget, this.handle);
11647
11625
  }
11648
11626
  return this;
11649
11627
  }
11650
11628
  unbind(options) {
11651
11629
  const {
11652
- target = this.target,
11630
+ glTarget = this.glTarget,
11653
11631
  index = this.accessor && this.accessor.index
11654
11632
  } = options || {};
11655
- const isIndexedBuffer = target === GL.UNIFORM_BUFFER || target === GL.TRANSFORM_FEEDBACK_BUFFER;
11633
+ const isIndexedBuffer = glTarget === GL.UNIFORM_BUFFER || glTarget === GL.TRANSFORM_FEEDBACK_BUFFER;
11656
11634
  if (isIndexedBuffer) {
11657
- this.gl2?.bindBufferBase(target, index, null);
11635
+ this.gl2?.bindBufferBase(glTarget, index, null);
11658
11636
  } else {
11659
- this.gl.bindBuffer(target, null);
11637
+ this.gl.bindBuffer(glTarget, null);
11660
11638
  }
11661
11639
  return this;
11662
11640
  }
@@ -11687,7 +11665,7 @@ void main(void) {}`;
11687
11665
  this.trackDeallocatedMemory();
11688
11666
  const target = this._getTarget();
11689
11667
  this.gl.bindBuffer(target, this.handle);
11690
- this.gl.bufferData(target, byteLength, this.webglUsage);
11668
+ this.gl.bufferData(target, byteLength, this.glUsage);
11691
11669
  this.gl.bufferSubData(target, offset, data);
11692
11670
  this.gl.bindBuffer(target, null);
11693
11671
  this.debugData = data.slice(0, DEBUG_DATA_LENGTH2);
@@ -11702,18 +11680,17 @@ void main(void) {}`;
11702
11680
  return this;
11703
11681
  }
11704
11682
  // Allocate a GPU buffer of specified size.
11705
- _setByteLength(byteLength, webglUsage = this.webglUsage) {
11683
+ _setByteLength(byteLength) {
11706
11684
  assert2(byteLength >= 0);
11707
11685
  this.trackDeallocatedMemory();
11708
11686
  let data = byteLength;
11709
11687
  if (byteLength === 0) {
11710
11688
  data = new Float32Array(0);
11711
11689
  }
11712
- const target = this._getTarget();
11713
- this.gl.bindBuffer(target, this.handle);
11714
- this.gl.bufferData(target, data, webglUsage);
11715
- this.gl.bindBuffer(target, null);
11716
- this.webglUsage = webglUsage;
11690
+ const glTarget = this._getTarget();
11691
+ this.gl.bindBuffer(glTarget, this.handle);
11692
+ this.gl.bufferData(glTarget, data, this.glUsage);
11693
+ this.gl.bindBuffer(glTarget, null);
11717
11694
  this.debugData = null;
11718
11695
  this.bytesUsed = byteLength;
11719
11696
  this.byteLength = byteLength;
@@ -11723,7 +11700,7 @@ void main(void) {}`;
11723
11700
  // Binding a buffer for the first time locks the type
11724
11701
  // In WebGL2, use GL.COPY_WRITE_BUFFER to avoid locking the type
11725
11702
  _getTarget() {
11726
- return this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.target;
11703
+ return this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
11727
11704
  }
11728
11705
  _getAvailableElementCount(srcByteOffset) {
11729
11706
  const ArrayType = getTypedArrayFromGLType(this.accessor.type || GL.FLOAT, {
@@ -11743,9 +11720,9 @@ void main(void) {}`;
11743
11720
  }
11744
11721
  // RESOURCE METHODS
11745
11722
  getParameter(pname) {
11746
- this.gl.bindBuffer(this.target, this.handle);
11747
- const value = this.gl.getBufferParameter(this.target, pname);
11748
- this.gl.bindBuffer(this.target, null);
11723
+ this.gl.bindBuffer(this.glTarget, this.handle);
11724
+ const value = this.gl.getBufferParameter(this.glTarget, pname);
11725
+ this.gl.bindBuffer(this.glTarget, null);
11749
11726
  return value;
11750
11727
  }
11751
11728
  // DEPRECATIONS - v7.0
@@ -12091,12 +12068,12 @@ ${formattedLog}`)();
12091
12068
 
12092
12069
  // ../webgl/src/adapter/helpers/get-shader-layout.ts
12093
12070
  function getShaderLayout(gl, program) {
12094
- const programBindings = getProgramBindings(gl, program);
12095
12071
  const shaderLayout = {
12096
12072
  attributes: [],
12097
12073
  bindings: []
12098
12074
  };
12099
- for (const attribute of programBindings.attributes) {
12075
+ const attributes = readAttributeBindings(gl, program);
12076
+ for (const attribute of attributes) {
12100
12077
  const size = Math.min(attribute.accessor.size, 4);
12101
12078
  const format = (
12102
12079
  // attribute.accessor.format ||
@@ -12109,7 +12086,8 @@ ${formattedLog}`)();
12109
12086
  stepMode: attribute.accessor.divisor === 1 ? "instance" : "vertex"
12110
12087
  });
12111
12088
  }
12112
- for (const uniformBlock of programBindings.uniformBlocks) {
12089
+ const uniformBlocks = readUniformBlocks(gl, program);
12090
+ for (const uniformBlock of uniformBlocks) {
12113
12091
  const uniforms2 = uniformBlock.uniforms.map((uniform) => ({
12114
12092
  name: uniform.name,
12115
12093
  format: uniform.format,
@@ -12126,8 +12104,9 @@ ${formattedLog}`)();
12126
12104
  uniforms: uniforms2
12127
12105
  });
12128
12106
  }
12107
+ const uniforms = readUniformBindings(gl, program);
12129
12108
  let textureUnit = 0;
12130
- for (const uniform of programBindings.uniforms) {
12109
+ for (const uniform of uniforms) {
12131
12110
  if (isSamplerUniform(uniform.type)) {
12132
12111
  const {
12133
12112
  viewDimension,
@@ -12144,24 +12123,65 @@ ${formattedLog}`)();
12144
12123
  textureUnit += 1;
12145
12124
  }
12146
12125
  }
12147
- const uniforms = programBindings.uniforms?.filter((uniform) => uniform.location !== null) || [];
12148
12126
  if (uniforms.length) {
12149
12127
  shaderLayout.uniforms = uniforms;
12150
12128
  }
12151
- if (programBindings.varyings?.length) {
12152
- shaderLayout.varyings = programBindings.varyings;
12129
+ const varyings = readVaryings(gl, program);
12130
+ if (varyings?.length) {
12131
+ shaderLayout.varyings = varyings;
12153
12132
  }
12154
12133
  return shaderLayout;
12155
12134
  }
12156
- function getProgramBindings(gl, program) {
12157
- const config2 = {
12158
- attributes: readAttributeBindings(gl, program),
12159
- uniforms: readUniformBindings(gl, program),
12160
- uniformBlocks: readUniformBlocks(gl, program),
12161
- varyings: readVaryings(gl, program)
12135
+ function mergeShaderLayout(baseLayout, overrideLayout) {
12136
+ const mergedLayout = {
12137
+ ...baseLayout,
12138
+ attributes: baseLayout.attributes.map((attribute) => ({
12139
+ ...attribute
12140
+ }))
12162
12141
  };
12163
- Object.seal(config2);
12164
- return config2;
12142
+ for (const attribute of overrideLayout?.attributes || []) {
12143
+ const baseAttribute = mergedLayout.attributes.find((attr) => attr.name === attribute.name);
12144
+ if (!baseAttribute) {
12145
+ log.warn(`shader layout attribute ${attribute.name} not present in shader`);
12146
+ } else {
12147
+ baseAttribute.format = attribute.format || baseAttribute.format;
12148
+ baseAttribute.stepMode = attribute.stepMode || baseAttribute.stepMode;
12149
+ }
12150
+ }
12151
+ return mergedLayout;
12152
+ }
12153
+ function mergeBufferMap(baseLayout, bufferMap) {
12154
+ const mergedLayout = {
12155
+ ...baseLayout,
12156
+ attributes: baseLayout.attributes.map((attribute) => ({
12157
+ ...attribute
12158
+ }))
12159
+ };
12160
+ for (const bufferMapping of bufferMap) {
12161
+ switch (bufferMapping.type) {
12162
+ case "interleave":
12163
+ for (const attributeOverride of bufferMapping.attributes) {
12164
+ overrideShaderLayoutAttribute(mergedLayout, attributeOverride);
12165
+ }
12166
+ break;
12167
+ default:
12168
+ overrideShaderLayoutAttribute(mergedLayout, bufferMapping);
12169
+ }
12170
+ }
12171
+ return mergedLayout;
12172
+ }
12173
+ function overrideShaderLayoutAttribute(layout, attributeOverride) {
12174
+ const attribute = getAttributeFromLayout(layout, attributeOverride.name);
12175
+ if (attribute && attributeOverride.format) {
12176
+ attribute.format = attributeOverride.format;
12177
+ }
12178
+ }
12179
+ function getAttributeFromLayout(shaderLayout, name) {
12180
+ const attribute = shaderLayout.attributes.find((attr) => attr.name === name);
12181
+ if (!attribute) {
12182
+ log.warn(`shader layout attribute "${name}" not present in shader`);
12183
+ }
12184
+ return attribute || null;
12165
12185
  }
12166
12186
  function readAttributeBindings(gl, program) {
12167
12187
  const attributes = [];
@@ -12507,15 +12527,15 @@ ${formattedLog}`)();
12507
12527
  // Set (bind) an elements buffer, for indexed rendering.
12508
12528
  // Must be a Buffer bound to GL.ELEMENT_ARRAY_BUFFER. Constants not supported
12509
12529
  setElementBuffer(elementBuffer = null, opts = {}) {
12510
- assert2(!elementBuffer || elementBuffer.target === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);
12530
+ assert2(!elementBuffer || elementBuffer.glTarget === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);
12511
12531
  this.bind(() => {
12512
12532
  this.gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, elementBuffer ? elementBuffer.handle : null);
12513
12533
  });
12514
12534
  }
12515
12535
  /** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */
12516
- setBuffer(location, buffer2, accessor) {
12517
- if (buffer2.target === GL.ELEMENT_ARRAY_BUFFER) {
12518
- this.setElementBuffer(buffer2, accessor);
12536
+ setBuffer(location, buffer, accessor) {
12537
+ if (buffer.glTarget === GL.ELEMENT_ARRAY_BUFFER) {
12538
+ this.setElementBuffer(buffer, accessor);
12519
12539
  return;
12520
12540
  }
12521
12541
  const {
@@ -12533,7 +12553,7 @@ ${formattedLog}`)();
12533
12553
  } = this;
12534
12554
  location = Number(location);
12535
12555
  this.bind(() => {
12536
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer2.handle);
12556
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer.handle);
12537
12557
  if (integer) {
12538
12558
  this.device.assertWebGL2();
12539
12559
  gl2.vertexAttribIPointer(location, size, type, stride, offset);
@@ -12647,11 +12667,23 @@ ${formattedLog}`)();
12647
12667
  // ../webgl/src/adapter/resources/webgl-render-pipeline.ts
12648
12668
  var LOG_PROGRAM_PERF_PRIORITY = 4;
12649
12669
  var WEBGLRenderPipeline = class extends RenderPipeline {
12650
- // configuration: ProgramConfiguration;
12651
- // Experimental flag to avoid deleting Program object while it is cached
12652
- varyings = null;
12670
+ /** The WebGL device that created this render pipeline */
12671
+ /** Handle to underlying WebGL program */
12672
+ /** vertex shader */
12673
+ /** fragment shader */
12674
+ /** The merged layout */
12675
+ /** The layout extracted from shader by WebGL introspection APIs */
12676
+ /** Buffer map describing buffer interleaving etc */
12677
+ /** Uniforms set on this model */
12653
12678
  uniforms = {};
12679
+ /** Bindings set on this model */
12654
12680
  bindings = {};
12681
+ /** Any constant attributes */
12682
+ constantAttributes = {};
12683
+ /** Index buffer is stored separately */
12684
+ /** WebGL varyings */
12685
+ varyings = null;
12686
+ /** Stores attribute bindings */
12655
12687
  _textureUniforms = {};
12656
12688
  _textureIndexCounter = 0;
12657
12689
  _uniformCount = 0;
@@ -12676,7 +12708,10 @@ ${formattedLog}`)();
12676
12708
  this.device.gl2?.transformFeedbackVaryings(this.handle, varyings, bufferMode);
12677
12709
  }
12678
12710
  this._compileAndLink();
12679
- this.layout = props.layout || getShaderLayout(this.device.gl, this.handle);
12711
+ this.introspectedLayout = getShaderLayout(this.device.gl, this.handle);
12712
+ this.layout = mergeShaderLayout(this.introspectedLayout, props.layout);
12713
+ this.bufferMap = props.bufferMap || [];
12714
+ this.layout = mergeBufferMap(this.layout, this.bufferMap);
12680
12715
  this.vertexArrayObject = new WEBGLVertexArrayObject(this.device);
12681
12716
  }
12682
12717
  destroy() {
@@ -12688,15 +12723,15 @@ ${formattedLog}`)();
12688
12723
  setIndexBuffer(indexBuffer) {
12689
12724
  const webglBuffer = cast(indexBuffer);
12690
12725
  this.vertexArrayObject.setElementBuffer(webglBuffer);
12691
- this._indexBuffer = indexBuffer;
12726
+ this._indexBuffer = webglBuffer;
12692
12727
  }
12693
12728
  /** @todo needed for portable model */
12694
12729
  setAttributes(attributes) {
12695
- for (const [name, buffer2] of Object.entries(attributes)) {
12696
- const webglBuffer = cast(buffer2);
12730
+ for (const [name, buffer] of Object.entries(attributes)) {
12731
+ const webglBuffer = cast(buffer);
12697
12732
  const attribute = getAttributeLayout(this.layout, name);
12698
12733
  if (!attribute) {
12699
- log.warn(`Ignoring buffer supplied for unknown attribute "${name}" in pipeline "${this.id}" (buffer "${buffer2.id}")`)();
12734
+ log.warn(`Ignoring buffer supplied for unknown attribute "${name}" in pipeline "${this.id}" (buffer "${buffer.id}")`)();
12700
12735
  continue;
12701
12736
  }
12702
12737
  const decoded = decodeVertexFormat(attribute.format);
@@ -12735,6 +12770,7 @@ ${formattedLog}`)();
12735
12770
  }
12736
12771
  this.vertexArrayObject.setConstant(attribute.location, value);
12737
12772
  }
12773
+ Object.assign(this.constantAttributes, attributes);
12738
12774
  }
12739
12775
  /**
12740
12776
  * Bindings include: textures, samplers and uniform buffers
@@ -12790,7 +12826,7 @@ ${formattedLog}`)();
12790
12826
  } = options;
12791
12827
  const drawMode = getDrawMode(this.props.topology);
12792
12828
  const isIndexed = Boolean(this._indexBuffer);
12793
- const indexType = this._indexBuffer?.props.indexType === "uint16" ? GL.UNSIGNED_SHORT : GL.UNSIGNED_INT;
12829
+ const indexType = this._indexBuffer?.glIndexType;
12794
12830
  const isInstanced = Number(options.instanceCount) > 0;
12795
12831
  if (!this._areTexturesRenderable() || options.vertexCount === 0) {
12796
12832
  return false;
@@ -12804,6 +12840,7 @@ ${formattedLog}`)();
12804
12840
  }
12805
12841
  this._applyBindings();
12806
12842
  this._applyUniforms();
12843
+ this._applyConstantAttributes();
12807
12844
  const webglRenderPass = renderPass;
12808
12845
  withDeviceParameters(this.device, this.props.parameters, () => {
12809
12846
  withGLParameters(this.device, webglRenderPass.glParameters, () => {
@@ -12937,6 +12974,21 @@ ${formattedLog}`)();
12937
12974
  }
12938
12975
  }
12939
12976
  }
12977
+ /**
12978
+ * Constant attributes are only supported in WebGL, not in WebGPU
12979
+ * Any attribute that is disabled in the current vertex array object
12980
+ * is read from the context's global constant value for that attribute location.
12981
+ */
12982
+ _applyConstantAttributes() {
12983
+ for (const [name, value] of Object.entries(this.constantAttributes)) {
12984
+ const attribute = getAttributeLayout(this.layout, name);
12985
+ if (!attribute) {
12986
+ log.warn(`Ignoring constant value supplied for unknown attribute "${name}" in pipeline "${this.id}"`)();
12987
+ continue;
12988
+ }
12989
+ this.vertexArrayObject.setConstant(attribute.location, value);
12990
+ }
12991
+ }
12940
12992
  };
12941
12993
  function getDrawMode(topology) {
12942
12994
  switch (topology) {
@@ -13275,10 +13327,13 @@ ${formattedLog}`)();
13275
13327
  if (typeof props.canvas === "string") {
13276
13328
  await CanvasContext.pageLoaded;
13277
13329
  }
13278
- if (props.debug) {
13330
+ if (log.get("debug") || props.debug) {
13279
13331
  await loadWebGLDeveloperTools();
13280
13332
  }
13281
- if (props.spector) {
13333
+ const {
13334
+ spector: spector2
13335
+ } = props;
13336
+ if (log.get("spector") || spector2) {
13282
13337
  await loadSpectorJS();
13283
13338
  }
13284
13339
  log.probe(LOG_LEVEL2 + 1, "DOM is loaded")();