Fix autoscaler

This commit is contained in:
schmelczerandras 2020-09-19 17:30:39 +02:00
parent c58728215f
commit 7a7273c2be
2 changed files with 87 additions and 84 deletions

View file

@ -1,42 +1,105 @@
import { Autoscaler as AutoScaler } from '../../helper/autoscaler';
import { clamp } from '../../helper/clamp';
import { exponentialDecay } from '../../helper/exponential-decay';
import { settings } from '../settings';
import { mix } from '../../helper/mix';
import { Insights } from './insights';
export class FpsAutoscaler extends AutoScaler {
const settings = {
targetDeltaTimeInMilliseconds: 20,
deltaTimeErrorInMilliseconds: 3,
deltaTimeResponsiveness: 1 / 32,
adjusmentRateInMilliseconds: 1000,
targets: [
{
distanceRenderScale: 0.1,
finalRenderScale: 0.2,
},
{
distanceRenderScale: 0.1,
finalRenderScale: 0.6,
},
{
distanceRenderScale: 0.3,
finalRenderScale: 1.0,
},
{
distanceRenderScale: 1.0,
finalRenderScale: 1.0,
},
],
qualityStepIncrease: 0.01,
qualityStepDecrese: 0.2,
};
export class FpsAutoscaler {
private timeSinceLastAdjusment = 0;
private exponentialDecayedDeltaTime = 0.0;
private exponentialDecayedDeltaTime = settings.targetDeltaTimeInMilliseconds;
constructor(setters: { [key: string]: (value: number | boolean) => void }) {
super(
setters,
settings.qualityScaling.qualityTargets,
settings.qualityScaling.startingTargetIndex,
settings.qualityScaling.scalingOptions
);
// can have fractions
private index = 3;
constructor(private setters: { [key: string]: (value: number | boolean) => void }) {
this.applyScaling();
}
public increase() {
this.index += settings.qualityStepIncrease;
this.applyScaling();
}
public decrease() {
this.index -= settings.qualityStepDecrese;
this.applyScaling();
}
private applyScaling() {
this.index = clamp(this.index, 0, settings.targets.length - 1);
const floor = Math.floor(this.index);
const fract = this.index - floor;
const previousTarget: any = settings.targets[floor];
const nextTarget =
floor + 1 == settings.targets.length ? previousTarget : settings.targets[floor + 1];
const result: any = {};
for (const key in this.setters) {
const previous = previousTarget[key];
const next = nextTarget[key];
let current: number | boolean;
if (typeof previous == 'number') {
current = mix(previous, next as number, fract);
} else {
current = next;
}
result[key] = current;
this.setters[key](current);
}
Insights.setValue('quality', result);
}
public autoscale(lastDeltaTime: DOMHighResTimeStamp) {
this.timeSinceLastAdjusment += lastDeltaTime;
this.exponentialDecayedDeltaTime = exponentialDecay(
this.exponentialDecayedDeltaTime,
lastDeltaTime,
settings.deltaTimeResponsiveness
);
Insights.setValue('FPS', 1000 / this.exponentialDecayedDeltaTime);
if (
this.timeSinceLastAdjusment >= settings.qualityScaling.adjusmentRateInMilliseconds
(this.timeSinceLastAdjusment += lastDeltaTime) >=
settings.adjusmentRateInMilliseconds
) {
this.timeSinceLastAdjusment = 0;
this.exponentialDecayedDeltaTime = exponentialDecay(
this.exponentialDecayedDeltaTime,
lastDeltaTime,
settings.qualityScaling.deltaTimeResponsiveness
);
if (
this.exponentialDecayedDeltaTime <=
settings.qualityScaling.targetDeltaTimeInMilliseconds -
settings.qualityScaling.deltaTimeError
this.exponentialDecayedDeltaTime + settings.deltaTimeErrorInMilliseconds <=
settings.targetDeltaTimeInMilliseconds
) {
this.increase();
} else if (
this.exponentialDecayedDeltaTime >
settings.qualityScaling.targetDeltaTimeInMilliseconds +
settings.qualityScaling.deltaTimeError
this.exponentialDecayedDeltaTime > settings.targetDeltaTimeInMilliseconds
) {
this.decrease();
}

View file

@ -1,60 +0,0 @@
import { Insights } from '../graphics/rendering/insights';
import { clamp } from './clamp';
import { mix } from './mix';
export class Autoscaler {
// can have fractions
private index: number;
constructor(
private setters: { [key: string]: (value: number | boolean) => void },
private targets: Array<{ [key: string]: number | boolean }>,
startingIndex: number,
private scalingOptions: {
additiveIncrease: number;
multiplicativeDecrease: number;
}
) {
this.index = startingIndex;
this.applyScaling();
}
public increase() {
this.index += this.scalingOptions.additiveIncrease;
this.applyScaling();
}
public decrease() {
this.index /= this.scalingOptions.multiplicativeDecrease;
this.applyScaling();
}
private applyScaling() {
this.index = clamp(this.index, 0, this.targets.length - 1);
const floor = Math.floor(this.index);
const fract = this.index - floor;
const previousTarget = this.targets[floor];
const nextTarget =
floor + 1 == this.targets.length ? previousTarget : this.targets[floor + 1];
const result: any = {};
for (const key in this.setters) {
const previous = previousTarget[key];
const next = nextTarget[key];
let current: number | boolean;
if (typeof previous == 'number') {
current = mix(previous, next as number, fract);
} else {
current = next;
}
result[key] = current;
this.setters[key](current);
}
Insights.setValue('quality', result);
}
}