@expofp/renderer 3.2.1 → 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 +63 -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";
@@ -1079,6 +1079,15 @@ var dimColorFrag = `
1079
1079
  * configured camera pitch. See {@link MaterialSystem.addPolygonOffset} for derivation.
1080
1080
  */
1081
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;
1082
1091
  var sharedParameters = {
1083
1092
  side: DoubleSide,
1084
1093
  forceSinglePass: true,
@@ -1089,6 +1098,7 @@ var MaterialSystem = class {
1089
1098
  backgroundMaterial;
1090
1099
  viewport = new Vector4();
1091
1100
  lightingMaterials = [];
1101
+ nextLineStencilRef = LINE_STENCIL_REF_MAX;
1092
1102
  /**
1093
1103
  * Creates a line material.
1094
1104
  * @param params {@link LineMaterialParameters}
@@ -1099,6 +1109,11 @@ var MaterialSystem = class {
1099
1109
  ...sharedParameters,
1100
1110
  ...params
1101
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;
1102
1117
  material.onBeforeCompile = (shader) => {
1103
1118
  shader.defines ??= {};
1104
1119
  shader.defines["USE_BATCHING_COLOR"] = "";
@@ -1762,6 +1777,19 @@ function getAtlasSizeBytes(width, height) {
1762
1777
  return Math.ceil(width * height * 4 * 1.33);
1763
1778
  }
1764
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
1765
1793
  //#region src/geometry/line.ts
1766
1794
  var logger$13 = createLogger("line");
1767
1795
  /**
@@ -1769,6 +1797,7 @@ var logger$13 = createLogger("line");
1769
1797
  */
1770
1798
  var LineSystem = class extends RenderableSystem {
1771
1799
  lineColor = new Color();
1800
+ opacityByDef = /* @__PURE__ */ new WeakMap();
1772
1801
  /**
1773
1802
  * @param ctx {@link RendererContext}
1774
1803
  * @param materialSystem {@link MaterialSystem}
@@ -1784,6 +1813,8 @@ var LineSystem = class extends RenderableSystem {
1784
1813
  const geometries = /* @__PURE__ */ new Map();
1785
1814
  const lines = layer.children;
1786
1815
  for (const line of lines) {
1816
+ const normColor = normalizeColor(line.color);
1817
+ if (normColor !== void 0) this.opacityByDef.set(line, normColor.a);
1787
1818
  const lineGeometry = new LineSegmentsGeometry();
1788
1819
  lineGeometry.setPositions(line.points.flatMap((pt) => [
1789
1820
  pt.x,
@@ -1794,10 +1825,16 @@ var LineSystem = class extends RenderableSystem {
1794
1825
  vertexCount += lineGeometry.attributes["position"].count;
1795
1826
  indexCount += lineGeometry.index?.count ?? 0;
1796
1827
  }
1797
- 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
+ });
1798
1832
  const batchedMesh = new BatchedMesh$1(lines.length, vertexCount, indexCount, material);
1799
- batchedMesh.addPerInstanceUniforms({ vertex: { linewidth: "float" } });
1800
- 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));
1801
1838
  for (const [line, geometry] of geometries.entries()) {
1802
1839
  const geometryId = batchedMesh.addGeometry(geometry);
1803
1840
  const instanceId = batchedMesh.addInstance(geometryId);
@@ -1807,11 +1844,28 @@ var LineSystem = class extends RenderableSystem {
1807
1844
  return group;
1808
1845
  }
1809
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);
1810
1854
  for (const instanceId of instanceIds) {
1811
- mesh.setColorAt(instanceId, this.lineColor.set(lineDef.color));
1855
+ mesh.setColorAt(instanceId, color);
1812
1856
  mesh.setUniformAt(instanceId, "linewidth", lineDef.width);
1857
+ mesh.setUniformAt(instanceId, "opacity", normColor.a);
1813
1858
  }
1814
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
+ }
1815
1869
  deinterleaveGeometry(geometry) {
1816
1870
  const instanceStart = geometry.getAttribute("instanceStart");
1817
1871
  const instanceEnd = geometry.getAttribute("instanceEnd");
@@ -2183,7 +2237,6 @@ function computeBoundingSphere(bounds, origin, out = new Sphere()) {
2183
2237
  //#endregion
2184
2238
  //#region src/geometry/mesh.ts
2185
2239
  var logger$12 = createLogger("mesh");
2186
- extend([namesPlugin]);
2187
2240
  /**
2188
2241
  * A system that handles the rendering of shape defs.
2189
2242
  */
@@ -2209,7 +2262,7 @@ var MeshSystem = class extends RenderableSystem {
2209
2262
  const shapes = layer.children;
2210
2263
  const mapShapeToNormColor = /* @__PURE__ */ new Map();
2211
2264
  for (const shapeDef of shapes) {
2212
- const normColor = this.normalizeColor(shapeDef.color);
2265
+ const normColor = normalizeColor(shapeDef.color);
2213
2266
  if (normColor !== void 0) mapShapeToNormColor.set(shapeDef, normColor);
2214
2267
  }
2215
2268
  const [opaqueShapes, transparentShapes] = partition(shapes, (shapeDef) => (mapShapeToNormColor.get(shapeDef)?.a ?? 1) === 1);
@@ -2256,7 +2309,7 @@ var MeshSystem = class extends RenderableSystem {
2256
2309
  } else if (isRect) this.updateRect(shape, mesh, instanceId);
2257
2310
  }
2258
2311
  updateColor(shapeDef, mesh, instanceId) {
2259
- const color = this.normalizeColor(shapeDef.color);
2312
+ const color = normalizeColor(shapeDef.color);
2260
2313
  if (!color) {
2261
2314
  logger$12.warn(`Invalid color: ${shapeDef.color} %O`, shapeDef);
2262
2315
  return;
@@ -2321,11 +2374,6 @@ var MeshSystem = class extends RenderableSystem {
2321
2374
  }
2322
2375
  return batchedMesh;
2323
2376
  }
2324
- normalizeColor(colorInput) {
2325
- const color = colord(typeof colorInput === "string" ? colorInput : `#${colorInput.toString(16).padStart(6, "0")}`);
2326
- if (!color.isValid()) return void 0;
2327
- return color.toRgb();
2328
- }
2329
2377
  buildPolygonGeometry(polygon) {
2330
2378
  return new BufferGeometry().setFromPoints(polygon.vertices).setIndex(polygon.indices.flat());
2331
2379
  }
@@ -7674,7 +7722,8 @@ var Renderer = class {
7674
7722
  antialias: true,
7675
7723
  context: gl,
7676
7724
  canvas: this.canvas,
7677
- precision: "highp"
7725
+ precision: "highp",
7726
+ stencil: true
7678
7727
  };
7679
7728
  this.clock = new Clock();
7680
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.1",
3
+ "version": "3.2.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"