@expofp/renderer 3.2.0 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +74 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AlwaysDepth, BatchedMesh, Box3, BufferAttribute, BufferGeometry, Camera, Clock, Color, CustomBlending, DataTexture, DirectionalLight, DoubleSide, DynamicDrawUsage, FloatType, Frustum, Group, HemisphereLight, IntType, LessDepth, LessEqualDepth, LinearSRGBColorSpace, MathUtils, Matrix3, Matrix4, Mesh, MeshBasicMaterial, MeshPhysicalMaterial, MeshStandardMaterial, OneFactor, PMREMGenerator, PerspectiveCamera, Plane, PlaneGeometry, Quaternion, RGBAFormat, RGBAIntegerFormat, RGFormat, RGIntegerFormat, Raycaster, RedFormat, RedIntegerFormat, SRGBColorSpace, Scene, Sphere, Spherical, StreamDrawUsage, Texture, UnsignedIntType, Vector2, Vector3, Vector4, WebGLRenderer } from "three";
1
+ import { AlwaysDepth, BatchedMesh, Box3, BufferAttribute, BufferGeometry, Camera, Clock, Color, CustomBlending, DataTexture, DirectionalLight, DoubleSide, DynamicDrawUsage, FloatType, Frustum, Group, HemisphereLight, IntType, LessDepth, LessEqualDepth, LinearSRGBColorSpace, MathUtils, Matrix3, Matrix4, Mesh, MeshBasicMaterial, MeshPhysicalMaterial, MeshStandardMaterial, NotEqualStencilFunc, OneFactor, PMREMGenerator, PerspectiveCamera, Plane, PlaneGeometry, Quaternion, RGBAFormat, RGBAIntegerFormat, RGFormat, RGIntegerFormat, Raycaster, RedFormat, RedIntegerFormat, ReplaceStencilOp, SRGBColorSpace, Scene, Sphere, Spherical, StreamDrawUsage, Texture, UnsignedIntType, Vector2, Vector3, Vector4, WebGLRenderer } from "three";
2
2
  import { traverseAncestorsGenerator } from "three/examples/jsm/utils/SceneUtils.js";
3
3
  import createLog from "debug";
4
4
  import { BatchedText, Text } from "troika-three-text";
@@ -730,6 +730,17 @@ var BatchedText$1 = class extends BatchedText {
730
730
  if (pendingSyncs.length) Promise.all(pendingSyncs).then(repack);
731
731
  else repack();
732
732
  }
733
+ createDerivedMaterial(baseMaterial) {
734
+ const derivedMaterial = super.createDerivedMaterial(baseMaterial);
735
+ derivedMaterial.onBeforeCompile = (shader) => {
736
+ shader.vertexShader = shader.vertexShader.replace("void main() {", `
737
+ void main () {
738
+ // Uninitialized vec2 causes problems on Samsung Android devices
739
+ uTroikaPositionOffset = vec2(0., 0.);
740
+ `);
741
+ };
742
+ return derivedMaterial;
743
+ }
733
744
  repackBatchedGeometry() {
734
745
  const geometry = this.geometry;
735
746
  const batchedAttributes = geometry.attributes;
@@ -1068,6 +1079,15 @@ var dimColorFrag = `
1068
1079
  * configured camera pitch. See {@link MaterialSystem.addPolygonOffset} for derivation.
1069
1080
  */
1070
1081
  var POLYGON_OFFSET_MULTIPLIER = 12;
1082
+ /**
1083
+ * Stencil refs for line materials are allocated downward from 255 to stay clear of
1084
+ * maplibre's stencil IDs (tile clipping masks), which grow upward from 1 in external
1085
+ * mode where the stencil buffer is shared. Allocation wraps back to 255 at the floor;
1086
+ * two line layers only share a ref (and stop blending where they overlap) in scenes
1087
+ * with more line layers than the 255..200 range holds.
1088
+ */
1089
+ var LINE_STENCIL_REF_MAX = 255;
1090
+ var LINE_STENCIL_REF_MIN = 200;
1071
1091
  var sharedParameters = {
1072
1092
  side: DoubleSide,
1073
1093
  forceSinglePass: true,
@@ -1078,6 +1098,7 @@ var MaterialSystem = class {
1078
1098
  backgroundMaterial;
1079
1099
  viewport = new Vector4();
1080
1100
  lightingMaterials = [];
1101
+ nextLineStencilRef = LINE_STENCIL_REF_MAX;
1081
1102
  /**
1082
1103
  * Creates a line material.
1083
1104
  * @param params {@link LineMaterialParameters}
@@ -1088,6 +1109,11 @@ var MaterialSystem = class {
1088
1109
  ...sharedParameters,
1089
1110
  ...params
1090
1111
  });
1112
+ material.stencilWrite = true;
1113
+ material.stencilFunc = NotEqualStencilFunc;
1114
+ material.stencilZPass = ReplaceStencilOp;
1115
+ material.stencilRef = this.nextLineStencilRef;
1116
+ this.nextLineStencilRef = this.nextLineStencilRef <= LINE_STENCIL_REF_MIN ? LINE_STENCIL_REF_MAX : this.nextLineStencilRef - 1;
1091
1117
  material.onBeforeCompile = (shader) => {
1092
1118
  shader.defines ??= {};
1093
1119
  shader.defines["USE_BATCHING_COLOR"] = "";
@@ -1751,6 +1777,19 @@ function getAtlasSizeBytes(width, height) {
1751
1777
  return Math.ceil(width * height * 4 * 1.33);
1752
1778
  }
1753
1779
  //#endregion
1780
+ //#region src/util/colors.ts
1781
+ extend([namesPlugin]);
1782
+ /**
1783
+ * Normalizes a {@link ColorInput} into an rgba color object.
1784
+ * @param colorInput color as a css color string or a numeric 0xRRGGBB value
1785
+ * @returns rgba color (r/g/b 0-255, a 0-1), or undefined if the input is not a valid color
1786
+ */
1787
+ function normalizeColor(colorInput) {
1788
+ const color = colord(typeof colorInput === "string" ? colorInput : `#${colorInput.toString(16).padStart(6, "0")}`);
1789
+ if (!color.isValid()) return void 0;
1790
+ return color.toRgb();
1791
+ }
1792
+ //#endregion
1754
1793
  //#region src/geometry/line.ts
