@deck.gl/geo-layers 9.3.0-alpha.3 → 9.3.0-alpha.6

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 (47) hide show
  1. package/dist/dist.dev.js +2566 -460
  2. package/dist/index.cjs +57 -15
  3. package/dist/index.cjs.map +2 -2
  4. package/dist/mesh-layer/mesh-layer-fragment.glsl.d.ts +1 -1
  5. package/dist/mesh-layer/mesh-layer-fragment.glsl.js +1 -1
  6. package/dist/mesh-layer/mesh-layer-uniforms.d.ts +2 -2
  7. package/dist/mesh-layer/mesh-layer-uniforms.js +1 -1
  8. package/dist/mesh-layer/mesh-layer-vertex.glsl.d.ts +1 -1
  9. package/dist/mesh-layer/mesh-layer-vertex.glsl.d.ts.map +1 -1
  10. package/dist/mesh-layer/mesh-layer-vertex.glsl.js +4 -3
  11. package/dist/mesh-layer/mesh-layer-vertex.glsl.js.map +1 -1
  12. package/dist/mvt-layer/mvt-layer.d.ts.map +1 -1
  13. package/dist/mvt-layer/mvt-layer.js +6 -3
  14. package/dist/mvt-layer/mvt-layer.js.map +1 -1
  15. package/dist/tile-3d-layer/tile-3d-layer.d.ts +2 -1
  16. package/dist/tile-3d-layer/tile-3d-layer.d.ts.map +1 -1
  17. package/dist/tile-3d-layer/tile-3d-layer.js +8 -0
  18. package/dist/tile-3d-layer/tile-3d-layer.js.map +1 -1
  19. package/dist/tile-layer/tile-layer.d.ts +14 -0
  20. package/dist/tile-layer/tile-layer.d.ts.map +1 -1
  21. package/dist/tile-layer/tile-layer.js +24 -3
  22. package/dist/tile-layer/tile-layer.js.map +1 -1
  23. package/dist/tileset-2d/tile-2d-header.d.ts.map +1 -1
  24. package/dist/tileset-2d/tile-2d-header.js +5 -1
  25. package/dist/tileset-2d/tile-2d-header.js.map +1 -1
  26. package/dist/tileset-2d/tileset-2d.d.ts +4 -0
  27. package/dist/tileset-2d/tileset-2d.d.ts.map +1 -1
  28. package/dist/tileset-2d/tileset-2d.js +8 -2
  29. package/dist/tileset-2d/tileset-2d.js.map +1 -1
  30. package/dist/tileset-2d/utils.d.ts +3 -1
  31. package/dist/tileset-2d/utils.d.ts.map +1 -1
  32. package/dist/tileset-2d/utils.js +7 -1
  33. package/dist/tileset-2d/utils.js.map +1 -1
  34. package/dist/trips-layer/trips-layer-uniforms.d.ts +2 -2
  35. package/dist/trips-layer/trips-layer-uniforms.js +1 -1
  36. package/dist.min.js +1566 -242
  37. package/package.json +19 -19
  38. package/src/mesh-layer/mesh-layer-fragment.glsl.ts +1 -1
  39. package/src/mesh-layer/mesh-layer-uniforms.ts +1 -1
  40. package/src/mesh-layer/mesh-layer-vertex.glsl.ts +4 -3
  41. package/src/mvt-layer/mvt-layer.ts +6 -3
  42. package/src/tile-3d-layer/tile-3d-layer.ts +11 -1
  43. package/src/tile-layer/tile-layer.ts +43 -3
  44. package/src/tileset-2d/tile-2d-header.ts +5 -1
  45. package/src/tileset-2d/tileset-2d.ts +12 -3
  46. package/src/tileset-2d/utils.ts +11 -1
  47. package/src/trips-layer/trips-layer-uniforms.ts +1 -1
