@expofp/renderer 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -470,6 +470,7 @@ export declare class Renderer {
470
470
  private memoryInfoExtension;
471
471
  private memoryInfo?;
472
472
  private eventSystem;
473
+ private lightsSystem;
473
474
  private layerSystem;
474
475
  private viewportSystem;
475
476
  private updatesSystem;
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  var _a;
5
- import { DataTexture, FloatType, UnsignedIntType, IntType, RGBAFormat, RGBAIntegerFormat, RGFormat, RGIntegerFormat, RedFormat, RedIntegerFormat, BatchedMesh as BatchedMesh$1, BufferAttribute, StreamDrawUsage, Color, Matrix4, Vector3, Frustum, Sphere, Box3, DynamicDrawUsage, Vector4, AlwaysDepth, DoubleSide, MeshBasicMaterial, LessEqualDepth, Texture, Group, PlaneGeometry, SRGBColorSpace, Vector2, Quaternion, BufferGeometry, LinearSRGBColorSpace, Mesh, Camera, Spherical, MathUtils, Plane, Raycaster, PerspectiveCamera, Scene, Clock, WebGLRenderer } from "three";
5
+ import { DataTexture, FloatType, UnsignedIntType, IntType, RGBAFormat, RGBAIntegerFormat, RGFormat, RGIntegerFormat, RedFormat, RedIntegerFormat, BatchedMesh as BatchedMesh$1, BufferAttribute, StreamDrawUsage, Color, Matrix4, Vector3, Frustum, Sphere, Box3, DynamicDrawUsage, Vector4, AlwaysDepth, DoubleSide, MeshPhongMaterial, MeshBasicMaterial, LessEqualDepth, Texture, Group, PlaneGeometry, SRGBColorSpace, Vector2, Quaternion, BufferGeometry, LinearSRGBColorSpace, Mesh, AmbientLight, DirectionalLight, Camera, Spherical, MathUtils, Plane, Raycaster, PerspectiveCamera, Scene, Clock, WebGLRenderer } from "three";
6
6
  import { traverseAncestorsGenerator } from "three/examples/jsm/utils/SceneUtils.js";
7
7
  import createLog from "debug";
8
8
  import { BatchedText as BatchedText$1, Text as Text$1 } from "troika-three-text";
@@ -1102,12 +1102,13 @@ class MaterialSystem {
1102
1102
  * @returns MeshBasicMaterial instance
1103
1103
  */
1104
1104
  createColorMaterial(params = {}) {
1105
- const material = new MeshBasicMaterial({
1105
+ const materialConstructor = params.lightingEnable ? MeshPhongMaterial : MeshBasicMaterial;
1106
+ const material = new materialConstructor({
1106
1107
  ...sharedParameters,
1107
1108
  color: params.color ?? 16777215,
1108
1109
  opacity: params.opacity ?? 1
1109
1110
  });
1110
- if (params.is3D) material.depthFunc = LessEqualDepth;
1111
+ if (params.depthEnable) material.depthFunc = LessEqualDepth;
1111
1112
  addDimToMaterial(material);
1112
1113
  this.addPolygonOffset(material);
1113
1114
  return material;
@@ -1119,7 +1120,7 @@ class MaterialSystem {
1119
1120
  */
1120
1121
  createTextureMaterial(params) {
1121
1122
  const material = new MeshBasicMaterial({ ...sharedParameters, map: params.map });
1122
- if (params.is3D) material.depthFunc = LessEqualDepth;
1123
+ if (params.depthEnable) material.depthFunc = LessEqualDepth;
1123
1124
  if (params.uvOffset) {
1124
1125
  material.onBeforeCompile = (shader) => {
1125
1126
  shader.vertexShader = shader.vertexShader.replace(
@@ -1509,7 +1510,11 @@ class ImageSystem extends RenderableSystem {
1509
1510
  ).sort((a, b) => a.originalIndex - b.originalIndex);
1510
1511
  const instanceCount = rectsWithDef.length;
1511
1512
  const texture = createAtlas(bin);
1512
- const instanceMaterial = this.materialSystem.createTextureMaterial({ map: texture, uvOffset: true, is3D });
1513
+ const instanceMaterial = this.materialSystem.createTextureMaterial({
1514
+ map: texture,
1515
+ uvOffset: true,
1516
+ depthEnable: is3D
1517
+ });
1513
1518
  const instanceGeometry = new PlaneGeometry();
1514
1519
  const vertexCount = instanceGeometry.attributes["position"].count;
1515
1520
  const indexCount = ((_a2 = instanceGeometry.index) == null ? void 0 : _a2.count) ?? 0;
@@ -2024,11 +2029,10 @@ class MeshSystem extends RenderableSystem {
2024
2029
  __publicField(this, "rotation", new Quaternion());
2025
2030
  __publicField(this, "scale", new Vector3());
2026
2031
  __publicField(this, "matrix", new Matrix4());
2027
- __publicField(this, "rectGeometry", new PlaneGeometry(1, 1));
2032
+ __publicField(this, "rectGeometry", new PlaneGeometry(1, 1).deleteAttribute("uv").deleteAttribute("normal"));
2033
+ __publicField(this, "rectGeometry3D", new PlaneGeometry(1, 1).deleteAttribute("uv").toNonIndexed());
2028
2034
  __publicField(this, "mapInstanceIdToShapeType", /* @__PURE__ */ new Map());
2029
2035
  this.materialSystem = materialSystem;
2030
- this.rectGeometry.deleteAttribute("normal");
2031
- this.rectGeometry.deleteAttribute("uv");
2032
2036
  }
2033
2037
  buildLayer(layer) {
2034
2038
  const is3D = layer.mode === "3D";
@@ -2081,7 +2085,9 @@ class MeshSystem extends RenderableSystem {
2081
2085
  logger$a.warn("Polygon geometry changing not supported %O", shapeDef);
2082
2086
  return;
2083
2087
  }
2084
- mesh.setGeometryAt(geometryId, this.buildPolygonGeometry(shape));
2088
+ const geometry = this.buildPolygonGeometry(shape);
2089
+ if (mesh.geometry.hasAttribute("normal")) geometry.computeVertexNormals();
2090
+ mesh.setGeometryAt(geometryId, geometry);
2085
2091
  } else if (isRect) {
2086
2092
  this.updateRect(shape, mesh, instanceId);
2087
2093
  }
@@ -2106,23 +2112,28 @@ class MeshSystem extends RenderableSystem {
2106
2112
  let indexCount = 0;
2107
2113
  let rectAdded = false;
2108
2114
  const shapeDefToGeometry = /* @__PURE__ */ new Map();
2115
+ const rectGeom = is3D ? this.rectGeometry3D : this.rectGeometry;
2109
2116
  for (const shapeDef of shapes) {
2110
2117
  let vertices = 0;
2111
2118
  let indices = 0;
2112
2119
  if (shapeDef.shape instanceof Rect && !rectAdded) {
2113
2120
  rectAdded = true;
2114
- ({ vertices, indices } = countGeometry(this.rectGeometry));
2121
+ ({ vertices, indices } = countGeometry(rectGeom));
2115
2122
  } else if (shapeDef.shape instanceof Polygon) {
2116
- const geometry = this.buildPolygonGeometry(shapeDef.shape);
2123
+ let geometry = this.buildPolygonGeometry(shapeDef.shape);
2124
+ if (is3D) {
2125
+ geometry = geometry.toNonIndexed();
2126
+ geometry.computeVertexNormals();
2127
+ }
2117
2128
  shapeDefToGeometry.set(shapeDef, geometry);
2118
2129
  ({ vertices, indices } = countGeometry(geometry));
2119
2130
  }
2120
2131
  vertexCount += vertices;
2121
2132
  indexCount += indices;
2122
2133
  }
2123
- const material = this.materialSystem.createColorMaterial({ opacity, is3D });
2134
+ const material = this.materialSystem.createColorMaterial({ opacity, depthEnable: is3D, lightingEnable: is3D });
2124
2135
  const batchedMesh = new BatchedMesh(shapes.length, vertexCount, indexCount, material);
2125
- const rectGeometryId = rectAdded ? batchedMesh.addGeometry(this.rectGeometry) : void 0;
2136
+ const rectGeometryId = rectAdded ? batchedMesh.addGeometry(rectGeom) : void 0;
2126
2137
  batchedMesh.setCustomSort((list) => this.sortInstances(batchedMesh, list));
2127
2138
  for (const shapeDef of shapes) {
2128
2139
  let instanceId;
@@ -2259,7 +2270,7 @@ class TextSystem extends RenderableSystem {
2259
2270
  const is3D = layer.mode === "3D";
2260
2271
  const textDefs = layer.children;
2261
2272
  const batchedText = new BatchedText();
2262
- batchedText.material = this.materialSystem.createColorMaterial({ is3D });
2273
+ batchedText.material = this.materialSystem.createColorMaterial({ depthEnable: is3D });
2263
2274
  const mappingData = [];
2264
2275
  let instanceId = 0;
2265
2276
  for (const textDef of textDefs) {
@@ -2572,6 +2583,36 @@ class LayerSystem {
2572
2583
  return fullName;
2573
2584
  }
2574
2585
  }
2586
+ class LightsSystem {
2587
+ constructor() {
2588
+ __publicField(this, "color", 16777215);
2589
+ __publicField(this, "intensity", 0.5);
2590
+ __publicField(this, "mapSceneToLight", /* @__PURE__ */ new Map());
2591
+ }
2592
+ /**
2593
+ * Initializes a directional light for the given scene.
2594
+ * @param scene {@link Scene} to add the light to
2595
+ */
2596
+ initLights(scene) {
2597
+ const ambientLight = new AmbientLight(16777215, this.intensity);
2598
+ scene.add(ambientLight);
2599
+ const directionalLight = new DirectionalLight(this.color, this.intensity * Math.PI * 2);
2600
+ scene.add(directionalLight);
2601
+ scene.add(directionalLight.target);
2602
+ this.mapSceneToLight.set(scene, directionalLight);
2603
+ }
2604
+ /**
2605
+ * Updates the light direction to match the camera's viewing direction.
2606
+ * @param scene {@link Scene} containing the light
2607
+ * @param camera {@link Camera} to derive the light direction from
2608
+ */
2609
+ updateLights(scene, camera) {
2610
+ const light = this.mapSceneToLight.get(scene);
2611
+ if (!light) return;
2612
+ const e = scene.matrixWorld.elements;
2613
+ camera.getWorldDirection(light.position).multiply({ x: Math.sign(e[0]), y: Math.sign(e[5]), z: Math.sign(e[10]) }).normalize().negate();
2614
+ }
2615
+ }
2575
2616
  const logger$7 = createLogger("");
2576
2617
  function assertNotDisposed(renderer, funcName) {
2577
2618
  if (renderer.isDisposed) {
@@ -6705,7 +6746,7 @@ class SceneSystem {
6705
6746
  const scaleFactor = Math.min(visibleRectSize.width, visibleRectSize.height);
6706
6747
  const { x: centerX, y: centerY } = viewbox.center;
6707
6748
  this.translationMatrix.makeTranslation(-centerX, -centerY, 0);
6708
- this.scaleMatrix.makeScale(scaleFactor, scaleFactor, -1);
6749
+ this.scaleMatrix.makeScale(scaleFactor, scaleFactor, -scaleFactor);
6709
6750
  targetMatrix.copy(this.translationMatrix).premultiply(this.scaleMatrix);
6710
6751
  const viewportRectCenter = this.tempVector2.copy(viewportRectPx.center);
6711
6752
  const offset = viewportRectCenter.sub({ x: bufferW / 2, y: bufferH / 2 });
@@ -6948,6 +6989,7 @@ class Renderer {
6948
6989
  __publicField(this, "memoryInfoExtension", null);
6949
6990
  __publicField(this, "memoryInfo");
6950
6991
  __publicField(this, "eventSystem");
6992
+ __publicField(this, "lightsSystem");
6951
6993
  __publicField(this, "layerSystem");
6952
6994
  __publicField(this, "viewportSystem");
6953
6995
  __publicField(this, "updatesSystem");
@@ -6966,7 +7008,8 @@ class Renderer {
6966
7008
  const rendererOptions = {
6967
7009
  antialias: true,
6968
7010
  context: gl,
6969
- canvas: this.canvas
7011
+ canvas: this.canvas,
7012
+ precision: "highp"
6970
7013
  };
6971
7014
  this.clock = new Clock();
6972
7015
  this.renderer = new WebGLRenderer(rendererOptions);
@@ -6975,6 +7018,7 @@ class Renderer {
6975
7018
  this.renderer.autoClear = !this.isExternalMode;
6976
7019
  this.ctx = this.createRendererContext();
6977
7020
  this.eventSystem = new EventSystem();
7021
+ this.lightsSystem = new LightsSystem();
6978
7022
  this.layerSystem = new LayerSystem(this.ctx);
6979
7023
  this.viewportSystem = new ViewportSystem(this.ctx, this.eventSystem);
6980
7024
  this.updatesSystem = new UpdatesSystem(this.ctx, this.layerSystem);
@@ -7152,6 +7196,7 @@ class Renderer {
7152
7196
  const hasDefsUpdated = this.updatesSystem.processPendingUpdates(frustum2, 3);
7153
7197
  const forceRedraw = hasControlsUpdated || hasDefsUpdated || justLoaded || this.isExternalMode || this.ui;
7154
7198
  if (this.isExternalMode) patchMatricesInExternalMode(scene);
7199
+ this.lightsSystem.updateLights(scene, camera);
7155
7200
  if (this.needsRedraw || forceRedraw) this.renderer.render(scene, camera);
7156
7201
  if (hasDefsUpdated || this.needsRedraw) this.viewportSystem.invalidateSceneBounds(sceneState);
7157
7202
  }
@@ -7188,7 +7233,9 @@ class Renderer {
7188
7233
  }
7189
7234
  initScene(sceneDef, sceneId) {
7190
7235
  const root = this.layerSystem.buildScene(sceneDef);
7191
- this.viewportSystem.initScene(sceneDef, sceneId).add(root);
7236
+ const scene = this.viewportSystem.initScene(sceneDef, sceneId);
7237
+ scene.add(root);
7238
+ this.lightsSystem.initLights(scene);
7192
7239
  }
7193
7240
  // https://webgl2fundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
7194
7241
  resizeCanvasToDisplaySize() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expofp/renderer",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"