1755
1794
  var logger$13 = createLogger("line");
1756
1795
  /**
@@ -1758,6 +1797,7 @@ var logger$13 = createLogger("line");
1758
1797
  */
1759
1798
  var LineSystem = class extends RenderableSystem {
1760
1799
  lineColor = new Color();
1800
+ opacityByDef = /* @__PURE__ */ new WeakMap();
1761
1801
  /**
1762
1802
  * @param ctx {@link RendererContext}
1763
1803
  * @param materialSystem {@link MaterialSystem}
@@ -1773,6 +1813,8 @@ var LineSystem = class extends RenderableSystem {
1773
1813
  const geometries = /* @__PURE__ */ new Map();
1774
1814
  const lines = layer.children;
1775
1815
  for (const line of lines) {
1816
+ const normColor = normalizeColor(line.color);
1817
+ if (normColor !== void 0) this.opacityByDef.set(line, normColor.a);
1776
1818
  const lineGeometry = new LineSegmentsGeometry();
1777
1819
  lineGeometry.setPositions(line.points.flatMap((pt) => [
1778
1820
  pt.x,
@@ -1783,10 +1825,16 @@ var LineSystem = class extends RenderableSystem {
1783
1825
  vertexCount += lineGeometry.attributes["position"].count;
1784
1826
  indexCount += lineGeometry.index?.count ?? 0;
1785
1827
  }
1786
- const material = this.materialSystem.createLineMaterial({ color: "white" });
1828
+ const material = this.materialSystem.createLineMaterial({
1829
+ color: "white",
1830
+ transparent: lines.some((line) => (this.opacityByDef.get(line) ?? 1) < 1)
1831
+ });
1787
1832
  const batchedMesh = new BatchedMesh$1(lines.length, vertexCount, indexCount, material);
1788
- batchedMesh.addPerInstanceUniforms({ vertex: { linewidth: "float" } });
1789
- batchedMesh.setCustomSort((list) => list.sort((a, b) => a.z - b.z));
1833
+ batchedMesh.addPerInstanceUniforms({
1834
+ vertex: { linewidth: "float" },
1835
+ fragment: { opacity: "float" }
1836
+ });
1837
+ batchedMesh.setCustomSort((list) => this.sortInstances(batchedMesh, list));
1790
1838
  for (const [line, geometry] of geometries.entries()) {
1791
1839
  const geometryId = batchedMesh.addGeometry(geometry);
1792
1840
  const instanceId = batchedMesh.addInstance(geometryId);
@@ -1796,11 +1844,28 @@ var LineSystem = class extends RenderableSystem {
1796
1844
  return group;
1797
1845
  }
1798
1846
  updateDefImpl(lineDef, mesh, instanceIds) {
1847
+ const normColor = normalizeColor(lineDef.color);
1848
+ if (!normColor) {
1849
+ logger$13.warn(`Invalid color: ${lineDef.color} %O`, lineDef);
1850
+ return;
1851
+ }
1852
+ const color = this.lineColor.setRGB(normColor.r / 255, normColor.g / 255, normColor.b / 255, SRGBColorSpace);
1853
+ this.opacityByDef.set(lineDef, normColor.a);
1799
1854
  for (const instanceId of instanceIds) {
1800
- mesh.setColorAt(instanceId, this.lineColor.set(lineDef.color));
1855
+ mesh.setColorAt(instanceId, color);
1801
1856
  mesh.setUniformAt(instanceId, "linewidth", lineDef.width);
1857
+ mesh.setUniformAt(instanceId, "opacity", normColor.a);
1802
1858
  }
1803
1859
  }
1860
+ sortInstances(mesh, list) {
1861
+ const lineDefs = this.getDefsByObject(mesh);
1862
+ list.sort((a, b) => {
1863
+ const aOpacity = this.opacityByDef.get(lineDefs[a.index]) ?? 1;
1864
+ const bOpacity = this.opacityByDef.get(lineDefs[b.index]) ?? 1;
1865
+ if (aOpacity !== bOpacity) return bOpacity - aOpacity;
1866
+ return a.index - b.index;
1867
+ });
1868
+ }
1804
1869
  deinterleaveGeometry(geometry) {
1805
1870
  const instanceStart = geometry.getAttribute("instanceStart");
1806
1871
  const instanceEnd = geometry.getAttribute("instanceEnd");
@@ -2172,7 +2237,6 @@ function computeBoundingSphere(bounds, origin, out = new Sphere()) {
2172
2237
  //#endregion
2173
2238
  //#region src/geometry/mesh.ts
2174
2239
  var logger$12 = createLogger("mesh");
2175
- extend([namesPlugin]);
2176
2240
  /**
2177
2241
  * A system that handles the rendering of shape defs.
2178
2242
  */
@@ -2198,7 +2262,7 @@ var MeshSystem = class extends RenderableSystem {
2198
2262
  const shapes = layer.children;
2199
2263
  const mapShapeToNormColor = /* @__PURE__ */ new Map();
2200
2264
  for (const shapeDef of shapes) {
2201
- const normColor = this.normalizeColor(shapeDef.color);
2265
+ const normColor = normalizeColor(shapeDef.color);
2202
2266
  if (normColor !== void 0) mapShapeToNormColor.set(shapeDef, normColor);
2203
2267
  }
2204
2268
  const [opaqueShapes, transparentShapes] = partition(shapes, (shapeDef) => (mapShapeToNormColor.get(shapeDef)?.a ?? 1) === 1);
@@ -2245,7 +2309,7 @@ var MeshSystem = class extends RenderableSystem {
2245
2309
  } else if (isRect) this.updateRect(shape, mesh, instanceId);
2246
2310
  }
2247
2311
  updateColor(shapeDef, mesh, instanceId) {
2248
- const color = this.normalizeColor(shapeDef.color);
2312
+ const color = normalizeColor(shapeDef.color);
2249
2313
  if (!color) {
2250
2314
  logger$12.warn(`Invalid color: ${shapeDef.color} %O`, shapeDef);
2251
2315
  return;
@@ -2310,11 +2374,6 @@ var MeshSystem = class extends RenderableSystem {
2310
2374
  }
2311
2375
  return batchedMesh;
2312
2376
  }
2313
- normalizeColor(colorInput) {
2314
- const color = colord(typeof colorInput === "string" ? colorInput : `#${colorInput.toString(16).padStart(6, "0")}`);
2315
- if (!color.isValid()) return void 0;
2316
- return color.toRgb();
2317
- }
2318
2377
  buildPolygonGeometry(polygon) {
2319
2378
  return new BufferGeometry().setFromPoints(polygon.vertices).setIndex(polygon.indices.flat());
2320
2379
  }
@@ -7663,7 +7722,8 @@ var Renderer = class {
7663
7722
  antialias: true,
7664
7723
  context: gl,
7665
7724
  canvas: this.canvas,
7666
- precision: "highp"
7725
+ precision: "highp",
7726
+ stencil: true
7667
7727
  };
7668
7728
  this.clock = new Clock();
7669
7729
  this.renderer = new WebGLRenderer(rendererOptions);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expofp/renderer",
3
- "version": "3.2.0",
3
+ "version": "3.2.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"