@galacean/engine-core 0.0.0-experimental-2.0-game.15 → 0.0.0-experimental-2.0-game.16

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
@@ -4568,6 +4568,18 @@ var RenderElement = /*#__PURE__*/ function() {
4568
4568
  this.subChunk = subChunk;
4569
4569
  this.instancedRenderers.length = 0;
4570
4570
  };
4571
+ /**
4572
+ * @internal
4573
+ * Copy identity fields from `source` and reset per-queue batch state, so the same
4574
+ * logical element can live in multiple queues (e.g. an Opaque + Transparent multi-pass
4575
+ * material) without one queue's batching corrupting another's `instancedRenderers`.
4576
+ */ _proto._cloneFrom = function _cloneFrom(source) {
4577
+ this.set(source.component, source.material, source.primitive, source.subPrimitive, source.texture, source.subChunk);
4578
+ this.priority = source.priority;
4579
+ this.distanceForSort = source.distanceForSort;
4580
+ this.subShader = source.subShader;
4581
+ this.shaderData = source.shaderData;
4582
+ };
4571
4583
  _proto.dispose = function dispose() {
4572
4584
  this.component = null;
4573
4585
  this.material = null;
@@ -5568,7 +5580,7 @@ function dependentComponents(componentOrComponents, dependentMode) {
5568
5580
  _inherits(Transform, Component);
5569
5581
  function Transform(entity) {
5570
5582
  var _this;
5571
- _this = Component.call(this, entity) || this, _this._position = new engineMath.Vector3(), _this._rotation = new engineMath.Vector3(), _this._rotationQuaternion = new engineMath.Quaternion(), _this._scale = new engineMath.Vector3(1, 1, 1), _this._localUniformScaling = true, _this._worldPosition = new engineMath.Vector3(), _this._worldRotation = new engineMath.Vector3(), _this._worldRotationQuaternion = new engineMath.Quaternion(), _this._worldUniformScaling = true, _this._lossyWorldScale = new engineMath.Vector3(1, 1, 1), _this._localMatrix = new engineMath.Matrix(), _this._worldMatrix = new engineMath.Matrix(), _this._worldForward = null, _this._worldRight = null, _this._worldUp = null, _this._isParentDirty = true, _this._parentTransformCache = null, _this._dirtyFlag = 510;
5583
+ _this = Component.call(this, entity) || this, _this._position = new engineMath.Vector3(), _this._rotation = new engineMath.Vector3(), _this._rotationQuaternion = new engineMath.Quaternion(), _this._scale = new engineMath.Vector3(1, 1, 1), _this._localUniformScaling = true, _this._worldPosition = new engineMath.Vector3(), _this._worldRotation = new engineMath.Vector3(), _this._worldRotationQuaternion = new engineMath.Quaternion(), _this._worldUniformScaling = true, _this._lossyWorldScale = new engineMath.Vector3(1, 1, 1), _this._localMatrix = new engineMath.Matrix(), _this._worldMatrix = new engineMath.Matrix(), _this._worldForward = null, _this._worldRight = null, _this._worldUp = null, _this._frontFaceInvert = false, _this._isParentDirty = true, _this._parentTransformCache = null, _this._dirtyFlag = 2558;
5572
5584
  _this._onPositionChanged = _this._onPositionChanged.bind(_this);
5573
5585
  _this._onWorldPositionChanged = _this._onWorldPositionChanged.bind(_this);
5574
5586
  _this._onRotationChanged = _this._onRotationChanged.bind(_this);
@@ -5726,7 +5738,7 @@ function dependentComponents(componentOrComponents, dependentMode) {
5726
5738
  // `_getParentTransform` was ever called while their ancestor chain was
5727
5739
  // partially constructed during clone/instantiate). Force them to
5728
5740
  // re-resolve the parent transform on next access.
5729
- this._propagateReparentDirty(444);
5741
+ this._propagateReparentDirty(2492);
5730
5742
  };
5731
5743
  _proto._propagateReparentDirty = function _propagateReparentDirty(flags) {
5732
5744
  this._worldAssociatedChange(flags);
@@ -5742,11 +5754,16 @@ function dependentComponents(componentOrComponents, dependentMode) {
5742
5754
  /**
5743
5755
  * @internal
5744
5756
  */ _proto._isFrontFaceInvert = function _isFrontFaceInvert() {
5745
- var scale = this.lossyWorldScale;
5746
- var isInvert = scale.x < 0;
5747
- scale.y < 0 && (isInvert = !isInvert);
5748
- scale.z < 0 && (isInvert = !isInvert);
5749
- return isInvert;
5757
+ if (this._isContainDirtyFlag(2048)) {
5758
+ var s = this._scale;
5759
+ var invert = s.x < 0;
5760
+ s.y < 0 && (invert = !invert);
5761
+ s.z < 0 && (invert = !invert);
5762
+ var parent = this._getParentTransform();
5763
+ this._frontFaceInvert = parent ? invert !== parent._isFrontFaceInvert() : invert;
5764
+ this._setDirtyFlagFalse(2048);
5765
+ }
5766
+ return this._frontFaceInvert;
5750
5767
  };
5751
5768
  /**
5752
5769
  * @internal
@@ -5769,7 +5786,7 @@ function dependentComponents(componentOrComponents, dependentMode) {
5769
5786
  // the computed value. After this _cloneTo writes new local values, those world-derived caches are stale,
5770
5787
  // so re-dirty them and notify listeners (Collider._updateFlag etc.) so subsequent reads recompute correctly.
5771
5788
  target._setDirtyFlagTrue(2 | 64);
5772
- target._worldAssociatedChange(444);
5789
+ target._worldAssociatedChange(2492);
5773
5790
  };
5774
5791
  _proto._onLocalMatrixChanging = function _onLocalMatrixChanging() {
5775
5792
  this._setDirtyFlagFalse(64);
@@ -5852,10 +5869,10 @@ function dependentComponents(componentOrComponents, dependentMode) {
5852
5869
  */ _proto._updateWorldRotationFlag = function _updateWorldRotationFlag() {
5853
5870
  var parent = this._getParentTransform();
5854
5871
  var parentWorldUniformScaling = parent ? parent._getWorldUniformScaling() : true;
5855
- var flags = parentWorldUniformScaling ? 152 : 184;
5872
+ var flags = parentWorldUniformScaling ? 152 : 2232;
5856
5873
  if (!this._isContainDirtyFlags(flags)) {
5857
5874
  this._worldAssociatedChange(flags);
5858
- flags = this._getWorldUniformScaling() ? 156 : 188;
5875
+ flags = this._getWorldUniformScaling() ? 156 : 2236;
5859
5876
  var children = this._entity._children;
5860
5877
  for(var i = 0, n = children.length; i < n; i++){
5861
5878
  var _children_i_transform;
@@ -5874,7 +5891,7 @@ function dependentComponents(componentOrComponents, dependentMode) {
5874
5891
  */ _proto._updateWorldPositionAndRotationFlag = function _updateWorldPositionAndRotationFlag(flags) {
5875
5892
  if (!this._isContainDirtyFlags(flags)) {
5876
5893
  this._worldAssociatedChange(flags);
5877
- flags = this._getWorldUniformScaling() ? 156 : 188;
5894
+ flags = this._getWorldUniformScaling() ? 156 : 2236;
5878
5895
  var children = this._entity._children;
5879
5896
  for(var i = 0, n = children.length; i < n; i++){
5880
5897
  var _children_i_transform;
@@ -5996,9 +6013,9 @@ function dependentComponents(componentOrComponents, dependentMode) {
5996
6013
  var localUniformScaling = x == y && y == z;
5997
6014
  if (this._localUniformScaling !== localUniformScaling) {
5998
6015
  this._localUniformScaling = localUniformScaling;
5999
- this._updateWorldScaleFlag(416);
6016
+ this._updateWorldScaleFlag(2464);
6000
6017
  } else {
6001
- this._updateWorldScaleFlag(160);
6018
+ this._updateWorldScaleFlag(2208);
6002
6019
  }
6003
6020
  };
6004
6021
  _proto._getWorldUniformScaling = function _getWorldUniformScaling() {
@@ -6236,9 +6253,9 @@ function dependentComponents(componentOrComponents, dependentMode) {
6236
6253
  var localUniformScaling = scale.x === scale.y && scale.y === scale.z;
6237
6254
  if (this._localUniformScaling !== localUniformScaling) {
6238
6255
  this._localUniformScaling = localUniformScaling;
6239
- this._updateAllWorldFlag(444);
6256
+ this._updateAllWorldFlag(2492);
6240
6257
  } else {
6241
- this._updateAllWorldFlag(188);
6258
+ this._updateAllWorldFlag(2236);
6242
6259
  }
6243
6260
  }
6244
6261
  },
@@ -6364,6 +6381,9 @@ __decorate([
6364
6381
  __decorate([
6365
6382
  ignoreClone
6366
6383
  ], Transform.prototype, "_worldUp", void 0);
6384
+ __decorate([
6385
+ ignoreClone
6386
+ ], Transform.prototype, "_frontFaceInvert", void 0);
6367
6387
  __decorate([
6368
6388
  ignoreClone
6369
6389
  ], Transform.prototype, "_isParentDirty", void 0);
@@ -6405,16 +6425,18 @@ __decorate([
6405
6425
  /** This is an internal flag used to assist in determining the dispatch
6406
6426
  * of world scaling dirty flags in the case of non-uniform scaling.
6407
6427
  */ TransformModifyFlags[TransformModifyFlags["IsWorldUniformScaling"] = 256] = "IsWorldUniformScaling";
6428
+ // Note: 0x200 (UITransformModifyFlags.Size) and 0x400 (Pivot) are reserved by UITransform — do not reuse.
6429
+ TransformModifyFlags[TransformModifyFlags["WorldFrontFaceInvert"] = 2048] = "WorldFrontFaceInvert";
6408
6430
  /** WorldMatrix | WorldPosition */ TransformModifyFlags[TransformModifyFlags["WmWp"] = 132] = "WmWp";
6409
6431
  /** WorldMatrix | WorldEuler | WorldQuat */ TransformModifyFlags[TransformModifyFlags["WmWeWq"] = 152] = "WmWeWq";
6410
- /** WorldMatrix | WorldEuler | WorldQuat | WorldScale*/ TransformModifyFlags[TransformModifyFlags["WmWeWqWs"] = 184] = "WmWeWqWs";
6432
+ /** WorldMatrix | WorldEuler | WorldQuat | WorldScale | WorldFrontFaceInvert */ TransformModifyFlags[TransformModifyFlags["WmWeWqWs"] = 2232] = "WmWeWqWs";
6411
6433
  /** WorldMatrix | WorldPosition | WorldEuler | WorldQuat */ TransformModifyFlags[TransformModifyFlags["WmWpWeWq"] = 156] = "WmWpWeWq";
6412
- /** WorldMatrix | WorldScale */ TransformModifyFlags[TransformModifyFlags["WmWs"] = 160] = "WmWs";
6413
- /** WorldMatrix | WorldScale | WorldUniformScaling */ TransformModifyFlags[TransformModifyFlags["WmWsWus"] = 416] = "WmWsWus";
6414
- /** WorldMatrix | WorldPosition | WorldScale */ TransformModifyFlags[TransformModifyFlags["WmWpWs"] = 164] = "WmWpWs";
6415
- /** WorldMatrix | WorldPosition | WorldEuler | WorldQuat | WorldScale */ TransformModifyFlags[TransformModifyFlags["WmWpWeWqWs"] = 188] = "WmWpWeWqWs";
6416
- /** WorldMatrix | WorldPosition | WorldEuler | WorldQuat | WorldScale | WorldUniformScaling */ TransformModifyFlags[TransformModifyFlags["WmWpWeWqWsWus"] = 444] = "WmWpWeWqWsWus";
6417
- /** LocalQuat | LocalMatrix | WorldMatrix | WorldPosition | WorldEuler | WorldQuat | WorldScale | WorldUniformScaling */ TransformModifyFlags[TransformModifyFlags["LqLmWmWpWeWqWsWus"] = 510] = "LqLmWmWpWeWqWsWus";
6434
+ /** WorldMatrix | WorldScale | WorldFrontFaceInvert */ TransformModifyFlags[TransformModifyFlags["WmWs"] = 2208] = "WmWs";
6435
+ /** WorldMatrix | WorldScale | WorldUniformScaling | WorldFrontFaceInvert */ TransformModifyFlags[TransformModifyFlags["WmWsWus"] = 2464] = "WmWsWus";
6436
+ /** WorldMatrix | WorldPosition | WorldScale | WorldFrontFaceInvert */ TransformModifyFlags[TransformModifyFlags["WmWpWs"] = 2212] = "WmWpWs";
6437
+ /** WorldMatrix | WorldPosition | WorldEuler | WorldQuat | WorldScale | WorldFrontFaceInvert */ TransformModifyFlags[TransformModifyFlags["WmWpWeWqWs"] = 2236] = "WmWpWeWqWs";
6438
+ /** WorldMatrix | WorldPosition | WorldEuler | WorldQuat | WorldScale | WorldUniformScaling | WorldFrontFaceInvert */ TransformModifyFlags[TransformModifyFlags["WmWpWeWqWsWus"] = 2492] = "WmWpWeWqWsWus";
6439
+ /** LocalQuat | LocalMatrix | WorldMatrix | WorldPosition | WorldEuler | WorldQuat | WorldScale | WorldUniformScaling | WorldFrontFaceInvert */ TransformModifyFlags[TransformModifyFlags["LqLmWmWpWeWqWsWus"] = 2558] = "LqLmWmWpWeWqWsWus";
6418
6440
  return TransformModifyFlags;
6419
6441
  }({});
6420
6442
 
@@ -6464,6 +6486,12 @@ __decorate([
6464
6486
  function ShaderData(group) {
6465
6487
  /** @internal */ this._propertyValueMap = Object.create(null);
6466
6488
  /** @internal */ this._macroCollection = new ShaderMacroCollection();
6489
+ /**
6490
+ * @internal
6491
+ * Sorted (ascending) property ids of renderer-group samplers and arrays. These values
6492
+ * can't differ across instances inside an instanced draw call — `_canBatch` uses this
6493
+ * list to refuse batching renderers that would disagree on what to bind
6494
+ */ this._instanceBatchFields = [];
6467
6495
  this._macroMap = Object.create(null);
6468
6496
  this._refCount = 0;
6469
6497
  this._group = group;
@@ -6682,7 +6710,52 @@ __decorate([
6682
6710
  throw "Shader property " + property.name + " has been used as " + ShaderPropertyType[property._type] + " type.";
6683
6711
  }
6684
6712
  }
6685
- this._propertyValueMap[property._uniqueId] = value;
6713
+ var id = property._uniqueId;
6714
+ // Track renderer-group samplers/arrays so `_canBatch` can refuse instanced batches
6715
+ // whose leader and follower would disagree on what to bind
6716
+ if (this._group === ShaderDataGroup.Renderer && (type === ShaderPropertyType.Texture || type === ShaderPropertyType.TextureArray || type === ShaderPropertyType.FloatArray || type === ShaderPropertyType.IntArray)) {
6717
+ var oldHas = this._propertyValueMap[id] != null;
6718
+ var newHas = value != null;
6719
+ if (oldHas !== newHas) {
6720
+ var fields = this._instanceBatchFields;
6721
+ if (newHas) {
6722
+ // Insert keeping ascending order so exact compare is index-by-index
6723
+ var lo = 0;
6724
+ var hi = fields.length;
6725
+ while(lo < hi){
6726
+ var mid = lo + hi >>> 1;
6727
+ if (fields[mid] < id) {
6728
+ lo = mid + 1;
6729
+ } else {
6730
+ hi = mid;
6731
+ }
6732
+ }
6733
+ fields.splice(lo, 0, id);
6734
+ } else {
6735
+ fields.splice(fields.indexOf(id), 1);
6736
+ }
6737
+ }
6738
+ }
6739
+ this._propertyValueMap[id] = value;
6740
+ };
6741
+ /**
6742
+ * @internal
6743
+ */ _proto._matchesRendererInstanceBatch = function _matchesRendererInstanceBatch(other) {
6744
+ var selfFields = this._instanceBatchFields;
6745
+ var otherFields = other._instanceBatchFields;
6746
+ var fieldCount = selfFields.length;
6747
+ if (fieldCount !== otherFields.length) {
6748
+ return false;
6749
+ }
6750
+ var selfMap = this._propertyValueMap;
6751
+ var otherMap = other._propertyValueMap;
6752
+ for(var i = 0; i < fieldCount; i++){
6753
+ var id = selfFields[i];
6754
+ if (id !== otherFields[i] || selfMap[id] !== otherMap[id]) {
6755
+ return false;
6756
+ }
6757
+ }
6758
+ return true;
6686
6759
  };
6687
6760
  /**
6688
6761
  * @internal
@@ -6713,6 +6786,9 @@ __decorate([
6713
6786
  __decorate([
6714
6787
  ignoreClone
6715
6788
  ], ShaderData.prototype, "_macroCollection", void 0);
6789
+ __decorate([
6790
+ ignoreClone
6791
+ ], ShaderData.prototype, "_instanceBatchFields", void 0);
6716
6792
  __decorate([
6717
6793
  ignoreClone
6718
6794
  ], ShaderData.prototype, "_macroMap", void 0);
@@ -14405,7 +14481,9 @@ var BlendShapeFrameDirty = /*#__PURE__*/ function(BlendShapeFrameDirty) {
14405
14481
  * @internal
14406
14482
  */ _proto._canBatch = function _canBatch(preElement, curElement) {
14407
14483
  if (!this._engine._hardwareRenderer.isWebGL2) return false;
14408
- return preElement.primitive === curElement.primitive && preElement.subPrimitive === curElement.subPrimitive && preElement.material === curElement.material && this._isFrontFaceInvert() === curElement.component._isFrontFaceInvert() && this.shaderData._macroCollection.isEqual(curElement.component.shaderData._macroCollection);
14484
+ var curShaderData = curElement.component.shaderData;
14485
+ return preElement.primitive === curElement.primitive && preElement.subPrimitive === curElement.subPrimitive && preElement.material === curElement.material && this._isFrontFaceInvert() === curElement.component._isFrontFaceInvert() && this.shaderData._macroCollection.isEqual(curShaderData._macroCollection) && // Renderer-group samplers/arrays are shared across the whole instanced draw call
14486
+ this.shaderData._matchesRendererInstanceBatch(curShaderData);
14409
14487
  };
14410
14488
  /**
14411
14489
  * @internal
@@ -18979,8 +19057,11 @@ RenderContext._flipYViewProjectionMatrix = new engineMath.Matrix();
18979
19057
  * @internal
18980
19058
  */ var RenderTargetPool = /*#__PURE__*/ function() {
18981
19059
  function RenderTargetPool(engine) {
19060
+ /** Frames an entry may sit idle before `tick()` destroys it. */ this.maxFreeAgeFrames = 60;
18982
19061
  this._freeRenderTargets = [];
19062
+ this._freeRenderTargetFrames = [];
18983
19063
  this._freeTextures = [];
19064
+ this._freeTextureFrames = [];
18984
19065
  this._engine = engine;
18985
19066
  }
18986
19067
  var _proto = RenderTargetPool.prototype;
@@ -18989,8 +19070,7 @@ RenderContext._flipYViewProjectionMatrix = new engineMath.Matrix();
18989
19070
  for(var i = freeRenderTargets.length - 1; i >= 0; i--){
18990
19071
  var renderTarget = freeRenderTargets[i];
18991
19072
  if (RenderTargetPool._matchRenderTarget(renderTarget, width, height, colorFormat, depthFormat, needDepthTexture, mipmap, isSRGBColorSpace, antiAliasing)) {
18992
- freeRenderTargets[i] = freeRenderTargets[freeRenderTargets.length - 1];
18993
- freeRenderTargets.length--;
19073
+ this._removeFreeRenderTargetAt(i);
18994
19074
  var colorTexture = renderTarget.getColorTexture(0);
18995
19075
  if (colorTexture) {
18996
19076
  colorTexture.wrapModeU = colorTexture.wrapModeV = wrapMode;
@@ -19033,8 +19113,7 @@ RenderContext._flipYViewProjectionMatrix = new engineMath.Matrix();
19033
19113
  for(var i = freeTextures.length - 1; i >= 0; i--){
19034
19114
  var texture = freeTextures[i];
19035
19115
  if (texture.width === width && texture.height === height && texture.format === format && texture.mipmapCount > 1 === mipmap && texture.isSRGBColorSpace === isSRGBColorSpace) {
19036
- freeTextures[i] = freeTextures[freeTextures.length - 1];
19037
- freeTextures.length--;
19116
+ this._removeFreeTextureAt(i);
19038
19117
  texture.wrapModeU = texture.wrapModeV = wrapMode;
19039
19118
  texture.filterMode = filterMode;
19040
19119
  return texture;
@@ -19049,29 +19128,98 @@ RenderContext._flipYViewProjectionMatrix = new engineMath.Matrix();
19049
19128
  _proto.freeRenderTarget = function freeRenderTarget(renderTarget) {
19050
19129
  if (!renderTarget || renderTarget.destroyed) return;
19051
19130
  this._freeRenderTargets.push(renderTarget);
19131
+ this._freeRenderTargetFrames.push(this._engine.time.frameCount);
19052
19132
  };
19053
19133
  _proto.freeTexture = function freeTexture(texture) {
19054
19134
  if (!texture || texture.destroyed) return;
19055
19135
  this._freeTextures.push(texture);
19136
+ this._freeTextureFrames.push(this._engine.time.frameCount);
19137
+ };
19138
+ _proto.tick = function tick(currentFrame) {
19139
+ var maxAge = this.maxFreeAgeFrames;
19140
+ var rtFrames = this._freeRenderTargetFrames;
19141
+ for(var i = rtFrames.length - 1; i >= 0; i--){
19142
+ if (currentFrame - rtFrames[i] > maxAge) {
19143
+ this._destroyFreeRenderTargetAt(i);
19144
+ }
19145
+ }
19146
+ var texFrames = this._freeTextureFrames;
19147
+ for(var i1 = texFrames.length - 1; i1 >= 0; i1--){
19148
+ if (currentFrame - texFrames[i1] > maxAge) {
19149
+ this._destroyFreeTextureAt(i1);
19150
+ }
19151
+ }
19152
+ };
19153
+ _proto.evictBySize = function evictBySize(width, height) {
19154
+ var freeRenderTargets = this._freeRenderTargets;
19155
+ for(var i = freeRenderTargets.length - 1; i >= 0; i--){
19156
+ var rt = freeRenderTargets[i];
19157
+ if (rt.width === width && rt.height === height) {
19158
+ this._destroyFreeRenderTargetAt(i);
19159
+ }
19160
+ }
19161
+ var freeTextures = this._freeTextures;
19162
+ for(var i1 = freeTextures.length - 1; i1 >= 0; i1--){
19163
+ var tex = freeTextures[i1];
19164
+ if (tex.width === width && tex.height === height) {
19165
+ this._destroyFreeTextureAt(i1);
19166
+ }
19167
+ }
19056
19168
  };
19057
19169
  _proto.gc = function gc() {
19058
19170
  var freeRenderTargets = this._freeRenderTargets;
19059
19171
  for(var i = 0, n = freeRenderTargets.length; i < n; i++){
19060
- var renderTarget = freeRenderTargets[i];
19061
- var colorTexture = renderTarget.getColorTexture(0);
19062
- var depthTexture = renderTarget.depthTexture;
19063
- renderTarget.destroy(true);
19064
- colorTexture == null ? void 0 : colorTexture.destroy(true);
19065
- if (depthTexture && depthTexture !== colorTexture) {
19066
- depthTexture.destroy(true);
19067
- }
19172
+ RenderTargetPool._destroyRenderTargetResource(freeRenderTargets[i]);
19068
19173
  }
19069
19174
  freeRenderTargets.length = 0;
19175
+ this._freeRenderTargetFrames.length = 0;
19070
19176
  var freeTextures = this._freeTextures;
19071
19177
  for(var i1 = 0, n1 = freeTextures.length; i1 < n1; i1++){
19072
19178
  freeTextures[i1].destroy(true);
19073
19179
  }
19074
19180
  freeTextures.length = 0;
19181
+ this._freeTextureFrames.length = 0;
19182
+ };
19183
+ _proto._removeFreeRenderTargetAt = function _removeFreeRenderTargetAt(index) {
19184
+ var rts = this._freeRenderTargets;
19185
+ var frames = this._freeRenderTargetFrames;
19186
+ var last = rts.length - 1;
19187
+ if (index !== last) {
19188
+ rts[index] = rts[last];
19189
+ frames[index] = frames[last];
19190
+ }
19191
+ rts.length = last;
19192
+ frames.length = last;
19193
+ };
19194
+ _proto._removeFreeTextureAt = function _removeFreeTextureAt(index) {
19195
+ var texs = this._freeTextures;
19196
+ var frames = this._freeTextureFrames;
19197
+ var last = texs.length - 1;
19198
+ if (index !== last) {
19199
+ texs[index] = texs[last];
19200
+ frames[index] = frames[last];
19201
+ }
19202
+ texs.length = last;
19203
+ frames.length = last;
19204
+ };
19205
+ _proto._destroyFreeRenderTargetAt = function _destroyFreeRenderTargetAt(index) {
19206
+ var rt = this._freeRenderTargets[index];
19207
+ this._removeFreeRenderTargetAt(index);
19208
+ RenderTargetPool._destroyRenderTargetResource(rt);
19209
+ };
19210
+ _proto._destroyFreeTextureAt = function _destroyFreeTextureAt(index) {
19211
+ var tex = this._freeTextures[index];
19212
+ this._removeFreeTextureAt(index);
19213
+ tex.destroy(true);
19214
+ };
19215
+ RenderTargetPool._destroyRenderTargetResource = function _destroyRenderTargetResource(rt) {
19216
+ var colorTexture = rt.getColorTexture(0);
19217
+ var depthTexture = rt.depthTexture;
19218
+ rt.destroy(true);
19219
+ colorTexture == null ? void 0 : colorTexture.destroy(true);
19220
+ if (depthTexture && depthTexture !== colorTexture) {
19221
+ depthTexture.destroy(true);
19222
+ }
19075
19223
  };
19076
19224
  RenderTargetPool._matchRenderTarget = function _matchRenderTarget(renderTarget, width, height, colorFormat, depthFormat, needDepthTexture, mipmap, isSRGBColorSpace, antiAliasing) {
19077
19225
  if (renderTarget.width !== width || renderTarget.height !== height || renderTarget.antiAliasing !== antiAliasing) {
@@ -27184,17 +27332,15 @@ Shader.create("FinalAntiAliasing", BlitVS, FinalAntiAliasingFS);
27184
27332
  }
27185
27333
  var switchProgram = program.bind();
27186
27334
  var switchRenderCount = renderCount !== program._uploadRenderCount;
27187
- // Upload uniforms (cache-aware per block)
27335
+ // Upload uniforms (cache-aware per block). Renderer block carries plain samplers/arrays
27336
+ // even on the instanced path (GLSL forbids them in UBOs); `_canBatch` ensures the whole
27337
+ // batch agrees on those, so the leader's values are correct for the draw call
27188
27338
  if (switchRenderCount) {
27189
27339
  program.groupingOtherUniformBlock();
27190
27340
  program.uploadAll(program.sceneUniformBlock, sceneData);
27191
27341
  program.uploadAll(program.cameraUniformBlock, cameraData);
27192
- if (isInstanced) {
27193
- program._uploadRendererId = -1;
27194
- } else {
27195
- program.uploadAll(program.rendererUniformBlock, rendererData);
27196
- program._uploadRendererId = rendererId;
27197
- }
27342
+ program.uploadAll(program.rendererUniformBlock, rendererData);
27343
+ program._uploadRendererId = isInstanced ? -1 : rendererId;
27198
27344
  program.uploadAll(program.materialUniformBlock, materialData);
27199
27345
  renderElementShaderData && program.uploadAll(program.renderElementUniformBlock, renderElementShaderData);
27200
27346
  // UnGroup textures should upload default value, texture uint maybe change by logic of texture bind
@@ -27216,13 +27362,15 @@ Shader.create("FinalAntiAliasing", BlitVS, FinalAntiAliasingFS);
27216
27362
  } else if (switchProgram) {
27217
27363
  program.uploadTextures(program.cameraUniformBlock, cameraData);
27218
27364
  }
27219
- if (!isInstanced) {
27220
- if (program._uploadRendererId !== rendererId) {
27221
- program.uploadAll(program.rendererUniformBlock, rendererData);
27222
- program._uploadRendererId = rendererId;
27223
- } else if (switchProgram) {
27224
- program.uploadTextures(program.rendererUniformBlock, rendererData);
27225
- }
27365
+ if (isInstanced) {
27366
+ // Different batches may have different leaders, re-upload every time
27367
+ program.uploadAll(program.rendererUniformBlock, rendererData);
27368
+ program._uploadRendererId = -1;
27369
+ } else if (program._uploadRendererId !== rendererId) {
27370
+ program.uploadAll(program.rendererUniformBlock, rendererData);
27371
+ program._uploadRendererId = rendererId;
27372
+ } else if (switchProgram) {
27373
+ program.uploadTextures(program.rendererUniformBlock, rendererData);
27226
27374
  }
27227
27375
  if (program._uploadMaterialId !== materialId) {
27228
27376
  program.uploadAll(program.materialUniformBlock, materialData);
@@ -28241,19 +28389,8 @@ CascadedShadowCasterPass._tempMatrix0 = new engineMath.Matrix();
28241
28389
  this._copyBackgroundTexture = copyBackgroundTexture;
28242
28390
  }
28243
28391
  this._internalColorTarget = internalColorTarget;
28244
- } else {
28245
- var internalColorTarget1 = this._internalColorTarget;
28246
- var copyBackgroundTexture1 = this._copyBackgroundTexture;
28247
- var pool = engine._renderTargetPool;
28248
- if (internalColorTarget1) {
28249
- pool.freeRenderTarget(internalColorTarget1);
28250
- this._internalColorTarget = null;
28251
- }
28252
- if (copyBackgroundTexture1) {
28253
- pool.freeTexture(copyBackgroundTexture1);
28254
- this._copyBackgroundTexture = null;
28255
- }
28256
28392
  }
28393
+ // Both fields are released at the end of `_drawRenderPass`, so they're null on every entry here.
28257
28394
  // Scalable ambient obscurance pass
28258
28395
  // Before opaque pass so materials can sample ambient occlusion in BRDF
28259
28396
  var saoPass = this._saoPass;
@@ -28370,6 +28507,16 @@ CascadedShadowCasterPass._tempMatrix0 = new engineMath.Matrix();
28370
28507
  }
28371
28508
  cameraRenderTarget == null ? void 0 : cameraRenderTarget._blitRenderTarget();
28372
28509
  cameraRenderTarget == null ? void 0 : cameraRenderTarget.generateMipmaps();
28510
+ // Release per-frame leases so the next camera with matching shape can reuse them.
28511
+ var pool = engine._renderTargetPool;
28512
+ if (this._internalColorTarget) {
28513
+ pool.freeRenderTarget(this._internalColorTarget);
28514
+ this._internalColorTarget = null;
28515
+ }
28516
+ if (this._copyBackgroundTexture) {
28517
+ pool.freeTexture(this._copyBackgroundTexture);
28518
+ this._copyBackgroundTexture = null;
28519
+ }
28373
28520
  };
28374
28521
  /**
28375
28522
  * Push render data to render queue.
@@ -28405,6 +28552,7 @@ CascadedShadowCasterPass._tempMatrix0 = new engineMath.Matrix();
28405
28552
  _proto._pushRenderElementByType = function _pushRenderElementByType(renderElement, subShader, renderStates) {
28406
28553
  var shaderPasses = subShader.passes;
28407
28554
  var cullingResults = this._cullingResults;
28555
+ renderElement.subShader = subShader;
28408
28556
  var pushedQueueFlags = 0;
28409
28557
  for(var i = 0, n = shaderPasses.length; i < n; i++){
28410
28558
  var renderQueueType = void 0;
@@ -28416,19 +28564,28 @@ CascadedShadowCasterPass._tempMatrix0 = new engineMath.Matrix();
28416
28564
  renderQueueType = renderStates[i].renderQueueType;
28417
28565
  }
28418
28566
  var flag = 1 << renderQueueType;
28419
- renderElement.subShader = subShader;
28420
28567
  if (pushedQueueFlags & flag) {
28421
28568
  continue;
28422
28569
  }
28570
+ // First queue keeps the original element; subsequent queues each get an isolated
28571
+ // clone so per-queue batch state (`_isBatched`, `instancedRenderers`) doesn't
28572
+ // leak across queues for multi-pass materials (e.g. Opaque + Transparent)
28573
+ var elementForQueue = void 0;
28574
+ if (pushedQueueFlags === 0) {
28575
+ elementForQueue = renderElement;
28576
+ } else {
28577
+ elementForQueue = renderElement.component.engine._renderElementPool.get();
28578
+ elementForQueue._cloneFrom(renderElement);
28579
+ }
28423
28580
  switch(renderQueueType){
28424
28581
  case RenderQueueType.Opaque:
28425
- cullingResults.opaqueQueue.pushRenderElement(renderElement);
28582
+ cullingResults.opaqueQueue.pushRenderElement(elementForQueue);
28426
28583
  break;
28427
28584
  case RenderQueueType.AlphaTest:
28428
- cullingResults.alphaTestQueue.pushRenderElement(renderElement);
28585
+ cullingResults.alphaTestQueue.pushRenderElement(elementForQueue);
28429
28586
  break;
28430
28587
  case RenderQueueType.Transparent:
28431
- cullingResults.transparentQueue.pushRenderElement(renderElement);
28588
+ cullingResults.transparentQueue.pushRenderElement(elementForQueue);
28432
28589
  break;
28433
28590
  }
28434
28591
  pushedQueueFlags |= flag;
@@ -28644,7 +28801,18 @@ ShaderPool.init();
28644
28801
  _inherits(Engine, EventDispatcher);
28645
28802
  function Engine(canvas, hardwareRenderer, configuration) {
28646
28803
  var _this;
28647
- _this = EventDispatcher.call(this) || this, /** @internal */ _this._renderingStatistics = new RenderingStatistics(), /** @internal */ _this._isDeviceLost = false, /** @internal */ _this._frameInProcess = false, /** @internal */ _this._pendingDestroyObjects = [], /** @internal */ _this._processingPendingDestroys = false, /** @internal */ _this._physicsInitialized = false, /* @internal */ _this._lastRenderState = new RenderState(), /* @internal */ _this._renderElementPool = new ClearableObjectPool(RenderElement), /* @internal */ _this._textRenderElementPool = new ClearableObjectPool(RenderElement), /* @internal */ _this._charRenderInfoPool = new ReturnableObjectPool(CharRenderInfo, 50), /* @internal */ _this._renderContext = new RenderContext(), /* @internal */ _this._renderCount = 0, /* @internal */ _this._shaderProgramMaps = [], /** @internal */ _this._fontMap = {}, /** @internal */ _this._macroCollection = new ShaderMacroCollection(), /** @internal */ _this._postProcessPassNeedRefresh = false, _this._settings = {}, _this._resourceManager = new ResourceManager(_this), _this._sceneManager = new SceneManager(_this), _this._vSyncCount = 1, _this._targetFrameRate = 60, _this._time = new Time(), _this._isPaused = true, _this._vSyncCounter = 1, _this._targetFrameInterval = 1000 / 60, _this._destroyed = false, _this._waitingDestroy = false, _this._waitingGC = false, _this._postProcessPasses = new Array(), _this._activePostProcessPasses = new Array(), _this._animate = function() {
28804
+ _this = EventDispatcher.call(this) || this, /** @internal */ _this._renderingStatistics = new RenderingStatistics(), /** @internal */ _this._isDeviceLost = false, /** @internal */ _this._frameInProcess = false, /** @internal */ _this._pendingDestroyObjects = [], /** @internal */ _this._processingPendingDestroys = false, /** @internal */ _this._physicsInitialized = false, /* @internal */ _this._lastRenderState = new RenderState(), /* @internal */ _this._renderElementPool = new ClearableObjectPool(RenderElement), /* @internal */ _this._textRenderElementPool = new ClearableObjectPool(RenderElement), /* @internal */ _this._charRenderInfoPool = new ReturnableObjectPool(CharRenderInfo, 50), /* @internal */ _this._renderContext = new RenderContext(), /* @internal */ _this._renderCount = 0, /* @internal */ _this._shaderProgramMaps = [], /** @internal */ _this._fontMap = {}, /** @internal */ _this._macroCollection = new ShaderMacroCollection(), /** @internal */ _this._postProcessPassNeedRefresh = false, _this._settings = {}, _this._resourceManager = new ResourceManager(_this), _this._sceneManager = new SceneManager(_this), _this._vSyncCount = 1, _this._targetFrameRate = 60, _this._time = new Time(), _this._isPaused = true, _this._vSyncCounter = 1, _this._targetFrameInterval = 1000 / 60, _this._destroyed = false, _this._waitingDestroy = false, _this._waitingGC = false, _this._postProcessPasses = new Array(), _this._activePostProcessPasses = new Array(), _this._lastCanvasWidth = -1, _this._lastCanvasHeight = -1, /** Evict pool entries sized to the previous canvas dimensions. */ _this._onCanvasResize = function() {
28805
+ var _$canvas = _this._canvas;
28806
+ var newWidth = _$canvas.width;
28807
+ var newHeight = _$canvas.height;
28808
+ if (_this._lastCanvasWidth !== newWidth || _this._lastCanvasHeight !== newHeight) {
28809
+ if (_this._lastCanvasWidth >= 0) {
28810
+ _this._renderTargetPool.evictBySize(_this._lastCanvasWidth, _this._lastCanvasHeight);
28811
+ }
28812
+ _this._lastCanvasWidth = newWidth;
28813
+ _this._lastCanvasHeight = newHeight;
28814
+ }
28815
+ }, _this._animate = function() {
28648
28816
  if (_this._vSyncCount) {
28649
28817
  var _this_xrManager;
28650
28818
  var raf = ((_this_xrManager = _this.xrManager) == null ? void 0 : _this_xrManager._getRequestAnimationFrame()) || requestAnimationFrame;
@@ -28665,6 +28833,9 @@ ShaderPool.init();
28665
28833
  _this._textDefaultFont.isGCIgnored = true;
28666
28834
  _this._batcherManager = new BatcherManager(_this);
28667
28835
  _this._renderTargetPool = new RenderTargetPool(_this);
28836
+ _this._lastCanvasWidth = canvas.width;
28837
+ _this._lastCanvasHeight = canvas.height;
28838
+ canvas._sizeUpdateFlagManager.addListener(_this._onCanvasResize);
28668
28839
  _this.inputManager = new InputManager(_this, configuration.input);
28669
28840
  var xrDevice = configuration.xrDevice;
28670
28841
  if (xrDevice) {
@@ -28724,6 +28895,7 @@ ShaderPool.init();
28724
28895
  var _this_xrManager;
28725
28896
  var time = this._time;
28726
28897
  time._update();
28898
+ this._renderTargetPool.tick(time.frameCount);
28727
28899
  var deltaTime = time.deltaTime;
28728
28900
  this._frameInProcess = true;
28729
28901
  this._renderElementPool.clear();
@@ -28868,6 +29040,7 @@ ShaderPool.init();
28868
29040
  var _this_xrManager;
28869
29041
  this._destroyed = true;
28870
29042
  this._waitingDestroy = false;
29043
+ this._canvas._sizeUpdateFlagManager.removeListener(this._onCanvasResize);
28871
29044
  this._sceneManager._destroyAllScene();
28872
29045
  this._resourceManager._destroy();
28873
29046
  this.inputManager._destroy();
@@ -31685,7 +31858,7 @@ AnimationCurveOwner.registerAssembler(SkinnedMeshRenderer, "blendShapeWeights",
31685
31858
  */ var AnimationClipCurveBinding = /*#__PURE__*/ function() {
31686
31859
  function AnimationClipCurveBinding() {
31687
31860
  /** The index of the component that is animated. */ this.typeIndex = 0;
31688
- this._tempCurveOwner = {};
31861
+ this._tempCurveOwner = new WeakMap();
31689
31862
  }
31690
31863
  var _proto = AnimationClipCurveBinding.prototype;
31691
31864
  /**
@@ -31711,11 +31884,12 @@ AnimationCurveOwner.registerAssembler(SkinnedMeshRenderer, "blendShapeWeights",
31711
31884
  /**
31712
31885
  * @internal
31713
31886
  */ _proto._getTempCurveOwner = function _getTempCurveOwner(entity, component) {
31714
- var instanceId = entity.instanceId;
31715
- if (!this._tempCurveOwner[instanceId]) {
31716
- this._tempCurveOwner[instanceId] = this._createCurveOwner(entity, component);
31887
+ var owner = this._tempCurveOwner.get(entity);
31888
+ if (!owner) {
31889
+ owner = this._createCurveOwner(entity, component);
31890
+ this._tempCurveOwner.set(entity, owner);
31717
31891
  }
31718
- return this._tempCurveOwner[instanceId];
31892
+ return owner;
31719
31893
  };
31720
31894
  return AnimationClipCurveBinding;
31721
31895
  }();
@@ -33197,7 +33371,7 @@ function _type_of(obj) {
33197
33371
  * @internal
33198
33372
  */ var AnimatorLayerData = /*#__PURE__*/ function() {
33199
33373
  function AnimatorLayerData() {
33200
- this.curveOwnerPool = Object.create(null);
33374
+ this.curveOwnerPool = new WeakMap();
33201
33375
  this.animatorStateDataMap = {};
33202
33376
  this.srcPlayData = new AnimatorStatePlayData();
33203
33377
  this.destPlayData = new AnimatorStatePlayData();
@@ -33235,7 +33409,7 @@ function _type_of(obj) {
33235
33409
  _inherits(Animator, Component);
33236
33410
  function Animator(entity) {
33237
33411
  var _this;
33238
- _this = Component.call(this, entity) || this, /** Culling mode of this Animator. */ _this.cullingMode = AnimatorCullingMode.None, /** The playback speed of the Animator, 1.0 is normal playback speed. */ _this.speed = 1.0, /** Whether the Animator sends AnimationEvent callbacks. */ _this.fireEvents = true, /** @internal */ _this._playFrameCount = -1, /** @internal */ _this._onUpdateIndex = -1, _this._updateMark = 0, _this._animatorLayersData = new Array(), _this._curveOwnerPool = Object.create(null), _this._animationEventHandlerPool = new ClearableObjectPool(AnimationEventHandler), _this._parametersValueMap = Object.create(null), _this._tempAnimatorStateInfo = {
33412
+ _this = Component.call(this, entity) || this, /** Culling mode of this Animator. */ _this.cullingMode = AnimatorCullingMode.None, /** The playback speed of the Animator, 1.0 is normal playback speed. */ _this.speed = 1.0, /** Whether the Animator sends AnimationEvent callbacks. */ _this.fireEvents = true, /** @internal */ _this._playFrameCount = -1, /** @internal */ _this._onUpdateIndex = -1, _this._updateMark = 0, _this._animatorLayersData = new Array(), _this._curveOwnerPool = new WeakMap(), _this._animationEventHandlerPool = new ClearableObjectPool(AnimationEventHandler), _this._parametersValueMap = Object.create(null), _this._tempAnimatorStateInfo = {
33239
33413
  layerIndex: -1,
33240
33414
  state: null
33241
33415
  }, _this._controlledRenderers = new Array();
@@ -33431,19 +33605,23 @@ function _type_of(obj) {
33431
33605
  /**
33432
33606
  * @internal
33433
33607
  */ _proto._reset = function _reset() {
33434
- var _this = this, animationCurveOwners = _this._curveOwnerPool;
33435
- for(var instanceId in animationCurveOwners){
33436
- var propertyOwners = animationCurveOwners[instanceId];
33437
- for(var property in propertyOwners){
33438
- var owner = propertyOwners[property];
33439
- owner.revertDefaultValue();
33440
- }
33441
- }
33608
+ // revertDefaultValue 可能在死 target 上抛;listener 清理必须始终发生,否则
33609
+ // polyfill clipChangedListener 会留在共享的 AnimatorState 上,捕获 this(Animator)→Entity 整树。
33610
+ // try/catch 隔离 revert,listener 块紧跟其后无条件执行。
33442
33611
  var layersData = this._animatorLayersData;
33443
33612
  for(var i = 0, n = layersData.length; i < n; i++){
33444
33613
  var stateDataMap = layersData[i].animatorStateDataMap;
33445
33614
  for(var stateName in stateDataMap){
33446
33615
  var stateData = stateDataMap[stateName];
33616
+ var layerOwners = stateData.curveLayerOwner;
33617
+ for(var j = 0, m = layerOwners.length; j < m; j++){
33618
+ try {
33619
+ var _layerOwners_j_curveOwner, _layerOwners_j;
33620
+ (_layerOwners_j = layerOwners[j]) == null ? void 0 : (_layerOwners_j_curveOwner = _layerOwners_j.curveOwner) == null ? void 0 : _layerOwners_j_curveOwner.revertDefaultValue();
33621
+ } catch (e) {
33622
+ Logger.warn("Animator._reset: revertDefaultValue threw", e);
33623
+ }
33624
+ }
33447
33625
  if (stateData.clipChangedListener && stateData.state) {
33448
33626
  stateData.state._updateFlagManager.removeListener(stateData.clipChangedListener);
33449
33627
  stateData.clipChangedListener = null;
@@ -33452,7 +33630,7 @@ function _type_of(obj) {
33452
33630
  }
33453
33631
  }
33454
33632
  this._animatorLayersData.length = 0;
33455
- this._curveOwnerPool = Object.create(null);
33633
+ this._curveOwnerPool = new WeakMap();
33456
33634
  this._parametersValueMap = Object.create(null);
33457
33635
  this._animationEventHandlerPool.clear();
33458
33636
  if (this._controllerUpdateFlag) {
@@ -33537,19 +33715,26 @@ function _type_of(obj) {
33537
33715
  var relativePath = curve.relativePath;
33538
33716
  var targetEntity = curve.relativePath === "" ? entity : entity.findByPath(curve.relativePath);
33539
33717
  if (targetEntity) {
33540
- var _curveOwnerPool, _instanceId, _propertyOwners, _property, _layerCurveOwnerPool, _instanceId1, _layerPropertyOwners, _property1;
33718
+ var _propertyOwners, _property, _layerPropertyOwners, _property1;
33541
33719
  var component = curve.typeIndex > 0 ? targetEntity.getComponents(curve.type, components)[curve.typeIndex] : targetEntity.getComponent(curve.type);
33542
33720
  components.length = 0;
33543
33721
  if (!component) {
33544
33722
  continue;
33545
33723
  }
33546
33724
  var property = curve.property;
33547
- var instanceId = component.instanceId;
33548
- // Get owner
33549
- var propertyOwners = (_curveOwnerPool = curveOwnerPool)[_instanceId = instanceId] || (_curveOwnerPool[_instanceId] = Object.create(null));
33725
+ // Get owner — WeakMap keyed by Component so dead components let entries GC.
33726
+ var propertyOwners = curveOwnerPool.get(component);
33727
+ if (!propertyOwners) {
33728
+ propertyOwners = Object.create(null);
33729
+ curveOwnerPool.set(component, propertyOwners);
33730
+ }
33550
33731
  var owner = (_propertyOwners = propertyOwners)[_property = property] || (_propertyOwners[_property] = curve._createCurveOwner(targetEntity, component));
33551
- // Get layer owner
33552
- var layerPropertyOwners = (_layerCurveOwnerPool = layerCurveOwnerPool)[_instanceId1 = instanceId] || (_layerCurveOwnerPool[_instanceId1] = Object.create(null));
33732
+ // Get layer owner — same WeakMap-by-Component pattern (was Record<instanceId,...> which kept dead components pinned for the Animator's lifetime).
33733
+ var layerPropertyOwners = layerCurveOwnerPool.get(component);
33734
+ if (!layerPropertyOwners) {
33735
+ layerPropertyOwners = Object.create(null);
33736
+ layerCurveOwnerPool.set(component, layerPropertyOwners);
33737
+ }
33553
33738
  var layerOwner = (_layerPropertyOwners = layerPropertyOwners)[_property1 = property] || (_layerPropertyOwners[_property1] = curve._createCurveLayerOwner(owner));
33554
33739
  if (mask && mask.pathMasks.length) {
33555
33740
  var _mask_getPathMask;