mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 23:36:44 +02:00
more tweaks to LOD logic
This commit is contained in:
parent
0e44126106
commit
ec2b11640c
2 changed files with 95 additions and 45 deletions
|
@ -40,26 +40,38 @@ float LODManager::getLODIncreaseFPS() {
|
||||||
|
|
||||||
|
|
||||||
void LODManager::autoAdjustLOD(float currentFPS) {
|
void LODManager::autoAdjustLOD(float currentFPS) {
|
||||||
|
|
||||||
// NOTE: our first ~100 samples at app startup are completely all over the place, and we don't
|
// NOTE: our first ~100 samples at app startup are completely all over the place, and we don't
|
||||||
// really want to count them in our average, so we will ignore the real frame rates and stuff
|
// really want to count them in our average, so we will ignore the real frame rates and stuff
|
||||||
// our moving average with simulated good data
|
// our moving average with simulated good data
|
||||||
const int IGNORE_THESE_SAMPLES = 100;
|
const int IGNORE_THESE_SAMPLES = 100;
|
||||||
const float ASSUMED_FPS = 60.0f;
|
//const float ASSUMED_FPS = 60.0f;
|
||||||
if (_fpsAverage.getSampleCount() < IGNORE_THESE_SAMPLES) {
|
if (_fpsAverageUpWindow.getSampleCount() < IGNORE_THESE_SAMPLES) {
|
||||||
currentFPS = ASSUMED_FPS;
|
currentFPS = ASSUMED_FPS;
|
||||||
|
_lastUpShift = _lastDownShift = usecTimestampNow();
|
||||||
}
|
}
|
||||||
_fpsAverage.updateAverage(currentFPS);
|
_fpsAverageStartWindow.updateAverage(currentFPS);
|
||||||
_fastFPSAverage.updateAverage(currentFPS);
|
_fpsAverageDownWindow.updateAverage(currentFPS);
|
||||||
|
_fpsAverageUpWindow.updateAverage(currentFPS);
|
||||||
|
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
bool octreeChanged = false;
|
bool octreeChanged = false;
|
||||||
quint64 elapsed = now - _lastAdjust;
|
quint64 elapsedSinceDownShift = now - _lastDownShift;
|
||||||
|
quint64 elapsedSinceUpShift = now - _lastUpShift;
|
||||||
|
|
||||||
if (_automaticLODAdjust) {
|
if (_automaticLODAdjust) {
|
||||||
// LOD Downward adjustment
|
|
||||||
if (elapsed > ADJUST_LOD_DOWN_DELAY && _fpsAverage.getAverage() < getLODDecreaseFPS()) {
|
// LOD Downward adjustment
|
||||||
|
// If our last adjust was an upshift, then we don't want to consider any downshifts until we've delayed at least
|
||||||
|
// our START_DELAY_WINDOW_IN_SECS
|
||||||
|
bool doDownShift = _lastAdjustWasUpShift
|
||||||
|
? (elapsedSinceUpShift > START_SHIFT_ELPASED && _fpsAverageStartWindow.getAverage() < getLODDecreaseFPS())
|
||||||
|
: (elapsedSinceDownShift > DOWN_SHIFT_ELPASED && _fpsAverageDownWindow.getAverage() < getLODDecreaseFPS());
|
||||||
|
|
||||||
|
|
||||||
|
if (doDownShift) {
|
||||||
|
|
||||||
// Octree items... stepwise adjustment
|
// Octree items... stepwise adjustment
|
||||||
if (_octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
|
if (_octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
|
||||||
|
@ -70,37 +82,58 @@ void LODManager::autoAdjustLOD(float currentFPS) {
|
||||||
octreeChanged = changed = true;
|
octreeChanged = changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
_lastAdjust = now;
|
if (_lastAdjustWasUpShift) {
|
||||||
qDebug() << "adjusting LOD down... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
|
qDebug() << "adjusting LOD DOWN after initial delay..."
|
||||||
<< "_octreeSizeScale=" << _octreeSizeScale;
|
<< "average fps for last "<< START_DELAY_WINDOW_IN_SECS <<"seconds was "
|
||||||
|
<< _fpsAverageStartWindow.getAverage()
|
||||||
|
<< "minimum is:" << getLODDecreaseFPS()
|
||||||
|
<< "elapsedSinceUpShift:" << elapsedSinceUpShift
|
||||||
|
<< " NEW _octreeSizeScale=" << _octreeSizeScale;
|
||||||
|
} else {
|
||||||
|
qDebug() << "adjusting LOD DOWN..."
|
||||||
|
<< "average fps for last "<< DOWN_SHIFT_WINDOW_IN_SECS <<"seconds was "
|
||||||
|
<< _fpsAverageDownWindow.getAverage()
|
||||||
|
<< "minimum is:" << getLODDecreaseFPS()
|
||||||
|
<< "elapsedSinceDownShift:" << elapsedSinceDownShift
|
||||||
|
<< " NEW _octreeSizeScale=" << _octreeSizeScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastDownShift = now;
|
||||||
|
_lastAdjustWasUpShift = false;
|
||||||
|
|
||||||
emit LODDecreased();
|
emit LODDecreased();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
// LOD Upward adjustment
|
// LOD Upward adjustment
|
||||||
if (elapsed > ADJUST_LOD_UP_DELAY && _fpsAverage.getAverage() > getLODIncreaseFPS()) {
|
if (elapsedSinceUpShift > UP_SHIFT_ELPASED && _fpsAverageUpWindow.getAverage() > getLODIncreaseFPS()) {
|
||||||
|
|
||||||
// Octee items... stepwise adjustment
|
// Octee items... stepwise adjustment
|
||||||
if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) {
|
if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) {
|
||||||
if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
|
if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
|
||||||
_octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
|
_octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
|
||||||
} else {
|
} else {
|
||||||
_octreeSizeScale *= ADJUST_LOD_UP_BY;
|
_octreeSizeScale *= ADJUST_LOD_UP_BY;
|
||||||
|
}
|
||||||
|
if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) {
|
||||||
|
_octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE;
|
||||||
|
}
|
||||||
|
octreeChanged = changed = true;
|
||||||
}
|
}
|
||||||
if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) {
|
|
||||||
_octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE;
|
|
||||||
}
|
|
||||||
octreeChanged = changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
_lastAdjust = now;
|
qDebug() << "adjusting LOD UP... average fps for last "<< UP_SHIFT_WINDOW_IN_SECS <<"seconds was "
|
||||||
qDebug() << "adjusting LOD up... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
|
<< _fpsAverageUpWindow.getAverage()
|
||||||
<< "_octreeSizeScale=" << _octreeSizeScale;
|
<< "upshift point is:" << getLODIncreaseFPS()
|
||||||
|
<< "elapsedSinceUpShift:" << elapsedSinceUpShift
|
||||||
|
<< " NEW _octreeSizeScale=" << _octreeSizeScale;
|
||||||
|
|
||||||
emit LODIncreased();
|
_lastUpShift = now;
|
||||||
|
_lastAdjustWasUpShift = true;
|
||||||
|
|
||||||
|
emit LODIncreased();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,9 +149,13 @@ void LODManager::autoAdjustLOD(float currentFPS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LODManager::resetLODAdjust() {
|
void LODManager::resetLODAdjust() {
|
||||||
_fpsAverage.reset();
|
|
||||||
_fastFPSAverage.reset();
|
// TODO: Do we need this???
|
||||||
|
/*
|
||||||
|
_fpsAverageDownWindow.reset();
|
||||||
|
_fpsAverageUpWindow.reset();
|
||||||
_lastAdjust = usecTimestampNow();
|
_lastAdjust = usecTimestampNow();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LODManager::getLODFeedbackText() {
|
QString LODManager::getLODFeedbackText() {
|
||||||
|
|
|
@ -19,10 +19,22 @@
|
||||||
|
|
||||||
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0;
|
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0;
|
||||||
const float DEFAULT_HMD_LOD_DOWN_FPS = 60.0;
|
const float DEFAULT_HMD_LOD_DOWN_FPS = 60.0;
|
||||||
const float INCREASE_LOD_GAP = 5.0f;
|
const float MAX_LIKELY_DESKTOP_FPS = 59.0; // this is essentially, V-synch - 1 fps
|
||||||
|
const float MAX_LIKELY_HMD_FPS = 74.0; // this is essentially, V-synch - 1 fps
|
||||||
|
const float INCREASE_LOD_GAP = 15.0f;
|
||||||
|
|
||||||
const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 0.5; // Consider adjusting LOD down after half a second
|
const float START_DELAY_WINDOW_IN_SECS = 3.0f; // wait at least this long after steady state/last upshift to consider downshifts
|
||||||
const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2;
|
const float DOWN_SHIFT_WINDOW_IN_SECS = 0.5f;
|
||||||
|
const float UP_SHIFT_WINDOW_IN_SECS = 2.5f;
|
||||||
|
|
||||||
|
const int ASSUMED_FPS = 60;
|
||||||
|
const quint64 START_SHIFT_ELPASED = USECS_PER_SECOND * START_DELAY_WINDOW_IN_SECS;
|
||||||
|
const quint64 DOWN_SHIFT_ELPASED = USECS_PER_SECOND * DOWN_SHIFT_WINDOW_IN_SECS; // Consider adjusting LOD down after half a second
|
||||||
|
const quint64 UP_SHIFT_ELPASED = USECS_PER_SECOND * UP_SHIFT_WINDOW_IN_SECS;
|
||||||
|
|
||||||
|
const int START_DELAY_SAMPLES_OF_FRAMES = ASSUMED_FPS * START_DELAY_WINDOW_IN_SECS;
|
||||||
|
const int DOWN_SHIFT_SAMPLES_OF_FRAMES = ASSUMED_FPS * DOWN_SHIFT_WINDOW_IN_SECS;
|
||||||
|
const int UP_SHIFT_SAMPLES_OF_FRAMES = ASSUMED_FPS * UP_SHIFT_WINDOW_IN_SECS;
|
||||||
|
|
||||||
const float ADJUST_LOD_DOWN_BY = 0.9f;
|
const float ADJUST_LOD_DOWN_BY = 0.9f;
|
||||||
const float ADJUST_LOD_UP_BY = 1.1f;
|
const float ADJUST_LOD_UP_BY = 1.1f;
|
||||||
|
@ -37,9 +49,6 @@ const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
|
||||||
// do. But both are still culled using the same angular size logic.
|
// do. But both are still culled using the same angular size logic.
|
||||||
const float AVATAR_TO_ENTITY_RATIO = 2.0f;
|
const float AVATAR_TO_ENTITY_RATIO = 2.0f;
|
||||||
|
|
||||||
const int ONE_SECOND_OF_FRAMES = 60;
|
|
||||||
const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES;
|
|
||||||
|
|
||||||
|
|
||||||
class LODManager : public QObject, public Dependency {
|
class LODManager : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -51,11 +60,11 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void setDesktopLODDecreaseFPS(float value) { _desktopLODDecreaseFPS = value; }
|
Q_INVOKABLE void setDesktopLODDecreaseFPS(float value) { _desktopLODDecreaseFPS = value; }
|
||||||
Q_INVOKABLE float getDesktopLODDecreaseFPS() const { return _desktopLODDecreaseFPS; }
|
Q_INVOKABLE float getDesktopLODDecreaseFPS() const { return _desktopLODDecreaseFPS; }
|
||||||
Q_INVOKABLE float getDesktopLODIncreaseFPS() const { return _desktopLODDecreaseFPS + INCREASE_LOD_GAP; }
|
Q_INVOKABLE float getDesktopLODIncreaseFPS() const { return glm::min(_desktopLODDecreaseFPS + INCREASE_LOD_GAP, MAX_LIKELY_DESKTOP_FPS); }
|
||||||
|
|
||||||
Q_INVOKABLE void setHMDLODDecreaseFPS(float value) { _hmdLODDecreaseFPS = value; }
|
Q_INVOKABLE void setHMDLODDecreaseFPS(float value) { _hmdLODDecreaseFPS = value; }
|
||||||
Q_INVOKABLE float getHMDLODDecreaseFPS() const { return _hmdLODDecreaseFPS; }
|
Q_INVOKABLE float getHMDLODDecreaseFPS() const { return _hmdLODDecreaseFPS; }
|
||||||
Q_INVOKABLE float getHMDLODIncreaseFPS() const { return _hmdLODDecreaseFPS + INCREASE_LOD_GAP; }
|
Q_INVOKABLE float getHMDLODIncreaseFPS() const { return glm::min(_hmdLODDecreaseFPS + INCREASE_LOD_GAP, MAX_LIKELY_HMD_FPS); }
|
||||||
|
|
||||||
Q_INVOKABLE float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
|
Q_INVOKABLE float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
|
||||||
|
|
||||||
|
@ -68,8 +77,8 @@ public:
|
||||||
Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
||||||
|
|
||||||
Q_INVOKABLE void resetLODAdjust();
|
Q_INVOKABLE void resetLODAdjust();
|
||||||
Q_INVOKABLE float getFPSAverage() const { return _fpsAverage.getAverage(); }
|
//Q_INVOKABLE float getFPSAverage() const { return _fpsAverage.getAverage(); }
|
||||||
Q_INVOKABLE float getFastFPSAverage() const { return _fastFPSAverage.getAverage(); }
|
//Q_INVOKABLE float getFastFPSAverage() const { return _fastFPSAverage.getAverage(); }
|
||||||
|
|
||||||
Q_INVOKABLE float getLODDecreaseFPS();
|
Q_INVOKABLE float getLODDecreaseFPS();
|
||||||
Q_INVOKABLE float getLODIncreaseFPS();
|
Q_INVOKABLE float getLODIncreaseFPS();
|
||||||
|
@ -96,9 +105,13 @@ private:
|
||||||
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
||||||
int _boundaryLevelAdjust = 0;
|
int _boundaryLevelAdjust = 0;
|
||||||
|
|
||||||
quint64 _lastAdjust = 0;
|
quint64 _lastDownShift = 0;
|
||||||
SimpleMovingAverage _fpsAverage = FIVE_SECONDS_OF_FRAMES;
|
quint64 _lastUpShift = 0;
|
||||||
SimpleMovingAverage _fastFPSAverage = ONE_SECOND_OF_FRAMES;
|
bool _lastAdjustWasUpShift = true; // start out as if we've just upshifted
|
||||||
|
|
||||||
|
SimpleMovingAverage _fpsAverageStartWindow = START_DELAY_SAMPLES_OF_FRAMES;
|
||||||
|
SimpleMovingAverage _fpsAverageDownWindow = DOWN_SHIFT_SAMPLES_OF_FRAMES;
|
||||||
|
SimpleMovingAverage _fpsAverageUpWindow = UP_SHIFT_SAMPLES_OF_FRAMES;
|
||||||
|
|
||||||
bool _shouldRenderTableNeedsRebuilding = true;
|
bool _shouldRenderTableNeedsRebuilding = true;
|
||||||
QMap<float, float> _shouldRenderTable;
|
QMap<float, float> _shouldRenderTable;
|
||||||
|
|
Loading…
Reference in a new issue