package/dist/dist.dev.js CHANGED
@@ -10208,7 +10208,7 @@ var __exports__ = (() => {
10208
10208
  }
10209
10209
 
10210
10210
  // ../../node_modules/@loaders.gl/xml/dist/xml-loader.js
10211
- var VERSION = true ? "4.4.0-alpha.18" : "latest";
10211
+ var VERSION = true ? "4.4.1" : "latest";
10212
10212
  var XMLLoader = {
10213
10213
  dataType: null,
10214
10214
  batchType: null,
@@ -10791,7 +10791,7 @@ var __exports__ = (() => {
10791
10791
  var dist_default = new ProbeLog({ id: "@probe.gl/log" });
10792
10792
 
10793
10793
  // ../../node_modules/@loaders.gl/loader-utils/dist/lib/log-utils/log.js
10794
- var VERSION3 = true ? "4.4.0-alpha.18" : "latest";
10794
+ var VERSION3 = true ? "4.4.1" : "latest";
10795
10795
  var version = VERSION3[0] >= "0" && VERSION3[0] <= "9" ? `v${VERSION3}` : "";
10796
10796
  function createLog() {
10797
10797
  const log8 = new ProbeLog({ id: "loaders.gl" });
@@ -10846,7 +10846,7 @@ var __exports__ = (() => {
10846
10846
  globalThis._loadersgl_.version = NPM_TAG;
10847
10847
  warningIssued = true;
10848
10848
  } else {
10849
- globalThis._loadersgl_.version = "4.4.0-alpha.18";
10849
+ globalThis._loadersgl_.version = "4.4.1";
10850
10850
  }
10851
10851
  }
10852
10852
  return globalThis._loadersgl_.version;
@@ -11616,7 +11616,7 @@ var __exports__ = (() => {
11616
11616
  }
11617
11617
  this.data = data;
11618
11618
  this.url = typeof data === "string" ? resolvePath(data) : "";
11619
- this.loadOptions = { ...this.options.core?.loadOptions };
11619
+ this.loadOptions = normalizeDirectLoaderOptions(this.options.core?.loadOptions);
11620
11620
  this.fetch = getFetchFunction(this.loadOptions);
11621
11621
  }
11622
11622
  setProps(options) {
@@ -11659,6 +11659,23 @@ var __exports__ = (() => {
11659
11659
  }
11660
11660
  return (url) => fetch(url);
11661
11661
  }
11662
+ function normalizeDirectLoaderOptions(options) {
11663
+ const loadOptions = { ...options };
11664
+ if (options?.core) {
11665
+ loadOptions.core = { ...options.core };
11666
+ }
11667
+ const topLevelBaseUri = typeof loadOptions.baseUri === "string" ? loadOptions.baseUri : void 0;
11668
+ const topLevelBaseUrl = typeof loadOptions.baseUrl === "string" ? loadOptions.baseUrl : void 0;
11669
+ if (topLevelBaseUri !== void 0 || topLevelBaseUrl !== void 0) {
11670
+ loadOptions.core ||= {};
11671
+ if (loadOptions.core.baseUrl === void 0) {
11672
+ loadOptions.core.baseUrl = topLevelBaseUrl ?? topLevelBaseUri;
11673
+ }
11674
+ delete loadOptions.baseUri;
11675
+ delete loadOptions.baseUrl;
11676
+ }
11677
+ return loadOptions;
11678
+ }
11662
11679
 
11663
11680
  // ../../node_modules/@loaders.gl/loader-utils/dist/lib/sources/image-source.js
11664
11681
  var ImageSource = class {
@@ -11675,7 +11692,7 @@ var __exports__ = (() => {
11675
11692
  }
11676
11693
 
11677
11694
  // ../../node_modules/@loaders.gl/wms/dist/wms-error-loader.js
11678
- var VERSION5 = true ? "4.4.0-alpha.18" : "latest";
11695
+ var VERSION5 = true ? "4.4.1" : "latest";
11679
11696
  var WMSErrorLoader = {
11680
11697
  dataType: null,
11681
11698
  batchType: null,
@@ -11954,7 +11971,7 @@ var __exports__ = (() => {
11954
11971
  }
11955
11972
 
11956
11973
  // ../../node_modules/@loaders.gl/wms/dist/wms-capabilities-loader.js
11957
- var VERSION6 = true ? "4.4.0-alpha.18" : "latest";
11974
+ var VERSION6 = true ? "4.4.1" : "latest";
11958
11975
  var WMSCapabilitiesLoader = {
11959
11976
  dataType: null,
11960
11977
  batchType: null,
@@ -12027,7 +12044,7 @@ var __exports__ = (() => {
12027
12044
  };
12028
12045
 
12029
12046
  // ../../node_modules/@loaders.gl/images/dist/lib/utils/version.js
12030
- var VERSION7 = true ? "4.4.0-alpha.18" : "latest";
12047
+ var VERSION7 = true ? "4.4.1" : "latest";
12031
12048
 
12032
12049
  // ../../node_modules/@loaders.gl/images/dist/lib/category-api/image-type.js
12033
12050
  var parseImageNode = globalThis.loaders?.parseImageNode;
@@ -14482,7 +14499,9 @@ var __exports__ = (() => {
14482
14499
  tileSize = TILE_SIZE4,
14483
14500
  modelMatrix,
14484
14501
  modelMatrixInverse,
14485
- zoomOffset = 0
14502
+ zoomOffset = 0,
14503
+ visibleMinZoom,
14504
+ visibleMaxZoom
14486
14505
  }) {
14487
14506
  let z = viewport.isGeospatial ? Math.round(viewport.zoom + Math.log2(TILE_SIZE4 / tileSize)) + zoomOffset : Math.ceil(viewport.zoom) + zoomOffset;
14488
14507
  if (typeof minZoom === "number" && Number.isFinite(minZoom) && z < minZoom) {
@@ -14494,6 +14513,12 @@ var __exports__ = (() => {
14494
14513
  if (typeof maxZoom === "number" && Number.isFinite(maxZoom) && z > maxZoom) {
14495
14514
  z = maxZoom;
14496
14515
  }
14516
+ if (visibleMinZoom != null && viewport.zoom < visibleMinZoom) {
14517
+ return [];
14518
+ }
14519
+ if (visibleMaxZoom != null && viewport.zoom > visibleMaxZoom) {
14520
+ return [];
14521
+ }
14497
14522
  let transformedExtent = extent;
14498
14523
  if (modelMatrix && modelMatrixInverse && extent && !viewport.isGeospatial) {
14499
14524
  transformedExtent = transformBox(extent, modelMatrix);
@@ -14572,6 +14597,8 @@ var __exports__ = (() => {
14572
14597
  maxRequests: 6,
14573
14598
  debounceTime: 0,
14574
14599
  zoomOffset: 0,
14600
+ visibleMinZoom: null,
14601
+ visibleMaxZoom: null,
14575
14602
  // onTileLoad: (tile: Tile2DHeader) => void, // onTileUnload: (tile: Tile2DHeader) => void, // onTileError: (error: any, tile: Tile2DHeader) => void, /** Called when all tiles in the current viewport are loaded. */
14576
14603
  // onViewportLoad: ((tiles: Tile2DHeader<DataT>[]) => void) | null,
14577
14604
  onTileLoad: () => {
@@ -14635,6 +14662,7 @@ var __exports__ = (() => {
14635
14662
  if (Number.isFinite(opts.minZoom)) {
14636
14663
  this._minZoom = Math.ceil(opts.minZoom);
14637
14664
  }
14665
+ this._viewport = null;
14638
14666
  }
14639
14667
  // Clean up any outstanding tile requests.
14640
14668
  finalize() {
@@ -14744,7 +14772,7 @@ var __exports__ = (() => {
14744
14772
  modelMatrix,
14745
14773
  modelMatrixInverse
14746
14774
  }) {
14747
- const { tileSize, extent, zoomOffset } = this.opts;
14775
+ const { tileSize, extent, zoomOffset, visibleMinZoom, visibleMaxZoom } = this.opts;
14748
14776
  return getTileIndices({
14749
14777
  viewport,
14750
14778
  maxZoom,
@@ -14754,7 +14782,9 @@ var __exports__ = (() => {
14754
14782
  extent,
14755
14783
  modelMatrix,
14756
14784
  modelMatrixInverse,
14757
- zoomOffset
14785
+ zoomOffset,
14786
+ visibleMinZoom,
14787
+ visibleMaxZoom
14758
14788
  });
14759
14789
  }
14760
14790
  /** Returns unique string key for a tile index */
@@ -14981,7 +15011,9 @@ var __exports__ = (() => {
14981
15011
  zRange: null,
14982
15012
  maxRequests: 6,
14983
15013
  debounceTime: 0,
14984
- zoomOffset: 0
15014
+ zoomOffset: 0,
15015
+ visibleMinZoom: null,
15016
+ visibleMaxZoom: null
14985
15017
  };
14986
15018
  var TileLayer = class extends import_core16.CompositeLayer {
14987
15019
  initializeState() {
@@ -14996,7 +15028,12 @@ var __exports__ = (() => {
14996
15028
  get isLoaded() {
14997
15029
  return Boolean(
14998
15030
  this.state?.tileset?.selectedTiles?.every(
14999
- (tile) => tile.isLoaded && tile.layers && tile.layers.every((layer) => layer.isLoaded)
15031
+ (tile) => (
15032
+ // Error / empty tiles resolve to `content === null`. Once Tile2DHeader marks those
15033
+ // requests as loaded, do not wait for generated sublayers because there is nothing to
15034
+ // render for that tile and `tile.layers` will remain null.
15035
+ tile.isLoaded && (!tile.content || !tile.layers || tile.layers.every((layer) => layer.isLoaded))
15036
+ )
15000
15037
  )
15001
15038
  );
15002
15039
  }
@@ -15033,7 +15070,9 @@ var __exports__ = (() => {
15033
15070
  minZoom,
15034
15071
  maxRequests,
15035
15072
  debounceTime,
15036
- zoomOffset
15073
+ zoomOffset,
15074
+ visibleMinZoom,
15075
+ visibleMaxZoom
15037
15076
  } = this.props;
15038
15077
  return {
15039
15078
  maxCacheSize,
@@ -15046,6 +15085,8 @@ var __exports__ = (() => {
15046
15085
  maxRequests,
15047
15086
  debounceTime,
15048
15087
  zoomOffset,
15088
+ visibleMinZoom,
15089
+ visibleMaxZoom,
15049
15090
  getTileData: this.getTileData.bind(this),
15050
15091
  onTileLoad: this._onTileLoad.bind(this),
15051
15092
  onTileError: this._onTileError.bind(this),
@@ -15121,6 +15162,15 @@ var __exports__ = (() => {
15121
15162
  info.sourceTileSubLayer.updateAutoHighlight(info);
15122
15163
  }
15123
15164
  renderLayers() {
15165
+ const { visibleMinZoom, visibleMaxZoom, minZoom, extent } = this.props;
15166
+ const zoom = this.context.viewport.zoom;
15167
+ const hidden = visibleMinZoom != null && zoom < visibleMinZoom || visibleMaxZoom != null && zoom > visibleMaxZoom || minZoom != null && !extent && zoom < minZoom;
15168
+ if (hidden) {
15169
+ for (const tile of this.state.tileset.tiles) {
15170
+ tile.layers = null;
15171
+ }
15172
+ return [];
15173
+ }
15124
15174
  return this.state.tileset.tiles.map((tile) => {
15125
15175
  const subLayerProps = this.getSubLayerPropsByTile(tile);
15126
15176
  if (!tile.isLoaded && !tile.content) {
@@ -15166,7 +15216,7 @@ var __exports__ = (() => {
15166
15216
  var import_layers6 = __toESM(require_layers(), 1);
15167
15217
 
15168
15218
  // src/trips-layer/trips-layer-uniforms.ts
15169
- var uniformBlock = `uniform tripsUniforms {
15219
+ var uniformBlock = `layout(std140) uniform tripsUniforms {
15170
15220
  bool fadeTrail;
15171
15221
  float trailLength;
15172
15222
  float currentTime;
@@ -15508,12 +15558,12 @@ out float vTime;
15508
15558
 
15509
15559
  // src/tile-3d-layer/tile-3d-layer.ts
15510
15560
  var import_engine2 = __toESM(require_engine(), 1);
15511
- var import_core46 = __toESM(require_core(), 1);
15561
+ var import_core47 = __toESM(require_core(), 1);
15512
15562
  var import_layers8 = __toESM(require_layers(), 1);
15513
15563
  var import_mesh_layers2 = __toESM(require_mesh_layers(), 1);
15514
15564
 
15515
15565
  // ../../node_modules/@loaders.gl/textures/dist/lib/utils/version.js
15516
- var VERSION8 = true ? "4.4.0-alpha.18" : "latest";
15566
+ var VERSION8 = true ? "4.4.1" : "latest";
15517
15567
 
15518
15568
  // ../../node_modules/@loaders.gl/textures/dist/lib/parsers/basis-module-loader.js
15519
15569
  var BASIS_EXTERNAL_LIBRARIES = {
@@ -15632,7 +15682,7 @@ out float vTime;
15632
15682
  "bc7-rgba-unorm",
15633
15683
  "bc7-rgba-unorm-srgb"
15634
15684
  ],
15635
- WEBGL_compressed_texture_etc1: ["etc1-rbg-unorm-webgl"],
15685
+ WEBGL_compressed_texture_etc1: ["etc1-rgb-unorm-webgl"],
15636
15686
  WEBGL_compressed_texture_etc: [
15637
15687
  "etc2-rgb8unorm",
15638
15688
  "etc2-rgb8unorm-srgb",
@@ -15648,7 +15698,7 @@ out float vTime;
15648
15698
  WEBGL_compressed_texture_pvrtc: [
15649
15699
  "pvrtc-rgb4unorm-webgl",
15650
15700
  "pvrtc-rgba4unorm-webgl",
15651
- "pvrtc-rbg2unorm-webgl",
15701
+ "pvrtc-rgb2unorm-webgl",
15652
15702
  "pvrtc-rgba2unorm-webgl"
15653
15703
  ],
15654
15704
  WEBGL_compressed_texture_atc: [
@@ -15748,12 +15798,13 @@ out float vTime;
15748
15798
  }
15749
15799
 
15750
15800
  // ../../node_modules/@loaders.gl/textures/dist/lib/parsers/parse-basis.js
15801
+ var basisTranscodingLock = Promise.resolve();
15751
15802
  var BASIS_FORMAT_TO_OUTPUT_OPTIONS = {
15752
15803
  etc1: {
15753
15804
  basisFormat: 0,
15754
15805
  compressed: true,
15755
15806
  format: GL_COMPRESSED_RGB_ETC1_WEBGL,
15756
- textureFormat: "etc1-rbg-unorm-webgl"
15807
+ textureFormat: "etc1-rgb-unorm-webgl"
15757
15808
  },
15758
15809
  etc2: {
15759
15810
  basisFormat: 1,
@@ -15853,31 +15904,46 @@ out float vTime;
15853
15904
  }
15854
15905
  };
15855
15906
  var BASIS_FORMATS = Object.freeze(Object.keys(BASIS_FORMAT_TO_OUTPUT_OPTIONS));
15907
+ async function withBasisTranscodingLock(transcode) {
15908
+ const previousLock = basisTranscodingLock;
15909
+ let releaseLock;
15910
+ basisTranscodingLock = new Promise((resolve2) => {
15911
+ releaseLock = resolve2;
15912
+ });
15913
+ await previousLock;
15914
+ try {
15915
+ return await transcode();
15916
+ } finally {
15917
+ releaseLock();
15918
+ }
15919
+ }
15856
15920
  async function parseBasis(data, options = {}) {
15857
15921
  const loadLibraryOptions = extractLoadLibraryOptions(options);
15858
- if (!options.basis?.containerFormat || options.basis.containerFormat === "auto") {
15859
- if (isKTX(data)) {
15860
- const fileConstructors = await loadBasisEncoderModule(loadLibraryOptions);
15861
- return parseKTX2File(fileConstructors.KTX2File, data, options);
15862
- }
15863
- const { BasisFile } = await loadBasisTranscoderModule(loadLibraryOptions);
15864
- return parseBasisFile(BasisFile, data, options);
15865
- }
15866
- switch (options.basis.module) {
15867
- case "encoder":
15868
- const fileConstructors = await loadBasisEncoderModule(loadLibraryOptions);
15869
- switch (options.basis.containerFormat) {
15870
- case "ktx2":
15871
- return parseKTX2File(fileConstructors.KTX2File, data, options);
15872
- case "basis":
15873
- default:
15874
- return parseBasisFile(fileConstructors.BasisFile, data, options);
15922
+ return await withBasisTranscodingLock(async () => {
15923
+ if (!options.basis?.containerFormat || options.basis.containerFormat === "auto") {
15924
+ if (isKTX(data)) {
15925
+ const fileConstructors = await loadBasisEncoderModule(loadLibraryOptions);
15926
+ return parseKTX2File(fileConstructors.KTX2File, data, options);
15875
15927
  }
15876
- case "transcoder":
15877
- default:
15878
15928
  const { BasisFile } = await loadBasisTranscoderModule(loadLibraryOptions);
15879
15929
  return parseBasisFile(BasisFile, data, options);
15880
- }
15930
+ }
15931
+ switch (options.basis.module) {
15932
+ case "encoder":
15933
+ const fileConstructors = await loadBasisEncoderModule(loadLibraryOptions);
15934
+ switch (options.basis.containerFormat) {
15935
+ case "ktx2":
15936
+ return parseKTX2File(fileConstructors.KTX2File, data, options);
15937
+ case "basis":
15938
+ default:
15939
+ return parseBasisFile(fileConstructors.BasisFile, data, options);
15940
+ }
15941
+ case "transcoder":
15942
+ default:
15943
+ const { BasisFile } = await loadBasisTranscoderModule(loadLibraryOptions);
15944
+ return parseBasisFile(BasisFile, data, options);
15945
+ }
15946
+ });
15881
15947
  }
15882
15948
  function parseBasisFile(BasisFile, data, options) {
15883
15949
  const basisFile = new BasisFile(new Uint8Array(data));
@@ -16017,7 +16083,7 @@ out float vTime;
16017
16083
  } else if (hasSupportedTextureFormat(textureFormats2, [
16018
16084
  "pvrtc-rgb4unorm-webgl",
16019
16085
  "pvrtc-rgba4unorm-webgl",
16020
- "pvrtc-rbg2unorm-webgl",
16086
+ "pvrtc-rgb2unorm-webgl",
16021
16087
  "pvrtc-rgba2unorm-webgl"
16022
16088
  ])) {
16023
16089
  return {
@@ -16037,7 +16103,7 @@ out float vTime;
16037
16103
  "eac-rg11snorm"
16038
16104
  ])) {
16039
16105
  return "etc2";
16040
- } else if (textureFormats2.has("etc1-rbg-unorm-webgl")) {
16106
+ } else if (textureFormats2.has("etc1-rgb-unorm-webgl")) {
16041
16107
  return "etc1";
16042
16108
  } else if (hasSupportedTextureFormat(textureFormats2, [
16043
16109
  "atc-rgb-unorm-webgl",
@@ -16082,7 +16148,36 @@ out float vTime;
16082
16148
  };
16083
16149
 
16084
16150
  // ../../node_modules/@luma.gl/gltf/dist/parsers/parse-pbr-material.js
16085
- var import_core20 = __toESM(require_core3(), 1);
16151
+ var import_core21 = __toESM(require_core3(), 1);
16152
+
16153
+ // ../../node_modules/@luma.gl/gltf/dist/webgl-to-webgpu/gltf-webgl-constants.js
16154
+ var GLEnum;
16155
+ (function(GLEnum2) {
16156
+ GLEnum2[GLEnum2["POINTS"] = 0] = "POINTS";
16157
+ GLEnum2[GLEnum2["LINES"] = 1] = "LINES";
16158
+ GLEnum2[GLEnum2["LINE_LOOP"] = 2] = "LINE_LOOP";
16159
+ GLEnum2[GLEnum2["LINE_STRIP"] = 3] = "LINE_STRIP";
16160
+ GLEnum2[GLEnum2["TRIANGLES"] = 4] = "TRIANGLES";
16161
+ GLEnum2[GLEnum2["TRIANGLE_STRIP"] = 5] = "TRIANGLE_STRIP";
16162
+ GLEnum2[GLEnum2["TRIANGLE_FAN"] = 6] = "TRIANGLE_FAN";
16163
+ GLEnum2[GLEnum2["ONE"] = 1] = "ONE";
16164
+ GLEnum2[GLEnum2["SRC_ALPHA"] = 770] = "SRC_ALPHA";
16165
+ GLEnum2[GLEnum2["ONE_MINUS_SRC_ALPHA"] = 771] = "ONE_MINUS_SRC_ALPHA";
16166
+ GLEnum2[GLEnum2["FUNC_ADD"] = 32774] = "FUNC_ADD";
16167
+ GLEnum2[GLEnum2["LINEAR"] = 9729] = "LINEAR";
16168
+ GLEnum2[GLEnum2["NEAREST"] = 9728] = "NEAREST";
16169
+ GLEnum2[GLEnum2["NEAREST_MIPMAP_NEAREST"] = 9984] = "NEAREST_MIPMAP_NEAREST";
16170
+ GLEnum2[GLEnum2["LINEAR_MIPMAP_NEAREST"] = 9985] = "LINEAR_MIPMAP_NEAREST";
16171
+ GLEnum2[GLEnum2["NEAREST_MIPMAP_LINEAR"] = 9986] = "NEAREST_MIPMAP_LINEAR";
16172
+ GLEnum2[GLEnum2["LINEAR_MIPMAP_LINEAR"] = 9987] = "LINEAR_MIPMAP_LINEAR";
16173
+ GLEnum2[GLEnum2["TEXTURE_MIN_FILTER"] = 10241] = "TEXTURE_MIN_FILTER";
16174
+ GLEnum2[GLEnum2["TEXTURE_WRAP_S"] = 10242] = "TEXTURE_WRAP_S";
16175
+ GLEnum2[GLEnum2["TEXTURE_WRAP_T"] = 10243] = "TEXTURE_WRAP_T";
16176
+ GLEnum2[GLEnum2["REPEAT"] = 10497] = "REPEAT";
16177
+ GLEnum2[GLEnum2["CLAMP_TO_EDGE"] = 33071] = "CLAMP_TO_EDGE";
16178
+ GLEnum2[GLEnum2["MIRRORED_REPEAT"] = 33648] = "MIRRORED_REPEAT";
16179
+ GLEnum2[GLEnum2["UNPACK_FLIP_Y_WEBGL"] = 37440] = "UNPACK_FLIP_Y_WEBGL";
16180
+ })(GLEnum || (GLEnum = {}));
16086
16181
 
16087
16182
  // ../../node_modules/@luma.gl/gltf/dist/webgl-to-webgpu/convert-webgl-sampler.js
16088
16183
  function convertSampler(gltfSampler) {
@@ -16095,11 +16190,11 @@ out float vTime;
16095
16190
  }
16096
16191
  function convertSamplerWrapMode(mode) {
16097
16192
  switch (mode) {
16098
- case 33071:
16193
+ case GLEnum.CLAMP_TO_EDGE:
16099
16194
  return "clamp-to-edge";
16100
- case 10497:
16195
+ case GLEnum.REPEAT:
16101
16196
  return "repeat";
16102
- case 33648:
16197
+ case GLEnum.MIRRORED_REPEAT:
16103
16198
  return "mirror-repeat";
16104
16199
  default:
16105
16200
  return void 0;
@@ -16107,9 +16202,9 @@ out float vTime;
16107
16202
  }
16108
16203
  function convertSamplerMagFilter(mode) {
16109
16204
  switch (mode) {
16110
- case 9728:
16205
+ case GLEnum.NEAREST:
16111
16206
  return "nearest";
16112
- case 9729:
16207
+ case GLEnum.LINEAR:
16113
16208
  return "linear";
16114
16209
  default:
16115
16210
  return void 0;
@@ -16117,23 +16212,92 @@ out float vTime;
16117
16212
  }
16118
16213
  function convertSamplerMinFilter(mode) {
16119
16214
  switch (mode) {
16120
- case 9728:
16215
+ case GLEnum.NEAREST:
16121
16216
  return { minFilter: "nearest" };
16122
- case 9729:
16217
+ case GLEnum.LINEAR:
16123
16218
  return { minFilter: "linear" };
16124
- case 9984:
16219
+ case GLEnum.NEAREST_MIPMAP_NEAREST:
16125
16220
  return { minFilter: "nearest", mipmapFilter: "nearest" };
16126
- case 9985:
16221
+ case GLEnum.LINEAR_MIPMAP_NEAREST:
16127
16222
  return { minFilter: "linear", mipmapFilter: "nearest" };
16128
- case 9986:
16223
+ case GLEnum.NEAREST_MIPMAP_LINEAR:
16129
16224
  return { minFilter: "nearest", mipmapFilter: "linear" };
16130
- case 9987:
16225
+ case GLEnum.LINEAR_MIPMAP_LINEAR:
16131
16226
  return { minFilter: "linear", mipmapFilter: "linear" };
16132
16227
  default:
16133
16228
  return {};
16134
16229
  }
16135
16230
  }
16136
16231
 
16232
+ // ../../node_modules/@luma.gl/gltf/dist/pbr/texture-transform.js
16233
+ var TEXTURE_TRANSFORM_SLOT_DEFINITIONS = [
16234
+ createTextureTransformSlotDefinition("baseColor", "pbr_baseColorSampler", "baseColorTexture", [
16235
+ "pbrMetallicRoughness",
16236
+ "baseColorTexture"
16237
+ ]),
16238
+ createTextureTransformSlotDefinition("metallicRoughness", "pbr_metallicRoughnessSampler", "metallicRoughnessTexture", ["pbrMetallicRoughness", "metallicRoughnessTexture"]),
16239
+ createTextureTransformSlotDefinition("normal", "pbr_normalSampler", "normalTexture", [
16240
+ "normalTexture"
16241
+ ]),
16242
+ createTextureTransformSlotDefinition("occlusion", "pbr_occlusionSampler", "occlusionTexture", [
16243
+ "occlusionTexture"
16244
+ ]),
16245
+ createTextureTransformSlotDefinition("emissive", "pbr_emissiveSampler", "emissiveTexture", [
16246
+ "emissiveTexture"
16247
+ ]),
16248
+ createTextureTransformSlotDefinition("specularColor", "pbr_specularColorSampler", "KHR_materials_specular.specularColorTexture", ["extensions", "KHR_materials_specular", "specularColorTexture"]),
16249
+ createTextureTransformSlotDefinition("specularIntensity", "pbr_specularIntensitySampler", "KHR_materials_specular.specularTexture", ["extensions", "KHR_materials_specular", "specularTexture"]),
16250
+ createTextureTransformSlotDefinition("transmission", "pbr_transmissionSampler", "KHR_materials_transmission.transmissionTexture", ["extensions", "KHR_materials_transmission", "transmissionTexture"]),
16251
+ createTextureTransformSlotDefinition("thickness", "pbr_thicknessSampler", "KHR_materials_volume.thicknessTexture", ["extensions", "KHR_materials_volume", "thicknessTexture"]),
16252
+ createTextureTransformSlotDefinition("clearcoat", "pbr_clearcoatSampler", "KHR_materials_clearcoat.clearcoatTexture", ["extensions", "KHR_materials_clearcoat", "clearcoatTexture"]),
16253
+ createTextureTransformSlotDefinition("clearcoatRoughness", "pbr_clearcoatRoughnessSampler", "KHR_materials_clearcoat.clearcoatRoughnessTexture", ["extensions", "KHR_materials_clearcoat", "clearcoatRoughnessTexture"]),
16254
+ createTextureTransformSlotDefinition("clearcoatNormal", "pbr_clearcoatNormalSampler", "KHR_materials_clearcoat.clearcoatNormalTexture", ["extensions", "KHR_materials_clearcoat", "clearcoatNormalTexture"]),
16255
+ createTextureTransformSlotDefinition("sheenColor", "pbr_sheenColorSampler", "KHR_materials_sheen.sheenColorTexture", ["extensions", "KHR_materials_sheen", "sheenColorTexture"]),
16256
+ createTextureTransformSlotDefinition("sheenRoughness", "pbr_sheenRoughnessSampler", "KHR_materials_sheen.sheenRoughnessTexture", ["extensions", "KHR_materials_sheen", "sheenRoughnessTexture"]),
16257
+ createTextureTransformSlotDefinition("iridescence", "pbr_iridescenceSampler", "KHR_materials_iridescence.iridescenceTexture", ["extensions", "KHR_materials_iridescence", "iridescenceTexture"]),
16258
+ createTextureTransformSlotDefinition("iridescenceThickness", "pbr_iridescenceThicknessSampler", "KHR_materials_iridescence.iridescenceThicknessTexture", ["extensions", "KHR_materials_iridescence", "iridescenceThicknessTexture"]),
16259
+ createTextureTransformSlotDefinition("anisotropy", "pbr_anisotropySampler", "KHR_materials_anisotropy.anisotropyTexture", ["extensions", "KHR_materials_anisotropy", "anisotropyTexture"])
16260
+ ];
16261
+ var TEXTURE_TRANSFORM_SLOT_DEFINITION_MAP = new Map(TEXTURE_TRANSFORM_SLOT_DEFINITIONS.map((definition) => [definition.slot, definition]));
16262
+ function createTextureTransformSlotDefinition(slot, binding, displayName, pathSegments) {
16263
+ return {
16264
+ slot,
16265
+ binding,
16266
+ displayName,
16267
+ pathSegments,
16268
+ uvSetUniform: `${slot}UVSet`,
16269
+ uvTransformUniform: `${slot}UVTransform`
16270
+ };
16271
+ }
16272
+ function getTextureTransformSlotDefinitions() {
16273
+ return TEXTURE_TRANSFORM_SLOT_DEFINITIONS;
16274
+ }
16275
+ function getTextureTransformSlotDefinition(slot) {
16276
+ const definition = TEXTURE_TRANSFORM_SLOT_DEFINITION_MAP.get(slot);
16277
+ if (!definition) {
16278
+ throw new Error(`Unknown PBR texture transform slot ${slot}`);
16279
+ }
16280
+ return definition;
16281
+ }
16282
+ function resolveTextureTransform(textureInfo) {
16283
+ const extensionTextureTransform = textureInfo?.["extensions"]?.["KHR_texture_transform"];
16284
+ return {
16285
+ offset: extensionTextureTransform?.offset ? [extensionTextureTransform.offset[0], extensionTextureTransform.offset[1]] : [0, 0],
16286
+ rotation: extensionTextureTransform?.rotation ?? 0,
16287
+ scale: extensionTextureTransform?.scale ? [extensionTextureTransform.scale[0], extensionTextureTransform.scale[1]] : [1, 1]
16288
+ };
16289
+ }
16290
+ function resolveTextureCoordinateSet(textureInfo) {
16291
+ const extensionTextureTransform = textureInfo?.["extensions"]?.["KHR_texture_transform"];
16292
+ return extensionTextureTransform?.["texCoord"] ?? textureInfo?.["texCoord"] ?? 0;
16293
+ }
16294
+ function getTextureTransformMatrix(transform2) {
16295
+ const translationMatrix = new Matrix3().set(1, 0, 0, 0, 1, 0, transform2.offset[0], transform2.offset[1], 1);
16296
+ const rotationMatrix = new Matrix3().set(Math.cos(transform2.rotation), Math.sin(transform2.rotation), 0, -Math.sin(transform2.rotation), Math.cos(transform2.rotation), 0, 0, 0, 1);
16297
+ const scaleMatrix = new Matrix3().set(transform2.scale[0], 0, 0, 0, transform2.scale[1], 0, 0, 0, 1);
16298
+ return Array.from(translationMatrix.multiplyRight(rotationMatrix).multiplyRight(scaleMatrix));
16299
+ }
16300
+
16137
16301
  // ../../node_modules/@luma.gl/gltf/dist/parsers/parse-pbr-material.js
16138
16302
  function parsePBRMaterial(device, material, attributes, options) {
16139
16303
  const parsedMaterial = {
@@ -16159,7 +16323,8 @@ out float vTime;
16159
16323
  if (imageBasedLightingEnvironment) {
16160
16324
  parsedMaterial.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler.texture;
16161
16325
  parsedMaterial.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler.texture;
16162
- parsedMaterial.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
16326
+ parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
16327
+ parsedMaterial.uniforms.IBLenabled = true;
16163
16328
  parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
16164
16329
  }
16165
16330
  if (options?.pbrDebug) {
@@ -16173,6 +16338,8 @@ out float vTime;
16173
16338
  parsedMaterial.defines["HAS_TANGENTS"] = true;
16174
16339
  if (attributes["TEXCOORD_0"])
16175
16340
  parsedMaterial.defines["HAS_UV"] = true;
16341
+ if (attributes["TEXCOORD_1"])
16342
+ parsedMaterial.defines["HAS_UV_1"] = true;
16176
16343
  if (attributes["JOINTS_0"] && attributes["WEIGHTS_0"])
16177
16344
  parsedMaterial.defines["HAS_SKIN"] = true;
16178
16345
  if (attributes["COLOR_0"])
@@ -16182,68 +16349,439 @@ out float vTime;
16182
16349
  if (options?.lights)
16183
16350
  parsedMaterial.defines["USE_LIGHTS"] = true;
16184
16351
  if (material) {
16185
- parseMaterial(device, material, parsedMaterial);
16352
+ if (options.validateAttributes !== false) {
16353
+ warnOnMissingExpectedAttributes(material, attributes);
16354
+ }
16355
+ parseMaterial(device, material, parsedMaterial, attributes, options.gltf);
16186
16356
  }
16187
16357
  return parsedMaterial;
16188
16358
  }
16189
- function parseMaterial(device, material, parsedMaterial) {
16190
- parsedMaterial.uniforms.unlit = Boolean(material.unlit);
16359
+ function warnOnMissingExpectedAttributes(material, attributes) {
16360
+ const uvDependentTextureSlots = getUvDependentTextureSlots(material, 0);
16361
+ if (uvDependentTextureSlots.length > 0 && !attributes["TEXCOORD_0"]) {
16362
+ import_core21.log.warn(`glTF material uses ${uvDependentTextureSlots.join(", ")} but primitive is missing TEXCOORD_0; textured shading will sample the default UV coordinates`)();
16363
+ }
16364
+ const uv1DependentTextureSlots = getUvDependentTextureSlots(material, 1);
16365
+ if (uv1DependentTextureSlots.length > 0 && !attributes["TEXCOORD_1"]) {
16366
+ import_core21.log.warn(`glTF material uses ${uv1DependentTextureSlots.join(", ")} with TEXCOORD_1 but primitive is missing TEXCOORD_1; those textures will be skipped`)();
16367
+ }
16368
+ const isUnlitMaterial = Boolean(material.unlit || material.extensions?.KHR_materials_unlit);
16369
+ if (isUnlitMaterial || attributes["NORMAL"]) {
16370
+ return;
16371
+ }
16372
+ const missingNormalReason = material.normalTexture ? "lit PBR shading with normalTexture" : "lit PBR shading";
16373
+ import_core21.log.warn(`glTF primitive is missing NORMAL while using ${missingNormalReason}; shading will fall back to geometric normals`)();
16374
+ }
16375
+ function getUvDependentTextureSlots(material, textureCoordinateSet) {
16376
+ const uvDependentTextureSlots = [];
16377
+ for (const slotDefinition of getTextureTransformSlotDefinitions()) {
16378
+ const textureInfo = getNestedTextureInfo(material, slotDefinition.pathSegments);
16379
+ if (!textureInfo) {
16380
+ continue;
16381
+ }
16382
+ if (resolveTextureCoordinateSet(textureInfo) === textureCoordinateSet) {
16383
+ uvDependentTextureSlots.push(slotDefinition.displayName);
16384
+ }
16385
+ }
16386
+ return uvDependentTextureSlots;
16387
+ }
16388
+ function getNestedTextureInfo(material, pathSegments) {
16389
+ let value = material;
16390
+ for (const pathSegment of pathSegments) {
16391
+ value = value?.[pathSegment];
16392
+ if (!value) {
16393
+ return null;
16394
+ }
16395
+ }
16396
+ return value;
16397
+ }
16398
+ function parseMaterial(device, material, parsedMaterial, attributes, gltf) {
16399
+ parsedMaterial.uniforms.unlit = Boolean(material.unlit || material.extensions?.KHR_materials_unlit);
16191
16400
  if (material.pbrMetallicRoughness) {
16192
- parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
16401
+ parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial, attributes, gltf);
16193
16402
  }
16194
16403
  if (material.normalTexture) {
16195
- addTexture(device, material.normalTexture, "pbr_normalSampler", "HAS_NORMALMAP", parsedMaterial);
16404
+ addTexture(device, material.normalTexture, "pbr_normalSampler", parsedMaterial, {
16405
+ featureOptions: {
16406
+ define: "HAS_NORMALMAP",
16407
+ enabledUniformName: "normalMapEnabled"
16408
+ },
16409
+ gltf,
16410
+ attributes,
16411
+ textureTransformSlot: "normal"
16412
+ });
16196
16413
  const { scale: scale12 = 1 } = material.normalTexture;
16197
16414
  parsedMaterial.uniforms.normalScale = scale12;
16198
16415
  }
16199
16416
  if (material.occlusionTexture) {
16200
- addTexture(device, material.occlusionTexture, "pbr_occlusionSampler", "HAS_OCCLUSIONMAP", parsedMaterial);
16417
+ addTexture(device, material.occlusionTexture, "pbr_occlusionSampler", parsedMaterial, {
16418
+ featureOptions: {
16419
+ define: "HAS_OCCLUSIONMAP",
16420
+ enabledUniformName: "occlusionMapEnabled"
16421
+ },
16422
+ gltf,
16423
+ attributes,
16424
+ textureTransformSlot: "occlusion"
16425
+ });
16201
16426
  const { strength = 1 } = material.occlusionTexture;
16202
16427
  parsedMaterial.uniforms.occlusionStrength = strength;
16203
16428
  }
16429
+ parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
16204
16430
  if (material.emissiveTexture) {
16205
- addTexture(device, material.emissiveTexture, "pbr_emissiveSampler", "HAS_EMISSIVEMAP", parsedMaterial);
16206
- parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
16431
+ addTexture(device, material.emissiveTexture, "pbr_emissiveSampler", parsedMaterial, {
16432
+ featureOptions: {
16433
+ define: "HAS_EMISSIVEMAP",
16434
+ enabledUniformName: "emissiveMapEnabled"
16435
+ },
16436
+ gltf,
16437
+ attributes,
16438
+ textureTransformSlot: "emissive"
16439
+ });
16207
16440
  }
16208
- switch (material.alphaMode || "MASK") {
16209
- case "MASK":
16441
+ parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf, attributes);
16442
+ switch (material.alphaMode || "OPAQUE") {
16443
+ case "OPAQUE":
16444
+ break;
16445
+ case "MASK": {
16210
16446
  const { alphaCutoff = 0.5 } = material;
16211
16447
  parsedMaterial.defines["ALPHA_CUTOFF"] = true;
16448
+ parsedMaterial.uniforms.alphaCutoffEnabled = true;
16212
16449
  parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
16213
16450
  break;
16451
+ }
16214
16452
  case "BLEND":
16215
- import_core20.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
16216
- parsedMaterial.parameters.blend = true;
16217
- parsedMaterial.parameters.blendColorOperation = "add";
16218
- parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
16219
- parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
16220
- parsedMaterial.parameters.blendAlphaOperation = "add";
16221
- parsedMaterial.parameters.blendAlphaSrcFactor = "one";
16222
- parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
16223
- parsedMaterial.glParameters["blend"] = true;
16224
- parsedMaterial.glParameters["blendEquation"] = 32774;
16225
- parsedMaterial.glParameters["blendFunc"] = [
16226
- 770,
16227
- 771,
16228
- 1,
16229
- 771
16230
- ];
16453
+ import_core21.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
16454
+ applyAlphaBlendParameters(parsedMaterial);
16231
16455
  break;
16232
16456
  }
16233
16457
  }
16234
- function parsePbrMetallicRoughness(device, pbrMetallicRoughness, parsedMaterial) {
16458
+ function applyAlphaBlendParameters(parsedMaterial) {
16459
+ parsedMaterial.parameters.blend = true;
16460
+ parsedMaterial.parameters.blendColorOperation = "add";
16461
+ parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
16462
+ parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
16463
+ parsedMaterial.parameters.blendAlphaOperation = "add";
16464
+ parsedMaterial.parameters.blendAlphaSrcFactor = "one";
16465
+ parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
16466
+ parsedMaterial.glParameters["blend"] = true;
16467
+ parsedMaterial.glParameters["blendEquation"] = GLEnum.FUNC_ADD;
16468
+ parsedMaterial.glParameters["blendFunc"] = [
16469
+ GLEnum.SRC_ALPHA,
16470
+ GLEnum.ONE_MINUS_SRC_ALPHA,
16471
+ GLEnum.ONE,
16472
+ GLEnum.ONE_MINUS_SRC_ALPHA
16473
+ ];
16474
+ }
16475
+ function applyTransmissionBlendApproximation(parsedMaterial) {
16476
+ parsedMaterial.parameters.blend = true;
16477
+ parsedMaterial.parameters.depthWriteEnabled = false;
16478
+ parsedMaterial.parameters.blendColorOperation = "add";
16479
+ parsedMaterial.parameters.blendColorSrcFactor = "one";
16480
+ parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
16481
+ parsedMaterial.parameters.blendAlphaOperation = "add";
16482
+ parsedMaterial.parameters.blendAlphaSrcFactor = "one";
16483
+ parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
16484
+ parsedMaterial.glParameters["blend"] = true;
16485
+ parsedMaterial.glParameters["depthMask"] = false;
16486
+ parsedMaterial.glParameters["blendEquation"] = GLEnum.FUNC_ADD;
16487
+ parsedMaterial.glParameters["blendFunc"] = [
16488
+ GLEnum.ONE,
16489
+ GLEnum.ONE_MINUS_SRC_ALPHA,
16490
+ GLEnum.ONE,
16491
+ GLEnum.ONE_MINUS_SRC_ALPHA
16492
+ ];
16493
+ }
16494
+ function parsePbrMetallicRoughness(device, pbrMetallicRoughness, parsedMaterial, attributes, gltf) {
16235
16495
  if (pbrMetallicRoughness.baseColorTexture) {
16236
- addTexture(device, pbrMetallicRoughness.baseColorTexture, "pbr_baseColorSampler", "HAS_BASECOLORMAP", parsedMaterial);
16496
+ addTexture(device, pbrMetallicRoughness.baseColorTexture, "pbr_baseColorSampler", parsedMaterial, {
16497
+ featureOptions: {
16498
+ define: "HAS_BASECOLORMAP",
16499
+ enabledUniformName: "baseColorMapEnabled"
16500
+ },
16501
+ gltf,
16502
+ attributes,
16503
+ textureTransformSlot: "baseColor"
16504
+ });
16237
16505
  }
16238
16506
  parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
16239
16507
  if (pbrMetallicRoughness.metallicRoughnessTexture) {
16240
- addTexture(device, pbrMetallicRoughness.metallicRoughnessTexture, "pbr_metallicRoughnessSampler", "HAS_METALROUGHNESSMAP", parsedMaterial);
16508
+ addTexture(device, pbrMetallicRoughness.metallicRoughnessTexture, "pbr_metallicRoughnessSampler", parsedMaterial, {
16509
+ featureOptions: {
16510
+ define: "HAS_METALROUGHNESSMAP",
16511
+ enabledUniformName: "metallicRoughnessMapEnabled"
16512
+ },
16513
+ gltf,
16514
+ attributes,
16515
+ textureTransformSlot: "metallicRoughness"
16516
+ });
16241
16517
  }
16242
16518
  const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
16243
16519
  parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
16244
16520
  }
16245
- function addTexture(device, gltfTexture, uniformName, define2, parsedMaterial) {
16246
- const image = gltfTexture.texture.source.image;
16521
+ function parseMaterialExtensions(device, extensions, parsedMaterial, gltf, attributes = {}) {
16522
+ if (!extensions) {
16523
+ return;
16524
+ }
16525
+ if (hasMaterialExtensionShading(extensions)) {
16526
+ parsedMaterial.defines["USE_MATERIAL_EXTENSIONS"] = true;
16527
+ }
16528
+ parseSpecularExtension(device, extensions.KHR_materials_specular, parsedMaterial, gltf, attributes);
16529
+ parseIorExtension(extensions.KHR_materials_ior, parsedMaterial);
16530
+ parseTransmissionExtension(device, extensions.KHR_materials_transmission, parsedMaterial, gltf, attributes);
16531
+ parseVolumeExtension(device, extensions.KHR_materials_volume, parsedMaterial, gltf, attributes);
16532
+ parseClearcoatExtension(device, extensions.KHR_materials_clearcoat, parsedMaterial, gltf, attributes);
16533
+ parseSheenExtension(device, extensions.KHR_materials_sheen, parsedMaterial, gltf, attributes);
16534
+ parseIridescenceExtension(device, extensions.KHR_materials_iridescence, parsedMaterial, gltf, attributes);
16535
+ parseAnisotropyExtension(device, extensions.KHR_materials_anisotropy, parsedMaterial, gltf, attributes);
16536
+ parseEmissiveStrengthExtension(extensions.KHR_materials_emissive_strength, parsedMaterial);
16537
+ }
16538
+ function hasMaterialExtensionShading(extensions) {
16539
+ return Boolean(extensions.KHR_materials_specular || extensions.KHR_materials_ior || extensions.KHR_materials_transmission || extensions.KHR_materials_volume || extensions.KHR_materials_clearcoat || extensions.KHR_materials_sheen || extensions.KHR_materials_iridescence || extensions.KHR_materials_anisotropy);
16540
+ }
16541
+ function parseSpecularExtension(device, extension, parsedMaterial, gltf, attributes = {}) {
16542
+ if (!extension) {
16543
+ return;
16544
+ }
16545
+ if (extension.specularColorFactor) {
16546
+ parsedMaterial.uniforms.specularColorFactor = extension.specularColorFactor;
16547
+ }
16548
+ if (extension.specularFactor !== void 0) {
16549
+ parsedMaterial.uniforms.specularIntensityFactor = extension.specularFactor;
16550
+ }
16551
+ if (extension.specularColorTexture) {
16552
+ addTexture(device, extension.specularColorTexture, "pbr_specularColorSampler", parsedMaterial, {
16553
+ featureOptions: {
16554
+ define: "HAS_SPECULARCOLORMAP",
16555
+ enabledUniformName: "specularColorMapEnabled"
16556
+ },
16557
+ gltf,
16558
+ attributes,
16559
+ textureTransformSlot: "specularColor"
16560
+ });
16561
+ }
16562
+ if (extension.specularTexture) {
16563
+ addTexture(device, extension.specularTexture, "pbr_specularIntensitySampler", parsedMaterial, {
16564
+ featureOptions: {
16565
+ define: "HAS_SPECULARINTENSITYMAP",
16566
+ enabledUniformName: "specularIntensityMapEnabled"
16567
+ },
16568
+ gltf,
16569
+ attributes,
16570
+ textureTransformSlot: "specularIntensity"
16571
+ });
16572
+ }
16573
+ }
16574
+ function parseIorExtension(extension, parsedMaterial) {
16575
+ if (extension?.ior !== void 0) {
16576
+ parsedMaterial.uniforms.ior = extension.ior;
16577
+ }
16578
+ }
16579
+ function parseTransmissionExtension(device, extension, parsedMaterial, gltf, attributes = {}) {
16580
+ if (!extension) {
16581
+ return;
16582
+ }
16583
+ if (extension.transmissionFactor !== void 0) {
16584
+ parsedMaterial.uniforms.transmissionFactor = extension.transmissionFactor;
16585
+ }
16586
+ if (extension.transmissionTexture) {
16587
+ addTexture(device, extension.transmissionTexture, "pbr_transmissionSampler", parsedMaterial, {
16588
+ featureOptions: {
16589
+ define: "HAS_TRANSMISSIONMAP",
16590
+ enabledUniformName: "transmissionMapEnabled"
16591
+ },
16592
+ gltf,
16593
+ attributes,
16594
+ textureTransformSlot: "transmission"
16595
+ });
16596
+ }
16597
+ if ((extension.transmissionFactor ?? 0) > 0 || extension.transmissionTexture) {
16598
+ import_core21.log.warn("KHR_materials_transmission uses a premultiplied-alpha blending approximation and may require mesh sorting")();
16599
+ applyTransmissionBlendApproximation(parsedMaterial);
16600
+ }
16601
+ }
16602
+ function parseVolumeExtension(device, extension, parsedMaterial, gltf, attributes = {}) {
16603
+ if (!extension) {
16604
+ return;
16605
+ }
16606
+ if (extension.thicknessFactor !== void 0) {
16607
+ parsedMaterial.uniforms.thicknessFactor = extension.thicknessFactor;
16608
+ }
16609
+ if (extension.thicknessTexture) {
16610
+ addTexture(device, extension.thicknessTexture, "pbr_thicknessSampler", parsedMaterial, {
16611
+ featureOptions: {
16612
+ define: "HAS_THICKNESSMAP"
16613
+ },
16614
+ gltf,
16615
+ attributes,
16616
+ textureTransformSlot: "thickness"
16617
+ });
16618
+ }
16619
+ if (extension.attenuationDistance !== void 0) {
16620
+ parsedMaterial.uniforms.attenuationDistance = extension.attenuationDistance;
16621
+ }
16622
+ if (extension.attenuationColor) {
16623
+ parsedMaterial.uniforms.attenuationColor = extension.attenuationColor;
16624
+ }
16625
+ }
16626
+ function parseClearcoatExtension(device, extension, parsedMaterial, gltf, attributes = {}) {
16627
+ if (!extension) {
16628
+ return;
16629
+ }
16630
+ if (extension.clearcoatFactor !== void 0) {
16631
+ parsedMaterial.uniforms.clearcoatFactor = extension.clearcoatFactor;
16632
+ }
16633
+ if (extension.clearcoatRoughnessFactor !== void 0) {
16634
+ parsedMaterial.uniforms.clearcoatRoughnessFactor = extension.clearcoatRoughnessFactor;
16635
+ }
16636
+ if (extension.clearcoatTexture) {
16637
+ addTexture(device, extension.clearcoatTexture, "pbr_clearcoatSampler", parsedMaterial, {
16638
+ featureOptions: {
16639
+ define: "HAS_CLEARCOATMAP",
16640
+ enabledUniformName: "clearcoatMapEnabled"
16641
+ },
16642
+ gltf,
16643
+ attributes,
16644
+ textureTransformSlot: "clearcoat"
16645
+ });
16646
+ }
16647
+ if (extension.clearcoatRoughnessTexture) {
16648
+ addTexture(device, extension.clearcoatRoughnessTexture, "pbr_clearcoatRoughnessSampler", parsedMaterial, {
16649
+ featureOptions: {
16650
+ define: "HAS_CLEARCOATROUGHNESSMAP",
16651
+ enabledUniformName: "clearcoatRoughnessMapEnabled"
16652
+ },
16653
+ gltf,
16654
+ attributes,
16655
+ textureTransformSlot: "clearcoatRoughness"
16656
+ });
16657
+ }
16658
+ if (extension.clearcoatNormalTexture) {
16659
+ addTexture(device, extension.clearcoatNormalTexture, "pbr_clearcoatNormalSampler", parsedMaterial, {
16660
+ featureOptions: {
16661
+ define: "HAS_CLEARCOATNORMALMAP"
16662
+ },
16663
+ gltf,
16664
+ attributes,
16665
+ textureTransformSlot: "clearcoatNormal"
16666
+ });
16667
+ }
16668
+ }
16669
+ function parseSheenExtension(device, extension, parsedMaterial, gltf, attributes = {}) {
16670
+ if (!extension) {
16671
+ return;
16672
+ }
16673
+ if (extension.sheenColorFactor) {
16674
+ parsedMaterial.uniforms.sheenColorFactor = extension.sheenColorFactor;
16675
+ }
16676
+ if (extension.sheenRoughnessFactor !== void 0) {
16677
+ parsedMaterial.uniforms.sheenRoughnessFactor = extension.sheenRoughnessFactor;
16678
+ }
16679
+ if (extension.sheenColorTexture) {
16680
+ addTexture(device, extension.sheenColorTexture, "pbr_sheenColorSampler", parsedMaterial, {
16681
+ featureOptions: {
16682
+ define: "HAS_SHEENCOLORMAP",
16683
+ enabledUniformName: "sheenColorMapEnabled"
16684
+ },
16685
+ gltf,
16686
+ attributes,
16687
+ textureTransformSlot: "sheenColor"
16688
+ });
16689
+ }
16690
+ if (extension.sheenRoughnessTexture) {
16691
+ addTexture(device, extension.sheenRoughnessTexture, "pbr_sheenRoughnessSampler", parsedMaterial, {
16692
+ featureOptions: {
16693
+ define: "HAS_SHEENROUGHNESSMAP",
16694
+ enabledUniformName: "sheenRoughnessMapEnabled"
16695
+ },
16696
+ gltf,
16697
+ attributes,
16698
+ textureTransformSlot: "sheenRoughness"
16699
+ });
16700
+ }
16701
+ }
16702
+ function parseIridescenceExtension(device, extension, parsedMaterial, gltf, attributes = {}) {
16703
+ if (!extension) {
16704
+ return;
16705
+ }
16706
+ if (extension.iridescenceFactor !== void 0) {
16707
+ parsedMaterial.uniforms.iridescenceFactor = extension.iridescenceFactor;
16708
+ }
16709
+ if (extension.iridescenceIor !== void 0) {
16710
+ parsedMaterial.uniforms.iridescenceIor = extension.iridescenceIor;
16711
+ }
16712
+ if (extension.iridescenceThicknessMinimum !== void 0 || extension.iridescenceThicknessMaximum !== void 0) {
16713
+ parsedMaterial.uniforms.iridescenceThicknessRange = [
16714
+ extension.iridescenceThicknessMinimum ?? 100,
16715
+ extension.iridescenceThicknessMaximum ?? 400
16716
+ ];
16717
+ }
16718
+ if (extension.iridescenceTexture) {
16719
+ addTexture(device, extension.iridescenceTexture, "pbr_iridescenceSampler", parsedMaterial, {
16720
+ featureOptions: {
16721
+ define: "HAS_IRIDESCENCEMAP",
16722
+ enabledUniformName: "iridescenceMapEnabled"
16723
+ },
16724
+ gltf,
16725
+ attributes,
16726
+ textureTransformSlot: "iridescence"
16727
+ });
16728
+ }
16729
+ if (extension.iridescenceThicknessTexture) {
16730
+ addTexture(device, extension.iridescenceThicknessTexture, "pbr_iridescenceThicknessSampler", parsedMaterial, {
16731
+ featureOptions: {
16732
+ define: "HAS_IRIDESCENCETHICKNESSMAP"
16733
+ },
16734
+ gltf,
16735
+ attributes,
16736
+ textureTransformSlot: "iridescenceThickness"
16737
+ });
16738
+ }
16739
+ }
16740
+ function parseAnisotropyExtension(device, extension, parsedMaterial, gltf, attributes = {}) {
16741
+ if (!extension) {
16742
+ return;
16743
+ }
16744
+ if (extension.anisotropyStrength !== void 0) {
16745
+ parsedMaterial.uniforms.anisotropyStrength = extension.anisotropyStrength;
16746
+ }
16747
+ if (extension.anisotropyRotation !== void 0) {
16748
+ parsedMaterial.uniforms.anisotropyRotation = extension.anisotropyRotation;
16749
+ }
16750
+ if (extension.anisotropyTexture) {
16751
+ addTexture(device, extension.anisotropyTexture, "pbr_anisotropySampler", parsedMaterial, {
16752
+ featureOptions: {
16753
+ define: "HAS_ANISOTROPYMAP",
16754
+ enabledUniformName: "anisotropyMapEnabled"
16755
+ },
16756
+ gltf,
16757
+ attributes,
16758
+ textureTransformSlot: "anisotropy"
16759
+ });
16760
+ }
16761
+ }
16762
+ function parseEmissiveStrengthExtension(extension, parsedMaterial) {
16763
+ if (extension?.emissiveStrength !== void 0) {
16764
+ parsedMaterial.uniforms.emissiveStrength = extension.emissiveStrength;
16765
+ }
16766
+ }
16767
+ function addTexture(device, gltfTexture, uniformName, parsedMaterial, textureParseOptions = {}) {
16768
+ const { featureOptions = {}, gltf, attributes = {}, textureTransformSlot } = textureParseOptions;
16769
+ const { define: define2, enabledUniformName } = featureOptions;
16770
+ const textureCoordinateSet = resolveTextureCoordinateSet(gltfTexture);
16771
+ if (textureCoordinateSet > 1) {
16772
+ import_core21.log.warn(`Skipping ${String(uniformName)} because ${textureCoordinateSet} is not supported; only TEXCOORD_0 and TEXCOORD_1 are currently available`)();
16773
+ return;
16774
+ }
16775
+ if (textureCoordinateSet === 1 && !attributes["TEXCOORD_1"]) {
16776
+ import_core21.log.warn(`Skipping ${String(uniformName)} because it requires TEXCOORD_1 but the primitive does not provide TEXCOORD_1`)();
16777
+ return;
16778
+ }
16779
+ const resolvedTextureInfo = resolveTextureInfo(gltfTexture, gltf);
16780
+ const image = resolvedTextureInfo.texture?.source?.image;
16781
+ if (!image) {
16782
+ import_core21.log.warn(`Skipping unresolved glTF texture for ${String(uniformName)}`)();
16783
+ return;
16784
+ }
16247
16785
  const gltfSampler = {
16248
16786
  wrapS: 10497,
16249
16787
  // default REPEAT S (U) wrapping mode.
@@ -16253,10 +16791,10 @@ out float vTime;
16253
16791
  // default LINEAR filtering
16254
16792
  magFilter: 9729,
16255
16793
  // default LINEAR filtering
16256
- ...gltfTexture?.texture?.sampler
16794
+ ...resolvedTextureInfo?.texture?.sampler
16257
16795
  };
16258
16796
  const baseOptions = {
16259
- id: gltfTexture.uniformName || gltfTexture.id,
16797
+ id: resolvedTextureInfo.uniformName || resolvedTextureInfo.id,
16260
16798
  sampler: convertSampler(gltfSampler)
16261
16799
  };
16262
16800
  let texture;
@@ -16274,8 +16812,39 @@ out float vTime;
16274
16812
  parsedMaterial.bindings[uniformName] = texture;
16275
16813
  if (define2)
16276
16814
  parsedMaterial.defines[define2] = true;
16815
+ if (enabledUniformName) {
16816
+ parsedMaterial.uniforms[enabledUniformName] = true;
16817
+ }
16818
+ if (textureTransformSlot) {
16819
+ const textureTransformSlotDefinition = getTextureTransformSlotDefinition(textureTransformSlot);
16820
+ parsedMaterial.uniforms[textureTransformSlotDefinition.uvSetUniform] = textureCoordinateSet;
16821
+ parsedMaterial.uniforms[textureTransformSlotDefinition.uvTransformUniform] = getTextureTransformMatrix(resolveTextureTransform(gltfTexture));
16822
+ }
16277
16823
  parsedMaterial.generatedTextures.push(texture);
16278
16824
  }
16825
+ function resolveTextureInfo(gltfTexture, gltf) {
16826
+ if (gltfTexture.texture || gltfTexture.index === void 0 || !gltf?.textures) {
16827
+ return gltfTexture;
16828
+ }
16829
+ const resolvedTextureEntry = gltf.textures[gltfTexture.index];
16830
+ if (!resolvedTextureEntry) {
16831
+ return gltfTexture;
16832
+ }
16833
+ if ("texture" in resolvedTextureEntry && resolvedTextureEntry.texture) {
16834
+ return {
16835
+ ...resolvedTextureEntry,
16836
+ ...gltfTexture,
16837
+ texture: resolvedTextureEntry.texture
16838
+ };
16839
+ }
16840
+ if (!("source" in resolvedTextureEntry)) {
16841
+ return gltfTexture;
16842
+ }
16843
+ return {
16844
+ ...gltfTexture,
16845
+ texture: resolvedTextureEntry
16846
+ };
16847
+ }
16279
16848
  function createCompressedTextureFallback(device, baseOptions) {
16280
16849
  return device.createTexture({
16281
16850
  ...baseOptions,
@@ -16289,7 +16858,7 @@ out float vTime;
16289
16858
  return level.textureFormat;
16290
16859
  }
16291
16860
  function getMaxCompressedMipLevels(baseWidth, baseHeight, format) {
16292
- const { blockWidth = 1, blockHeight = 1 } = import_core20.textureFormatDecoder.getInfo(format);
16861
+ const { blockWidth = 1, blockHeight = 1 } = import_core21.textureFormatDecoder.getInfo(format);
16293
16862
  let count = 1;
16294
16863
  for (let i = 1; ; i++) {
16295
16864
  const w2 = Math.max(1, baseWidth >> i);
@@ -16310,19 +16879,19 @@ out float vTime;
16310
16879
  levels = [];
16311
16880
  }
16312
16881
  if (levels.length === 0 || !levels[0]?.data) {
16313
- import_core20.log.warn("createCompressedTexture: compressed image has no valid mip levels, creating fallback")();
16882
+ import_core21.log.warn("createCompressedTexture: compressed image has no valid mip levels, creating fallback")();
16314
16883
  return createCompressedTextureFallback(device, baseOptions);
16315
16884
  }
16316
16885
  const baseLevel = levels[0];
16317
16886
  const baseWidth = baseLevel.width ?? image.width ?? 0;
16318
16887
  const baseHeight = baseLevel.height ?? image.height ?? 0;
16319
16888
  if (baseWidth <= 0 || baseHeight <= 0) {
16320
- import_core20.log.warn("createCompressedTexture: base level has invalid dimensions, creating fallback")();
16889
+ import_core21.log.warn("createCompressedTexture: base level has invalid dimensions, creating fallback")();
16321
16890
  return createCompressedTextureFallback(device, baseOptions);
16322
16891
  }
16323
16892
  const format = resolveCompressedTextureFormat(baseLevel);
16324
16893
  if (!format) {
16325
- import_core20.log.warn("createCompressedTexture: compressed image has no textureFormat, creating fallback")();
16894
+ import_core21.log.warn("createCompressedTexture: compressed image has no textureFormat, creating fallback")();
16326
16895
  return createCompressedTextureFallback(device, baseOptions);
16327
16896
  }
16328
16897
  const maxMipLevels = getMaxCompressedMipLevels(baseWidth, baseHeight, format);
@@ -16331,18 +16900,18 @@ out float vTime;
16331
16900
  for (let i = 1; i < levelLimit; i++) {
16332
16901
  const level = levels[i];
16333
16902
  if (!level.data || level.width <= 0 || level.height <= 0) {
16334
- import_core20.log.warn(`createCompressedTexture: mip level ${i} has invalid data/dimensions, truncating`)();
16903
+ import_core21.log.warn(`createCompressedTexture: mip level ${i} has invalid data/dimensions, truncating`)();
16335
16904
  break;
16336
16905
  }
16337
16906
  const levelFormat = resolveCompressedTextureFormat(level);
16338
16907
  if (levelFormat && levelFormat !== format) {
16339
- import_core20.log.warn(`createCompressedTexture: mip level ${i} format '${levelFormat}' differs from base '${format}', truncating`)();
16908
+ import_core21.log.warn(`createCompressedTexture: mip level ${i} format '${levelFormat}' differs from base '${format}', truncating`)();
16340
16909
  break;
16341
16910
  }
16342
16911
  const expectedW = Math.max(1, baseWidth >> i);
16343
16912
  const expectedH = Math.max(1, baseHeight >> i);
16344
16913
  if (level.width !== expectedW || level.height !== expectedH) {
16345
- import_core20.log.warn(`createCompressedTexture: mip level ${i} dimensions ${level.width}x${level.height} don't match expected ${expectedW}x${expectedH}, truncating`)();
16914
+ import_core21.log.warn(`createCompressedTexture: mip level ${i} dimensions ${level.width}x${level.height} don't match expected ${expectedW}x${expectedH}, truncating`)();
16346
16915
  break;
16347
16916
  }
16348
16917
  validLevelCount++;
@@ -16350,7 +16919,7 @@ out float vTime;
16350
16919
  const texture = device.createTexture({
16351
16920
  ...baseOptions,
16352
16921
  format,
16353
- usage: import_core20.Texture.TEXTURE | import_core20.Texture.COPY_DST,
16922
+ usage: import_core21.Texture.TEXTURE | import_core21.Texture.COPY_DST,
16354
16923
  width: baseWidth,
16355
16924
  height: baseHeight,
16356
16925
  mipLevels: validLevelCount,
@@ -16366,8 +16935,19 @@ out float vTime;
16366
16935
  return texture;
16367
16936
  }
16368
16937
 
16938
+ // ../../node_modules/@luma.gl/shadertools/dist/lib/color/normalize-byte-colors.js
16939
+ function resolveUseByteColors(useByteColors, defaultUseByteColors = true) {
16940
+ return useByteColors ?? defaultUseByteColors;
16941
+ }
16942
+ function normalizeByteColor3(color = [0, 0, 0], useByteColors = true) {
16943
+ if (!useByteColors) {
16944
+ return [...color];
16945
+ }
16946
+ return color.map((component) => component / 255);
16947
+ }
16948
+
16369
16949
  // ../../node_modules/@luma.gl/shadertools/dist/modules/lighting/lights/lighting.js
16370
- var import_core21 = __toESM(require_core3(), 1);
16950
+ var import_core22 = __toESM(require_core3(), 1);
16371
16951
 
16372
16952
  // ../../node_modules/@luma.gl/shadertools/dist/modules/lighting/lights/lighting-glsl.js
16373
16953
  var lightingUniformsGLSL = (
@@ -16385,77 +16965,51 @@ struct PointLight {
16385
16965
  vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential
16386
16966
  };
16387
16967
 
16968
+ struct SpotLight {
16969
+ vec3 color;
16970
+ vec3 position;
16971
+ vec3 direction;
16972
+ vec3 attenuation;
16973
+ vec2 coneCos;
16974
+ };
16975
+
16388
16976
  struct DirectionalLight {
16389
16977
  vec3 color;
16390
16978
  vec3 direction;
16391
16979
  };
16392
16980
 
16393
- uniform lightingUniforms {
16394
- int enabled;
16395
- int lightType;
16981
+ struct UniformLight {
16982
+ vec3 color;
16983
+ vec3 position;
16984
+ vec3 direction;
16985
+ vec3 attenuation;
16986
+ vec2 coneCos;
16987
+ };
16396
16988
 
16989
+ layout(std140) uniform lightingUniforms {
16990
+ int enabled;
16397
16991
  int directionalLightCount;
16398
16992
  int pointLightCount;
16399
-
16993
+ int spotLightCount;
16400
16994
  vec3 ambientColor;
16401
-
16402
- vec3 lightColor0;
16403
- vec3 lightPosition0;
16404
- vec3 lightDirection0;
16405
- vec3 lightAttenuation0;
16406
-
16407
- vec3 lightColor1;
16408
- vec3 lightPosition1;
16409
- vec3 lightDirection1;
16410
- vec3 lightAttenuation1;
16411
-
16412
- vec3 lightColor2;
16413
- vec3 lightPosition2;
16414
- vec3 lightDirection2;
16415
- vec3 lightAttenuation2;
16416
-
16417
- vec3 lightColor3;
16418
- vec3 lightPosition3;
16419
- vec3 lightDirection3;
16420
- vec3 lightAttenuation3;
16421
-
16422
- vec3 lightColor4;
16423
- vec3 lightPosition4;
16424
- vec3 lightDirection4;
16425
- vec3 lightAttenuation4;
16995
+ UniformLight lights[5];
16426
16996
  } lighting;
16427
16997
 
16428
16998
  PointLight lighting_getPointLight(int index) {
16429
- switch (index) {
16430
- case 0:
16431
- return PointLight(lighting.lightColor0, lighting.lightPosition0, lighting.lightAttenuation0);
16432
- case 1:
16433
- return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);
16434
- case 2:
16435
- return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
16436
- case 3:
16437
- return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
16438
- case 4:
16439
- default:
16440
- return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
16441
- }
16999
+ UniformLight light = lighting.lights[index];
17000
+ return PointLight(light.color, light.position, light.attenuation);
17001
+ }
17002
+
17003
+ SpotLight lighting_getSpotLight(int index) {
17004
+ UniformLight light = lighting.lights[lighting.pointLightCount + index];
17005
+ return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
16442
17006
  }
16443
17007
 
16444
17008
  DirectionalLight lighting_getDirectionalLight(int index) {
16445
- switch (index) {
16446
- case 0:
16447
- return DirectionalLight(lighting.lightColor0, lighting.lightDirection0);
16448
- case 1:
16449
- return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
16450
- case 2:
16451
- return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
16452
- case 3:
16453
- return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
16454
- case 4:
16455
- default:
16456
- return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
16457
- }
16458
- }
17009
+ UniformLight light =
17010
+ lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
17011
+ return DirectionalLight(light.color, light.direction);
17012
+ }
16459
17013
 
16460
17014
  float getPointLightAttenuation(PointLight pointLight, float distance) {
16461
17015
  return pointLight.attenuation.x
@@ -16463,6 +17017,20 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
16463
17017
  + pointLight.attenuation.z * distance * distance;
16464
17018
  }
16465
17019
 
17020
+ float getSpotLightAttenuation(SpotLight spotLight, vec3 positionWorldspace) {
17021
+ vec3 light_direction = normalize(positionWorldspace - spotLight.position);
17022
+ float coneFactor = smoothstep(
17023
+ spotLight.coneCos.y,
17024
+ spotLight.coneCos.x,
17025
+ dot(normalize(spotLight.direction), light_direction)
17026
+ );
17027
+ float distanceAttenuation = getPointLightAttenuation(
17028
+ PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
17029
+ distance(spotLight.position, positionWorldspace)
17030
+ );
17031
+ return distanceAttenuation / max(coneFactor, 0.0001);
17032
+ }
17033
+
16466
17034
  // #endif
16467
17035
  `
16468
17036
  );
@@ -16483,105 +17051,84 @@ struct PointLight {
16483
17051
  attenuation: vec3<f32>, // 2nd order x:Constant-y:Linear-z:Exponential
16484
17052
  };
16485
17053
 
17054
+ struct SpotLight {
17055
+ color: vec3<f32>,
17056
+ position: vec3<f32>,
17057
+ direction: vec3<f32>,
17058
+ attenuation: vec3<f32>,
17059
+ coneCos: vec2<f32>,
17060
+ };
17061
+
16486
17062
  struct DirectionalLight {
16487
17063
  color: vec3<f32>,
16488
17064
  direction: vec3<f32>,
16489
17065
  };
16490
17066
 
17067
+ struct UniformLight {
17068
+ color: vec3<f32>,
17069
+ position: vec3<f32>,
17070
+ direction: vec3<f32>,
17071
+ attenuation: vec3<f32>,
17072
+ coneCos: vec2<f32>,
17073
+ };
17074
+
16491
17075
  struct lightingUniforms {
16492
17076
  enabled: i32,
16493
- lightType: i32,
16494
-
16495
17077
  directionalLightCount: i32,
16496
17078
  pointLightCount: i32,
16497
-
17079
+ spotLightCount: i32,
16498
17080
  ambientColor: vec3<f32>,
16499
-
16500
- lightColor0: vec3<f32>,
16501
- lightPosition0: vec3<f32>,
16502
- lightDirection0: vec3<f32>,
16503
- lightAttenuation0: vec3<f32>,
16504
-
16505
- lightColor1: vec3<f32>,
16506
- lightPosition1: vec3<f32>,
16507
- lightDirection1: vec3<f32>,
16508
- lightAttenuation1: vec3<f32>,
16509
-
16510
- lightColor2: vec3<f32>,
16511
- lightPosition2: vec3<f32>,
16512
- lightDirection2: vec3<f32>,
16513
- lightAttenuation2: vec3<f32>,
16514
-
16515
- lightColor3: vec3<f32>,
16516
- lightPosition3: vec3<f32>,
16517
- lightDirection3: vec3<f32>,
16518
- lightAttenuation3: vec3<f32>,
16519
-
16520
- lightColor4: vec3<f32>,
16521
- lightPosition4: vec3<f32>,
16522
- lightDirection4: vec3<f32>,
16523
- lightAttenuation4: vec3<f32>,
17081
+ lights: array<UniformLight, 5>,
16524
17082
  };
16525
17083
 
16526
- // Binding 0:1 is reserved for lighting (Note: could go into separate bind group as it is stable across draw calls)
16527
- @binding(1) @group(0) var<uniform> lighting : lightingUniforms;
17084
+ @group(2) @binding(auto) var<uniform> lighting : lightingUniforms;
16528
17085
 
16529
17086
  fn lighting_getPointLight(index: i32) -> PointLight {
16530
- switch (index) {
16531
- case 0: {
16532
- return PointLight(lighting.lightColor0, lighting.lightPosition0, lighting.lightAttenuation0);
16533
- }
16534
- case 1: {
16535
- return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);
16536
- }
16537
- case 2: {
16538
- return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
16539
- }
16540
- case 3: {
16541
- return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
16542
- }
16543
- case 4, default: {
16544
- return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
16545
- }
16546
- }
17087
+ let light = lighting.lights[index];
17088
+ return PointLight(light.color, light.position, light.attenuation);
17089
+ }
17090
+
17091
+ fn lighting_getSpotLight(index: i32) -> SpotLight {
17092
+ let light = lighting.lights[lighting.pointLightCount + index];
17093
+ return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
16547
17094
  }
16548
17095
 
16549
17096
  fn lighting_getDirectionalLight(index: i32) -> DirectionalLight {
16550
- switch (index) {
16551
- case 0: {
16552
- return DirectionalLight(lighting.lightColor0, lighting.lightDirection0);
16553
- }
16554
- case 1: {
16555
- return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
16556
- }
16557
- case 2: {
16558
- return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
16559
- }
16560
- case 3: {
16561
- return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
16562
- }
16563
- case 4, default: {
16564
- return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
16565
- }
16566
- }
16567
- }
17097
+ let light = lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
17098
+ return DirectionalLight(light.color, light.direction);
17099
+ }
16568
17100
 
16569
17101
  fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
16570
17102
  return pointLight.attenuation.x
16571
17103
  + pointLight.attenuation.y * distance
16572
17104
  + pointLight.attenuation.z * distance * distance;
16573
17105
  }
17106
+
17107
+ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>) -> f32 {
17108
+ let lightDirection = normalize(positionWorldspace - spotLight.position);
17109
+ let coneFactor = smoothstep(
17110
+ spotLight.coneCos.y,
17111
+ spotLight.coneCos.x,
17112
+ dot(normalize(spotLight.direction), lightDirection)
17113
+ );
17114
+ let distanceAttenuation = getPointLightAttenuation(
17115
+ PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
17116
+ distance(spotLight.position, positionWorldspace)
17117
+ );
17118
+ return distanceAttenuation / max(coneFactor, 0.0001);
17119
+ }
16574
17120
  `
16575
17121
  );
16576
17122
 
16577
17123
  // ../../node_modules/@luma.gl/shadertools/dist/modules/lighting/lights/lighting.js
16578
17124
  var MAX_LIGHTS = 5;
16579
- var COLOR_FACTOR = 255;
16580
- var LIGHT_TYPE;
16581
- (function(LIGHT_TYPE2) {
16582
- LIGHT_TYPE2[LIGHT_TYPE2["POINT"] = 0] = "POINT";
16583
- LIGHT_TYPE2[LIGHT_TYPE2["DIRECTIONAL"] = 1] = "DIRECTIONAL";
16584
- })(LIGHT_TYPE || (LIGHT_TYPE = {}));
17125
+ var LIGHT_UNIFORM_TYPE = {
17126
+ color: "vec3<f32>",
17127
+ position: "vec3<f32>",
17128
+ direction: "vec3<f32>",
17129
+ attenuation: "vec3<f32>",
17130
+ coneCos: "vec2<f32>"
17131
+ };
16585
17132
  var lighting = {
16586
17133
  props: {},
16587
17134
  uniforms: {},
@@ -16591,127 +17138,110 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
16591
17138
  },
16592
17139
  uniformTypes: {
16593
17140
  enabled: "i32",
16594
- lightType: "i32",
16595
17141
  directionalLightCount: "i32",
16596
17142
  pointLightCount: "i32",
17143
+ spotLightCount: "i32",
16597
17144
  ambientColor: "vec3<f32>",
16598
- // TODO define as arrays once we have appropriate uniformTypes
16599
- lightColor0: "vec3<f32>",
16600
- lightPosition0: "vec3<f32>",
16601
- // TODO - could combine direction and attenuation
16602
- lightDirection0: "vec3<f32>",
16603
- lightAttenuation0: "vec3<f32>",
16604
- lightColor1: "vec3<f32>",
16605
- lightPosition1: "vec3<f32>",
16606
- lightDirection1: "vec3<f32>",
16607
- lightAttenuation1: "vec3<f32>",
16608
- lightColor2: "vec3<f32>",
16609
- lightPosition2: "vec3<f32>",
16610
- lightDirection2: "vec3<f32>",
16611
- lightAttenuation2: "vec3<f32>",
16612
- lightColor3: "vec3<f32>",
16613
- lightPosition3: "vec3<f32>",
16614
- lightDirection3: "vec3<f32>",
16615
- lightAttenuation3: "vec3<f32>",
16616
- lightColor4: "vec3<f32>",
16617
- lightPosition4: "vec3<f32>",
16618
- lightDirection4: "vec3<f32>",
16619
- lightAttenuation4: "vec3<f32>"
16620
- },
16621
- defaultUniforms: {
16622
- enabled: 1,
16623
- lightType: LIGHT_TYPE.POINT,
16624
- directionalLightCount: 0,
16625
- pointLightCount: 0,
16626
- ambientColor: [0.1, 0.1, 0.1],
16627
- lightColor0: [1, 1, 1],
16628
- lightPosition0: [1, 1, 2],
16629
- // TODO - could combine direction and attenuation
16630
- lightDirection0: [1, 1, 1],
16631
- lightAttenuation0: [1, 0, 0],
16632
- lightColor1: [1, 1, 1],
16633
- lightPosition1: [1, 1, 2],
16634
- lightDirection1: [1, 1, 1],
16635
- lightAttenuation1: [1, 0, 0],
16636
- lightColor2: [1, 1, 1],
16637
- lightPosition2: [1, 1, 2],
16638
- lightDirection2: [1, 1, 1],
16639
- lightAttenuation2: [1, 0, 0],
16640
- lightColor3: [1, 1, 1],
16641
- lightPosition3: [1, 1, 2],
16642
- lightDirection3: [1, 1, 1],
16643
- lightAttenuation3: [1, 0, 0],
16644
- lightColor4: [1, 1, 1],
16645
- lightPosition4: [1, 1, 2],
16646
- lightDirection4: [1, 1, 1],
16647
- lightAttenuation4: [1, 0, 0]
17145
+ lights: [LIGHT_UNIFORM_TYPE, MAX_LIGHTS]
16648
17146
  },
17147
+ defaultUniforms: createDefaultLightingUniforms(),
17148
+ bindingLayout: [{ name: "lighting", group: 2 }],
17149
+ firstBindingSlot: 0,
16649
17150
  source: lightingUniformsWGSL,
16650
17151
  vs: lightingUniformsGLSL,
16651
17152
  fs: lightingUniformsGLSL,
16652
17153
  getUniforms
16653
17154
  };
16654
- function getUniforms(props, prevUniforms = {}) {
17155
+ function getUniforms(props, _prevUniforms = {}) {
16655
17156
  props = props ? { ...props } : props;
16656
17157
  if (!props) {
16657
- return { ...lighting.defaultUniforms };
17158
+ return createDefaultLightingUniforms();
16658
17159
  }
16659
17160
  if (props.lights) {
16660
17161
  props = { ...props, ...extractLightTypes(props.lights), lights: void 0 };
16661
17162
  }
16662
- const { ambientLight, pointLights, directionalLights } = props || {};
16663
- const hasLights = ambientLight || pointLights && pointLights.length > 0 || directionalLights && directionalLights.length > 0;
17163
+ const { useByteColors, ambientLight, pointLights, spotLights, directionalLights } = props || {};
17164
+ const hasLights = ambientLight || pointLights && pointLights.length > 0 || spotLights && spotLights.length > 0 || directionalLights && directionalLights.length > 0;
16664
17165
  if (!hasLights) {
16665
- return { ...lighting.defaultUniforms, enabled: 0 };
17166
+ return {
17167
+ ...createDefaultLightingUniforms(),
17168
+ enabled: 0
17169
+ };
16666
17170
  }
16667
17171
  const uniforms = {
16668
- ...lighting.defaultUniforms,
16669
- ...prevUniforms,
16670
- ...getLightSourceUniforms({ ambientLight, pointLights, directionalLights })
17172
+ ...createDefaultLightingUniforms(),
17173
+ ...getLightSourceUniforms({
17174
+ useByteColors,
17175
+ ambientLight,
17176
+ pointLights,
17177
+ spotLights,
17178
+ directionalLights
17179
+ })
16671
17180
  };
16672
17181
  if (props.enabled !== void 0) {
16673
17182
  uniforms.enabled = props.enabled ? 1 : 0;
16674
17183
  }
16675
17184
  return uniforms;
16676
17185
  }
16677
- function getLightSourceUniforms({ ambientLight, pointLights = [], directionalLights = [] }) {
16678
- const lightSourceUniforms = {};
16679
- lightSourceUniforms.ambientColor = convertColor(ambientLight);
17186
+ function getLightSourceUniforms({ useByteColors, ambientLight, pointLights = [], spotLights = [], directionalLights = [] }) {
17187
+ const lights = createDefaultLightUniforms();
16680
17188
  let currentLight = 0;
16681
17189
  let pointLightCount = 0;
17190
+ let spotLightCount = 0;
16682
17191
  let directionalLightCount = 0;
16683
17192
  for (const pointLight of pointLights) {
16684
17193
  if (currentLight >= MAX_LIGHTS) {
16685
17194
  break;
16686
17195
  }
16687
- lightSourceUniforms.lightType = LIGHT_TYPE.POINT;
16688
- const i = currentLight;
16689
- lightSourceUniforms[`lightColor${i}`] = convertColor(pointLight);
16690
- lightSourceUniforms[`lightPosition${i}`] = pointLight.position;
16691
- lightSourceUniforms[`lightAttenuation${i}`] = pointLight.attenuation || [1, 0, 0];
17196
+ lights[currentLight] = {
17197
+ ...lights[currentLight],
17198
+ color: convertColor(pointLight, useByteColors),
17199
+ position: pointLight.position,
17200
+ attenuation: pointLight.attenuation || [1, 0, 0]
17201
+ };
16692
17202
  currentLight++;
16693
17203
  pointLightCount++;
16694
17204
  }
17205
+ for (const spotLight of spotLights) {
17206
+ if (currentLight >= MAX_LIGHTS) {
17207
+ break;
17208
+ }
17209
+ lights[currentLight] = {
17210
+ ...lights[currentLight],
17211
+ color: convertColor(spotLight, useByteColors),
17212
+ position: spotLight.position,
17213
+ direction: spotLight.direction,
17214
+ attenuation: spotLight.attenuation || [1, 0, 0],
17215
+ coneCos: getSpotConeCos(spotLight)
17216
+ };
17217
+ currentLight++;
17218
+ spotLightCount++;
17219
+ }
16695
17220
  for (const directionalLight of directionalLights) {
16696
17221
  if (currentLight >= MAX_LIGHTS) {
16697
17222
  break;
16698
17223
  }
16699
- lightSourceUniforms.lightType = LIGHT_TYPE.DIRECTIONAL;
16700
- const i = currentLight;
16701
- lightSourceUniforms[`lightColor${i}`] = convertColor(directionalLight);
16702
- lightSourceUniforms[`lightDirection${i}`] = directionalLight.direction;
17224
+ lights[currentLight] = {
17225
+ ...lights[currentLight],
17226
+ color: convertColor(directionalLight, useByteColors),
17227
+ direction: directionalLight.direction
17228
+ };
16703
17229
  currentLight++;
16704
17230
  directionalLightCount++;
16705
17231
  }
16706
- if (pointLights.length + directionalLights.length > MAX_LIGHTS) {
16707
- import_core21.log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();
17232
+ if (pointLights.length + spotLights.length + directionalLights.length > MAX_LIGHTS) {
17233
+ import_core22.log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();
16708
17234
  }
16709
- lightSourceUniforms.directionalLightCount = directionalLightCount;
16710
- lightSourceUniforms.pointLightCount = pointLightCount;
16711
- return lightSourceUniforms;
17235
+ return {
17236
+ ambientColor: convertColor(ambientLight, useByteColors),
17237
+ directionalLightCount,
17238
+ pointLightCount,
17239
+ spotLightCount,
17240
+ lights
17241
+ };
16712
17242
  }
16713
17243
  function extractLightTypes(lights) {
16714
- const lightSources = { pointLights: [], directionalLights: [] };
17244
+ const lightSources = { pointLights: [], spotLights: [], directionalLights: [] };
16715
17245
  for (const light of lights || []) {
16716
17246
  switch (light.type) {
16717
17247
  case "ambient":
@@ -16723,21 +17253,88 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
16723
17253
  case "point":
16724
17254
  lightSources.pointLights?.push(light);
16725
17255
  break;
17256
+ case "spot":
17257
+ lightSources.spotLights?.push(light);
17258
+ break;
16726
17259
  default:
16727
17260
  }
16728
17261
  }
16729
17262
  return lightSources;
16730
17263
  }
16731
- function convertColor(colorDef = {}) {
17264
+ function convertColor(colorDef = {}, useByteColors) {
16732
17265
  const { color = [0, 0, 0], intensity = 1 } = colorDef;
16733
- return color.map((component) => component * intensity / COLOR_FACTOR);
17266
+ const normalizedColor = normalizeByteColor3(color, resolveUseByteColors(useByteColors, true));
17267
+ return normalizedColor.map((component) => component * intensity);
17268
+ }
17269
+ function createDefaultLightingUniforms() {
17270
+ return {
17271
+ enabled: 1,
17272
+ directionalLightCount: 0,
17273
+ pointLightCount: 0,
17274
+ spotLightCount: 0,
17275
+ ambientColor: [0.1, 0.1, 0.1],
17276
+ lights: createDefaultLightUniforms()
17277
+ };
17278
+ }
17279
+ function createDefaultLightUniforms() {
17280
+ return Array.from({ length: MAX_LIGHTS }, () => createDefaultLightUniform());
17281
+ }
17282
+ function createDefaultLightUniform() {
17283
+ return {
17284
+ color: [1, 1, 1],
17285
+ position: [1, 1, 2],
17286
+ direction: [1, 1, 1],
17287
+ attenuation: [1, 0, 0],
17288
+ coneCos: [1, 0]
17289
+ };
17290
+ }
17291
+ function getSpotConeCos(spotLight) {
17292
+ const innerConeAngle = spotLight.innerConeAngle ?? 0;
17293
+ const outerConeAngle = spotLight.outerConeAngle ?? Math.PI / 4;
17294
+ return [Math.cos(innerConeAngle), Math.cos(outerConeAngle)];
16734
17295
  }
16735
17296
 
17297
+ // ../../node_modules/@luma.gl/shadertools/dist/modules/lighting/ibl/ibl.js
17298
+ var iblWGSL = (
17299
+ /* wgsl */
17300
+ `#ifdef USE_IBL
17301
+ @group(2) @binding(auto) var pbr_diffuseEnvSampler: texture_cube<f32>;
17302
+ @group(2) @binding(auto) var pbr_diffuseEnvSamplerSampler: sampler;
17303
+ @group(2) @binding(auto) var pbr_specularEnvSampler: texture_cube<f32>;
17304
+ @group(2) @binding(auto) var pbr_specularEnvSamplerSampler: sampler;
17305
+ @group(2) @binding(auto) var pbr_brdfLUT: texture_2d<f32>;
17306
+ @group(2) @binding(auto) var pbr_brdfLUTSampler: sampler;
17307
+ #endif
17308
+ `
17309
+ );
17310
+ var iblGLSL = (
17311
+ /* glsl */
17312
+ `#ifdef USE_IBL
17313
+ uniform samplerCube pbr_diffuseEnvSampler;
17314
+ uniform samplerCube pbr_specularEnvSampler;
17315
+ uniform sampler2D pbr_brdfLUT;
17316
+ #endif
17317
+ `
17318
+ );
17319
+ var ibl = {
17320
+ name: "ibl",
17321
+ firstBindingSlot: 32,
17322
+ bindingLayout: [
17323
+ { name: "pbr_diffuseEnvSampler", group: 2 },
17324
+ { name: "pbr_specularEnvSampler", group: 2 },
17325
+ { name: "pbr_brdfLUT", group: 2 }
17326
+ ],
17327
+ source: iblWGSL,
17328
+ vs: iblGLSL,
17329
+ fs: iblGLSL
17330
+ };
17331
+
16736
17332
  // ../../node_modules/@luma.gl/shadertools/dist/modules/lighting/pbr-material/pbr-material-glsl.js
16737
17333
  var vs = (
16738
17334
  /* glsl */
16739
17335
  `out vec3 pbr_vPosition;
16740
- out vec2 pbr_vUV;
17336
+ out vec2 pbr_vUV0;
17337
+ out vec2 pbr_vUV1;
16741
17338
 
16742
17339
  #ifdef HAS_NORMALS
16743
17340
  # ifdef HAS_TANGENTS
@@ -16747,7 +17344,13 @@ out vec3 pbr_vNormal;
16747
17344
  # endif
16748
17345
  #endif
16749
17346
 
16750
- void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv)
17347
+ void pbr_setPositionNormalTangentUV(
17348
+ vec4 position,
17349
+ vec4 normal,
17350
+ vec4 tangent,
17351
+ vec2 uv0,
17352
+ vec2 uv1
17353
+ )
16751
17354
  {
16752
17355
  vec4 pos = pbrProjection.modelMatrix * position;
16753
17356
  pbr_vPosition = vec3(pos.xyz) / pos.w;
@@ -16764,10 +17367,12 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
16764
17367
  #endif
16765
17368
 
16766
17369
  #ifdef HAS_UV
16767
- pbr_vUV = uv;
17370
+ pbr_vUV0 = uv0;
16768
17371
  #else
16769
- pbr_vUV = vec2(0.,0.);
17372
+ pbr_vUV0 = vec2(0.,0.);
16770
17373
  #endif
17374
+
17375
+ pbr_vUV1 = uv1;
16771
17376
  }
16772
17377
  `
16773
17378
  );
@@ -16775,7 +17380,7 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
16775
17380
  /* glsl */
16776
17381
  `precision highp float;
16777
17382
 
16778
- uniform pbrMaterialUniforms {
17383
+ layout(std140) uniform pbrMaterialUniforms {
16779
17384
  // Material is unlit
16780
17385
  bool unlit;
16781
17386
 
@@ -16815,10 +17420,12 @@ uniform pbrMaterialUniforms {
16815
17420
  float clearcoatFactor;
16816
17421
  float clearcoatRoughnessFactor;
16817
17422
  bool clearcoatMapEnabled;
17423
+ bool clearcoatRoughnessMapEnabled;
16818
17424
 
16819
17425
  vec3 sheenColorFactor;
16820
17426
  float sheenRoughnessFactor;
16821
17427
  bool sheenColorMapEnabled;
17428
+ bool sheenRoughnessMapEnabled;
16822
17429
 
16823
17430
  float iridescenceFactor;
16824
17431
  float iridescenceIor;
@@ -16841,6 +17448,41 @@ uniform pbrMaterialUniforms {
16841
17448
  vec4 scaleDiffBaseMR;
16842
17449
  vec4 scaleFGDSpec;
16843
17450
  // #endif
17451
+
17452
+ int baseColorUVSet;
17453
+ mat3 baseColorUVTransform;
17454
+ int metallicRoughnessUVSet;
17455
+ mat3 metallicRoughnessUVTransform;
17456
+ int normalUVSet;
17457
+ mat3 normalUVTransform;
17458
+ int occlusionUVSet;
17459
+ mat3 occlusionUVTransform;
17460
+ int emissiveUVSet;
17461
+ mat3 emissiveUVTransform;
17462
+ int specularColorUVSet;
17463
+ mat3 specularColorUVTransform;
17464
+ int specularIntensityUVSet;
17465
+ mat3 specularIntensityUVTransform;
17466
+ int transmissionUVSet;
17467
+ mat3 transmissionUVTransform;
17468
+ int thicknessUVSet;
17469
+ mat3 thicknessUVTransform;
17470
+ int clearcoatUVSet;
17471
+ mat3 clearcoatUVTransform;
17472
+ int clearcoatRoughnessUVSet;
17473
+ mat3 clearcoatRoughnessUVTransform;
17474
+ int clearcoatNormalUVSet;
17475
+ mat3 clearcoatNormalUVTransform;
17476
+ int sheenColorUVSet;
17477
+ mat3 sheenColorUVTransform;
17478
+ int sheenRoughnessUVSet;
17479
+ mat3 sheenRoughnessUVTransform;
17480
+ int iridescenceUVSet;
17481
+ mat3 iridescenceUVTransform;
17482
+ int iridescenceThicknessUVSet;
17483
+ mat3 iridescenceThicknessUVTransform;
17484
+ int anisotropyUVSet;
17485
+ mat3 anisotropyUVTransform;
16844
17486
  } pbrMaterial;
16845
17487
 
16846
17488
  // Samplers
@@ -16868,30 +17510,38 @@ uniform sampler2D pbr_specularIntensitySampler;
16868
17510
  #ifdef HAS_TRANSMISSIONMAP
16869
17511
  uniform sampler2D pbr_transmissionSampler;
16870
17512
  #endif
17513
+ #ifdef HAS_THICKNESSMAP
17514
+ uniform sampler2D pbr_thicknessSampler;
17515
+ #endif
16871
17516
  #ifdef HAS_CLEARCOATMAP
16872
17517
  uniform sampler2D pbr_clearcoatSampler;
17518
+ #endif
17519
+ #ifdef HAS_CLEARCOATROUGHNESSMAP
16873
17520
  uniform sampler2D pbr_clearcoatRoughnessSampler;
16874
17521
  #endif
17522
+ #ifdef HAS_CLEARCOATNORMALMAP
17523
+ uniform sampler2D pbr_clearcoatNormalSampler;
17524
+ #endif
16875
17525
  #ifdef HAS_SHEENCOLORMAP
16876
17526
  uniform sampler2D pbr_sheenColorSampler;
17527
+ #endif
17528
+ #ifdef HAS_SHEENROUGHNESSMAP
16877
17529
  uniform sampler2D pbr_sheenRoughnessSampler;
16878
17530
  #endif
16879
17531
  #ifdef HAS_IRIDESCENCEMAP
16880
17532
  uniform sampler2D pbr_iridescenceSampler;
16881
17533
  #endif
17534
+ #ifdef HAS_IRIDESCENCETHICKNESSMAP
17535
+ uniform sampler2D pbr_iridescenceThicknessSampler;
17536
+ #endif
16882
17537
  #ifdef HAS_ANISOTROPYMAP
16883
17538
  uniform sampler2D pbr_anisotropySampler;
16884
17539
  #endif
16885
- #ifdef USE_IBL
16886
- uniform samplerCube pbr_diffuseEnvSampler;
16887
- uniform samplerCube pbr_specularEnvSampler;
16888
- uniform sampler2D pbr_brdfLUT;
16889
- #endif
16890
-
16891
17540
  // Inputs from vertex shader
16892
17541
 
16893
17542
  in vec3 pbr_vPosition;
16894
- in vec2 pbr_vUV;
17543
+ in vec2 pbr_vUV0;
17544
+ in vec2 pbr_vUV1;
16895
17545
 
16896
17546
  #ifdef HAS_NORMALS
16897
17547
  #ifdef HAS_TANGENTS
@@ -16924,6 +17574,8 @@ struct PBRInfo {
16924
17574
  const float M_PI = 3.141592653589793;
16925
17575
  const float c_MinRoughness = 0.04;
16926
17576
 
17577
+ vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor);
17578
+
16927
17579
  vec4 SRGBtoLINEAR(vec4 srgbIn)
16928
17580
  {
16929
17581
  #ifdef MANUAL_SRGB
@@ -16939,16 +17591,20 @@ vec4 SRGBtoLINEAR(vec4 srgbIn)
16939
17591
  #endif //MANUAL_SRGB
16940
17592
  }
16941
17593
 
16942
- // Find the normal for this fragment, pulling either from a predefined normal map
16943
- // or from the interpolated mesh normal and tangent attributes.
16944
- vec3 getNormal()
17594
+ vec2 getMaterialUV(int uvSet, mat3 uvTransform)
17595
+ {
17596
+ vec2 baseUV = uvSet == 1 ? pbr_vUV1 : pbr_vUV0;
17597
+ return (uvTransform * vec3(baseUV, 1.0)).xy;
17598
+ }
17599
+
17600
+ // Build the tangent basis from interpolated attributes or screen-space derivatives.
17601
+ mat3 getTBN(vec2 uv)
16945
17602
  {
16946
- // Retrieve the tangent space matrix
16947
17603
  #ifndef HAS_TANGENTS
16948
17604
  vec3 pos_dx = dFdx(pbr_vPosition);
16949
17605
  vec3 pos_dy = dFdy(pbr_vPosition);
16950
- vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0));
16951
- vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0));
17606
+ vec3 tex_dx = dFdx(vec3(uv, 0.0));
17607
+ vec3 tex_dy = dFdy(vec3(uv, 0.0));
16952
17608
  vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);
16953
17609
 
16954
17610
  #ifdef HAS_NORMALS
@@ -16964,9 +17620,21 @@ vec3 getNormal()
16964
17620
  mat3 tbn = pbr_vTBN;
16965
17621
  #endif
16966
17622
 
17623
+ return tbn;
17624
+ }
17625
+
17626
+ // Find the normal for this fragment, pulling either from a predefined normal map
17627
+ // or from the interpolated mesh normal and tangent attributes.
17628
+ vec3 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale, vec2 uv)
17629
+ {
17630
+ vec3 n = texture(normalSampler, uv).rgb;
17631
+ return normalize(tbn * ((2.0 * n - 1.0) * vec3(normalScale, normalScale, 1.0)));
17632
+ }
17633
+
17634
+ vec3 getNormal(mat3 tbn, vec2 uv)
17635
+ {
16967
17636
  #ifdef HAS_NORMALMAP
16968
- vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;
16969
- n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
17637
+ vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale, uv);
16970
17638
  #else
16971
17639
  // The tbn matrix is linearly interpolated, so we need to re-normalize
16972
17640
  vec3 n = normalize(tbn[2].xyz);
@@ -16975,6 +17643,15 @@ vec3 getNormal()
16975
17643
  return n;
16976
17644
  }
16977
17645
 
17646
+ vec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal, vec2 uv)
17647
+ {
17648
+ #ifdef HAS_CLEARCOATNORMALMAP
17649
+ return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0, uv);
17650
+ #else
17651
+ return baseNormal;
17652
+ #endif
17653
+ }
17654
+
16978
17655
  // Calculation of the lighting contribution from an optional Image Based Light source.
16979
17656
  // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
16980
17657
  // See our README.md on Environment Maps [3] for additional discussion.
@@ -17050,6 +17727,169 @@ float microfacetDistribution(PBRInfo pbrInfo)
17050
17727
  return roughnessSq / (M_PI * f * f);
17051
17728
  }
17052
17729
 
17730
+ float maxComponent(vec3 value)
17731
+ {
17732
+ return max(max(value.r, value.g), value.b);
17733
+ }
17734
+
17735
+ float getDielectricF0(float ior)
17736
+ {
17737
+ float clampedIor = max(ior, 1.0);
17738
+ float ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
17739
+ return ratio * ratio;
17740
+ }
17741
+
17742
+ vec2 normalizeDirection(vec2 direction)
17743
+ {
17744
+ float directionLength = length(direction);
17745
+ return directionLength > 0.0001 ? direction / directionLength : vec2(1.0, 0.0);
17746
+ }
17747
+
17748
+ vec2 rotateDirection(vec2 direction, float rotation)
17749
+ {
17750
+ float s = sin(rotation);
17751
+ float c = cos(rotation);
17752
+ return vec2(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
17753
+ }
17754
+
17755
+ vec3 getIridescenceTint(float iridescence, float thickness, float NdotV)
17756
+ {
17757
+ if (iridescence <= 0.0) {
17758
+ return vec3(1.0);
17759
+ }
17760
+
17761
+ float phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
17762
+ vec3 thinFilmTint =
17763
+ 0.5 + 0.5 * cos(vec3(phase, phase + 2.0943951, phase + 4.1887902));
17764
+ return mix(vec3(1.0), thinFilmTint, iridescence);
17765
+ }
17766
+
17767
+ vec3 getVolumeAttenuation(float thickness)
17768
+ {
17769
+ if (thickness <= 0.0) {
17770
+ return vec3(1.0);
17771
+ }
17772
+
17773
+ vec3 attenuationCoefficient =
17774
+ -log(max(pbrMaterial.attenuationColor, vec3(0.0001))) /
17775
+ max(pbrMaterial.attenuationDistance, 0.0001);
17776
+ return exp(-attenuationCoefficient * thickness);
17777
+ }
17778
+
17779
+ PBRInfo createClearcoatPBRInfo(PBRInfo basePBRInfo, vec3 clearcoatNormal, float clearcoatRoughness)
17780
+ {
17781
+ float perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
17782
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
17783
+ float NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
17784
+
17785
+ return PBRInfo(
17786
+ basePBRInfo.NdotL,
17787
+ NdotV,
17788
+ basePBRInfo.NdotH,
17789
+ basePBRInfo.LdotH,
17790
+ basePBRInfo.VdotH,
17791
+ perceptualRoughness,
17792
+ 0.0,
17793
+ vec3(0.04),
17794
+ vec3(1.0),
17795
+ alphaRoughness,
17796
+ vec3(0.0),
17797
+ vec3(0.04),
17798
+ clearcoatNormal,
17799
+ basePBRInfo.v
17800
+ );
17801
+ }
17802
+
17803
+ vec3 calculateClearcoatContribution(
17804
+ PBRInfo pbrInfo,
17805
+ vec3 lightColor,
17806
+ vec3 clearcoatNormal,
17807
+ float clearcoatFactor,
17808
+ float clearcoatRoughness
17809
+ ) {
17810
+ if (clearcoatFactor <= 0.0) {
17811
+ return vec3(0.0);
17812
+ }
17813
+
17814
+ PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
17815
+ return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
17816
+ }
17817
+
17818
+ #ifdef USE_IBL
17819
+ vec3 calculateClearcoatIBLContribution(
17820
+ PBRInfo pbrInfo,
17821
+ vec3 clearcoatNormal,
17822
+ vec3 reflection,
17823
+ float clearcoatFactor,
17824
+ float clearcoatRoughness
17825
+ ) {
17826
+ if (clearcoatFactor <= 0.0) {
17827
+ return vec3(0.0);
17828
+ }
17829
+
17830
+ PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
17831
+ return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
17832
+ }
17833
+ #endif
17834
+
17835
+ vec3 calculateSheenContribution(
17836
+ PBRInfo pbrInfo,
17837
+ vec3 lightColor,
17838
+ vec3 sheenColor,
17839
+ float sheenRoughness
17840
+ ) {
17841
+ if (maxComponent(sheenColor) <= 0.0) {
17842
+ return vec3(0.0);
17843
+ }
17844
+
17845
+ float sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
17846
+ float sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
17847
+ return pbrInfo.NdotL *
17848
+ lightColor *
17849
+ sheenColor *
17850
+ (0.25 + 0.75 * sheenFresnel) *
17851
+ sheenVisibility *
17852
+ (1.0 - pbrInfo.metalness);
17853
+ }
17854
+
17855
+ float calculateAnisotropyBoost(
17856
+ PBRInfo pbrInfo,
17857
+ vec3 anisotropyTangent,
17858
+ float anisotropyStrength
17859
+ ) {
17860
+ if (anisotropyStrength <= 0.0) {
17861
+ return 1.0;
17862
+ }
17863
+
17864
+ vec3 anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
17865
+ float bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
17866
+ return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
17867
+ }
17868
+
17869
+ vec3 calculateMaterialLightColor(
17870
+ PBRInfo pbrInfo,
17871
+ vec3 lightColor,
17872
+ vec3 clearcoatNormal,
17873
+ float clearcoatFactor,
17874
+ float clearcoatRoughness,
17875
+ vec3 sheenColor,
17876
+ float sheenRoughness,
17877
+ vec3 anisotropyTangent,
17878
+ float anisotropyStrength
17879
+ ) {
17880
+ float anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
17881
+ vec3 color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
17882
+ color += calculateClearcoatContribution(
17883
+ pbrInfo,
17884
+ lightColor,
17885
+ clearcoatNormal,
17886
+ clearcoatFactor,
17887
+ clearcoatRoughness
17888
+ );
17889
+ color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
17890
+ return color;
17891
+ }
17892
+
17053
17893
  void PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {
17054
17894
  pbrInfo.NdotL = 1.0;
17055
17895
  pbrInfo.NdotH = 0.0;
@@ -17074,6 +17914,11 @@ void PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {
17074
17914
  PBRInfo_setDirectionalLight(pbrInfo, light_direction);
17075
17915
  }
17076
17916
 
17917
+ void PBRInfo_setSpotLight(inout PBRInfo pbrInfo, SpotLight spotLight) {
17918
+ vec3 light_direction = normalize(spotLight.position - pbr_vPosition);
17919
+ PBRInfo_setDirectionalLight(pbrInfo, light_direction);
17920
+ }
17921
+
17077
17922
  vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
17078
17923
  // Calculate the shading terms for the microfacet specular shading model
17079
17924
  vec3 F = specularReflection(pbrInfo);
@@ -17089,9 +17934,61 @@ vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
17089
17934
 
17090
17935
  vec4 pbr_filterColor(vec4 colorUnused)
17091
17936
  {
17937
+ vec2 baseColorUV = getMaterialUV(pbrMaterial.baseColorUVSet, pbrMaterial.baseColorUVTransform);
17938
+ vec2 metallicRoughnessUV = getMaterialUV(
17939
+ pbrMaterial.metallicRoughnessUVSet,
17940
+ pbrMaterial.metallicRoughnessUVTransform
17941
+ );
17942
+ vec2 normalUV = getMaterialUV(pbrMaterial.normalUVSet, pbrMaterial.normalUVTransform);
17943
+ vec2 occlusionUV = getMaterialUV(pbrMaterial.occlusionUVSet, pbrMaterial.occlusionUVTransform);
17944
+ vec2 emissiveUV = getMaterialUV(pbrMaterial.emissiveUVSet, pbrMaterial.emissiveUVTransform);
17945
+ vec2 specularColorUV = getMaterialUV(
17946
+ pbrMaterial.specularColorUVSet,
17947
+ pbrMaterial.specularColorUVTransform
17948
+ );
17949
+ vec2 specularIntensityUV = getMaterialUV(
17950
+ pbrMaterial.specularIntensityUVSet,
17951
+ pbrMaterial.specularIntensityUVTransform
17952
+ );
17953
+ vec2 transmissionUV = getMaterialUV(
17954
+ pbrMaterial.transmissionUVSet,
17955
+ pbrMaterial.transmissionUVTransform
17956
+ );
17957
+ vec2 thicknessUV = getMaterialUV(pbrMaterial.thicknessUVSet, pbrMaterial.thicknessUVTransform);
17958
+ vec2 clearcoatUV = getMaterialUV(pbrMaterial.clearcoatUVSet, pbrMaterial.clearcoatUVTransform);
17959
+ vec2 clearcoatRoughnessUV = getMaterialUV(
17960
+ pbrMaterial.clearcoatRoughnessUVSet,
17961
+ pbrMaterial.clearcoatRoughnessUVTransform
17962
+ );
17963
+ vec2 clearcoatNormalUV = getMaterialUV(
17964
+ pbrMaterial.clearcoatNormalUVSet,
17965
+ pbrMaterial.clearcoatNormalUVTransform
17966
+ );
17967
+ vec2 sheenColorUV = getMaterialUV(
17968
+ pbrMaterial.sheenColorUVSet,
17969
+ pbrMaterial.sheenColorUVTransform
17970
+ );
17971
+ vec2 sheenRoughnessUV = getMaterialUV(
17972
+ pbrMaterial.sheenRoughnessUVSet,
17973
+ pbrMaterial.sheenRoughnessUVTransform
17974
+ );
17975
+ vec2 iridescenceUV = getMaterialUV(
17976
+ pbrMaterial.iridescenceUVSet,
17977
+ pbrMaterial.iridescenceUVTransform
17978
+ );
17979
+ vec2 iridescenceThicknessUV = getMaterialUV(
17980
+ pbrMaterial.iridescenceThicknessUVSet,
17981
+ pbrMaterial.iridescenceThicknessUVTransform
17982
+ );
17983
+ vec2 anisotropyUV = getMaterialUV(
17984
+ pbrMaterial.anisotropyUVSet,
17985
+ pbrMaterial.anisotropyUVTransform
17986
+ );
17987
+
17092
17988
  // The albedo may be defined from a base texture or a flat color
17093
17989
  #ifdef HAS_BASECOLORMAP
17094
- vec4 baseColor = SRGBtoLINEAR(texture(pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;
17990
+ vec4 baseColor =
17991
+ SRGBtoLINEAR(texture(pbr_baseColorSampler, baseColorUV)) * pbrMaterial.baseColorFactor;
17095
17992
  #else
17096
17993
  vec4 baseColor = pbrMaterial.baseColorFactor;
17097
17994
  #endif
@@ -17104,6 +18001,8 @@ vec4 pbr_filterColor(vec4 colorUnused)
17104
18001
 
17105
18002
  vec3 color = vec3(0, 0, 0);
17106
18003
 
18004
+ float transmission = 0.0;
18005
+
17107
18006
  if(pbrMaterial.unlit){
17108
18007
  color.rgb = baseColor.rgb;
17109
18008
  }
@@ -17116,20 +18015,258 @@ vec4 pbr_filterColor(vec4 colorUnused)
17116
18015
  #ifdef HAS_METALROUGHNESSMAP
17117
18016
  // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
17118
18017
  // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
17119
- vec4 mrSample = texture(pbr_metallicRoughnessSampler, pbr_vUV);
18018
+ vec4 mrSample = texture(pbr_metallicRoughnessSampler, metallicRoughnessUV);
17120
18019
  perceptualRoughness = mrSample.g * perceptualRoughness;
17121
18020
  metallic = mrSample.b * metallic;
17122
18021
  #endif
17123
- perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
17124
- metallic = clamp(metallic, 0.0, 1.0);
18022
+ perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
18023
+ metallic = clamp(metallic, 0.0, 1.0);
18024
+ mat3 tbn = getTBN(normalUV);
18025
+ vec3 n = getNormal(tbn, normalUV); // normal at surface point
18026
+ vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
18027
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
18028
+ #ifdef USE_MATERIAL_EXTENSIONS
18029
+ bool useExtendedPBR =
18030
+ pbrMaterial.specularColorMapEnabled ||
18031
+ pbrMaterial.specularIntensityMapEnabled ||
18032
+ abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
18033
+ maxComponent(abs(pbrMaterial.specularColorFactor - vec3(1.0))) > 0.0001 ||
18034
+ abs(pbrMaterial.ior - 1.5) > 0.0001 ||
18035
+ pbrMaterial.transmissionMapEnabled ||
18036
+ pbrMaterial.transmissionFactor > 0.0001 ||
18037
+ pbrMaterial.clearcoatMapEnabled ||
18038
+ pbrMaterial.clearcoatRoughnessMapEnabled ||
18039
+ pbrMaterial.clearcoatFactor > 0.0001 ||
18040
+ pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
18041
+ pbrMaterial.sheenColorMapEnabled ||
18042
+ pbrMaterial.sheenRoughnessMapEnabled ||
18043
+ maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
18044
+ pbrMaterial.sheenRoughnessFactor > 0.0001 ||
18045
+ pbrMaterial.iridescenceMapEnabled ||
18046
+ pbrMaterial.iridescenceFactor > 0.0001 ||
18047
+ abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
18048
+ abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
18049
+ abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
18050
+ pbrMaterial.anisotropyMapEnabled ||
18051
+ pbrMaterial.anisotropyStrength > 0.0001 ||
18052
+ abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
18053
+ length(pbrMaterial.anisotropyDirection - vec2(1.0, 0.0)) > 0.0001;
18054
+ #else
18055
+ bool useExtendedPBR = false;
18056
+ #endif
18057
+
18058
+ if (!useExtendedPBR) {
18059
+ // Keep the baseline metallic-roughness implementation byte-for-byte equivalent in behavior.
18060
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
18061
+
18062
+ vec3 f0 = vec3(0.04);
18063
+ vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
18064
+ diffuseColor *= 1.0 - metallic;
18065
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
18066
+
18067
+ float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
18068
+ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
18069
+ vec3 specularEnvironmentR0 = specularColor.rgb;
18070
+ vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
18071
+ vec3 reflection = -normalize(reflect(v, n));
18072
+
18073
+ PBRInfo pbrInfo = PBRInfo(
18074
+ 0.0, // NdotL
18075
+ NdotV,
18076
+ 0.0, // NdotH
18077
+ 0.0, // LdotH
18078
+ 0.0, // VdotH
18079
+ perceptualRoughness,
18080
+ metallic,
18081
+ specularEnvironmentR0,
18082
+ specularEnvironmentR90,
18083
+ alphaRoughness,
18084
+ diffuseColor,
18085
+ specularColor,
18086
+ n,
18087
+ v
18088
+ );
18089
+
18090
+ #ifdef USE_LIGHTS
18091
+ PBRInfo_setAmbientLight(pbrInfo);
18092
+ color += calculateFinalColor(pbrInfo, lighting.ambientColor);
18093
+
18094
+ for(int i = 0; i < lighting.directionalLightCount; i++) {
18095
+ if (i < lighting.directionalLightCount) {
18096
+ PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
18097
+ color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
18098
+ }
18099
+ }
18100
+
18101
+ for(int i = 0; i < lighting.pointLightCount; i++) {
18102
+ if (i < lighting.pointLightCount) {
18103
+ PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
18104
+ float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
18105
+ color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
18106
+ }
18107
+ }
18108
+
18109
+ for(int i = 0; i < lighting.spotLightCount; i++) {
18110
+ if (i < lighting.spotLightCount) {
18111
+ PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
18112
+ float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
18113
+ color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
18114
+ }
18115
+ }
18116
+ #endif
18117
+
18118
+ #ifdef USE_IBL
18119
+ if (pbrMaterial.IBLenabled) {
18120
+ color += getIBLContribution(pbrInfo, n, reflection);
18121
+ }
18122
+ #endif
18123
+
18124
+ #ifdef HAS_OCCLUSIONMAP
18125
+ if (pbrMaterial.occlusionMapEnabled) {
18126
+ float ao = texture(pbr_occlusionSampler, occlusionUV).r;
18127
+ color = mix(color, color * ao, pbrMaterial.occlusionStrength);
18128
+ }
18129
+ #endif
18130
+
18131
+ vec3 emissive = pbrMaterial.emissiveFactor;
18132
+ #ifdef HAS_EMISSIVEMAP
18133
+ if (pbrMaterial.emissiveMapEnabled) {
18134
+ emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, emissiveUV)).rgb;
18135
+ }
18136
+ #endif
18137
+ color += emissive * pbrMaterial.emissiveStrength;
18138
+
18139
+ #ifdef PBR_DEBUG
18140
+ color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
18141
+ color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
18142
+ color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
18143
+ #endif
18144
+
18145
+ return vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a);
18146
+ }
18147
+
18148
+ float specularIntensity = pbrMaterial.specularIntensityFactor;
18149
+ #ifdef HAS_SPECULARINTENSITYMAP
18150
+ if (pbrMaterial.specularIntensityMapEnabled) {
18151
+ specularIntensity *= texture(pbr_specularIntensitySampler, specularIntensityUV).a;
18152
+ }
18153
+ #endif
18154
+
18155
+ vec3 specularFactor = pbrMaterial.specularColorFactor;
18156
+ #ifdef HAS_SPECULARCOLORMAP
18157
+ if (pbrMaterial.specularColorMapEnabled) {
18158
+ specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, specularColorUV)).rgb;
18159
+ }
18160
+ #endif
18161
+
18162
+ transmission = pbrMaterial.transmissionFactor;
18163
+ #ifdef HAS_TRANSMISSIONMAP
18164
+ if (pbrMaterial.transmissionMapEnabled) {
18165
+ transmission *= texture(pbr_transmissionSampler, transmissionUV).r;
18166
+ }
18167
+ #endif
18168
+ transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
18169
+ float thickness = max(pbrMaterial.thicknessFactor, 0.0);
18170
+ #ifdef HAS_THICKNESSMAP
18171
+ thickness *= texture(pbr_thicknessSampler, thicknessUV).g;
18172
+ #endif
18173
+
18174
+ float clearcoatFactor = pbrMaterial.clearcoatFactor;
18175
+ float clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
18176
+ #ifdef HAS_CLEARCOATMAP
18177
+ if (pbrMaterial.clearcoatMapEnabled) {
18178
+ clearcoatFactor *= texture(pbr_clearcoatSampler, clearcoatUV).r;
18179
+ }
18180
+ #endif
18181
+ #ifdef HAS_CLEARCOATROUGHNESSMAP
18182
+ if (pbrMaterial.clearcoatRoughnessMapEnabled) {
18183
+ clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, clearcoatRoughnessUV).g;
18184
+ }
18185
+ #endif
18186
+ clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
18187
+ clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
18188
+ vec3 clearcoatNormal = getClearcoatNormal(getTBN(clearcoatNormalUV), n, clearcoatNormalUV);
18189
+
18190
+ vec3 sheenColor = pbrMaterial.sheenColorFactor;
18191
+ float sheenRoughness = pbrMaterial.sheenRoughnessFactor;
18192
+ #ifdef HAS_SHEENCOLORMAP
18193
+ if (pbrMaterial.sheenColorMapEnabled) {
18194
+ sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, sheenColorUV)).rgb;
18195
+ }
18196
+ #endif
18197
+ #ifdef HAS_SHEENROUGHNESSMAP
18198
+ if (pbrMaterial.sheenRoughnessMapEnabled) {
18199
+ sheenRoughness *= texture(pbr_sheenRoughnessSampler, sheenRoughnessUV).a;
18200
+ }
18201
+ #endif
18202
+ sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
18203
+
18204
+ float iridescence = pbrMaterial.iridescenceFactor;
18205
+ #ifdef HAS_IRIDESCENCEMAP
18206
+ if (pbrMaterial.iridescenceMapEnabled) {
18207
+ iridescence *= texture(pbr_iridescenceSampler, iridescenceUV).r;
18208
+ }
18209
+ #endif
18210
+ iridescence = clamp(iridescence, 0.0, 1.0);
18211
+ float iridescenceThickness = mix(
18212
+ pbrMaterial.iridescenceThicknessRange.x,
18213
+ pbrMaterial.iridescenceThicknessRange.y,
18214
+ 0.5
18215
+ );
18216
+ #ifdef HAS_IRIDESCENCETHICKNESSMAP
18217
+ iridescenceThickness = mix(
18218
+ pbrMaterial.iridescenceThicknessRange.x,
18219
+ pbrMaterial.iridescenceThicknessRange.y,
18220
+ texture(pbr_iridescenceThicknessSampler, iridescenceThicknessUV).g
18221
+ );
18222
+ #endif
18223
+
18224
+ float anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
18225
+ vec2 anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
18226
+ #ifdef HAS_ANISOTROPYMAP
18227
+ if (pbrMaterial.anisotropyMapEnabled) {
18228
+ vec3 anisotropySample = texture(pbr_anisotropySampler, anisotropyUV).rgb;
18229
+ anisotropyStrength *= anisotropySample.b;
18230
+ vec2 mappedDirection = anisotropySample.rg * 2.0 - 1.0;
18231
+ if (length(mappedDirection) > 0.0001) {
18232
+ anisotropyDirection = normalize(mappedDirection);
18233
+ }
18234
+ }
18235
+ #endif
18236
+ anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
18237
+ vec3 anisotropyTangent = normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
18238
+ if (length(anisotropyTangent) < 0.0001) {
18239
+ anisotropyTangent = normalize(tbn[0]);
18240
+ }
18241
+ float anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
18242
+ perceptualRoughness = mix(
18243
+ perceptualRoughness,
18244
+ clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
18245
+ anisotropyStrength
18246
+ );
18247
+
17125
18248
  // Roughness is authored as perceptual roughness; as is convention,
17126
18249
  // convert to material roughness by squaring the perceptual roughness [2].
17127
18250
  float alphaRoughness = perceptualRoughness * perceptualRoughness;
17128
18251
 
17129
- vec3 f0 = vec3(0.04);
17130
- vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
17131
- diffuseColor *= 1.0 - metallic;
17132
- vec3 specularColor = mix(f0, baseColor.rgb, metallic);
18252
+ float dielectricF0 = getDielectricF0(pbrMaterial.ior);
18253
+ vec3 dielectricSpecularF0 = min(
18254
+ vec3(dielectricF0) * specularFactor * specularIntensity,
18255
+ vec3(1.0)
18256
+ );
18257
+ vec3 iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
18258
+ dielectricSpecularF0 = mix(
18259
+ dielectricSpecularF0,
18260
+ dielectricSpecularF0 * iridescenceTint,
18261
+ iridescence
18262
+ );
18263
+ vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - dielectricSpecularF0);
18264
+ diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
18265
+ vec3 specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
18266
+
18267
+ float baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
18268
+ diffuseColor *= baseLayerEnergy;
18269
+ specularColor *= baseLayerEnergy;
17133
18270
 
17134
18271
  // Compute reflectance.
17135
18272
  float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
@@ -17141,11 +18278,6 @@ vec4 pbr_filterColor(vec4 colorUnused)
17141
18278
  float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
17142
18279
  vec3 specularEnvironmentR0 = specularColor.rgb;
17143
18280
  vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
17144
-
17145
- vec3 n = getNormal(); // normal at surface point
17146
- vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
17147
-
17148
- float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
17149
18281
  vec3 reflection = -normalize(reflect(v, n));
17150
18282
 
17151
18283
  PBRInfo pbrInfo = PBRInfo(
@@ -17169,13 +18301,33 @@ vec4 pbr_filterColor(vec4 colorUnused)
17169
18301
  #ifdef USE_LIGHTS
17170
18302
  // Apply ambient light
17171
18303
  PBRInfo_setAmbientLight(pbrInfo);
17172
- color += calculateFinalColor(pbrInfo, lighting.ambientColor);
18304
+ color += calculateMaterialLightColor(
18305
+ pbrInfo,
18306
+ lighting.ambientColor,
18307
+ clearcoatNormal,
18308
+ clearcoatFactor,
18309
+ clearcoatRoughness,
18310
+ sheenColor,
18311
+ sheenRoughness,
18312
+ anisotropyTangent,
18313
+ anisotropyStrength
18314
+ );
17173
18315
 
17174
18316
  // Apply directional light
17175
18317
  for(int i = 0; i < lighting.directionalLightCount; i++) {
17176
18318
  if (i < lighting.directionalLightCount) {
17177
18319
  PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
17178
- color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
18320
+ color += calculateMaterialLightColor(
18321
+ pbrInfo,
18322
+ lighting_getDirectionalLight(i).color,
18323
+ clearcoatNormal,
18324
+ clearcoatFactor,
18325
+ clearcoatRoughness,
18326
+ sheenColor,
18327
+ sheenRoughness,
18328
+ anisotropyTangent,
18329
+ anisotropyStrength
18330
+ );
17179
18331
  }
17180
18332
  }
17181
18333
 
@@ -17184,7 +18336,35 @@ vec4 pbr_filterColor(vec4 colorUnused)
17184
18336
  if (i < lighting.pointLightCount) {
17185
18337
  PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
17186
18338
  float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
17187
- color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
18339
+ color += calculateMaterialLightColor(
18340
+ pbrInfo,
18341
+ lighting_getPointLight(i).color / attenuation,
18342
+ clearcoatNormal,
18343
+ clearcoatFactor,
18344
+ clearcoatRoughness,
18345
+ sheenColor,
18346
+ sheenRoughness,
18347
+ anisotropyTangent,
18348
+ anisotropyStrength
18349
+ );
18350
+ }
18351
+ }
18352
+
18353
+ for(int i = 0; i < lighting.spotLightCount; i++) {
18354
+ if (i < lighting.spotLightCount) {
18355
+ PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
18356
+ float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
18357
+ color += calculateMaterialLightColor(
18358
+ pbrInfo,
18359
+ lighting_getSpotLight(i).color / attenuation,
18360
+ clearcoatNormal,
18361
+ clearcoatFactor,
18362
+ clearcoatRoughness,
18363
+ sheenColor,
18364
+ sheenRoughness,
18365
+ anisotropyTangent,
18366
+ anisotropyStrength
18367
+ );
17188
18368
  }
17189
18369
  }
17190
18370
  #endif
@@ -17192,24 +18372,38 @@ vec4 pbr_filterColor(vec4 colorUnused)
17192
18372
  // Calculate lighting contribution from image based lighting source (IBL)
17193
18373
  #ifdef USE_IBL
17194
18374
  if (pbrMaterial.IBLenabled) {
17195
- color += getIBLContribution(pbrInfo, n, reflection);
18375
+ color += getIBLContribution(pbrInfo, n, reflection) *
18376
+ calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
18377
+ color += calculateClearcoatIBLContribution(
18378
+ pbrInfo,
18379
+ clearcoatNormal,
18380
+ -normalize(reflect(v, clearcoatNormal)),
18381
+ clearcoatFactor,
18382
+ clearcoatRoughness
18383
+ );
18384
+ color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
17196
18385
  }
17197
18386
  #endif
17198
18387
 
17199
18388
  // Apply optional PBR terms for additional (optional) shading
17200
18389
  #ifdef HAS_OCCLUSIONMAP
17201
18390
  if (pbrMaterial.occlusionMapEnabled) {
17202
- float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
18391
+ float ao = texture(pbr_occlusionSampler, occlusionUV).r;
17203
18392
  color = mix(color, color * ao, pbrMaterial.occlusionStrength);
17204
18393
  }
17205
18394
  #endif
17206
18395
 
18396
+ vec3 emissive = pbrMaterial.emissiveFactor;
17207
18397
  #ifdef HAS_EMISSIVEMAP
17208
18398
  if (pbrMaterial.emissiveMapEnabled) {
17209
- vec3 emissive = SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;
17210
- color += emissive;
18399
+ emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, emissiveUV)).rgb;
17211
18400
  }
17212
18401
  #endif
18402
+ color += emissive * pbrMaterial.emissiveStrength;
18403
+
18404
+ if (transmission > 0.0) {
18405
+ color = mix(color, color * getVolumeAttenuation(thickness), transmission);
18406
+ }
17213
18407
 
17214
18408
  // This section uses mix to override final color for reference app visualization
17215
18409
  // of various parameters in the lighting equation.
@@ -17229,7 +18423,8 @@ vec4 pbr_filterColor(vec4 colorUnused)
17229
18423
 
17230
18424
  }
17231
18425
 
17232
- return vec4(pow(color,vec3(1.0/2.2)), baseColor.a);
18426
+ float alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
18427
+ return vec4(pow(color,vec3(1.0/2.2)), alpha);
17233
18428
  }
17234
18429
  `
17235
18430
  );
@@ -17239,14 +18434,21 @@ vec4 pbr_filterColor(vec4 colorUnused)
17239
18434
  /* wgsl */
17240
18435
  `struct PBRFragmentInputs {
17241
18436
  pbr_vPosition: vec3f,
17242
- pbr_vUV: vec2f,
18437
+ pbr_vUV0: vec2f,
18438
+ pbr_vUV1: vec2f,
17243
18439
  pbr_vTBN: mat3x3f,
17244
18440
  pbr_vNormal: vec3f
17245
18441
  };
17246
18442
 
17247
18443
  var<private> fragmentInputs: PBRFragmentInputs;
17248
18444
 
17249
- fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)
18445
+ fn pbr_setPositionNormalTangentUV(
18446
+ position: vec4f,
18447
+ normal: vec4f,
18448
+ tangent: vec4f,
18449
+ uv0: vec2f,
18450
+ uv1: vec2f
18451
+ )
17250
18452
  {
17251
18453
  var pos: vec4f = pbrProjection.modelMatrix * position;
17252
18454
  fragmentInputs.pbr_vPosition = pos.xyz / pos.w;
@@ -17256,7 +18458,8 @@ fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f
17256
18458
  vec3f(0.0, 1.0, 0.0),
17257
18459
  vec3f(0.0, 0.0, 1.0)
17258
18460
  );
17259
- fragmentInputs.pbr_vUV = vec2f(0.0, 0.0);
18461
+ fragmentInputs.pbr_vUV0 = vec2f(0.0, 0.0);
18462
+ fragmentInputs.pbr_vUV1 = uv1;
17260
18463
 
17261
18464
  #ifdef HAS_NORMALS
17262
18465
  let normalW: vec3f = normalize((pbrProjection.normalMatrix * vec4f(normal.xyz, 0.0)).xyz);
@@ -17269,7 +18472,7 @@ fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f
17269
18472
  #endif
17270
18473
 
17271
18474
  #ifdef HAS_UV
17272
- fragmentInputs.pbr_vUV = uv;
18475
+ fragmentInputs.pbr_vUV0 = uv0;
17273
18476
  #endif
17274
18477
  }
17275
18478
 
@@ -17295,6 +18498,42 @@ struct pbrMaterialUniforms {
17295
18498
 
17296
18499
  alphaCutoffEnabled: i32,
17297
18500
  alphaCutoff: f32, // #ifdef ALPHA_CUTOFF
18501
+
18502
+ specularColorFactor: vec3f,
18503
+ specularIntensityFactor: f32,
18504
+ specularColorMapEnabled: i32,
18505
+ specularIntensityMapEnabled: i32,
18506
+
18507
+ ior: f32,
18508
+
18509
+ transmissionFactor: f32,
18510
+ transmissionMapEnabled: i32,
18511
+
18512
+ thicknessFactor: f32,
18513
+ attenuationDistance: f32,
18514
+ attenuationColor: vec3f,
18515
+
18516
+ clearcoatFactor: f32,
18517
+ clearcoatRoughnessFactor: f32,
18518
+ clearcoatMapEnabled: i32,
18519
+ clearcoatRoughnessMapEnabled: i32,
18520
+
18521
+ sheenColorFactor: vec3f,
18522
+ sheenRoughnessFactor: f32,
18523
+ sheenColorMapEnabled: i32,
18524
+ sheenRoughnessMapEnabled: i32,
18525
+
18526
+ iridescenceFactor: f32,
18527
+ iridescenceIor: f32,
18528
+ iridescenceThicknessRange: vec2f,
18529
+ iridescenceMapEnabled: i32,
18530
+
18531
+ anisotropyStrength: f32,
18532
+ anisotropyRotation: f32,
18533
+ anisotropyDirection: vec2f,
18534
+ anisotropyMapEnabled: i32,
18535
+
18536
+ emissiveStrength: f32,
17298
18537
 
17299
18538
  // IBL
17300
18539
  IBLenabled: i32,
@@ -17305,40 +18544,114 @@ struct pbrMaterialUniforms {
17305
18544
  scaleDiffBaseMR: vec4f,
17306
18545
  scaleFGDSpec: vec4f,
17307
18546
  // #endif
18547
+
18548
+ baseColorUVSet: i32,
18549
+ baseColorUVTransform: mat3x3f,
18550
+ metallicRoughnessUVSet: i32,
18551
+ metallicRoughnessUVTransform: mat3x3f,
18552
+ normalUVSet: i32,
18553
+ normalUVTransform: mat3x3f,
18554
+ occlusionUVSet: i32,
18555
+ occlusionUVTransform: mat3x3f,
18556
+ emissiveUVSet: i32,
18557
+ emissiveUVTransform: mat3x3f,
18558
+ specularColorUVSet: i32,
18559
+ specularColorUVTransform: mat3x3f,
18560
+ specularIntensityUVSet: i32,
18561
+ specularIntensityUVTransform: mat3x3f,
18562
+ transmissionUVSet: i32,
18563
+ transmissionUVTransform: mat3x3f,
18564
+ thicknessUVSet: i32,
18565
+ thicknessUVTransform: mat3x3f,
18566
+ clearcoatUVSet: i32,
18567
+ clearcoatUVTransform: mat3x3f,
18568
+ clearcoatRoughnessUVSet: i32,
18569
+ clearcoatRoughnessUVTransform: mat3x3f,
18570
+ clearcoatNormalUVSet: i32,
18571
+ clearcoatNormalUVTransform: mat3x3f,
18572
+ sheenColorUVSet: i32,
18573
+ sheenColorUVTransform: mat3x3f,
18574
+ sheenRoughnessUVSet: i32,
18575
+ sheenRoughnessUVTransform: mat3x3f,
18576
+ iridescenceUVSet: i32,
18577
+ iridescenceUVTransform: mat3x3f,
18578
+ iridescenceThicknessUVSet: i32,
18579
+ iridescenceThicknessUVTransform: mat3x3f,
18580
+ anisotropyUVSet: i32,
18581
+ anisotropyUVTransform: mat3x3f,
17308
18582
  }
17309
18583
 
17310
- @binding(2) @group(0) var<uniform> pbrMaterial : pbrMaterialUniforms;
18584
+ @group(3) @binding(auto) var<uniform> pbrMaterial : pbrMaterialUniforms;
17311
18585
 
17312
18586
  // Samplers
17313
18587
  #ifdef HAS_BASECOLORMAP
17314
- @binding(3) @group(0) var pbr_baseColorSampler: texture_2d<f32>;
17315
- @binding(4) @group(0) var pbr_baseColorSamplerSampler: sampler;
18588
+ @group(3) @binding(auto) var pbr_baseColorSampler: texture_2d<f32>;
18589
+ @group(3) @binding(auto) var pbr_baseColorSamplerSampler: sampler;
17316
18590
  #endif
17317
18591
  #ifdef HAS_NORMALMAP
17318
- @binding(5) @group(0) var pbr_normalSampler: texture_2d<f32>;
17319
- @binding(6) @group(0) var pbr_normalSamplerSampler: sampler;
18592
+ @group(3) @binding(auto) var pbr_normalSampler: texture_2d<f32>;
18593
+ @group(3) @binding(auto) var pbr_normalSamplerSampler: sampler;
17320
18594
  #endif
17321
18595
  #ifdef HAS_EMISSIVEMAP
17322
- @binding(7) @group(0) var pbr_emissiveSampler: texture_2d<f32>;
17323
- @binding(8) @group(0) var pbr_emissiveSamplerSampler: sampler;
18596
+ @group(3) @binding(auto) var pbr_emissiveSampler: texture_2d<f32>;
18597
+ @group(3) @binding(auto) var pbr_emissiveSamplerSampler: sampler;
17324
18598
  #endif
17325
18599
  #ifdef HAS_METALROUGHNESSMAP
17326
- @binding(9) @group(0) var pbr_metallicRoughnessSampler: texture_2d<f32>;
17327
- @binding(10) @group(0) var pbr_metallicRoughnessSamplerSampler: sampler;
18600
+ @group(3) @binding(auto) var pbr_metallicRoughnessSampler: texture_2d<f32>;
18601
+ @group(3) @binding(auto) var pbr_metallicRoughnessSamplerSampler: sampler;
17328
18602
  #endif
17329
18603
  #ifdef HAS_OCCLUSIONMAP
17330
- @binding(11) @group(0) var pbr_occlusionSampler: texture_2d<f32>;
17331
- @binding(12) @group(0) var pbr_occlusionSamplerSampler: sampler;
18604
+ @group(3) @binding(auto) var pbr_occlusionSampler: texture_2d<f32>;
18605
+ @group(3) @binding(auto) var pbr_occlusionSamplerSampler: sampler;
17332
18606
  #endif
17333
- #ifdef USE_IBL
17334
- @binding(13) @group(0) var pbr_diffuseEnvSampler: texture_cube<f32>;
17335
- @binding(14) @group(0) var pbr_diffuseEnvSamplerSampler: sampler;
17336
- @binding(15) @group(0) var pbr_specularEnvSampler: texture_cube<f32>;
17337
- @binding(16) @group(0) var pbr_specularEnvSamplerSampler: sampler;
17338
- @binding(17) @group(0) var pbr_BrdfLUT: texture_2d<f32>;
17339
- @binding(18) @group(0) var pbr_BrdfLUTSampler: sampler;
18607
+ #ifdef HAS_SPECULARCOLORMAP
18608
+ @group(3) @binding(auto) var pbr_specularColorSampler: texture_2d<f32>;
18609
+ @group(3) @binding(auto) var pbr_specularColorSamplerSampler: sampler;
18610
+ #endif
18611
+ #ifdef HAS_SPECULARINTENSITYMAP
18612
+ @group(3) @binding(auto) var pbr_specularIntensitySampler: texture_2d<f32>;
18613
+ @group(3) @binding(auto) var pbr_specularIntensitySamplerSampler: sampler;
18614
+ #endif
18615
+ #ifdef HAS_TRANSMISSIONMAP
18616
+ @group(3) @binding(auto) var pbr_transmissionSampler: texture_2d<f32>;
18617
+ @group(3) @binding(auto) var pbr_transmissionSamplerSampler: sampler;
18618
+ #endif
18619
+ #ifdef HAS_THICKNESSMAP
18620
+ @group(3) @binding(auto) var pbr_thicknessSampler: texture_2d<f32>;
18621
+ @group(3) @binding(auto) var pbr_thicknessSamplerSampler: sampler;
18622
+ #endif
18623
+ #ifdef HAS_CLEARCOATMAP
18624
+ @group(3) @binding(auto) var pbr_clearcoatSampler: texture_2d<f32>;
18625
+ @group(3) @binding(auto) var pbr_clearcoatSamplerSampler: sampler;
18626
+ #endif
18627
+ #ifdef HAS_CLEARCOATROUGHNESSMAP
18628
+ @group(3) @binding(auto) var pbr_clearcoatRoughnessSampler: texture_2d<f32>;
18629
+ @group(3) @binding(auto) var pbr_clearcoatRoughnessSamplerSampler: sampler;
18630
+ #endif
18631
+ #ifdef HAS_CLEARCOATNORMALMAP
18632
+ @group(3) @binding(auto) var pbr_clearcoatNormalSampler: texture_2d<f32>;
18633
+ @group(3) @binding(auto) var pbr_clearcoatNormalSamplerSampler: sampler;
18634
+ #endif
18635
+ #ifdef HAS_SHEENCOLORMAP
18636
+ @group(3) @binding(auto) var pbr_sheenColorSampler: texture_2d<f32>;
18637
+ @group(3) @binding(auto) var pbr_sheenColorSamplerSampler: sampler;
18638
+ #endif
18639
+ #ifdef HAS_SHEENROUGHNESSMAP
18640
+ @group(3) @binding(auto) var pbr_sheenRoughnessSampler: texture_2d<f32>;
18641
+ @group(3) @binding(auto) var pbr_sheenRoughnessSamplerSampler: sampler;
18642
+ #endif
18643
+ #ifdef HAS_IRIDESCENCEMAP
18644
+ @group(3) @binding(auto) var pbr_iridescenceSampler: texture_2d<f32>;
18645
+ @group(3) @binding(auto) var pbr_iridescenceSamplerSampler: sampler;
18646
+ #endif
18647
+ #ifdef HAS_IRIDESCENCETHICKNESSMAP
18648
+ @group(3) @binding(auto) var pbr_iridescenceThicknessSampler: texture_2d<f32>;
18649
+ @group(3) @binding(auto) var pbr_iridescenceThicknessSamplerSampler: sampler;
18650
+ #endif
18651
+ #ifdef HAS_ANISOTROPYMAP
18652
+ @group(3) @binding(auto) var pbr_anisotropySampler: texture_2d<f32>;
18653
+ @group(3) @binding(auto) var pbr_anisotropySamplerSampler: sampler;
17340
18654
  #endif
17341
-
17342
18655
  // Encapsulate the various inputs used by the various functions in the shading equation
17343
18656
  // We store values in this struct to simplify the integration of alternative implementations
17344
18657
  // of the shading terms, outlined in the Readme.MD Appendix.
@@ -17379,15 +18692,22 @@ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
17379
18692
  return vec4f(linOut, srgbIn.w);
17380
18693
  }
17381
18694
 
17382
- // Find the normal for this fragment, pulling either from a predefined normal map
17383
- // or from the interpolated mesh normal and tangent attributes.
17384
- fn getNormal() -> vec3f
18695
+ fn getMaterialUV(uvSet: i32, uvTransform: mat3x3f) -> vec2f
18696
+ {
18697
+ var baseUV = fragmentInputs.pbr_vUV0;
18698
+ if (uvSet == 1) {
18699
+ baseUV = fragmentInputs.pbr_vUV1;
18700
+ }
18701
+ return (uvTransform * vec3f(baseUV, 1.0)).xy;
18702
+ }
18703
+
18704
+ // Build the tangent basis from interpolated attributes or screen-space derivatives.
18705
+ fn getTBN(uv: vec2f) -> mat3x3f
17385
18706
  {
17386
- // Retrieve the tangent space matrix
17387
18707
  let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);
17388
18708
  let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);
17389
- let tex_dx: vec3f = dpdx(vec3f(fragmentInputs.pbr_vUV, 0.0));
17390
- let tex_dy: vec3f = dpdy(vec3f(fragmentInputs.pbr_vUV, 0.0));
18709
+ let tex_dx: vec3f = dpdx(vec3f(uv, 0.0));
18710
+ let tex_dy: vec3f = dpdy(vec3f(uv, 0.0));
17391
18711
  var t: vec3f = (tex_dy.y * pos_dx - tex_dx.y * pos_dy) / (tex_dx.x * tex_dy.y - tex_dy.x * tex_dx.y);
17392
18712
 
17393
18713
  var ng: vec3f = cross(pos_dx, pos_dy);
@@ -17401,16 +18721,55 @@ fn getNormal() -> vec3f
17401
18721
  tbn = fragmentInputs.pbr_vTBN;
17402
18722
  #endif
17403
18723
 
18724
+ return tbn;
18725
+ }
18726
+
18727
+ // Find the normal for this fragment, pulling either from a predefined normal map
18728
+ // or from the interpolated mesh normal and tangent attributes.
18729
+ fn getMappedNormal(
18730
+ normalSampler: texture_2d<f32>,
18731
+ normalSamplerBinding: sampler,
18732
+ tbn: mat3x3f,
18733
+ normalScale: f32,
18734
+ uv: vec2f
18735
+ ) -> vec3f
18736
+ {
18737
+ let n = textureSample(normalSampler, normalSamplerBinding, uv).rgb;
18738
+ return normalize(tbn * ((2.0 * n - 1.0) * vec3f(normalScale, normalScale, 1.0)));
18739
+ }
18740
+
18741
+ fn getNormal(tbn: mat3x3f, uv: vec2f) -> vec3f
18742
+ {
17404
18743
  // The tbn matrix is linearly interpolated, so we need to re-normalize
17405
18744
  var n: vec3f = normalize(tbn[2].xyz);
17406
18745
  #ifdef HAS_NORMALMAP
17407
- n = textureSample(pbr_normalSampler, pbr_normalSamplerSampler, fragmentInputs.pbr_vUV).rgb;
17408
- n = normalize(tbn * ((2.0 * n - 1.0) * vec3f(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
18746
+ n = getMappedNormal(
18747
+ pbr_normalSampler,
18748
+ pbr_normalSamplerSampler,
18749
+ tbn,
18750
+ pbrMaterial.normalScale,
18751
+ uv
18752
+ );
17409
18753
  #endif
17410
18754
 
17411
18755
  return n;
17412
18756
  }
17413
18757
 
18758
+ fn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f, uv: vec2f) -> vec3f
18759
+ {
18760
+ #ifdef HAS_CLEARCOATNORMALMAP
18761
+ return getMappedNormal(
18762
+ pbr_clearcoatNormalSampler,
18763
+ pbr_clearcoatNormalSamplerSampler,
18764
+ tbn,
18765
+ 1.0,
18766
+ uv
18767
+ );
18768
+ #else
18769
+ return baseNormal;
18770
+ #endif
18771
+ }
18772
+
17414
18773
  // Calculation of the lighting contribution from an optional Image Based Light source.
17415
18774
  // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
17416
18775
  // See our README.md on Environment Maps [3] for additional discussion.
@@ -17421,17 +18780,25 @@ fn getIBLContribution(pbrInfo: PBRInfo, n: vec3f, reflection: vec3f) -> vec3f
17421
18780
  let lod: f32 = pbrInfo.perceptualRoughness * mipCount;
17422
18781
  // retrieve a scale and bias to F0. See [1], Figure 3
17423
18782
  let brdf = SRGBtoLINEAR(
17424
- textureSample(
17425
- pbr_BrdfLUT,
17426
- pbr_BrdfLUTSampler,
17427
- vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness)
18783
+ textureSampleLevel(
18784
+ pbr_brdfLUT,
18785
+ pbr_brdfLUTSampler,
18786
+ vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness),
18787
+ 0.0
17428
18788
  )
17429
18789
  ).rgb;
17430
18790
  let diffuseLight =
17431
- SRGBtoLINEAR(textureSample(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n)).rgb;
17432
- let specularLightDefault =
17433
- SRGBtoLINEAR(textureSample(pbr_specularEnvSampler, pbr_specularEnvSamplerSampler, reflection)).rgb;
17434
- var specularLight = specularLightDefault;
18791
+ SRGBtoLINEAR(
18792
+ textureSampleLevel(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n, 0.0)
18793
+ ).rgb;
18794
+ var specularLight = SRGBtoLINEAR(
18795
+ textureSampleLevel(
18796
+ pbr_specularEnvSampler,
18797
+ pbr_specularEnvSamplerSampler,
18798
+ reflection,
18799
+ 0.0
18800
+ )
18801
+ ).rgb;
17435
18802
  #ifdef USE_TEX_LOD
17436
18803
  specularLight = SRGBtoLINEAR(
17437
18804
  textureSampleLevel(
@@ -17492,6 +18859,172 @@ fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
17492
18859
  return roughnessSq / (M_PI * f * f);
17493
18860
  }
17494
18861
 
18862
+ fn maxComponent(value: vec3f) -> f32 {
18863
+ return max(max(value.r, value.g), value.b);
18864
+ }
18865
+
18866
+ fn getDielectricF0(ior: f32) -> f32 {
18867
+ let clampedIor = max(ior, 1.0);
18868
+ let ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
18869
+ return ratio * ratio;
18870
+ }
18871
+
18872
+ fn normalizeDirection(direction: vec2f) -> vec2f {
18873
+ let directionLength = length(direction);
18874
+ if (directionLength > 0.0001) {
18875
+ return direction / directionLength;
18876
+ }
18877
+
18878
+ return vec2f(1.0, 0.0);
18879
+ }
18880
+
18881
+ fn rotateDirection(direction: vec2f, rotation: f32) -> vec2f {
18882
+ let s = sin(rotation);
18883
+ let c = cos(rotation);
18884
+ return vec2f(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
18885
+ }
18886
+
18887
+ fn getIridescenceTint(iridescence: f32, thickness: f32, NdotV: f32) -> vec3f {
18888
+ if (iridescence <= 0.0) {
18889
+ return vec3f(1.0);
18890
+ }
18891
+
18892
+ let phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
18893
+ let thinFilmTint =
18894
+ 0.5 +
18895
+ 0.5 *
18896
+ cos(vec3f(phase, phase + 2.0943951, phase + 4.1887902));
18897
+ return mix(vec3f(1.0), thinFilmTint, iridescence);
18898
+ }
18899
+
18900
+ fn getVolumeAttenuation(thickness: f32) -> vec3f {
18901
+ if (thickness <= 0.0) {
18902
+ return vec3f(1.0);
18903
+ }
18904
+
18905
+ let attenuationCoefficient =
18906
+ -log(max(pbrMaterial.attenuationColor, vec3f(0.0001))) /
18907
+ max(pbrMaterial.attenuationDistance, 0.0001);
18908
+ return exp(-attenuationCoefficient * thickness);
18909
+ }
18910
+
18911
+ fn createClearcoatPBRInfo(
18912
+ basePBRInfo: PBRInfo,
18913
+ clearcoatNormal: vec3f,
18914
+ clearcoatRoughness: f32
18915
+ ) -> PBRInfo {
18916
+ let perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
18917
+ let alphaRoughness = perceptualRoughness * perceptualRoughness;
18918
+ let NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
18919
+
18920
+ return PBRInfo(
18921
+ basePBRInfo.NdotL,
18922
+ NdotV,
18923
+ basePBRInfo.NdotH,
18924
+ basePBRInfo.LdotH,
18925
+ basePBRInfo.VdotH,
18926
+ perceptualRoughness,
18927
+ 0.0,
18928
+ vec3f(0.04),
18929
+ vec3f(1.0),
18930
+ alphaRoughness,
18931
+ vec3f(0.0),
18932
+ vec3f(0.04),
18933
+ clearcoatNormal,
18934
+ basePBRInfo.v
18935
+ );
18936
+ }
18937
+
18938
+ fn calculateClearcoatContribution(
18939
+ pbrInfo: PBRInfo,
18940
+ lightColor: vec3f,
18941
+ clearcoatNormal: vec3f,
18942
+ clearcoatFactor: f32,
18943
+ clearcoatRoughness: f32
18944
+ ) -> vec3f {
18945
+ if (clearcoatFactor <= 0.0) {
18946
+ return vec3f(0.0);
18947
+ }
18948
+
18949
+ let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
18950
+ return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
18951
+ }
18952
+
18953
+ #ifdef USE_IBL
18954
+ fn calculateClearcoatIBLContribution(
18955
+ pbrInfo: PBRInfo,
18956
+ clearcoatNormal: vec3f,
18957
+ reflection: vec3f,
18958
+ clearcoatFactor: f32,
18959
+ clearcoatRoughness: f32
18960
+ ) -> vec3f {
18961
+ if (clearcoatFactor <= 0.0) {
18962
+ return vec3f(0.0);
18963
+ }
18964
+
18965
+ let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
18966
+ return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
18967
+ }
18968
+ #endif
18969
+
18970
+ fn calculateSheenContribution(
18971
+ pbrInfo: PBRInfo,
18972
+ lightColor: vec3f,
18973
+ sheenColor: vec3f,
18974
+ sheenRoughness: f32
18975
+ ) -> vec3f {
18976
+ if (maxComponent(sheenColor) <= 0.0) {
18977
+ return vec3f(0.0);
18978
+ }
18979
+
18980
+ let sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
18981
+ let sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
18982
+ return pbrInfo.NdotL *
18983
+ lightColor *
18984
+ sheenColor *
18985
+ (0.25 + 0.75 * sheenFresnel) *
18986
+ sheenVisibility *
18987
+ (1.0 - pbrInfo.metalness);
18988
+ }
18989
+
18990
+ fn calculateAnisotropyBoost(
18991
+ pbrInfo: PBRInfo,
18992
+ anisotropyTangent: vec3f,
18993
+ anisotropyStrength: f32
18994
+ ) -> f32 {
18995
+ if (anisotropyStrength <= 0.0) {
18996
+ return 1.0;
18997
+ }
18998
+
18999
+ let anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
19000
+ let bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
19001
+ return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
19002
+ }
19003
+
19004
+ fn calculateMaterialLightColor(
19005
+ pbrInfo: PBRInfo,
19006
+ lightColor: vec3f,
19007
+ clearcoatNormal: vec3f,
19008
+ clearcoatFactor: f32,
19009
+ clearcoatRoughness: f32,
19010
+ sheenColor: vec3f,
19011
+ sheenRoughness: f32,
19012
+ anisotropyTangent: vec3f,
19013
+ anisotropyStrength: f32
19014
+ ) -> vec3f {
19015
+ let anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
19016
+ var color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
19017
+ color += calculateClearcoatContribution(
19018
+ pbrInfo,
19019
+ lightColor,
19020
+ clearcoatNormal,
19021
+ clearcoatFactor,
19022
+ clearcoatRoughness
19023
+ );
19024
+ color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
19025
+ return color;
19026
+ }
19027
+
17495
19028
  fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
17496
19029
  (*pbrInfo).NdotL = 1.0;
17497
19030
  (*pbrInfo).NdotH = 0.0;
@@ -17516,6 +19049,11 @@ fn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight
17516
19049
  PBRInfo_setDirectionalLight(pbrInfo, light_direction);
17517
19050
  }
17518
19051
 
19052
+ fn PBRInfo_setSpotLight(pbrInfo: ptr<function, PBRInfo>, spotLight: SpotLight) {
19053
+ let light_direction = normalize(spotLight.position - fragmentInputs.pbr_vPosition);
19054
+ PBRInfo_setDirectionalLight(pbrInfo, light_direction);
19055
+ }
19056
+
17519
19057
  fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
17520
19058
  // Calculate the shading terms for the microfacet specular shading model
17521
19059
  let F = specularReflection(pbrInfo);
@@ -17530,11 +19068,62 @@ fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
17530
19068
  }
17531
19069
 
17532
19070
  fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
19071
+ let baseColorUV = getMaterialUV(pbrMaterial.baseColorUVSet, pbrMaterial.baseColorUVTransform);
19072
+ let metallicRoughnessUV = getMaterialUV(
19073
+ pbrMaterial.metallicRoughnessUVSet,
19074
+ pbrMaterial.metallicRoughnessUVTransform
19075
+ );
19076
+ let normalUV = getMaterialUV(pbrMaterial.normalUVSet, pbrMaterial.normalUVTransform);
19077
+ let occlusionUV = getMaterialUV(pbrMaterial.occlusionUVSet, pbrMaterial.occlusionUVTransform);
19078
+ let emissiveUV = getMaterialUV(pbrMaterial.emissiveUVSet, pbrMaterial.emissiveUVTransform);
19079
+ let specularColorUV = getMaterialUV(
19080
+ pbrMaterial.specularColorUVSet,
19081
+ pbrMaterial.specularColorUVTransform
19082
+ );
19083
+ let specularIntensityUV = getMaterialUV(
19084
+ pbrMaterial.specularIntensityUVSet,
19085
+ pbrMaterial.specularIntensityUVTransform
19086
+ );
19087
+ let transmissionUV = getMaterialUV(
19088
+ pbrMaterial.transmissionUVSet,
19089
+ pbrMaterial.transmissionUVTransform
19090
+ );
19091
+ let thicknessUV = getMaterialUV(pbrMaterial.thicknessUVSet, pbrMaterial.thicknessUVTransform);
19092
+ let clearcoatUV = getMaterialUV(pbrMaterial.clearcoatUVSet, pbrMaterial.clearcoatUVTransform);
19093
+ let clearcoatRoughnessUV = getMaterialUV(
19094
+ pbrMaterial.clearcoatRoughnessUVSet,
19095
+ pbrMaterial.clearcoatRoughnessUVTransform
19096
+ );
19097
+ let clearcoatNormalUV = getMaterialUV(
19098
+ pbrMaterial.clearcoatNormalUVSet,
19099
+ pbrMaterial.clearcoatNormalUVTransform
19100
+ );
19101
+ let sheenColorUV = getMaterialUV(
19102
+ pbrMaterial.sheenColorUVSet,
19103
+ pbrMaterial.sheenColorUVTransform
19104
+ );
19105
+ let sheenRoughnessUV = getMaterialUV(
19106
+ pbrMaterial.sheenRoughnessUVSet,
19107
+ pbrMaterial.sheenRoughnessUVTransform
19108
+ );
19109
+ let iridescenceUV = getMaterialUV(
19110
+ pbrMaterial.iridescenceUVSet,
19111
+ pbrMaterial.iridescenceUVTransform
19112
+ );
19113
+ let iridescenceThicknessUV = getMaterialUV(
19114
+ pbrMaterial.iridescenceThicknessUVSet,
19115
+ pbrMaterial.iridescenceThicknessUVTransform
19116
+ );
19117
+ let anisotropyUV = getMaterialUV(
19118
+ pbrMaterial.anisotropyUVSet,
19119
+ pbrMaterial.anisotropyUVTransform
19120
+ );
19121
+
17533
19122
  // The albedo may be defined from a base texture or a flat color
17534
19123
  var baseColor: vec4<f32> = pbrMaterial.baseColorFactor;
17535
19124
  #ifdef HAS_BASECOLORMAP
17536
19125
  baseColor = SRGBtoLINEAR(
17537
- textureSample(pbr_baseColorSampler, pbr_baseColorSamplerSampler, fragmentInputs.pbr_vUV)
19126
+ textureSample(pbr_baseColorSampler, pbr_baseColorSamplerSampler, baseColorUV)
17538
19127
  ) * pbrMaterial.baseColorFactor;
17539
19128
  #endif
17540
19129
 
@@ -17545,6 +19134,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17545
19134
  #endif
17546
19135
 
17547
19136
  var color = vec3<f32>(0.0, 0.0, 0.0);
19137
+ var transmission = 0.0;
17548
19138
 
17549
19139
  if (pbrMaterial.unlit != 0u) {
17550
19140
  color = baseColor.rgb;
@@ -17560,21 +19150,314 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17560
19150
  let mrSample = textureSample(
17561
19151
  pbr_metallicRoughnessSampler,
17562
19152
  pbr_metallicRoughnessSamplerSampler,
17563
- fragmentInputs.pbr_vUV
19153
+ metallicRoughnessUV
17564
19154
  );
17565
19155
  perceptualRoughness = mrSample.g * perceptualRoughness;
17566
19156
  metallic = mrSample.b * metallic;
17567
19157
  #endif
17568
19158
  perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
17569
19159
  metallic = clamp(metallic, 0.0, 1.0);
19160
+ let tbn = getTBN(normalUV);
19161
+ let n = getNormal(tbn, normalUV); // normal at surface point
19162
+ let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
19163
+ let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
19164
+ var useExtendedPBR = false;
19165
+ #ifdef USE_MATERIAL_EXTENSIONS
19166
+ useExtendedPBR =
19167
+ pbrMaterial.specularColorMapEnabled != 0 ||
19168
+ pbrMaterial.specularIntensityMapEnabled != 0 ||
19169
+ abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
19170
+ maxComponent(abs(pbrMaterial.specularColorFactor - vec3f(1.0))) > 0.0001 ||
19171
+ abs(pbrMaterial.ior - 1.5) > 0.0001 ||
19172
+ pbrMaterial.transmissionMapEnabled != 0 ||
19173
+ pbrMaterial.transmissionFactor > 0.0001 ||
19174
+ pbrMaterial.clearcoatMapEnabled != 0 ||
19175
+ pbrMaterial.clearcoatRoughnessMapEnabled != 0 ||
19176
+ pbrMaterial.clearcoatFactor > 0.0001 ||
19177
+ pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
19178
+ pbrMaterial.sheenColorMapEnabled != 0 ||
19179
+ pbrMaterial.sheenRoughnessMapEnabled != 0 ||
19180
+ maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
19181
+ pbrMaterial.sheenRoughnessFactor > 0.0001 ||
19182
+ pbrMaterial.iridescenceMapEnabled != 0 ||
19183
+ pbrMaterial.iridescenceFactor > 0.0001 ||
19184
+ abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
19185
+ abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
19186
+ abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
19187
+ pbrMaterial.anisotropyMapEnabled != 0 ||
19188
+ pbrMaterial.anisotropyStrength > 0.0001 ||
19189
+ abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
19190
+ length(pbrMaterial.anisotropyDirection - vec2f(1.0, 0.0)) > 0.0001;
19191
+ #endif
19192
+
19193
+ if (!useExtendedPBR) {
19194
+ let alphaRoughness = perceptualRoughness * perceptualRoughness;
19195
+
19196
+ let f0 = vec3<f32>(0.04);
19197
+ var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
19198
+ diffuseColor *= 1.0 - metallic;
19199
+ let specularColor = mix(f0, baseColor.rgb, metallic);
19200
+
19201
+ let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
19202
+ let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
19203
+ let specularEnvironmentR0 = specularColor;
19204
+ let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
19205
+ let reflection = -normalize(reflect(v, n));
19206
+
19207
+ var pbrInfo = PBRInfo(
19208
+ 0.0, // NdotL
19209
+ NdotV,
19210
+ 0.0, // NdotH
19211
+ 0.0, // LdotH
19212
+ 0.0, // VdotH
19213
+ perceptualRoughness,
19214
+ metallic,
19215
+ specularEnvironmentR0,
19216
+ specularEnvironmentR90,
19217
+ alphaRoughness,
19218
+ diffuseColor,
19219
+ specularColor,
19220
+ n,
19221
+ v
19222
+ );
19223
+
19224
+ #ifdef USE_LIGHTS
19225
+ PBRInfo_setAmbientLight(&pbrInfo);
19226
+ color += calculateFinalColor(pbrInfo, lighting.ambientColor);
19227
+
19228
+ for (var i = 0; i < lighting.directionalLightCount; i++) {
19229
+ if (i < lighting.directionalLightCount) {
19230
+ PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
19231
+ color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
19232
+ }
19233
+ }
19234
+
19235
+ for (var i = 0; i < lighting.pointLightCount; i++) {
19236
+ if (i < lighting.pointLightCount) {
19237
+ PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));
19238
+ let attenuation = getPointLightAttenuation(
19239
+ lighting_getPointLight(i),
19240
+ distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
19241
+ );
19242
+ color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
19243
+ }
19244
+ }
19245
+
19246
+ for (var i = 0; i < lighting.spotLightCount; i++) {
19247
+ if (i < lighting.spotLightCount) {
19248
+ PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
19249
+ let attenuation = getSpotLightAttenuation(
19250
+ lighting_getSpotLight(i),
19251
+ fragmentInputs.pbr_vPosition
19252
+ );
19253
+ color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
19254
+ }
19255
+ }
19256
+ #endif
19257
+
19258
+ #ifdef USE_IBL
19259
+ if (pbrMaterial.IBLenabled != 0) {
19260
+ color += getIBLContribution(pbrInfo, n, reflection);
19261
+ }
19262
+ #endif
19263
+
19264
+ #ifdef HAS_OCCLUSIONMAP
19265
+ if (pbrMaterial.occlusionMapEnabled != 0) {
19266
+ let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, occlusionUV).r;
19267
+ color = mix(color, color * ao, pbrMaterial.occlusionStrength);
19268
+ }
19269
+ #endif
19270
+
19271
+ var emissive = pbrMaterial.emissiveFactor;
19272
+ #ifdef HAS_EMISSIVEMAP
19273
+ if (pbrMaterial.emissiveMapEnabled != 0u) {
19274
+ emissive *= SRGBtoLINEAR(
19275
+ textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, emissiveUV)
19276
+ ).rgb;
19277
+ }
19278
+ #endif
19279
+ color += emissive * pbrMaterial.emissiveStrength;
19280
+
19281
+ #ifdef PBR_DEBUG
19282
+ color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
19283
+ color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);
19284
+ color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
19285
+ #endif
19286
+
19287
+ return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
19288
+ }
19289
+
19290
+ var specularIntensity = pbrMaterial.specularIntensityFactor;
19291
+ #ifdef HAS_SPECULARINTENSITYMAP
19292
+ if (pbrMaterial.specularIntensityMapEnabled != 0) {
19293
+ specularIntensity *= textureSample(
19294
+ pbr_specularIntensitySampler,
19295
+ pbr_specularIntensitySamplerSampler,
19296
+ specularIntensityUV
19297
+ ).a;
19298
+ }
19299
+ #endif
19300
+
19301
+ var specularFactor = pbrMaterial.specularColorFactor;
19302
+ #ifdef HAS_SPECULARCOLORMAP
19303
+ if (pbrMaterial.specularColorMapEnabled != 0) {
19304
+ specularFactor *= SRGBtoLINEAR(
19305
+ textureSample(
19306
+ pbr_specularColorSampler,
19307
+ pbr_specularColorSamplerSampler,
19308
+ specularColorUV
19309
+ )
19310
+ ).rgb;
19311
+ }
19312
+ #endif
19313
+
19314
+ transmission = pbrMaterial.transmissionFactor;
19315
+ #ifdef HAS_TRANSMISSIONMAP
19316
+ if (pbrMaterial.transmissionMapEnabled != 0) {
19317
+ transmission *= textureSample(
19318
+ pbr_transmissionSampler,
19319
+ pbr_transmissionSamplerSampler,
19320
+ transmissionUV
19321
+ ).r;
19322
+ }
19323
+ #endif
19324
+ transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
19325
+ var thickness = max(pbrMaterial.thicknessFactor, 0.0);
19326
+ #ifdef HAS_THICKNESSMAP
19327
+ thickness *= textureSample(
19328
+ pbr_thicknessSampler,
19329
+ pbr_thicknessSamplerSampler,
19330
+ thicknessUV
19331
+ ).g;
19332
+ #endif
19333
+
19334
+ var clearcoatFactor = pbrMaterial.clearcoatFactor;
19335
+ var clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
19336
+ #ifdef HAS_CLEARCOATMAP
19337
+ if (pbrMaterial.clearcoatMapEnabled != 0) {
19338
+ clearcoatFactor *= textureSample(
19339
+ pbr_clearcoatSampler,
19340
+ pbr_clearcoatSamplerSampler,
19341
+ clearcoatUV
19342
+ ).r;
19343
+ }
19344
+ #endif
19345
+ #ifdef HAS_CLEARCOATROUGHNESSMAP
19346
+ if (pbrMaterial.clearcoatRoughnessMapEnabled != 0) {
19347
+ clearcoatRoughness *= textureSample(
19348
+ pbr_clearcoatRoughnessSampler,
19349
+ pbr_clearcoatRoughnessSamplerSampler,
19350
+ clearcoatRoughnessUV
19351
+ ).g;
19352
+ }
19353
+ #endif
19354
+ clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
19355
+ clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
19356
+ let clearcoatNormal = getClearcoatNormal(getTBN(clearcoatNormalUV), n, clearcoatNormalUV);
19357
+
19358
+ var sheenColor = pbrMaterial.sheenColorFactor;
19359
+ var sheenRoughness = pbrMaterial.sheenRoughnessFactor;
19360
+ #ifdef HAS_SHEENCOLORMAP
19361
+ if (pbrMaterial.sheenColorMapEnabled != 0) {
19362
+ sheenColor *= SRGBtoLINEAR(
19363
+ textureSample(
19364
+ pbr_sheenColorSampler,
19365
+ pbr_sheenColorSamplerSampler,
19366
+ sheenColorUV
19367
+ )
19368
+ ).rgb;
19369
+ }
19370
+ #endif
19371
+ #ifdef HAS_SHEENROUGHNESSMAP
19372
+ if (pbrMaterial.sheenRoughnessMapEnabled != 0) {
19373
+ sheenRoughness *= textureSample(
19374
+ pbr_sheenRoughnessSampler,
19375
+ pbr_sheenRoughnessSamplerSampler,
19376
+ sheenRoughnessUV
19377
+ ).a;
19378
+ }
19379
+ #endif
19380
+ sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
19381
+
19382
+ var iridescence = pbrMaterial.iridescenceFactor;
19383
+ #ifdef HAS_IRIDESCENCEMAP
19384
+ if (pbrMaterial.iridescenceMapEnabled != 0) {
19385
+ iridescence *= textureSample(
19386
+ pbr_iridescenceSampler,
19387
+ pbr_iridescenceSamplerSampler,
19388
+ iridescenceUV
19389
+ ).r;
19390
+ }
19391
+ #endif
19392
+ iridescence = clamp(iridescence, 0.0, 1.0);
19393
+ var iridescenceThickness = mix(
19394
+ pbrMaterial.iridescenceThicknessRange.x,
19395
+ pbrMaterial.iridescenceThicknessRange.y,
19396
+ 0.5
19397
+ );
19398
+ #ifdef HAS_IRIDESCENCETHICKNESSMAP
19399
+ iridescenceThickness = mix(
19400
+ pbrMaterial.iridescenceThicknessRange.x,
19401
+ pbrMaterial.iridescenceThicknessRange.y,
19402
+ textureSample(
19403
+ pbr_iridescenceThicknessSampler,
19404
+ pbr_iridescenceThicknessSamplerSampler,
19405
+ iridescenceThicknessUV
19406
+ ).g
19407
+ );
19408
+ #endif
19409
+
19410
+ var anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
19411
+ var anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
19412
+ #ifdef HAS_ANISOTROPYMAP
19413
+ if (pbrMaterial.anisotropyMapEnabled != 0) {
19414
+ let anisotropySample = textureSample(
19415
+ pbr_anisotropySampler,
19416
+ pbr_anisotropySamplerSampler,
19417
+ anisotropyUV
19418
+ ).rgb;
19419
+ anisotropyStrength *= anisotropySample.b;
19420
+ let mappedDirection = anisotropySample.rg * 2.0 - 1.0;
19421
+ if (length(mappedDirection) > 0.0001) {
19422
+ anisotropyDirection = normalize(mappedDirection);
19423
+ }
19424
+ }
19425
+ #endif
19426
+ anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
19427
+ var anisotropyTangent =
19428
+ normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
19429
+ if (length(anisotropyTangent) < 0.0001) {
19430
+ anisotropyTangent = normalize(tbn[0]);
19431
+ }
19432
+ let anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
19433
+ perceptualRoughness = mix(
19434
+ perceptualRoughness,
19435
+ clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
19436
+ anisotropyStrength
19437
+ );
19438
+
17570
19439
  // Roughness is authored as perceptual roughness; as is convention,
17571
19440
  // convert to material roughness by squaring the perceptual roughness [2].
17572
19441
  let alphaRoughness = perceptualRoughness * perceptualRoughness;
17573
19442
 
17574
- let f0 = vec3<f32>(0.04);
17575
- var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
17576
- diffuseColor *= 1.0 - metallic;
17577
- let specularColor = mix(f0, baseColor.rgb, metallic);
19443
+ let dielectricF0 = getDielectricF0(pbrMaterial.ior);
19444
+ var dielectricSpecularF0 = min(
19445
+ vec3f(dielectricF0) * specularFactor * specularIntensity,
19446
+ vec3f(1.0)
19447
+ );
19448
+ let iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
19449
+ dielectricSpecularF0 = mix(
19450
+ dielectricSpecularF0,
19451
+ dielectricSpecularF0 * iridescenceTint,
19452
+ iridescence
19453
+ );
19454
+ var diffuseColor = baseColor.rgb * (vec3f(1.0) - dielectricSpecularF0);
19455
+ diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
19456
+ var specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
19457
+
19458
+ let baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
19459
+ diffuseColor *= baseLayerEnergy;
19460
+ specularColor *= baseLayerEnergy;
17578
19461
 
17579
19462
  // Compute reflectance.
17580
19463
  let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
@@ -17586,11 +19469,6 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17586
19469
  let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
17587
19470
  let specularEnvironmentR0 = specularColor;
17588
19471
  let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
17589
-
17590
- let n = getNormal(); // normal at surface point
17591
- let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
17592
-
17593
- let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
17594
19472
  let reflection = -normalize(reflect(v, n));
17595
19473
 
17596
19474
  var pbrInfo = PBRInfo(
@@ -17613,13 +19491,33 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17613
19491
  #ifdef USE_LIGHTS
17614
19492
  // Apply ambient light
17615
19493
  PBRInfo_setAmbientLight(&pbrInfo);
17616
- color += calculateFinalColor(pbrInfo, lighting.ambientColor);
19494
+ color += calculateMaterialLightColor(
19495
+ pbrInfo,
19496
+ lighting.ambientColor,
19497
+ clearcoatNormal,
19498
+ clearcoatFactor,
19499
+ clearcoatRoughness,
19500
+ sheenColor,
19501
+ sheenRoughness,
19502
+ anisotropyTangent,
19503
+ anisotropyStrength
19504
+ );
17617
19505
 
17618
19506
  // Apply directional light
17619
19507
  for (var i = 0; i < lighting.directionalLightCount; i++) {
17620
19508
  if (i < lighting.directionalLightCount) {
17621
19509
  PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
17622
- color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
19510
+ color += calculateMaterialLightColor(
19511
+ pbrInfo,
19512
+ lighting_getDirectionalLight(i).color,
19513
+ clearcoatNormal,
19514
+ clearcoatFactor,
19515
+ clearcoatRoughness,
19516
+ sheenColor,
19517
+ sheenRoughness,
19518
+ anisotropyTangent,
19519
+ anisotropyStrength
19520
+ );
17623
19521
  }
17624
19522
  }
17625
19523
 
@@ -17631,7 +19529,35 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17631
19529
  lighting_getPointLight(i),
17632
19530
  distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
17633
19531
  );
17634
- color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
19532
+ color += calculateMaterialLightColor(
19533
+ pbrInfo,
19534
+ lighting_getPointLight(i).color / attenuation,
19535
+ clearcoatNormal,
19536
+ clearcoatFactor,
19537
+ clearcoatRoughness,
19538
+ sheenColor,
19539
+ sheenRoughness,
19540
+ anisotropyTangent,
19541
+ anisotropyStrength
19542
+ );
19543
+ }
19544
+ }
19545
+
19546
+ for (var i = 0; i < lighting.spotLightCount; i++) {
19547
+ if (i < lighting.spotLightCount) {
19548
+ PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
19549
+ let attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), fragmentInputs.pbr_vPosition);
19550
+ color += calculateMaterialLightColor(
19551
+ pbrInfo,
19552
+ lighting_getSpotLight(i).color / attenuation,
19553
+ clearcoatNormal,
19554
+ clearcoatFactor,
19555
+ clearcoatRoughness,
19556
+ sheenColor,
19557
+ sheenRoughness,
19558
+ anisotropyTangent,
19559
+ anisotropyStrength
19560
+ );
17635
19561
  }
17636
19562
  }
17637
19563
  #endif
@@ -17639,27 +19565,40 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17639
19565
  // Calculate lighting contribution from image based lighting source (IBL)
17640
19566
  #ifdef USE_IBL
17641
19567
  if (pbrMaterial.IBLenabled != 0) {
17642
- color += getIBLContribution(pbrInfo, n, reflection);
19568
+ color += getIBLContribution(pbrInfo, n, reflection) *
19569
+ calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
19570
+ color += calculateClearcoatIBLContribution(
19571
+ pbrInfo,
19572
+ clearcoatNormal,
19573
+ -normalize(reflect(v, clearcoatNormal)),
19574
+ clearcoatFactor,
19575
+ clearcoatRoughness
19576
+ );
19577
+ color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
17643
19578
  }
17644
19579
  #endif
17645
19580
 
17646
19581
  // Apply optional PBR terms for additional (optional) shading
17647
19582
  #ifdef HAS_OCCLUSIONMAP
17648
19583
  if (pbrMaterial.occlusionMapEnabled != 0) {
17649
- let ao =
17650
- textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
19584
+ let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, occlusionUV).r;
17651
19585
  color = mix(color, color * ao, pbrMaterial.occlusionStrength);
17652
19586
  }
17653
19587
  #endif
17654
19588
 
19589
+ var emissive = pbrMaterial.emissiveFactor;
17655
19590
  #ifdef HAS_EMISSIVEMAP
17656
19591
  if (pbrMaterial.emissiveMapEnabled != 0u) {
17657
- let emissive = SRGBtoLINEAR(
17658
- textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
17659
- ).rgb * pbrMaterial.emissiveFactor;
17660
- color += emissive;
19592
+ emissive *= SRGBtoLINEAR(
19593
+ textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, emissiveUV)
19594
+ ).rgb;
17661
19595
  }
17662
19596
  #endif
19597
+ color += emissive * pbrMaterial.emissiveStrength;
19598
+
19599
+ if (transmission > 0.0) {
19600
+ color = mix(color, color * getVolumeAttenuation(thickness), transmission);
19601
+ }
17663
19602
 
17664
19603
  // This section uses mix to override final color for reference app visualization
17665
19604
  // of various parameters in the lighting equation.
@@ -17678,7 +19617,8 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17678
19617
  #endif
17679
19618
  }
17680
19619
 
17681
- return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
19620
+ let alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
19621
+ return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), alpha);
17682
19622
  }
17683
19623
  `
17684
19624
  );
@@ -17686,7 +19626,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17686
19626
  // ../../node_modules/@luma.gl/shadertools/dist/modules/lighting/pbr-material/pbr-projection.js
17687
19627
  var uniformBlock2 = (
17688
19628
  /* glsl */
17689
- `uniform pbrProjectionUniforms {
19629
+ `layout(std140) uniform pbrProjectionUniforms {
17690
19630
  mat4 modelViewProjectionMatrix;
17691
19631
  mat4 modelMatrix;
17692
19632
  mat4 normalMatrix;
@@ -17703,11 +19643,12 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17703
19643
  camera: vec3<f32>
17704
19644
  };
17705
19645
 
17706
- @binding(0) @group(0) var<uniform> pbrProjection: pbrProjectionUniforms;
19646
+ @group(0) @binding(auto) var<uniform> pbrProjection: pbrProjectionUniforms;
17707
19647
  `
17708
19648
  );
17709
19649
  var pbrProjection = {
17710
19650
  name: "pbrProjection",
19651
+ bindingLayout: [{ name: "pbrProjection", group: 0 }],
17711
19652
  source: wgslUniformBlock,
17712
19653
  vs: uniformBlock2,
17713
19654
  fs: uniformBlock2,
@@ -17725,8 +19666,109 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17725
19666
  var pbrMaterial = {
17726
19667
  props: {},
17727
19668
  uniforms: {},
19669
+ defaultUniforms: {
19670
+ unlit: false,
19671
+ baseColorMapEnabled: false,
19672
+ baseColorFactor: [1, 1, 1, 1],
19673
+ normalMapEnabled: false,
19674
+ normalScale: 1,
19675
+ emissiveMapEnabled: false,
19676
+ emissiveFactor: [0, 0, 0],
19677
+ metallicRoughnessValues: [1, 1],
19678
+ metallicRoughnessMapEnabled: false,
19679
+ occlusionMapEnabled: false,
19680
+ occlusionStrength: 1,
19681
+ alphaCutoffEnabled: false,
19682
+ alphaCutoff: 0.5,
19683
+ IBLenabled: false,
19684
+ scaleIBLAmbient: [1, 1],
19685
+ scaleDiffBaseMR: [0, 0, 0, 0],
19686
+ scaleFGDSpec: [0, 0, 0, 0],
19687
+ specularColorFactor: [1, 1, 1],
19688
+ specularIntensityFactor: 1,
19689
+ specularColorMapEnabled: false,
19690
+ specularIntensityMapEnabled: false,
19691
+ ior: 1.5,
19692
+ transmissionFactor: 0,
19693
+ transmissionMapEnabled: false,
19694
+ thicknessFactor: 0,
19695
+ attenuationDistance: 1e9,
19696
+ attenuationColor: [1, 1, 1],
19697
+ clearcoatFactor: 0,
19698
+ clearcoatRoughnessFactor: 0,
19699
+ clearcoatMapEnabled: false,
19700
+ clearcoatRoughnessMapEnabled: false,
19701
+ sheenColorFactor: [0, 0, 0],
19702
+ sheenRoughnessFactor: 0,
19703
+ sheenColorMapEnabled: false,
19704
+ sheenRoughnessMapEnabled: false,
19705
+ iridescenceFactor: 0,
19706
+ iridescenceIor: 1.3,
19707
+ iridescenceThicknessRange: [100, 400],
19708
+ iridescenceMapEnabled: false,
19709
+ anisotropyStrength: 0,
19710
+ anisotropyRotation: 0,
19711
+ anisotropyDirection: [1, 0],
19712
+ anisotropyMapEnabled: false,
19713
+ emissiveStrength: 1,
19714
+ baseColorUVSet: 0,
19715
+ baseColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19716
+ metallicRoughnessUVSet: 0,
19717
+ metallicRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19718
+ normalUVSet: 0,
19719
+ normalUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19720
+ occlusionUVSet: 0,
19721
+ occlusionUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19722
+ emissiveUVSet: 0,
19723
+ emissiveUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19724
+ specularColorUVSet: 0,
19725
+ specularColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19726
+ specularIntensityUVSet: 0,
19727
+ specularIntensityUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19728
+ transmissionUVSet: 0,
19729
+ transmissionUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19730
+ thicknessUVSet: 0,
19731
+ thicknessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19732
+ clearcoatUVSet: 0,
19733
+ clearcoatUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19734
+ clearcoatRoughnessUVSet: 0,
19735
+ clearcoatRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19736
+ clearcoatNormalUVSet: 0,
19737
+ clearcoatNormalUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19738
+ sheenColorUVSet: 0,
19739
+ sheenColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19740
+ sheenRoughnessUVSet: 0,
19741
+ sheenRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19742
+ iridescenceUVSet: 0,
19743
+ iridescenceUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19744
+ iridescenceThicknessUVSet: 0,
19745
+ iridescenceThicknessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
19746
+ anisotropyUVSet: 0,
19747
+ anisotropyUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1]
19748
+ },
17728
19749
  name: "pbrMaterial",
17729
- dependencies: [lighting, pbrProjection],
19750
+ firstBindingSlot: 0,
19751
+ bindingLayout: [
19752
+ { name: "pbrMaterial", group: 3 },
19753
+ { name: "pbr_baseColorSampler", group: 3 },
19754
+ { name: "pbr_normalSampler", group: 3 },
19755
+ { name: "pbr_emissiveSampler", group: 3 },
19756
+ { name: "pbr_metallicRoughnessSampler", group: 3 },
19757
+ { name: "pbr_occlusionSampler", group: 3 },
19758
+ { name: "pbr_specularColorSampler", group: 3 },
19759
+ { name: "pbr_specularIntensitySampler", group: 3 },
19760
+ { name: "pbr_transmissionSampler", group: 3 },
19761
+ { name: "pbr_thicknessSampler", group: 3 },
19762
+ { name: "pbr_clearcoatSampler", group: 3 },
19763
+ { name: "pbr_clearcoatRoughnessSampler", group: 3 },
19764
+ { name: "pbr_clearcoatNormalSampler", group: 3 },
19765
+ { name: "pbr_sheenColorSampler", group: 3 },
19766
+ { name: "pbr_sheenRoughnessSampler", group: 3 },
19767
+ { name: "pbr_iridescenceSampler", group: 3 },
19768
+ { name: "pbr_iridescenceThicknessSampler", group: 3 },
19769
+ { name: "pbr_anisotropySampler", group: 3 }
19770
+ ],
19771
+ dependencies: [lighting, ibl, pbrProjection],
17730
19772
  source,
17731
19773
  vs,
17732
19774
  fs,
@@ -17740,10 +19782,16 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17740
19782
  HAS_SPECULARCOLORMAP: false,
17741
19783
  HAS_SPECULARINTENSITYMAP: false,
17742
19784
  HAS_TRANSMISSIONMAP: false,
19785
+ HAS_THICKNESSMAP: false,
17743
19786
  HAS_CLEARCOATMAP: false,
19787
+ HAS_CLEARCOATROUGHNESSMAP: false,
19788
+ HAS_CLEARCOATNORMALMAP: false,
17744
19789
  HAS_SHEENCOLORMAP: false,
19790
+ HAS_SHEENROUGHNESSMAP: false,
17745
19791
  HAS_IRIDESCENCEMAP: false,
19792
+ HAS_IRIDESCENCETHICKNESSMAP: false,
17746
19793
  HAS_ANISOTROPYMAP: false,
19794
+ USE_MATERIAL_EXTENSIONS: false,
17747
19795
  ALPHA_CUTOFF: false,
17748
19796
  USE_IBL: false,
17749
19797
  PBR_DEBUG: false
@@ -17769,14 +19817,6 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17769
19817
  alphaCutoffEnabled: "i32",
17770
19818
  alphaCutoff: "f32",
17771
19819
  // #ifdef ALPHA_CUTOFF
17772
- // IBL
17773
- IBLenabled: "i32",
17774
- scaleIBLAmbient: "vec2<f32>",
17775
- // #ifdef USE_IBL
17776
- // debugging flags used for shader output of intermediate PBR variables
17777
- // #ifdef PBR_DEBUG
17778
- scaleDiffBaseMR: "vec4<f32>",
17779
- scaleFGDSpec: "vec4<f32>",
17780
19820
  specularColorFactor: "vec3<f32>",
17781
19821
  specularIntensityFactor: "f32",
17782
19822
  specularColorMapEnabled: "i32",
@@ -17790,9 +19830,11 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17790
19830
  clearcoatFactor: "f32",
17791
19831
  clearcoatRoughnessFactor: "f32",
17792
19832
  clearcoatMapEnabled: "i32",
19833
+ clearcoatRoughnessMapEnabled: "i32",
17793
19834
  sheenColorFactor: "vec3<f32>",
17794
19835
  sheenRoughnessFactor: "f32",
17795
19836
  sheenColorMapEnabled: "i32",
19837
+ sheenRoughnessMapEnabled: "i32",
17796
19838
  iridescenceFactor: "f32",
17797
19839
  iridescenceIor: "f32",
17798
19840
  iridescenceThicknessRange: "vec2<f32>",
@@ -17801,7 +19843,49 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17801
19843
  anisotropyRotation: "f32",
17802
19844
  anisotropyDirection: "vec2<f32>",
17803
19845
  anisotropyMapEnabled: "i32",
17804
- emissiveStrength: "f32"
19846
+ emissiveStrength: "f32",
19847
+ // IBL
19848
+ IBLenabled: "i32",
19849
+ scaleIBLAmbient: "vec2<f32>",
19850
+ // #ifdef USE_IBL
19851
+ // debugging flags used for shader output of intermediate PBR variables
19852
+ // #ifdef PBR_DEBUG
19853
+ scaleDiffBaseMR: "vec4<f32>",
19854
+ scaleFGDSpec: "vec4<f32>",
19855
+ baseColorUVSet: "i32",
19856
+ baseColorUVTransform: "mat3x3<f32>",
19857
+ metallicRoughnessUVSet: "i32",
19858
+ metallicRoughnessUVTransform: "mat3x3<f32>",
19859
+ normalUVSet: "i32",
19860
+ normalUVTransform: "mat3x3<f32>",
19861
+ occlusionUVSet: "i32",
19862
+ occlusionUVTransform: "mat3x3<f32>",
19863
+ emissiveUVSet: "i32",
19864
+ emissiveUVTransform: "mat3x3<f32>",
19865
+ specularColorUVSet: "i32",
19866
+ specularColorUVTransform: "mat3x3<f32>",
19867
+ specularIntensityUVSet: "i32",
19868
+ specularIntensityUVTransform: "mat3x3<f32>",
19869
+ transmissionUVSet: "i32",
19870
+ transmissionUVTransform: "mat3x3<f32>",
19871
+ thicknessUVSet: "i32",
19872
+ thicknessUVTransform: "mat3x3<f32>",
19873
+ clearcoatUVSet: "i32",
19874
+ clearcoatUVTransform: "mat3x3<f32>",
19875
+ clearcoatRoughnessUVSet: "i32",
19876
+ clearcoatRoughnessUVTransform: "mat3x3<f32>",
19877
+ clearcoatNormalUVSet: "i32",
19878
+ clearcoatNormalUVTransform: "mat3x3<f32>",
19879
+ sheenColorUVSet: "i32",
19880
+ sheenColorUVTransform: "mat3x3<f32>",
19881
+ sheenRoughnessUVSet: "i32",
19882
+ sheenRoughnessUVTransform: "mat3x3<f32>",
19883
+ iridescenceUVSet: "i32",
19884
+ iridescenceUVTransform: "mat3x3<f32>",
19885
+ iridescenceThicknessUVSet: "i32",
19886
+ iridescenceThicknessUVTransform: "mat3x3<f32>",
19887
+ anisotropyUVSet: "i32",
19888
+ anisotropyUVTransform: "mat3x3<f32>"
17805
19889
  }
17806
19890
  };
17807
19891
 
@@ -17810,7 +19894,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
17810
19894
  var import_mesh_layers = __toESM(require_mesh_layers(), 1);
17811
19895
 
17812
19896
  // src/mesh-layer/mesh-layer-uniforms.ts
17813
- var uniformBlock3 = `uniform meshUniforms {
19897
+ var uniformBlock3 = `layout(std140) uniform meshUniforms {
17814
19898
  bool pickFeatureIds;
17815
19899
  } mesh;
17816
19900
  `;
@@ -17893,11 +19977,12 @@ void main(void) {
17893
19977
  #endif
17894
19978
 
17895
19979
  #ifdef HAS_UV
17896
- pbr_vUV = uv;
19980
+ pbr_vUV0 = uv;
17897
19981
  #else
17898
- pbr_vUV = vec2(0., 0.);
19982
+ pbr_vUV0 = vec2(0., 0.);
17899
19983
  #endif
17900
- geometry.uv = pbr_vUV;
19984
+ pbr_vUV1 = vec2(0., 0.);
19985
+ geometry.uv = pbr_vUV0;
17901
19986
  #endif
17902
19987
 
17903
19988
  DECKGL_FILTER_COLOR(vColor, geometry);
@@ -17925,7 +20010,7 @@ void main(void) {
17925
20010
  #ifdef MODULE_PBRMATERIAL
17926
20011
 
17927
20012
  fragColor = vColor * pbr_filterColor(vec4(0));
17928
- geometry.uv = pbr_vUV;
20013
+ geometry.uv = pbr_vUV0;
17929
20014
  fragColor.a *= layer.opacity;
17930
20015
 
17931
20016
  #else
@@ -18092,7 +20177,7 @@ void main(void) {
18092
20177
  MeshLayer.defaultProps = defaultProps11;
18093
20178
 
18094
20179
  // src/tile-3d-layer/tile-3d-layer.ts
18095
- var import_core47 = __toESM(require_core2(), 1);
20180
+ var import_core48 = __toESM(require_core2(), 1);
18096
20181
 
18097
20182
  // ../../node_modules/@math.gl/geospatial/dist/constants.js
18098
20183
  var WGS84_RADIUS_X = 6378137;
@@ -18808,7 +20893,7 @@ void main(void) {
18808
20893
  }
18809
20894
 
18810
20895
  // ../../node_modules/@loaders.gl/tiles/dist/tileset/tile-3d.js
18811
- var import_core33 = __toESM(require_core2(), 1);
20896
+ var import_core34 = __toESM(require_core2(), 1);
18812
20897
 
18813
20898
  // ../../node_modules/@loaders.gl/tiles/dist/constants.js
18814
20899
  var TILE_CONTENT_STATE = {
@@ -19781,7 +21866,7 @@ void main(void) {
19781
21866
  }
19782
21867
  // TODO add typecheck - as const satisfies ...
19783
21868
  };
19784
- this.content = await (0, import_core33.load)(contentUrl, loader, options);
21869
+ this.content = await (0, import_core34.load)(contentUrl, loader, options);
19785
21870
  if (this.tileset.options.contentLoader) {
19786
21871
  await this.tileset.options.contentLoader(this);
19787
21872
  }
@@ -20065,7 +22150,7 @@ void main(void) {
20065
22150
  };
20066
22151
 
20067
22152
  // ../../node_modules/@loaders.gl/tiles/dist/tileset/format-i3s/i3s-tileset-traverser.js
20068
- var import_core34 = __toESM(require_core2(), 1);
22153
+ var import_core35 = __toESM(require_core2(), 1);
20069
22154
 
20070
22155
  // ../../node_modules/@loaders.gl/tiles/dist/tileset/format-i3s/i3s-pending-tiles-register.js
20071
22156
  var I3SPendingTilesRegister = class {
@@ -20229,7 +22314,7 @@ void main(void) {
20229
22314
  isTileHeader: true
20230
22315
  }
20231
22316
  };
20232
- return await (0, import_core34.load)(nodeUrl, loader, options);
22317
+ return await (0, import_core35.load)(nodeUrl, loader, options);
20233
22318
  }
20234
22319
  /**
20235
22320
  * The callback to init Tile3D instance after loading the tile JSON
@@ -20956,7 +23041,7 @@ void main(void) {
20956
23041
  };
20957
23042
 
20958
23043
  // ../../node_modules/@loaders.gl/3d-tiles/dist/lib/utils/version.js
20959
- var VERSION9 = true ? "4.4.0-alpha.18" : "latest";
23044
+ var VERSION9 = true ? "4.4.1" : "latest";
20960
23045
 
20961
23046
  // ../../node_modules/@loaders.gl/3d-tiles/dist/lib/constants.js
20962
23047
  var TILE3D_TYPE = {
@@ -21075,7 +23160,7 @@ void main(void) {
21075
23160
  }
21076
23161
 
21077
23162
  // ../../node_modules/@loaders.gl/draco/dist/lib/utils/version.js
21078
- var VERSION10 = true ? "4.4.0-alpha.18" : "latest";
23163
+ var VERSION10 = true ? "4.4.1" : "latest";
21079
23164
 
21080
23165
  // ../../node_modules/@loaders.gl/schema-utils/dist/lib/schema/data-type.js
21081
23166
  function getDataTypeFromTypedArray(array) {
@@ -24511,7 +26596,7 @@ void main(void) {
24511
26596
  }
24512
26597
 
24513
26598
  // ../../node_modules/@loaders.gl/gltf/dist/lib/utils/version.js
24514
- var VERSION11 = true ? "4.4.0-alpha.18" : "latest";
26599
+ var VERSION11 = true ? "4.4.1" : "latest";
24515
26600
 
24516
26601
  // ../../node_modules/@loaders.gl/gltf/dist/lib/parsers/parse-glb.js
24517
26602
  var LITTLE_ENDIAN2 = true;
@@ -24624,16 +26709,26 @@ void main(void) {
24624
26709
  }
24625
26710
 
24626
26711
  // ../../node_modules/@loaders.gl/gltf/dist/lib/gltf-utils/resolve-url.js
24627
- function resolveUrl(url, options) {
26712
+ function resolveUrl(url, options, context) {
24628
26713
  const absolute = url.startsWith("data:") || url.startsWith("http:") || url.startsWith("https:");
24629
26714
  if (absolute) {
24630
26715
  return url;
24631
26716
  }
24632
- const baseUrl = options?.core?.baseUri || options.baseUri || options.uri;
26717
+ const baseUrl = context?.baseUrl || getResolveBaseUrl(options?.core?.baseUrl);
26718
+ if (!baseUrl) {
26719
+ throw new Error(`'baseUrl' must be provided to resolve relative url ${url}`);
26720
+ }
26721
+ return baseUrl.endsWith("/") ? `${baseUrl}${url}` : `${baseUrl}/${url}`;
26722
+ }
26723
+ function getResolveBaseUrl(baseUrl) {
24633
26724
  if (!baseUrl) {
24634
- throw new Error(`'baseUri' must be provided to resolve relative url ${url}`);
26725
+ return void 0;
26726
+ }
26727
+ if (baseUrl.endsWith("/")) {
26728
+ return baseUrl;
24635
26729
  }
24636
- return baseUrl.substr(0, baseUrl.lastIndexOf("/") + 1) + url;
26730
+ const slashIndex = baseUrl.lastIndexOf("/");
26731
+ return slashIndex >= 0 ? baseUrl.slice(0, slashIndex + 1) : "";
24637
26732
  }
24638
26733
 
24639
26734
  // ../../node_modules/@loaders.gl/gltf/dist/lib/extensions/EXT_meshopt_compression.js
@@ -25670,8 +27765,8 @@ void main(void) {
25670
27765
  return gltf;
25671
27766
  }
25672
27767
  function parseGLTFContainerSync(gltf, data, byteOffset, options) {
25673
- if (options.core?.baseUri) {
25674
- gltf.baseUri = options.core?.baseUri;
27768
+ if (options.core?.baseUrl) {
27769
+ gltf.baseUri = options.core?.baseUrl;
25675
27770
  }
25676
27771
  if (data instanceof ArrayBuffer && !isGLB(data, byteOffset, options.glb)) {
25677
27772
  const textDecoder = new TextDecoder();
@@ -25708,7 +27803,7 @@ void main(void) {
25708
27803
  if (buffer.uri) {
25709
27804
  const { fetch: fetch2 } = context;
25710
27805
  assert8(fetch2);
25711
- const uri = resolveUrl(buffer.uri, options);
27806
+ const uri = resolveUrl(buffer.uri, options, context);
25712
27807
  const response = await context?.fetch?.(uri);
25713
27808
  const arrayBuffer = await response?.arrayBuffer?.();
25714
27809
  gltf.buffers[i] = {
@@ -25748,7 +27843,7 @@ void main(void) {
25748
27843
  async function loadImage(gltf, image, index, options, context) {
25749
27844
  let arrayBuffer;
25750
27845
  if (image.uri && !image.hasOwnProperty("bufferView")) {
25751
- const uri = resolveUrl(image.uri, options);
27846
+ const uri = resolveUrl(image.uri, options, context);
25752
27847
  const { fetch: fetch2 } = context;
25753
27848
  const response = await fetch2(uri);
25754
27849
  arrayBuffer = await response.arrayBuffer();
@@ -26562,10 +28657,10 @@ void main(void) {
26562
28657
  };
26563
28658
 
26564
28659
  // ../../node_modules/@loaders.gl/3d-tiles/dist/lib/parsers/parse-3d-tile-header.js
26565
- var import_core45 = __toESM(require_core2(), 1);
28660
+ var import_core46 = __toESM(require_core2(), 1);
26566
28661
 
26567
28662
  // ../../node_modules/@loaders.gl/3d-tiles/dist/lib/parsers/helpers/parse-3d-implicit-tiles.js
26568
- var import_core44 = __toESM(require_core2(), 1);
28663
+ var import_core45 = __toESM(require_core2(), 1);
26569
28664
 
26570
28665
  // ../../node_modules/@loaders.gl/3d-tiles/node_modules/long/index.js
26571
28666
  var wasm = null;
@@ -27843,7 +29938,7 @@ void main(void) {
27843
29938
  if (isChildSubtreeAvailable) {
27844
29939
  const subtreePath = `${basePath}/${subtreesUriTemplate}`;
27845
29940
  const childSubtreeUrl = replaceContentUrlTemplate(subtreePath, level, x, y, z);
27846
- const childSubtree = await (0, import_core44.load)(childSubtreeUrl, Tile3DSubtreeLoader, loaderOptions);
29941
+ const childSubtree = await (0, import_core45.load)(childSubtreeUrl, Tile3DSubtreeLoader, loaderOptions);
27847
29942
  nextSubtree = childSubtree;
27848
29943
  tileAvailabilityIndex = 0;
27849
29944
  nextSubtreeData = { level, x, y, z };
@@ -28072,7 +30167,7 @@ void main(void) {
28072
30167
  const { subdivisionScheme, maximumLevel, availableLevels, subtreeLevels, subtrees: { uri: subtreesUriTemplate } } = implicitTilingExtension;
28073
30168
  const replacedUrlTemplate = replaceContentUrlTemplate(subtreesUriTemplate, 0, 0, 0, 0);
28074
30169
  const subtreeUrl = resolveUri(replacedUrlTemplate, basePath);
28075
- const subtree = await (0, import_core45.load)(subtreeUrl, Tile3DSubtreeLoader, options);
30170
+ const subtree = await (0, import_core46.load)(subtreeUrl, Tile3DSubtreeLoader, options);
28076
30171
  const tileContentUri = tile.content?.uri;
28077
30172
  const contentUrlTemplate = tileContentUri ? resolveUri(tileContentUri, basePath) : "";
28078
30173
  const refine = tileset?.root?.refine;
@@ -28216,10 +30311,10 @@ void main(void) {
28216
30311
  } },
28217
30312
  _getMeshColor: { type: "function", value: (tileHeader) => [255, 255, 255] }
28218
30313
  };
28219
- var Tile3DLayer = class extends import_core46.CompositeLayer {
30314
+ var Tile3DLayer = class extends import_core47.CompositeLayer {
28220
30315
  initializeState() {
28221
30316
  if ("onTileLoadFail" in this.props) {
28222
- import_core46.log.removed("onTileLoadFail", "onTileError")();
30317
+ import_core47.log.removed("onTileLoadFail", "onTileError")();
28223
30318
  }
28224
30319
  this.state = {
28225
30320
  layerMap: {},
@@ -28254,6 +30349,14 @@ void main(void) {
28254
30349
  }
28255
30350
  }
28256
30351
  }
30352
+ finalizeState(context) {
30353
+ this.state.tileset3d?.destroy();
30354
+ this.state.tileset3d = null;
30355
+ this.state.layerMap = {};
30356
+ this.state.activeViewports = {};
30357
+ this.state.lastUpdatedViewports = null;
30358
+ super.finalizeState(context);
30359
+ }
28257
30360
  activateViewport(viewport) {
28258
30361
  const { activeViewports, lastUpdatedViewports } = this.state;
28259
30362
  this.internalState.viewport = viewport;
@@ -28321,7 +30424,7 @@ void main(void) {
28321
30424
  }
28322
30425
  Object.assign(options, preloadOptions);
28323
30426
  }
28324
- const tilesetJson = await (0, import_core47.load)(actualTilesetUrl, loader, options.loadOptions);
30427
+ const tilesetJson = await (0, import_core48.load)(actualTilesetUrl, loader, options.loadOptions);
28325
30428
  const tileset3d = new Tileset3D(tilesetJson, {
28326
30429
  onTileLoad: this._onTileLoad.bind(this),
28327
30430
  onTileUnload: this._onTileUnload.bind(this),
@@ -28408,7 +30511,7 @@ void main(void) {
28408
30511
  id: `${this.id}-pointcloud-${tileHeader.id}`,
28409
30512
  tile: tileHeader,
28410
30513
  data,
28411
- coordinateSystem: import_core46.COORDINATE_SYSTEM.METER_OFFSETS,
30514
+ coordinateSystem: import_core47.COORDINATE_SYSTEM.METER_OFFSETS,
28412
30515
  coordinateOrigin: cartographicOrigin,
28413
30516
  modelMatrix,
28414
30517
  getColor: constantRGBA || getPointColor,
@@ -28431,7 +30534,7 @@ void main(void) {
28431
30534
  tile: tileHeader,
28432
30535
  data: instances || SINGLE_DATA,
28433
30536
  scenegraph: gltf,
28434
- coordinateSystem: import_core46.COORDINATE_SYSTEM.METER_OFFSETS,
30537
+ coordinateSystem: import_core47.COORDINATE_SYSTEM.METER_OFFSETS,
28435
30538
  coordinateOrigin: cartographicOrigin,
28436
30539
  modelMatrix,
28437
30540
  getTransformMatrix: (instance) => instance.modelMatrix,
@@ -28450,7 +30553,7 @@ void main(void) {
28450
30553
  indices,
28451
30554
  modelMatrix,
28452
30555
  cartographicOrigin,
28453
- coordinateSystem = import_core46.COORDINATE_SYSTEM.METER_OFFSETS,
30556
+ coordinateSystem = import_core47.COORDINATE_SYSTEM.METER_OFFSETS,
28454
30557
  material,
28455
30558
  featureIds
28456
30559
  } = content;
@@ -28525,9 +30628,9 @@ void main(void) {
28525
30628
  }
28526
30629
 
28527
30630
  // src/terrain-layer/terrain-layer.ts
28528
- var import_core48 = __toESM(require_core(), 1);
28529
- var import_mesh_layers3 = __toESM(require_mesh_layers(), 1);
28530
30631
  var import_core49 = __toESM(require_core(), 1);
30632
+ var import_mesh_layers3 = __toESM(require_mesh_layers(), 1);
30633
+ var import_core50 = __toESM(require_core(), 1);
28531
30634
 
28532
30635
  // ../../node_modules/@loaders.gl/terrain/dist/lib/decode-quantized-mesh.js
28533
30636
  var QUANTIZED_MESH_HEADER = /* @__PURE__ */ new Map([
@@ -29488,7 +31591,7 @@ void main(void) {
29488
31591
  }
29489
31592
 
29490
31593
  // ../../node_modules/@loaders.gl/terrain/dist/lib/utils/version.js
29491
- var VERSION12 = true ? "4.4.0-alpha.18" : "latest";
31594
+ var VERSION12 = true ? "4.4.1" : "latest";
29492
31595
 
29493
31596
  // ../../node_modules/@loaders.gl/terrain/dist/terrain-loader.js
29494
31597
  var TerrainLoader = {
@@ -29595,7 +31698,7 @@ void main(void) {
29595
31698
  }
29596
31699
  return template || "";
29597
31700
  }
29598
- var TerrainLayer = class extends import_core48.CompositeLayer {
31701
+ var TerrainLayer = class extends import_core49.CompositeLayer {
29599
31702
  updateState({ props, oldProps }) {
29600
31703
  const elevationDataChanged = props.elevationData !== oldProps.elevationData;
29601
31704
  if (elevationDataChanged) {
@@ -29609,7 +31712,7 @@ void main(void) {
29609
31712
  this.setState({ terrain });
29610
31713
  }
29611
31714
  if (props.workerUrl) {
29612
- import_core48.log.removed("workerUrl", "loadOptions.terrain.workerUrl")();
31715
+ import_core49.log.removed("workerUrl", "loadOptions.terrain.workerUrl")();
29613
31716
  }
29614
31717
  }
29615
31718
  loadTerrain({
@@ -29680,7 +31783,7 @@ void main(void) {
29680
31783
  mesh,
29681
31784
  texture,
29682
31785
  _instanced: false,
29683
- coordinateSystem: import_core49.COORDINATE_SYSTEM.CARTESIAN,
31786
+ coordinateSystem: import_core50.COORDINATE_SYSTEM.CARTESIAN,
29684
31787
  getPosition: (d2) => [0, 0, 0],
29685
31788
  getColor: color,
29686
31789
  wireframe,
@@ -29785,7 +31888,7 @@ void main(void) {
29785
31888
  var isTileSetURL = (url) => url.includes("{x}") && (url.includes("{y}") || url.includes("{-y}"));
29786
31889
 
29787
31890
  // src/mvt-layer/mvt-layer.ts
29788
- var import_core51 = __toESM(require_core(), 1);
31891
+ var import_core52 = __toESM(require_core(), 1);
29789
31892
  var import_layers9 = __toESM(require_layers(), 1);
29790
31893
  var import_extensions = __toESM(require_extensions(), 1);
29791
31894
 
@@ -31360,7 +33463,7 @@ void main(void) {
31360
33463
  };
31361
33464
 
31362
33465
  // ../../node_modules/@loaders.gl/mvt/dist/mvt-loader.js
31363
- var VERSION13 = true ? "4.4.0-alpha.18" : "latest";
33466
+ var VERSION13 = true ? "4.4.1" : "latest";
31364
33467
  var MVTWorkerLoader = {
31365
33468
  ...MVTFormat,
31366
33469
  dataType: null,
@@ -31612,17 +33715,20 @@ void main(void) {
31612
33715
  const { fetch: fetch2 } = this.props;
31613
33716
  loadOptions = {
31614
33717
  ...loadOptions,
31615
- mimeType: "application/x-protobuf",
33718
+ core: {
33719
+ ...loadOptions?.core,
33720
+ mimeType: "application/x-protobuf"
33721
+ },
31616
33722
  mvt: {
31617
33723
  ...loadOptions?.mvt,
33724
+ shape: binary ? "binary" : "geojson",
31618
33725
  coordinates: this.context.viewport.resolution ? "wgs84" : "local",
31619
33726
  tileIndex: index
31620
33727
  // Local worker debug
31621
33728
  // workerUrl: `modules/mvt/dist/mvt-loader.worker.js`
31622
33729
  // Set worker to null to skip web workers
31623
33730
  // workerUrl: null
31624
- },
31625
- gis: binary ? { format: "binary" } : {}
33731
+ }
31626
33732
  };
31627
33733
  return fetch2(url, { propName: "data", layer: this, loadOptions, signal });
31628
33734
  }
@@ -31638,12 +33744,12 @@ void main(void) {
31638
33744
  if (!this.context.viewport.resolution) {
31639
33745
  props.modelMatrix = modelMatrix;
31640
33746
  props.coordinateOrigin = [xOffset, yOffset, 0];
31641
- props.coordinateSystem = import_core51.COORDINATE_SYSTEM.CARTESIAN;
33747
+ props.coordinateSystem = import_core52.COORDINATE_SYSTEM.CARTESIAN;
31642
33748
  props.extensions = [...props.extensions || [], new import_extensions.ClipExtension()];
31643
33749
  }
31644
33750
  const subLayers = super.renderSubLayers(props);
31645
33751
  if (this.state.binary && !(subLayers instanceof import_layers9.GeoJsonLayer)) {
31646
- import_core51.log.warn("renderSubLayers() must return GeoJsonLayer when using binary:true")();
33752
+ import_core52.log.warn("renderSubLayers() must return GeoJsonLayer when using binary:true")();
31647
33753
  }
31648
33754
  return subLayers;
31649
33755
  }