@expofp/renderer 3.2.1 → 3.2.3

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 +68 -17
  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, SrcAlphaFactor, 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"] = "";
@@ -1151,10 +1166,12 @@ var MaterialSystem = class {
1151
1166
  createTextureMaterial(params) {
1152
1167
  const material = new MeshBasicMaterial({
1153
1168
  ...sharedParameters,
1154
- map: params.map,
1155
- transparent: true,
1156
- depthFunc: LessDepth
1169
+ map: params.map
1157
1170
  });
1171
+ material.blending = CustomBlending;
1172
+ material.blendSrc = SrcAlphaFactor;
1173
+ material.blendSrcAlpha = OneFactor;
1174
+ if (params.depthEnable) material.depthFunc = LessEqualDepth;
1158
1175
  if (params.uvOffset) material.onBeforeCompile = (shader) => {
1159
1176
  shader.vertexShader = shader.vertexShader.replace("#include <uv_vertex>", `
1160
1177
  #include <uv_vertex>
@@ -1762,6 +1779,19 @@ function getAtlasSizeBytes(width, height) {
1762
1779
  return Math.ceil(width * height * 4 * 1.33);
1763
1780
  }
1764
1781
  //#endregion
1782
+ //#region src/util/colors.ts
1783
+ extend([namesPlugin]);
1784
+ /**
1785
+ * Normalizes a {@link ColorInput} into an rgba color object.
1786
+ * @param colorInput color as a css color string or a numeric 0xRRGGBB value
1787
+ * @returns rgba color (r/g/b 0-255, a 0-1), or undefined if the input is not a valid color
1788
+ */
1789
+ function normalizeColor(colorInput) {
1790
+ const color = colord(typeof colorInput === "string" ? colorInput : `#${colorInput.toString(16).padStart(6, "0")}`);
1791
+ if (!color.isValid()) return void 0;
1792
+ return color.toRgb();
1793
+ }
1794
+ //#endregion
1765
1795
  //#region src/geometry/line.ts
1766
1796
  var logger$13 = createLogger("line");
1767
1797
  /**
@@ -1769,6 +1799,7 @@ var logger$13 = createLogger("line");
1769
1799
  */
1770
1800
  var LineSystem = class extends RenderableSystem {
1771
1801
  lineColor = new Color();
1802
+ opacityByDef = /* @__PURE__ */ new WeakMap();
1772
1803
  /**
1773
1804
  * @param ctx {@link RendererContext}
1774
1805
  * @param materialSystem {@link MaterialSystem}
@@ -1784,6 +1815,8 @@ var LineSystem = class extends RenderableSystem {
1784
1815
  const geometries = /* @__PURE__ */ new Map();
1785
1816
  const lines = layer.children;
1786
1817
  for (const line of lines) {
1818
+ const normColor = normalizeColor(line.color);
1819
+ if (normColor !== void 0) this.opacityByDef.set(line, normColor.a);
1787
1820
  const lineGeometry = new LineSegmentsGeometry();
1788
1821
  lineGeometry.setPositions(line.points.flatMap((pt) => [
1789
1822
  pt.x,
@@ -1794,10 +1827,16 @@ var LineSystem = class extends RenderableSystem {
1794
1827
  vertexCount += lineGeometry.attributes["position"].count;
1795
1828
  indexCount += lineGeometry.index?.count ?? 0;
1796
1829
  }
1797
- const material = this.materialSystem.createLineMaterial({ color: "white" });
1830
+ const material = this.materialSystem.createLineMaterial({
1831
+ color: "white",
1832
+ transparent: lines.some((line) => (this.opacityByDef.get(line) ?? 1) < 1)
1833
+ });
1798
1834
  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));
1835
+ batchedMesh.addPerInstanceUniforms({
1836
+ vertex: { linewidth: "float" },
1837
+ fragment: { opacity: "float" }
1838
+ });
1839
+ batchedMesh.setCustomSort((list) => this.sortInstances(batchedMesh, list));
1801
1840
  for (const [line, geometry] of geometries.entries()) {
1802
1841
  const geometryId = batchedMesh.addGeometry(geometry);
1803
1842
  const instanceId = batchedMesh.addInstance(geometryId);
@@ -1807,11 +1846,28 @@ var LineSystem = class extends RenderableSystem {
1807
1846
  return group;
1808
1847
  }
1809
1848
  updateDefImpl(lineDef, mesh, instanceIds) {
1849
+ const normColor = normalizeColor(lineDef.color);
1850
+ if (!normColor) {
1851
+ logger$13.warn(`Invalid color: ${lineDef.color} %O`, lineDef);
1852
+ return;
1853
+ }
1854
+ const color = this.lineColor.setRGB(normColor.r / 255, normColor.g / 255, normColor.b / 255, SRGBColorSpace);
1855
+ this.opacityByDef.set(lineDef, normColor.a);
1810
1856
  for (const instanceId of instanceIds) {
1811
- mesh.setColorAt(instanceId, this.lineColor.set(lineDef.color));
1857
+ mesh.setColorAt(instanceId, color);
1812
1858
  mesh.setUniformAt(instanceId, "linewidth", lineDef.width);
1859
+ mesh.setUniformAt(instanceId, "opacity", normColor.a);
1813
1860
  }
1814
1861
  }
1862
+ sortInstances(mesh, list) {
1863
+ const lineDefs = this.getDefsByObject(mesh);
1864
+ list.sort((a, b) => {
1865
+ const aOpacity = this.opacityByDef.get(lineDefs[a.index]) ?? 1;
1866
+ const bOpacity = this.opacityByDef.get(lineDefs[b.index]) ?? 1;
1867
+ if (aOpacity !== bOpacity) return bOpacity - aOpacity;
1868
+ return a.index - b.index;
1869
+ });
1870
+ }
1815
1871
  deinterleaveGeometry(geometry) {
1816
1872
  const instanceStart = geometry.getAttribute("instanceStart");
1817
1873
  const instanceEnd = geometry.getAttribute("instanceEnd");
@@ -2183,7 +2239,6 @@ function computeBoundingSphere(bounds, origin, out = new Sphere()) {
2183
2239
  //#endregion
2184
2240
  //#region src/geometry/mesh.ts
2185
2241
  var logger$12 = createLogger("mesh");
2186
- extend([namesPlugin]);
2187
2242
  /**
2188
2243
  * A system that handles the rendering of shape defs.
2189
2244
  */
@@ -2209,7 +2264,7 @@ var MeshSystem = class extends RenderableSystem {
2209
2264
  const shapes = layer.children;
2210
2265
  const mapShapeToNormColor = /* @__PURE__ */ new Map();
2211
2266
  for (const shapeDef of shapes) {
2212
- const normColor = this.normalizeColor(shapeDef.color);
2267
+ const normColor = normalizeColor(shapeDef.color);
2213
2268
  if (normColor !== void 0) mapShapeToNormColor.set(shapeDef, normColor);
2214
2269
  }
2215
2270
  const [opaqueShapes, transparentShapes] = partition(shapes, (shapeDef) => (mapShapeToNormColor.get(shapeDef)?.a ?? 1) === 1);
@@ -2256,7 +2311,7 @@ var MeshSystem = class extends RenderableSystem {
2256
2311
  } else if (isRect) this.updateRect(shape, mesh, instanceId);
2257
2312
  }
2258
2313
  updateColor(shapeDef, mesh, instanceId) {
2259
- const color = this.normalizeColor(shapeDef.color);
2314
+ const color = normalizeColor(shapeDef.color);
2260
2315
  if (!color) {
2261
2316
  logger$12.warn(`Invalid color: ${shapeDef.color} %O`, shapeDef);
2262
2317
  return;
@@ -2321,11 +2376,6 @@ var MeshSystem = class extends RenderableSystem {
2321
2376
  }
2322
2377
  return batchedMesh;
2323
2378
  }
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
2379
  buildPolygonGeometry(polygon) {
2330
2380
  return new BufferGeometry().setFromPoints(polygon.vertices).setIndex(polygon.indices.flat());
2331
2381
  }
@@ -7674,7 +7724,8 @@ var Renderer = class {
7674
7724
  antialias: true,
7675
7725
  context: gl,
7676
7726
  canvas: this.canvas,
7677
- precision: "highp"
7727
+ precision: "highp",
7728
+ stencil: true
7678
7729
  };
7679
7730
  this.clock = new Clock();
7680
7731
  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.3",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"