@galacean/engine-core 0.0.0-experimental-2.0-game.10 → 0.0.0-experimental-2.0-game.12

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/main.js CHANGED
@@ -5759,8 +5759,13 @@ function dependentComponents(componentOrComponents, dependentMode) {
5759
5759
  rotation._onValueChanged = target._onRotationChanged;
5760
5760
  // @ts-ignore
5761
5761
  scale._onValueChanged = target._onScaleChanged;
5762
- // When cloning, other components may obtain properties such as `rotationQuaternion` in the constructor, local related dirty flags need to be corrected
5762
+ // When cloning, other components may obtain properties such as `rotationQuaternion` in the constructor, local related dirty flags need to be corrected.
5763
+ // Earlier in this Entity's construction other components (e.g. DynamicCollider) may have queried
5764
+ // `worldPosition`, which clears the WorldPosition / WorldMatrix dirty flags as a side effect of caching
5765
+ // the computed value. After this _cloneTo writes new local values, those world-derived caches are stale,
5766
+ // so re-dirty them and notify listeners (Collider._updateFlag etc.) so subsequent reads recompute correctly.
5763
5767
  target._setDirtyFlagTrue(2 | 64);
5768
+ target._worldAssociatedChange(444);
5764
5769
  };
5765
5770
  _proto._onLocalMatrixChanging = function _onLocalMatrixChanging() {
5766
5771
  this._setDirtyFlagFalse(64);
@@ -11544,7 +11549,6 @@ __decorate([
11544
11549
  if (charLength > 0) {
11545
11550
  this._buildChunk(curTextChunk, charLength);
11546
11551
  }
11547
- this._setDirtyFlagTrue(4);
11548
11552
  charRenderInfos.length = 0;
11549
11553
  };
11550
11554
  _proto._onTransformChanged = function _onTransformChanged(bit) {
@@ -20592,17 +20596,23 @@ exports.Collider = /*#__PURE__*/ function(Component) {
20592
20596
  /**
20593
20597
  * @internal
20594
20598
  */ _proto._onUpdate = function _onUpdate() {
20599
+ var shapes = this._shapes;
20595
20600
  if (this._updateFlag.flag) {
20596
20601
  var transform = this.entity.transform;
20597
- this._nativeCollider.setWorldTransform(transform.worldPosition, transform.worldRotationQuaternion);
20602
+ this._syncEntityTransformToNative(transform.worldPosition, transform.worldRotationQuaternion);
20598
20603
  var worldScale = transform.lossyWorldScale;
20599
- var shapes = this._shapes;
20600
20604
  for(var i = 0, n = shapes.length; i < n; i++){
20601
20605
  var _shapes_i__nativeShape;
20602
20606
  (_shapes_i__nativeShape = shapes[i]._nativeShape) == null ? void 0 : _shapes_i__nativeShape.setWorldScale(worldScale);
20603
20607
  }
20604
20608
  this._updateFlag.flag = false;
20605
20609
  }
20610
+ // Drive per-shape physics update (e.g. MeshColliderShape retries pending
20611
+ // native shape creation when mesh data becomes accessible asynchronously).
20612
+ // No-op for shape types that don't override `_onPhysicsUpdate`.
20613
+ for(var i1 = 0, n1 = shapes.length; i1 < n1; i1++){
20614
+ shapes[i1]._onPhysicsUpdate();
20615
+ }
20606
20616
  };
20607
20617
  /**
20608
20618
  * @internal
@@ -20634,6 +20644,28 @@ exports.Collider = /*#__PURE__*/ function(Component) {
20634
20644
  this._addNativeShape(this.shapes[i]);
20635
20645
  }
20636
20646
  this._setCollisionLayer();
20647
+ // Teleport native actor to entity's current world pose.
20648
+ // The native actor was created in constructor() with the entity's then-current
20649
+ // worldPosition/Rotation. On clone, the entity's transform fields are deep-cloned
20650
+ // AFTER the Component (and its native actor) are constructed, so the native actor's
20651
+ // pose lags behind the cloned entity transform until this sync.
20652
+ var transform = this.entity.transform;
20653
+ this._teleportToEntityTransform(transform.worldPosition, transform.worldRotationQuaternion);
20654
+ };
20655
+ /**
20656
+ * Teleport native actor to a world pose (instant, no implied velocity).
20657
+ * Used during initialization paths (clone) where the native actor must be re-aligned
20658
+ * with the entity transform after construction-time pose was based on stale defaults.
20659
+ */ _proto._teleportToEntityTransform = function _teleportToEntityTransform(worldPosition, worldRotation) {
20660
+ this._nativeCollider.setWorldTransform(worldPosition, worldRotation);
20661
+ };
20662
+ /**
20663
+ * Sync entity world transform to native actor for per-frame updates.
20664
+ * Default semantics: teleport (setGlobalPose). Subclasses override to express
20665
+ * physics-aware movement (e.g. DynamicCollider routes kinematic actors through
20666
+ * setKinematicTarget to generate contact events on swept motion).
20667
+ */ _proto._syncEntityTransformToNative = function _syncEntityTransformToNative(worldPosition, worldRotation) {
20668
+ this._nativeCollider.setWorldTransform(worldPosition, worldRotation);
20637
20669
  };
20638
20670
  /**
20639
20671
  * @internal
@@ -20793,6 +20825,9 @@ exports.Collider = __decorate([
20793
20825
  this._nativeCollider.setUpDirection(this._upDirection);
20794
20826
  this._nativeCollider.setSlopeLimit(this._slopeLimit);
20795
20827
  };
20828
+ _proto._teleportToEntityTransform = function _teleportToEntityTransform(worldPosition, _worldRotation) {
20829
+ this._nativeCollider.setWorldPosition(worldPosition);
20830
+ };
20796
20831
  _proto._syncWorldPositionFromPhysicalSpace = function _syncWorldPositionFromPhysicalSpace() {
20797
20832
  this._nativeCollider.getWorldPosition(this.entity.transform.worldPosition);
20798
20833
  };
@@ -20895,7 +20930,7 @@ __decorate([
20895
20930
  this._staticFriction = 0.6;
20896
20931
  this._bounceCombine = PhysicsMaterialCombineMode.Average;
20897
20932
  this._frictionCombine = PhysicsMaterialCombineMode.Average;
20898
- this._nativeMaterial = Engine._nativePhysics.createPhysicsMaterial(this._staticFriction, this._dynamicFriction, this._bounciness, this._bounceCombine, this._frictionCombine);
20933
+ this._nativeMaterial = Engine._nativePhysics.createPhysicsMaterial(this._staticFriction, this._dynamicFriction, this._bounciness, this._frictionCombine, this._bounceCombine);
20899
20934
  }
20900
20935
  var _proto = PhysicsMaterial.prototype;
20901
20936
  /**
@@ -20904,6 +20939,21 @@ __decorate([
20904
20939
  !this._destroyed && this._nativeMaterial.destroy();
20905
20940
  this._destroyed = true;
20906
20941
  };
20942
+ /**
20943
+ * @internal
20944
+ */ _proto._cloneTo = function _cloneTo(target) {
20945
+ target._syncNative();
20946
+ };
20947
+ /**
20948
+ * @internal
20949
+ */ _proto._syncNative = function _syncNative() {
20950
+ var nativeMaterial = this._nativeMaterial;
20951
+ nativeMaterial.setStaticFriction(this._staticFriction);
20952
+ nativeMaterial.setDynamicFriction(this._dynamicFriction);
20953
+ nativeMaterial.setBounciness(this._bounciness);
20954
+ nativeMaterial.setFrictionCombine(this._frictionCombine);
20955
+ nativeMaterial.setBounceCombine(this._bounceCombine);
20956
+ };
20907
20957
  _create_class(PhysicsMaterial, [
20908
20958
  {
20909
20959
  key: "bounciness",
@@ -20978,6 +21028,9 @@ __decorate([
20978
21028
  ]);
20979
21029
  return PhysicsMaterial;
20980
21030
  }();
21031
+ __decorate([
21032
+ ignoreClone
21033
+ ], PhysicsMaterial.prototype, "_nativeMaterial", void 0);
20981
21034
 
20982
21035
  /**
20983
21036
  * Abstract class for collider shapes.
@@ -21030,6 +21083,16 @@ __decorate([
21030
21083
  };
21031
21084
  /**
21032
21085
  * @internal
21086
+ *
21087
+ * Called once per physics update tick by `Collider._onUpdate`. Base no-op.
21088
+ *
21089
+ * Subclasses can override for frame-driven maintenance. Currently used by
21090
+ * `MeshColliderShape` to retry native shape creation when mesh data becomes
21091
+ * accessible later or PhysX cooking previously failed due to transient state
21092
+ * (async resource loading, cook pipeline warmup, etc.).
21093
+ */ _proto._onPhysicsUpdate = function _onPhysicsUpdate() {};
21094
+ /**
21095
+ * @internal
21033
21096
  */ _proto._destroy = function _destroy() {
21034
21097
  if (this._nativeShape) {
21035
21098
  this._nativeShape.destroy();
@@ -21179,7 +21242,11 @@ __decorate([
21179
21242
  _inherits(MeshColliderShape, ColliderShape);
21180
21243
  function MeshColliderShape() {
21181
21244
  var _this;
21182
- _this = ColliderShape.apply(this, arguments) || this, _this._mesh = null, _this._isConvex = false, _this._positions = null, _this._indices = null, _this._cookingFlags = MeshColliderShapeCookingFlag.Cleaning | MeshColliderShapeCookingFlag.VertexWelding, _this._isShapeAttached = false;
21245
+ _this = ColliderShape.apply(this, arguments) || this, _this._mesh = null, _this._isConvex = false, _this._positions = null, _this._indices = null, _this._cookingFlags = MeshColliderShapeCookingFlag.Cleaning | MeshColliderShapeCookingFlag.VertexWelding, _this._isShapeAttached = false, /**
21246
+ * `true` if a native shape creation was attempted but failed (mesh data not yet
21247
+ * accessible, PhysX cooking transient failure, etc.). The `_onPhysicsUpdate` hook
21248
+ * will keep retrying every frame until creation succeeds.
21249
+ */ _this._pendingNativeShapeCreation = false;
21183
21250
  return _this;
21184
21251
  }
21185
21252
  var _proto = MeshColliderShape.prototype;
@@ -21263,9 +21330,12 @@ __decorate([
21263
21330
  }
21264
21331
  var nativeShape = Engine._nativePhysics.createMeshColliderShape(this._id, this._positions, this._indices, this._isConvex, this._material._nativeMaterial, this._cookingFlags);
21265
21332
  if (!nativeShape) {
21333
+ // Cook failed — `_onPhysicsUpdate` will retry next frame
21334
+ this._pendingNativeShapeCreation = true;
21266
21335
  return;
21267
21336
  }
21268
21337
  this._nativeShape = nativeShape;
21338
+ this._pendingNativeShapeCreation = false;
21269
21339
  // Sync base class properties (position, rotation, contactOffset, isTrigger, material)
21270
21340
  ColliderShape.prototype._syncNative.call(this);
21271
21341
  // If already attached to a collider, add the newly created native shape to it
@@ -21274,6 +21344,36 @@ __decorate([
21274
21344
  this._attachToCollider();
21275
21345
  }
21276
21346
  };
21347
+ /**
21348
+ * @internal
21349
+ * Retry hook: keep attempting `_createNativeShape` until it succeeds.
21350
+ *
21351
+ * Triggered every physics update tick by `Collider._onUpdate`. Handles the case
21352
+ * where `_cookMesh` fails on first attempt due to PhysX cooking pipeline timing
21353
+ * (the mesh data was extracted successfully at `set mesh` time, but the native
21354
+ * cook call returned null). No-op once a valid native shape exists.
21355
+ *
21356
+ * We DO NOT re-call `_extractMeshData` here — once `set mesh` finished, either:
21357
+ * - extraction succeeded → `_positions` is populated and we reuse it
21358
+ * - extraction failed → `_clearMeshData` cleared `_positions`, and `mesh.accessible`
21359
+ * won't recover (GPU upload is one-way), so re-extracting would fail again
21360
+ */ _proto._onPhysicsUpdate = function _onPhysicsUpdate() {
21361
+ if (!this._pendingNativeShapeCreation || !this._mesh || !this._positions) return;
21362
+ this._createNativeShape();
21363
+ };
21364
+ /**
21365
+ * @internal
21366
+ * After CloneManager deep-copies `_positions` / `_indices` / `_mesh` and remaps `_collider`,
21367
+ * the cloned shape still has no native PhysX shape because `_nativeShape` is `@ignoreClone`.
21368
+ * Cook a fresh native shape now using the already-cloned vertex/index buffers; on transient
21369
+ * cook failure `_createNativeShape` sets `_pendingNativeShapeCreation = true` and
21370
+ * `_onPhysicsUpdate` will retry next tick.
21371
+ */ _proto._cloneTo = function _cloneTo(target) {
21372
+ ColliderShape.prototype._cloneTo.call(this, target);
21373
+ if (target._positions) {
21374
+ target._createNativeShape();
21375
+ }
21376
+ };
21277
21377
  _create_class(MeshColliderShape, [
21278
21378
  {
21279
21379
  key: "cookingFlags",
@@ -21333,15 +21433,25 @@ __decorate([
21333
21433
  (_this__mesh = this._mesh) == null ? void 0 : _this__mesh._addReferCount(-1);
21334
21434
  value == null ? void 0 : value._addReferCount(1);
21335
21435
  this._mesh = value;
21336
- if (value && this._extractMeshData(value)) {
21337
- if (this._nativeShape) {
21338
- this._updateNativeShapeData();
21436
+ if (value) {
21437
+ if (this._extractMeshData(value)) {
21438
+ if (this._nativeShape) {
21439
+ this._updateNativeShapeData();
21440
+ } else {
21441
+ this._createNativeShape();
21442
+ }
21443
+ // _createNativeShape can fail silently (cookMesh transient failure); mark pending if so
21444
+ this._pendingNativeShapeCreation = !this._nativeShape;
21339
21445
  } else {
21340
- this._createNativeShape();
21446
+ // Mesh not yet accessible — keep pending so `_onPhysicsUpdate` retries later
21447
+ this._destroyNativeShape();
21448
+ this._clearMeshData();
21449
+ this._pendingNativeShapeCreation = true;
21341
21450
  }
21342
21451
  } else {
21343
21452
  this._destroyNativeShape();
21344
21453
  this._clearMeshData();
21454
+ this._pendingNativeShapeCreation = false;
21345
21455
  }
21346
21456
  }
21347
21457
  }
@@ -21386,6 +21496,27 @@ __decorate([
21386
21496
  */ _proto.applyTorque = function applyTorque(torque) {
21387
21497
  this._phasedActiveInScene && this._nativeCollider.addTorque(torque);
21388
21498
  };
21499
+ /**
21500
+ * Apply a force to the DynamicCollider at a given position in world space.
21501
+ * The force generates both linear acceleration through the center of mass and angular
21502
+ * acceleration about it (torque = (position - centerOfMass) × force).
21503
+ * @param force - The force to apply, in world space
21504
+ * @param position - The position where the force is applied, in world space
21505
+ */ _proto.applyForceAtPosition = function applyForceAtPosition(force, position) {
21506
+ if (!this._phasedActiveInScene) return;
21507
+ var nativeCollider = this._nativeCollider;
21508
+ var localCoM = DynamicCollider._tempVector3;
21509
+ nativeCollider.getCenterOfMass(localCoM);
21510
+ var transform = this.entity.transform;
21511
+ var worldCoM = DynamicCollider._tempVector3_1;
21512
+ engineMath.Vector3.transformByQuat(localCoM, transform.worldRotationQuaternion, worldCoM);
21513
+ worldCoM.add(transform.worldPosition);
21514
+ var torque = DynamicCollider._tempVector3_2;
21515
+ engineMath.Vector3.subtract(position, worldCoM, torque);
21516
+ engineMath.Vector3.cross(torque, force, torque);
21517
+ nativeCollider.addForce(force);
21518
+ nativeCollider.addTorque(torque);
21519
+ };
21389
21520
  _proto.move = function move(positionOrRotation, rotation) {
21390
21521
  if (!this._isKinematic) {
21391
21522
  console.warn("DynamicCollider: move() is only supported when isKinematic is true.");
@@ -21419,6 +21550,31 @@ __decorate([
21419
21550
  Collider.prototype.addShape.call(this, shape);
21420
21551
  };
21421
21552
  /**
21553
+ * Route per-frame entity → native transform sync to the correct physics API based
21554
+ * on kinematic state.
21555
+ *
21556
+ * PhysX 4.x docs (PxRigidDynamic):
21557
+ * "If you intend to move a kinematic actor with [setGlobalPose] and want
21558
+ * collision detection, use setKinematicTarget() instead."
21559
+ *
21560
+ * setGlobalPose is a teleport: PhysX skips contact detection between the old
21561
+ * and new pose, so two kinematic actors moved onto each other via entity.transform
21562
+ * mutation would NOT produce onCollisionEnter / onCollisionStay events even when
21563
+ * scene.kineKineFilteringMode = eKEEP. Routing the per-frame sync through
21564
+ * IDynamicCollider.move() (which the PhysX backend implements as
21565
+ * setKinematicTarget) tells PhysX the actor is animating to the target during the
21566
+ * next simulate(), enabling sweep contact detection for kine-kine and kine-dynamic
21567
+ * pairs alike.
21568
+ *
21569
+ * @internal
21570
+ */ _proto._syncEntityTransformToNative = function _syncEntityTransformToNative(worldPosition, worldRotation) {
21571
+ if (this._isKinematic) {
21572
+ this._nativeCollider.move(worldPosition, worldRotation);
21573
+ } else {
21574
+ Collider.prototype._syncEntityTransformToNative.call(this, worldPosition, worldRotation);
21575
+ }
21576
+ };
21577
+ /**
21422
21578
  * @internal
21423
21579
  */ _proto._onLateUpdate = function _onLateUpdate() {
21424
21580
  var transform = this.entity.transform;
@@ -21792,6 +21948,8 @@ __decorate([
21792
21948
  return DynamicCollider;
21793
21949
  }(exports.Collider);
21794
21950
  DynamicCollider._tempVector3 = new engineMath.Vector3();
21951
+ DynamicCollider._tempVector3_1 = new engineMath.Vector3();
21952
+ DynamicCollider._tempVector3_2 = new engineMath.Vector3();
21795
21953
  DynamicCollider._tempQuat = new engineMath.Quaternion();
21796
21954
  __decorate([
21797
21955
  ignoreClone
@@ -24960,7 +25118,7 @@ var spriteFs = "#include <common>\nuniform sampler2D renderer_SpriteTexture;\n\n
24960
25118
 
24961
25119
  var spriteVs = "uniform mat4 renderer_MVPMat;\n\nattribute vec3 POSITION;\nattribute vec2 TEXCOORD_0;\nattribute vec4 COLOR_0;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nvoid main()\n{\n gl_Position = renderer_MVPMat * vec4(POSITION, 1.0);\n\n v_uv = TEXCOORD_0;\n v_color = COLOR_0;\n}\n"; // eslint-disable-line
24962
25120
 
24963
- var textFs = "uniform sampler2D renderElement_TextTexture;\nuniform vec2 renderElement_TextTextureSize;\nuniform vec4 renderer_OutlineColor;\nuniform float renderer_OutlineWidth;\n\nuniform vec4 renderer_UIRectClipRect;\nuniform float renderer_UIRectClipEnabled;\nuniform vec4 renderer_UIRectClipSoftness;\nuniform float renderer_UIRectClipHardClip;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\nvarying vec2 v_worldPosition;\n\nfloat getUIRectClipAlpha()\n{\n vec4 edgeDistance = vec4(\n v_worldPosition.x - renderer_UIRectClipRect.x,\n v_worldPosition.y - renderer_UIRectClipRect.y,\n renderer_UIRectClipRect.z - v_worldPosition.x,\n renderer_UIRectClipRect.w - v_worldPosition.y\n );\n vec4 hardClipFactor = step(vec4(0.0), edgeDistance);\n vec4 softness = max(renderer_UIRectClipSoftness, vec4(1e-5));\n vec4 softClipFactor = clamp(edgeDistance / softness, 0.0, 1.0);\n vec4 useSoftness = step(vec4(1e-5), renderer_UIRectClipSoftness);\n vec4 clipFactor = mix(hardClipFactor, softClipFactor, useSoftness);\n return clipFactor.x * clipFactor.y * clipFactor.z * clipFactor.w;\n}\n\nfloat sampleCoverage(vec2 uv)\n{\n vec4 c = texture2D(renderElement_TextTexture, uv);\n #ifdef GRAPHICS_API_WEBGL2\n return c.r;\n #else\n return c.a;\n #endif\n}\n\nvoid main()\n{\n float rectClipAlpha = 1.0;\n if (renderer_UIRectClipEnabled > 0.5) {\n rectClipAlpha = getUIRectClipAlpha();\n }\n\n float coverage = sampleCoverage(v_uv);\n vec4 finalColor;\n\n if (renderer_OutlineWidth > 0.0) {\n vec2 texelSize = 1.0 / renderElement_TextTextureSize;\n vec2 step = texelSize * renderer_OutlineWidth;\n float outlineCoverage = coverage;\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( step.x, 0.0)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2(-step.x, 0.0)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( 0.0, step.y)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( 0.0, -step.y)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( step.x * 0.7071, step.y * 0.7071)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2(-step.x * 0.7071, step.y * 0.7071)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( step.x * 0.7071, -step.y * 0.7071)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2(-step.x * 0.7071, -step.y * 0.7071)));\n\n vec3 rgb = mix(renderer_OutlineColor.rgb, v_color.rgb, coverage);\n float alpha = max(coverage * v_color.a, outlineCoverage * renderer_OutlineColor.a);\n finalColor = vec4(rgb, alpha);\n } else {\n finalColor = vec4(v_color.rgb, v_color.a * coverage);\n }\n\n finalColor.a *= rectClipAlpha;\n if (renderer_UIRectClipEnabled > 0.5 && renderer_UIRectClipHardClip > 0.5 && finalColor.a < 0.001) {\n discard;\n }\n gl_FragColor = finalColor;\n}\n"; // eslint-disable-line
25121
+ var textFs = "uniform sampler2D renderElement_TextTexture;\nuniform vec2 renderElement_TextTextureSize;\nuniform vec4 renderer_OutlineColor;\nuniform float renderer_OutlineWidth;\n\nuniform vec4 renderer_UIRectClipRect;\nuniform float renderer_UIRectClipEnabled;\nuniform vec4 renderer_UIRectClipSoftness;\nuniform float renderer_UIRectClipHardClip;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\nvarying vec2 v_worldPosition;\n\nfloat getUIRectClipAlpha()\n{\n vec4 edgeDistance = vec4(\n v_worldPosition.x - renderer_UIRectClipRect.x,\n v_worldPosition.y - renderer_UIRectClipRect.y,\n renderer_UIRectClipRect.z - v_worldPosition.x,\n renderer_UIRectClipRect.w - v_worldPosition.y\n );\n vec4 hardClipFactor = step(vec4(0.0), edgeDistance);\n vec4 softness = max(renderer_UIRectClipSoftness, vec4(1e-5));\n vec4 softClipFactor = clamp(edgeDistance / softness, 0.0, 1.0);\n vec4 useSoftness = step(vec4(1e-5), renderer_UIRectClipSoftness);\n vec4 clipFactor = mix(hardClipFactor, softClipFactor, useSoftness);\n return clipFactor.x * clipFactor.y * clipFactor.z * clipFactor.w;\n}\n\nfloat sampleCoverage(vec2 uv)\n{\n vec4 c = texture2D(renderElement_TextTexture, uv);\n #ifdef GRAPHICS_API_WEBGL2\n return c.r;\n #else\n return c.a;\n #endif\n}\n\nvoid main()\n{\n float rectClipAlpha = 1.0;\n if (renderer_UIRectClipEnabled > 0.5) {\n rectClipAlpha = getUIRectClipAlpha();\n }\n\n float coverage = sampleCoverage(v_uv);\n vec4 finalColor;\n\n if (renderer_OutlineWidth > 0.0) {\n vec2 texelSize = 1.0 / renderElement_TextTextureSize;\n vec2 step = texelSize * renderer_OutlineWidth;\n float outlineCoverage = coverage;\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( step.x, 0.0)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2(-step.x, 0.0)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( 0.0, step.y)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( 0.0, -step.y)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( step.x * 0.7071, step.y * 0.7071)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2(-step.x * 0.7071, step.y * 0.7071)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2( step.x * 0.7071, -step.y * 0.7071)));\n outlineCoverage = max(outlineCoverage, sampleCoverage(v_uv + vec2(-step.x * 0.7071, -step.y * 0.7071)));\n\n vec3 rgb = mix(renderer_OutlineColor.rgb, v_color.rgb, coverage);\n float alpha = max(coverage, outlineCoverage * renderer_OutlineColor.a) * v_color.a;\n finalColor = vec4(rgb, alpha);\n } else {\n finalColor = vec4(v_color.rgb, v_color.a * coverage);\n }\n\n finalColor.a *= rectClipAlpha;\n if (renderer_UIRectClipEnabled > 0.5 && renderer_UIRectClipHardClip > 0.5 && finalColor.a < 0.001) {\n discard;\n }\n gl_FragColor = finalColor;\n}\n"; // eslint-disable-line
24964
25122
 
24965
25123
  var textVs = "uniform mat4 renderer_MVPMat;\nuniform mat4 renderer_ModelMat;\n\nattribute vec3 POSITION;\nattribute vec2 TEXCOORD_0;\nattribute vec4 COLOR_0;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\nvarying vec2 v_worldPosition;\n\nvoid main()\n{\n gl_Position = renderer_MVPMat * vec4(POSITION, 1.0);\n\n v_uv = TEXCOORD_0;\n v_color = COLOR_0;\n v_worldPosition = POSITION.xy;\n}\n"; // eslint-disable-line
24966
25124