diff --git a/extensions/reviewed/Light3D.json b/extensions/reviewed/Light3D.json index aa5b72be6..e72ed1c35 100644 --- a/extensions/reviewed/Light3D.json +++ b/extensions/reviewed/Light3D.json @@ -774,18 +774,18 @@ "function getLightManager(runtimeScene) {", " if (!runtimeScene.__lightManager) {", " // Create the shared manager if necessary.", - " const threeRenderer = runtimeScene", - " .getGame()", - " .getRenderer()", - " .getThreeRenderer();", " const requestedCount = isInGameEdition", " ? editorLightCountMax : lightCountMax;", " const requestedShadowCount = isInGameEdition", " ? editorLightShadowCountMax : lightShadowCountMax;", "", + " // The renderer is read anew on every recomputation: it may not", + " // exist yet when the manager is created on the first frame.", " runtimeScene.__lightManager = new LightManager(", " requestedCount, requestedShadowCount,", - " kindCount => computeDeviceLightBudget(threeRenderer, kindCount));", + " kindCount => computeDeviceLightBudget(", + " runtimeScene.getGame().getRenderer().getThreeRenderer(),", + " kindCount));", " }", " return runtimeScene.__lightManager;", "}", @@ -825,10 +825,16 @@ " this.objects.length = 0;", " }", "", + " /** Drop the farthest lights until the list fits its capacity again. */", + " trimToCapacity() {", + " while (this.objects.length > this.capacity.value) {", + " this.onDeletion(this.objects.pop().object);", + " }", + " }", + "", " /**", " * @param object {LightRuntimeObject}", - " * @param sortDistance {number} The squared distance to the camera, which", - " * more expensive lights can inflate to lose ties against cheaper ones.", + " * @param sortDistance {number} The squared distance to the camera.", " */", " insertByDistance(object, sortDistance) {", " let insertionIndex = 0;", @@ -955,6 +961,15 @@ " this.usedKinds.add(kind);", " this.deviceBudget = this._computeDeviceBudget(this.usedKinds.size);", "", + " // The budget just shrank: evict the lights that no longer fit, so", + " // that even this frame stays within what the device can take.", + " for (const list of this.visibleLists.values()) {", + " list.trimToCapacity();", + " }", + " for (const list of this.shadowLists.values()) {", + " list.trimToCapacity();", + " }", + "", " if (this.deviceBudget.count < this._requestedCount.value", " || this.deviceBudget.shadowCount", " < this._requestedShadowCount.value) {", @@ -1051,7 +1066,7 @@ "objectGroups": [] }, { - "description": "the maximum number of nearest lights displayed simultaneously.", + "description": "the maximum number of nearest lights displayed simultaneously, counted separately for each kind of light (point lights, spot lights, spot lights projecting a texture). Devices that can't take that many lights enforce a lower limit.", "fullName": "Max lights count", "functionType": "ExpressionAndCondition", "name": "LightCountMax", @@ -1124,7 +1139,7 @@ "objectGroups": [] }, { - "description": "the maximum number of nearest lights displayed with shadow simultaneously.", + "description": "the maximum number of nearest lights displayed with shadow simultaneously, counted separately for each kind of light (point lights, spot lights, spot lights projecting a texture). Devices that can't take that many shadows enforce a lower limit.", "fullName": "Max lights with shadow count", "functionType": "ExpressionAndCondition", "name": "LightShadowCountMax",