mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-08 07:02:25 +02:00
clening up the code in LODmanager and the associated js/qml
This commit is contained in:
parent
8179de35b0
commit
194903692e
6 changed files with 317 additions and 411 deletions
|
@ -19,27 +19,15 @@
|
|||
#include "ui/DialogsManager.h"
|
||||
#include "InterfaceLogging.h"
|
||||
|
||||
const float LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS = LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS;
|
||||
const float LODManager::DEFAULT_HMD_LOD_DOWN_FPS = LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS;
|
||||
|
||||
Setting::Handle<float> desktopLODDecreaseFPS("desktopLODDecreaseFPS", DEFAULT_DESKTOP_LOD_DOWN_FPS);
|
||||
Setting::Handle<float> hmdLODDecreaseFPS("hmdLODDecreaseFPS", DEFAULT_HMD_LOD_DOWN_FPS);
|
||||
Setting::Handle<float> desktopLODDecreaseFPS("desktopLODDecreaseFPS", LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS);
|
||||
Setting::Handle<float> hmdLODDecreaseFPS("hmdLODDecreaseFPS", LODManager::DEFAULT_HMD_LOD_DOWN_FPS);
|
||||
|
||||
LODManager::LODManager() {
|
||||
}
|
||||
|
||||
float LODManager::getLODDecreaseFPS() const {
|
||||
if (qApp->isHMDMode()) {
|
||||
return getHMDLODDecreaseFPS();
|
||||
}
|
||||
return getDesktopLODDecreaseFPS();
|
||||
}
|
||||
|
||||
float LODManager::getLODIncreaseFPS() const {
|
||||
if (qApp->isHMDMode()) {
|
||||
return getHMDLODIncreaseFPS();
|
||||
}
|
||||
return getDesktopLODIncreaseFPS();
|
||||
}
|
||||
|
||||
// We use a "time-weighted running average" of the maxRenderTime and compare it against min/max thresholds
|
||||
// to determine if we should adjust the level of detail (LOD).
|
||||
//
|
||||
|
@ -55,8 +43,12 @@ const float LOD_ADJUST_RUNNING_AVG_TIMESCALE = 0.08f; // sec
|
|||
// multiples of the running average timescale:
|
||||
const uint64_t LOD_AUTO_ADJUST_PERIOD = 4 * (uint64_t)(LOD_ADJUST_RUNNING_AVG_TIMESCALE * (float)USECS_PER_MSEC); // usec
|
||||
|
||||
const float LOD_AUTO_ADJUST_DECREMENT_FACTOR = 0.8f;
|
||||
const float LOD_AUTO_ADJUST_INCREMENT_FACTOR = 1.2f;
|
||||
// batchTIme is always contained in presentTime.
|
||||
// We favor using batchTime instead of presentTime as a representative value for rendering duration (on present thread)
|
||||
// if batchTime + cushionTime < presentTime.
|
||||
// since we are shooting for fps around 60, 90Hz, the ideal frames are around 10ms
|
||||
// so we are picking a cushion time of 3ms
|
||||
const float LOD_BATCH_TO_PRESENT_CUSHION_TIME = 10.0f; // msec
|
||||
|
||||
void LODManager::setRenderTimes(float presentTime, float engineRunTime, float batchTime, float gpuTime) {
|
||||
_presentTime = presentTime;
|
||||
|
@ -66,6 +58,7 @@ void LODManager::setRenderTimes(float presentTime, float engineRunTime, float ba
|
|||
}
|
||||
|
||||
void LODManager::autoAdjustLOD(float realTimeDelta) {
|
||||
|
||||
// The "render time" is the worse of:
|
||||
// - engineRunTime: Time spent in the render thread in the engine producing the gpu::Frame N
|
||||
// - batchTime: Time spent in the present thread processing the batches of gpu::Frame N+1
|
||||
|
@ -73,50 +66,42 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
// - gpuTime: Time spent in the GPU executing the gpu::Frame N + 2
|
||||
|
||||
// But Present time is in reality synched with the monitor/display refresh rate, it s always longer than batchTime.
|
||||
// So if batchTime is fast enough relative to PResent Time we are using it, otherwise we are using presentTime. got it ?
|
||||
auto presentTime = (_presentTime - _batchTime > 3.0f ? _batchTime + 3.0f : _presentTime);
|
||||
// So if batchTime is fast enough relative to presentTime we are using it, otherwise we are using presentTime. got it ?
|
||||
auto presentTime = (_presentTime > _batchTime + LOD_BATCH_TO_PRESENT_CUSHION_TIME ? _batchTime + LOD_BATCH_TO_PRESENT_CUSHION_TIME : _presentTime);
|
||||
float maxRenderTime = glm::max(glm::max(presentTime, _engineRunTime), _gpuTime);
|
||||
|
||||
// compute time-weighted running average maxRenderTime
|
||||
// Note: we MUST clamp the blend to 1.0 for stability
|
||||
float blend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE) ? realTimeDelta / LOD_ADJUST_RUNNING_AVG_TIMESCALE : 1.0f;
|
||||
_avgRenderTime = (1.0f - blend) * _avgRenderTime + blend * maxRenderTime; // msec
|
||||
float nowBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE) ? realTimeDelta / LOD_ADJUST_RUNNING_AVG_TIMESCALE : 1.0f;
|
||||
_nowRenderTime = (1.0f - nowBlend) * _nowRenderTime + nowBlend * maxRenderTime; // msec
|
||||
|
||||
float smoothBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) ? realTimeDelta / (LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) : 1.0f;
|
||||
_smoothRenderTime = (1.0f - smoothBlend) * _smoothRenderTime + smoothBlend * maxRenderTime; // msec
|
||||
|
||||
|
||||
// _avgRenderTime = maxRenderTime;
|
||||
if (!_automaticLODAdjust || _avgRenderTime == 0.0f) {
|
||||
if (!_automaticLODAdjust || _nowRenderTime == 0.0f) {
|
||||
// early exit
|
||||
return;
|
||||
}
|
||||
|
||||
float oldOctreeSizeScale = _octreeSizeScale;
|
||||
float oldSolidAngle = getLODAngleDeg();
|
||||
// Previous values for output
|
||||
float oldOctreeSizeScale = getOctreeSizeScale();
|
||||
float oldLODAngle = getLODAngleDeg();
|
||||
|
||||
float targetFPS = 0.5 * (getLODDecreaseFPS() + getLODIncreaseFPS());
|
||||
float targetPeriod = 1.0f / targetFPS;
|
||||
|
||||
float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime;
|
||||
// Target fps and current fps based on latest measurments
|
||||
float targetFPS = getLODTargetFPS();
|
||||
float currentNowFPS = (float)MSECS_PER_SECOND / _nowRenderTime;
|
||||
float currentSmoothFPS = (float)MSECS_PER_SECOND / _smoothRenderTime;
|
||||
|
||||
// Compute the Variance of the FPS signal (FPS - smouthFPS)^2
|
||||
// Also scale it by a percentage for fine tuning (default is 100%)
|
||||
float currentVarianceFPS = (currentSmoothFPS - currentFPS);
|
||||
float currentVarianceFPS = (currentSmoothFPS - currentNowFPS);
|
||||
currentVarianceFPS *= currentVarianceFPS;
|
||||
currentVarianceFPS *= _pidCoefs.w;
|
||||
|
||||
auto dt = realTimeDelta;
|
||||
|
||||
auto previous_error = _pidHistory.x;
|
||||
auto previous_integral = _pidHistory.y;
|
||||
|
||||
auto smoothError = (targetFPS - currentSmoothFPS);
|
||||
|
||||
auto fpsError = smoothError;
|
||||
|
||||
auto errorSquare = smoothError * smoothError;
|
||||
// evaluate current error between the current smoothFPS and target FPS
|
||||
// and the sqaure of the error to compare against the Variance
|
||||
auto currentErrorFPS = (targetFPS - currentSmoothFPS);
|
||||
auto currentErrorFPSSquare = currentErrorFPS * currentErrorFPS;
|
||||
|
||||
// Define a noiseCoef that is trying to adjust the error to the FPS target value based on its strength
|
||||
// relative to the current Variance of the FPS signal.
|
||||
|
@ -124,41 +109,48 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
// if its within 2x the variance scale the control
|
||||
// and full control if error is bigger than 2x variance
|
||||
auto noiseCoef = 1.0f;
|
||||
if (errorSquare < currentVarianceFPS) {
|
||||
if (currentErrorFPSSquare < currentVarianceFPS) {
|
||||
noiseCoef = 0.0f;
|
||||
} else if (errorSquare < 2.0f * currentVarianceFPS) {
|
||||
noiseCoef = (errorSquare - currentVarianceFPS) / currentVarianceFPS;
|
||||
} else if (currentErrorFPSSquare < 2.0f * currentVarianceFPS) {
|
||||
noiseCoef = (currentErrorFPSSquare - currentVarianceFPS) / currentVarianceFPS;
|
||||
}
|
||||
|
||||
// The final normalized error is the the error to the FPS target, weighted by the noiseCoef, then normailzed by the target FPS.
|
||||
// it s also clamped in the [-1, 1] range
|
||||
auto error = noiseCoef * smoothError / targetFPS;
|
||||
auto error = noiseCoef * currentErrorFPS / targetFPS;
|
||||
error = glm::clamp(error, -1.0f, 1.0f);
|
||||
|
||||
// Now we are getting into the P.I.D. controler code
|
||||
// retreive the history of pid error and integral
|
||||
auto previous_error = _pidHistory.x;
|
||||
auto previous_integral = _pidHistory.y;
|
||||
|
||||
// The dt used for temporal values of the controller is the current realTimedelta
|
||||
// clamped to a reasonable granularity to make sure we are not over reacting
|
||||
auto dt = std::min(realTimeDelta, LOD_ADJUST_RUNNING_AVG_TIMESCALE);
|
||||
|
||||
// Compute the current integral and clamp to avoid accumulation
|
||||
auto integral = previous_integral + error * dt;
|
||||
glm::clamp(integral, -1.0f, 1.0f);
|
||||
|
||||
// Compute derivative
|
||||
auto derivative = (error - previous_error) / dt;
|
||||
|
||||
// remember history
|
||||
_pidHistory.x = error;
|
||||
_pidHistory.y = integral;
|
||||
_pidHistory.z = derivative;
|
||||
|
||||
auto Kp = _pidCoefs.x;
|
||||
auto Ki = _pidCoefs.y;
|
||||
auto Kd = _pidCoefs.z;
|
||||
|
||||
_pidOutputs.x = Kp * error;
|
||||
_pidOutputs.y = Ki * integral;
|
||||
_pidOutputs.z = Kd * derivative;
|
||||
// Compute the output of the PID and record intermediate results for tuning
|
||||
_pidOutputs.x = _pidCoefs.x * error; // Kp * error
|
||||
_pidOutputs.y = _pidCoefs.y * integral; // Ki * integral
|
||||
_pidOutputs.z = _pidCoefs.z * derivative; // Kd * derivative
|
||||
|
||||
auto output = _pidOutputs.x + _pidOutputs.y + _pidOutputs.z;
|
||||
|
||||
_pidOutputs.w = output;
|
||||
|
||||
auto newSolidAngle = oldSolidAngle + output;
|
||||
|
||||
setLODAngleDeg(newSolidAngle);
|
||||
// And now add the output of the controller to the LODAngle where we will guarantee it is in the proper range
|
||||
setLODAngleDeg(oldLODAngle + output);
|
||||
|
||||
if (oldOctreeSizeScale != _octreeSizeScale) {
|
||||
auto lodToolsDialog = DependencyManager::get<DialogsManager>()->getLodToolsDialog();
|
||||
|
@ -168,207 +160,6 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
}
|
||||
}
|
||||
|
||||
void LODManager::resetLODAdjust() {
|
||||
_decreaseFPSExpiry = _increaseFPSExpiry = usecTimestampNow() + LOD_AUTO_ADJUST_PERIOD;
|
||||
}
|
||||
|
||||
void LODManager::setAutomaticLODAdjust(bool value) {
|
||||
_automaticLODAdjust = value;
|
||||
emit autoLODChanged();
|
||||
}
|
||||
|
||||
float LODManager::getLODLevel() const {
|
||||
// simpleLOD is a linearized and normalized number that represents how much LOD is being applied.
|
||||
// It ranges from:
|
||||
// 1.0 = normal (max) level of detail
|
||||
// 0.0 = min level of detail
|
||||
// In other words: as LOD "drops" the value of simpleLOD will also "drop", and it cannot go lower than 0.0.
|
||||
const float LOG_MIN_LOD_RATIO = logf(ADJUST_LOD_MIN_SIZE_SCALE / ADJUST_LOD_MAX_SIZE_SCALE);
|
||||
float power = logf(_octreeSizeScale / ADJUST_LOD_MAX_SIZE_SCALE);
|
||||
float simpleLOD = (LOG_MIN_LOD_RATIO - power) / LOG_MIN_LOD_RATIO;
|
||||
return simpleLOD;
|
||||
}
|
||||
|
||||
void LODManager::setLODLevel(float level) {
|
||||
float simpleLOD = level;
|
||||
if (!_automaticLODAdjust) {
|
||||
const float LOG_MIN_LOD_RATIO = logf(ADJUST_LOD_MIN_SIZE_SCALE / ADJUST_LOD_MAX_SIZE_SCALE);
|
||||
|
||||
float power = LOG_MIN_LOD_RATIO - (simpleLOD * LOG_MIN_LOD_RATIO);
|
||||
float sizeScale = expf(power) * ADJUST_LOD_MAX_SIZE_SCALE;
|
||||
setOctreeSizeScale(sizeScale);
|
||||
}
|
||||
}
|
||||
|
||||
const float MIN_DECREASE_FPS = 0.5f;
|
||||
|
||||
void LODManager::setDesktopLODDecreaseFPS(float fps) {
|
||||
if (fps < MIN_DECREASE_FPS) {
|
||||
// avoid divide by zero
|
||||
fps = MIN_DECREASE_FPS;
|
||||
}
|
||||
_desktopMaxRenderTime = (float)MSECS_PER_SECOND / fps;
|
||||
}
|
||||
|
||||
float LODManager::getDesktopLODDecreaseFPS() const {
|
||||
return (float)MSECS_PER_SECOND / _desktopMaxRenderTime;
|
||||
}
|
||||
|
||||
float LODManager::getDesktopLODIncreaseFPS() const {
|
||||
return glm::min(((float)MSECS_PER_SECOND / _desktopMaxRenderTime) + INCREASE_LOD_GAP_FPS, MAX_LIKELY_DESKTOP_FPS);
|
||||
}
|
||||
|
||||
void LODManager::setHMDLODDecreaseFPS(float fps) {
|
||||
if (fps < MIN_DECREASE_FPS) {
|
||||
// avoid divide by zero
|
||||
fps = MIN_DECREASE_FPS;
|
||||
}
|
||||
_hmdMaxRenderTime = (float)MSECS_PER_SECOND / fps;
|
||||
}
|
||||
|
||||
float LODManager::getHMDLODDecreaseFPS() const {
|
||||
return (float)MSECS_PER_SECOND / _hmdMaxRenderTime;
|
||||
}
|
||||
|
||||
float LODManager::getHMDLODIncreaseFPS() const {
|
||||
return glm::min(((float)MSECS_PER_SECOND / _hmdMaxRenderTime) + INCREASE_LOD_GAP_FPS, MAX_LIKELY_HMD_FPS);
|
||||
}
|
||||
|
||||
QString LODManager::getLODFeedbackText() {
|
||||
// determine granularity feedback
|
||||
int boundaryLevelAdjust = getBoundaryLevelAdjust();
|
||||
QString granularityFeedback;
|
||||
switch (boundaryLevelAdjust) {
|
||||
case 0: {
|
||||
granularityFeedback = QString(".");
|
||||
} break;
|
||||
case 1: {
|
||||
granularityFeedback = QString(" at half of standard granularity.");
|
||||
} break;
|
||||
case 2: {
|
||||
granularityFeedback = QString(" at a third of standard granularity.");
|
||||
} break;
|
||||
default: {
|
||||
granularityFeedback = QString(" at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1);
|
||||
} break;
|
||||
}
|
||||
// distance feedback
|
||||
float octreeSizeScale = getOctreeSizeScale();
|
||||
float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE;
|
||||
int relativeToTwentyTwenty = 20 / relativeToDefault;
|
||||
|
||||
QString result;
|
||||
if (relativeToDefault > 1.01f) {
|
||||
result = QString("20:%1 or %2 times further than average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault,0,'f',2).arg(granularityFeedback);
|
||||
} else if (relativeToDefault > 0.99f) {
|
||||
result = QString("20:20 or the default distance for average vision%1").arg(granularityFeedback);
|
||||
} else if (relativeToDefault > 0.01f) {
|
||||
result = QString("20:%1 or %2 of default distance for average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault,0,'f',3).arg(granularityFeedback);
|
||||
} else {
|
||||
result = QString("%2 of default distance for average vision%3").arg(relativeToDefault,0,'f',3).arg(granularityFeedback);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
||||
// FIXME - eventually we want to use the render accuracy as an indicator for the level of detail
|
||||
// to use in rendering.
|
||||
// float renderAccuracy = calculateRenderAccuracy(args->getViewFrustum().getPosition(), bounds, args->_sizeScale, args->_boundaryLevelAdjust);
|
||||
// return (renderAccuracy > 0.0f);
|
||||
|
||||
auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter();
|
||||
auto dim = bounds.getDimensions();
|
||||
auto halfTanSq = 0.25f * glm::dot(dim, dim) / glm::dot(pos, pos);
|
||||
return (halfTanSq >= args->_solidAngleHalfTanSq);
|
||||
|
||||
};
|
||||
|
||||
void LODManager::setOctreeSizeScale(float sizeScale) {
|
||||
_octreeSizeScale = sizeScale;
|
||||
}
|
||||
|
||||
void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
|
||||
_boundaryLevelAdjust = boundaryLevelAdjust;
|
||||
}
|
||||
|
||||
void LODManager::loadSettings() {
|
||||
setDesktopLODDecreaseFPS(desktopLODDecreaseFPS.get());
|
||||
setHMDLODDecreaseFPS(hmdLODDecreaseFPS.get());
|
||||
}
|
||||
|
||||
void LODManager::saveSettings() {
|
||||
desktopLODDecreaseFPS.set(getDesktopLODDecreaseFPS());
|
||||
hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS());
|
||||
}
|
||||
|
||||
|
||||
void LODManager::setSmoothScale(float t) {
|
||||
_smoothScale = glm::max(1.0f, t);
|
||||
}
|
||||
|
||||
void LODManager::setWorldDetailQuality(float quality) {
|
||||
|
||||
static const float MAX_DESKTOP_FPS = 60;
|
||||
static const float MAX_HMD_FPS = 90;
|
||||
static const float MIN_FPS = 10;
|
||||
static const float LOW = 0.25f;
|
||||
static const float MEDIUM = 0.5f;
|
||||
static const float HIGH = 0.75f;
|
||||
static const float THRASHING_DIFFERENCE = 10;
|
||||
|
||||
bool isLowestValue = quality == LOW;
|
||||
bool isHMDMode = qApp->isHMDMode();
|
||||
|
||||
float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS;
|
||||
float desiredFPS = maxFPS /* - THRASHING_DIFFERENCE*/;
|
||||
|
||||
if (!isLowestValue) {
|
||||
float calculatedFPS = (maxFPS - (maxFPS * quality))/* - THRASHING_DIFFERENCE*/;
|
||||
desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS;
|
||||
}
|
||||
|
||||
if (isHMDMode) {
|
||||
setHMDLODDecreaseFPS(desiredFPS);
|
||||
}
|
||||
else {
|
||||
setDesktopLODDecreaseFPS(desiredFPS);
|
||||
}
|
||||
|
||||
emit worldDetailQualityChanged();
|
||||
}
|
||||
|
||||
float LODManager::getWorldDetailQuality() const {
|
||||
|
||||
|
||||
static const float MAX_DESKTOP_FPS = 60;
|
||||
static const float MAX_HMD_FPS = 90;
|
||||
static const float MIN_FPS = 10;
|
||||
static const float LOW = 0.25f;
|
||||
static const float MEDIUM = 0.5f;
|
||||
static const float HIGH = 0.75f;
|
||||
|
||||
bool inHMD = qApp->isHMDMode();
|
||||
|
||||
float increaseFPS = 0;
|
||||
if (inHMD) {
|
||||
increaseFPS = getHMDLODDecreaseFPS();
|
||||
} else {
|
||||
increaseFPS = getDesktopLODDecreaseFPS();
|
||||
}
|
||||
float maxFPS = inHMD ? MAX_HMD_FPS : MAX_DESKTOP_FPS;
|
||||
float percentage = 1.0 - increaseFPS / maxFPS;
|
||||
|
||||
if (percentage <= LOW) {
|
||||
return LOW;
|
||||
}
|
||||
else if (percentage <= MEDIUM) {
|
||||
return MEDIUM;
|
||||
}
|
||||
|
||||
return HIGH;
|
||||
}
|
||||
|
||||
|
||||
float LODManager::getLODAngleHalfTan() const {
|
||||
return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust);
|
||||
}
|
||||
|
@ -386,6 +177,10 @@ void LODManager::setLODAngleDeg(float lodAngle) {
|
|||
setOctreeSizeScale(octreeSizeScale);
|
||||
}
|
||||
|
||||
void LODManager::setSmoothScale(float t) {
|
||||
_smoothScale = glm::max(1.0f, t);
|
||||
}
|
||||
|
||||
float LODManager::getPidKp() const {
|
||||
return _pidCoefs.x;
|
||||
}
|
||||
|
@ -422,4 +217,189 @@ float LODManager::getPidOd() const {
|
|||
}
|
||||
float LODManager::getPidO() const {
|
||||
return _pidOutputs.w;
|
||||
}
|
||||
}
|
||||
|
||||
void LODManager::resetLODAdjust() {
|
||||
// _decreaseFPSExpiry = _increaseFPSExpiry = usecTimestampNow() + LOD_AUTO_ADJUST_PERIOD;
|
||||
}
|
||||
|
||||
void LODManager::setAutomaticLODAdjust(bool value) {
|
||||
_automaticLODAdjust = value;
|
||||
emit autoLODChanged();
|
||||
}
|
||||
|
||||
bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
||||
// To decide if the bound should be rendered or not at the specified Args->lodAngle,
|
||||
// we need to compute the apparent angle of the bound from the frustum origin,
|
||||
// and compare it against the lodAngle, if it is greater or equal we should render the content of that bound.
|
||||
// we abstract the bound as a sphere centered on the bound center and of radius half diagonal of the bound.
|
||||
|
||||
// Instead of comparing angles, we are comparing the tangent of the half angle which are more efficient to compute:
|
||||
// we are comparing the square of the half tangent apparent angle for the bound against the LODAngle Half tangent square
|
||||
// if smaller, the bound is too small and we should NOT render it, return true otherwise.
|
||||
|
||||
// Tangent Adjacent side is eye to bound center vector length
|
||||
auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter();
|
||||
auto halfTanAdjacentSq = glm::dot(pos, pos);
|
||||
|
||||
// Tangent Opposite side is the half length of the dimensions vector of the bound
|
||||
auto dim = bounds.getDimensions();
|
||||
auto halfTanOppositeSq = 0.25f * glm::dot(dim, dim);
|
||||
|
||||
// The test is:
|
||||
// isVisible = halfTanSq >= lodHalfTanSq = (halfTanOppositeSq / halfTanAdjacentSq) >= lodHalfTanSq
|
||||
// which we express as below to avoid division
|
||||
// (halfTanOppositeSq) >= lodHalfTanSq * halfTanAdjacentSq
|
||||
return (halfTanOppositeSq >= args->_lodAngleHalfTanSq * halfTanAdjacentSq);
|
||||
};
|
||||
|
||||
void LODManager::setOctreeSizeScale(float sizeScale) {
|
||||
_octreeSizeScale = sizeScale;
|
||||
}
|
||||
|
||||
void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
|
||||
_boundaryLevelAdjust = boundaryLevelAdjust;
|
||||
}
|
||||
|
||||
QString LODManager::getLODFeedbackText() {
|
||||
// determine granularity feedback
|
||||
int boundaryLevelAdjust = getBoundaryLevelAdjust();
|
||||
QString granularityFeedback;
|
||||
switch (boundaryLevelAdjust) {
|
||||
case 0: {
|
||||
granularityFeedback = QString(".");
|
||||
} break;
|
||||
case 1: {
|
||||
granularityFeedback = QString(" at half of standard granularity.");
|
||||
} break;
|
||||
case 2: {
|
||||
granularityFeedback = QString(" at a third of standard granularity.");
|
||||
} break;
|
||||
default: {
|
||||
granularityFeedback = QString(" at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1);
|
||||
} break;
|
||||
}
|
||||
// distance feedback
|
||||
float octreeSizeScale = getOctreeSizeScale();
|
||||
float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE;
|
||||
int relativeToTwentyTwenty = 20 / relativeToDefault;
|
||||
|
||||
QString result;
|
||||
if (relativeToDefault > 1.01f) {
|
||||
result = QString("20:%1 or %2 times further than average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault, 0, 'f', 2).arg(granularityFeedback);
|
||||
}
|
||||
else if (relativeToDefault > 0.99f) {
|
||||
result = QString("20:20 or the default distance for average vision%1").arg(granularityFeedback);
|
||||
}
|
||||
else if (relativeToDefault > 0.01f) {
|
||||
result = QString("20:%1 or %2 of default distance for average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault, 0, 'f', 3).arg(granularityFeedback);
|
||||
}
|
||||
else {
|
||||
result = QString("%2 of default distance for average vision%3").arg(relativeToDefault, 0, 'f', 3).arg(granularityFeedback);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LODManager::loadSettings() {
|
||||
setDesktopLODTargetFPS(desktopLODDecreaseFPS.get());
|
||||
setHMDLODTargetFPS(hmdLODDecreaseFPS.get());
|
||||
}
|
||||
|
||||
void LODManager::saveSettings() {
|
||||
desktopLODDecreaseFPS.set(getDesktopLODTargetFPS());
|
||||
hmdLODDecreaseFPS.set(getHMDLODTargetFPS());
|
||||
}
|
||||
|
||||
const float MIN_DECREASE_FPS = 0.5f;
|
||||
|
||||
void LODManager::setDesktopLODTargetFPS(float fps) {
|
||||
if (fps < MIN_DECREASE_FPS) {
|
||||
// avoid divide by zero
|
||||
fps = MIN_DECREASE_FPS;
|
||||
}
|
||||
_desktopTargetFPS = fps;
|
||||
}
|
||||
|
||||
float LODManager::getDesktopLODTargetFPS() const {
|
||||
return _desktopTargetFPS;
|
||||
}
|
||||
|
||||
void LODManager::setHMDLODTargetFPS(float fps) {
|
||||
if (fps < MIN_DECREASE_FPS) {
|
||||
// avoid divide by zero
|
||||
fps = MIN_DECREASE_FPS;
|
||||
}
|
||||
_hmdTargetFPS = fps;
|
||||
}
|
||||
|
||||
float LODManager::getHMDLODTargetFPS() const {
|
||||
return _hmdTargetFPS;
|
||||
}
|
||||
|
||||
float LODManager::getLODTargetFPS() const {
|
||||
if (qApp->isHMDMode()) {
|
||||
return getHMDLODTargetFPS();
|
||||
}
|
||||
return getDesktopLODTargetFPS();
|
||||
}
|
||||
|
||||
void LODManager::setWorldDetailQuality(float quality) {
|
||||
static const float MIN_FPS = 10;
|
||||
static const float LOW = 0.25f;
|
||||
|
||||
bool isLowestValue = quality == LOW;
|
||||
bool isHMDMode = qApp->isHMDMode();
|
||||
|
||||
float maxFPS = isHMDMode ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS;
|
||||
float desiredFPS = maxFPS;
|
||||
|
||||
if (!isLowestValue) {
|
||||
float calculatedFPS = (maxFPS - (maxFPS * quality));
|
||||
desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS;
|
||||
}
|
||||
|
||||
if (isHMDMode) {
|
||||
setHMDLODTargetFPS(desiredFPS);
|
||||
}
|
||||
else {
|
||||
setDesktopLODTargetFPS(desiredFPS);
|
||||
}
|
||||
|
||||
emit worldDetailQualityChanged();
|
||||
}
|
||||
|
||||
float LODManager::getWorldDetailQuality() const {
|
||||
|
||||
static const float LOW = 0.25f;
|
||||
static const float MEDIUM = 0.5f;
|
||||
static const float HIGH = 0.75f;
|
||||
|
||||
bool inHMD = qApp->isHMDMode();
|
||||
|
||||
float targetFPS = 0;
|
||||
if (inHMD) {
|
||||
targetFPS = getHMDLODTargetFPS();
|
||||
} else {
|
||||
targetFPS = getDesktopLODTargetFPS();
|
||||
}
|
||||
float maxFPS = inHMD ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS;
|
||||
float percentage = 1.0 - targetFPS / maxFPS;
|
||||
|
||||
if (percentage <= LOW) {
|
||||
return LOW;
|
||||
}
|
||||
else if (percentage <= MEDIUM) {
|
||||
return MEDIUM;
|
||||
}
|
||||
|
||||
return HIGH;
|
||||
}
|
||||
|
||||
|
||||
void LODManager::setLODQualityLevel(float quality) {
|
||||
_lodQualityLevel;
|
||||
}
|
||||
|
||||
float LODManager::getLODQualityLevel() const {
|
||||
return _lodQualityLevel;
|
||||
}
|
||||
|
|
|
@ -19,20 +19,11 @@
|
|||
#include <SimpleMovingAverage.h>
|
||||
#include <render/Args.h>
|
||||
|
||||
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0f;
|
||||
const float DEFAULT_HMD_LOD_DOWN_FPS = 34.0f;
|
||||
const float DEFAULT_DESKTOP_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_DESKTOP_LOD_DOWN_FPS; // msec
|
||||
const float DEFAULT_HMD_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_HMD_LOD_DOWN_FPS; // msec
|
||||
const float MAX_LIKELY_DESKTOP_FPS = 61.0f; // this is essentially, V-synch - 1 fps
|
||||
const float MAX_LIKELY_HMD_FPS = 91.0f; // this is essentially, V-synch - 1 fps
|
||||
const float INCREASE_LOD_GAP_FPS = 10.0f; // fps
|
||||
|
||||
// The default value DEFAULT_OCTREE_SIZE_SCALE means you can be 400 meters away from a 1 meter object in order to see it (which is ~20:20 vision).
|
||||
const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
|
||||
// This controls how low the auto-adjust LOD will go. We want a minimum vision of ~20:500 or 0.04 of default
|
||||
// const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.04f;
|
||||
// const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.02f;
|
||||
const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.01f;
|
||||
const float LOD_DEFAULT_QUALITY_LEVEL = 0.5f; // default quality level setting is Mid
|
||||
const float LOD_MAX_LIKELY_DESKTOP_FPS = 60.0f; // this is essentially, V-synch fps
|
||||
const float LOD_MAX_LIKELY_HMD_FPS = 90.0f; // this is essentially, V-synch fps
|
||||
const float LOD_OFFSET_FPS = 5.0f; // offset of FPS to add for computing the target framerate
|
||||
|
||||
class AABox;
|
||||
|
||||
|
@ -55,41 +46,42 @@ class AABox;
|
|||
|
||||
class LODManager : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
Q_PROPERTY(float presentTime READ getPresentTime)
|
||||
Q_PROPERTY(float engineRunTime READ getEngineRunTime)
|
||||
Q_PROPERTY(float batchTime READ getBatchTime)
|
||||
Q_PROPERTY(float gpuTime READ getGPUTime)
|
||||
Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged)
|
||||
|
||||
Q_PROPERTY(float avgRenderTime READ getAverageRenderTime)
|
||||
Q_PROPERTY(float fps READ getMaxTheoreticalFPS)
|
||||
Q_PROPERTY(float lodQualityLevel READ getLODQualityLevel WRITE setLODQualityLevel NOTIFY lodQualityLevelChanged)
|
||||
|
||||
Q_PROPERTY(float smoothRenderTime READ getSmoothRenderTime)
|
||||
Q_PROPERTY(float smoothFPS READ getSmoothFPS)
|
||||
Q_PROPERTY(float smoothScale READ getSmoothScale WRITE setSmoothScale)
|
||||
Q_PROPERTY(bool automaticLODAdjust READ getAutomaticLODAdjust WRITE setAutomaticLODAdjust NOTIFY autoLODChanged)
|
||||
|
||||
Q_PROPERTY(float lodLevel READ getLODLevel WRITE setLODLevel NOTIFY LODChanged)
|
||||
Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS)
|
||||
Q_PROPERTY(float lodIncreaseFPS READ getLODIncreaseFPS)
|
||||
Q_PROPERTY(bool automaticLODAdjust READ getAutomaticLODAdjust WRITE setAutomaticLODAdjust NOTIFY autoLODChanged)
|
||||
Q_PROPERTY(float presentTime READ getPresentTime)
|
||||
Q_PROPERTY(float engineRunTime READ getEngineRunTime)
|
||||
Q_PROPERTY(float batchTime READ getBatchTime)
|
||||
Q_PROPERTY(float gpuTime READ getGPUTime)
|
||||
|
||||
Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged)
|
||||
Q_PROPERTY(float nowRenderTime READ getNowRenderTime)
|
||||
Q_PROPERTY(float nowRenderFPS READ getNowRenderFPS)
|
||||
|
||||
Q_PROPERTY(float lodAngleDeg READ getLODAngleDeg WRITE setLODAngleDeg)
|
||||
Q_PROPERTY(float smoothScale READ getSmoothScale WRITE setSmoothScale)
|
||||
Q_PROPERTY(float smoothRenderTime READ getSmoothRenderTime)
|
||||
Q_PROPERTY(float smoothRenderFPS READ getSmoothRenderFPS)
|
||||
|
||||
Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp)
|
||||
Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi)
|
||||
Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd)
|
||||
Q_PROPERTY(float pidKv READ getPidKv WRITE setPidKv)
|
||||
Q_PROPERTY(float lodTargetFPS READ getLODTargetFPS)
|
||||
|
||||
Q_PROPERTY(float pidOp READ getPidOp)
|
||||
Q_PROPERTY(float pidOi READ getPidOi)
|
||||
Q_PROPERTY(float pidOd READ getPidOd)
|
||||
Q_PROPERTY(float pidO READ getPidO)
|
||||
Q_PROPERTY(float lodAngleDeg READ getLODAngleDeg WRITE setLODAngleDeg)
|
||||
|
||||
Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp)
|
||||
Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi)
|
||||
Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd)
|
||||
Q_PROPERTY(float pidKv READ getPidKv WRITE setPidKv)
|
||||
|
||||
Q_PROPERTY(float pidOp READ getPidOp)
|
||||
Q_PROPERTY(float pidOi READ getPidOi)
|
||||
Q_PROPERTY(float pidOd READ getPidOd)
|
||||
Q_PROPERTY(float pidO READ getPidO)
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.setAutomaticLODAdjust
|
||||
* @param {boolean} value
|
||||
|
@ -103,42 +95,31 @@ public:
|
|||
Q_INVOKABLE bool getAutomaticLODAdjust() const { return _automaticLODAdjust; }
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.setDesktopLODDecreaseFPS
|
||||
* @function LODManager.setDesktopLODTargetFPS
|
||||
* @param {number} value
|
||||
*/
|
||||
Q_INVOKABLE void setDesktopLODDecreaseFPS(float value);
|
||||
Q_INVOKABLE void setDesktopLODTargetFPS(float value);
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getDesktopLODDecreaseFPS
|
||||
* @function LODManager.getDesktopLODTargetFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE float getDesktopLODDecreaseFPS() const;
|
||||
Q_INVOKABLE float getDesktopLODTargetFPS() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getDesktopLODIncreaseFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
Q_INVOKABLE float getDesktopLODIncreaseFPS() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.setHMDLODDecreaseFPS
|
||||
* @function LODManager.setHMDLODTargetFPS
|
||||
* @param {number} value
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setHMDLODDecreaseFPS(float value);
|
||||
|
||||
Q_INVOKABLE void setHMDLODTargetFPS(float value);
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getHMDLODDecreaseFPS
|
||||
* @function LODManager.getHMDLODTargetFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
Q_INVOKABLE float getHMDLODDecreaseFPS() const;
|
||||
Q_INVOKABLE float getHMDLODTargetFPS() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getHMDLODIncreaseFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
Q_INVOKABLE float getHMDLODIncreaseFPS() const;
|
||||
|
||||
// User Tweakable LOD Items
|
||||
/**jsdoc
|
||||
|
@ -172,16 +153,11 @@ public:
|
|||
Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getLODDecreaseFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
Q_INVOKABLE float getLODDecreaseFPS() const;
|
||||
* @function LODManager.getLODTargetFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
Q_INVOKABLE float getLODTargetFPS() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getLODIncreaseFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
Q_INVOKABLE float getLODIncreaseFPS() const;
|
||||
|
||||
float getPresentTime() const { return _presentTime; }
|
||||
float getEngineRunTime() const { return _engineRunTime; }
|
||||
|
@ -196,22 +172,21 @@ public:
|
|||
void saveSettings();
|
||||
void resetLODAdjust();
|
||||
|
||||
float getNowRenderTime() const { return _nowRenderTime; };
|
||||
float getNowRenderFPS() const { return (float)MSECS_PER_SECOND / _nowRenderTime; };
|
||||
|
||||
void setSmoothScale(float t);
|
||||
float getSmoothScale() const { return _smoothScale; }
|
||||
|
||||
float getAverageRenderTime() const { return _avgRenderTime; };
|
||||
float getMaxTheoreticalFPS() const { return (float)MSECS_PER_SECOND / _avgRenderTime; };
|
||||
|
||||
float getSmoothRenderTime() const { return _smoothRenderTime; };
|
||||
float getSmoothFPS() const { return (float)MSECS_PER_SECOND / _smoothRenderTime; };
|
||||
|
||||
|
||||
float getLODLevel() const;
|
||||
void setLODLevel(float level);
|
||||
float getSmoothRenderFPS() const { return (float)MSECS_PER_SECOND / _smoothRenderTime; };
|
||||
|
||||
void setWorldDetailQuality(float quality);
|
||||
float getWorldDetailQuality() const;
|
||||
|
||||
void setLODQualityLevel(float quality);
|
||||
float getLODQualityLevel() const;
|
||||
|
||||
float getLODAngleDeg() const;
|
||||
void setLODAngleDeg(float lodAngle);
|
||||
float getLODAngleHalfTan() const;
|
||||
|
@ -225,12 +200,15 @@ public:
|
|||
void setPidKi(float k);
|
||||
void setPidKd(float k);
|
||||
void setPidKv(float t);
|
||||
|
||||
|
||||
float getPidOp() const;
|
||||
float getPidOi() const;
|
||||
float getPidOd() const;
|
||||
float getPidO() const;
|
||||
|
||||
static const float DEFAULT_DESKTOP_LOD_DOWN_FPS;
|
||||
static const float DEFAULT_HMD_LOD_DOWN_FPS;
|
||||
|
||||
signals:
|
||||
|
||||
/**jsdoc
|
||||
|
@ -245,24 +223,28 @@ signals:
|
|||
*/
|
||||
void LODDecreased();
|
||||
|
||||
void LODChanged();
|
||||
void autoLODChanged();
|
||||
void lodQualityLevelChanged();
|
||||
void worldDetailQualityChanged();
|
||||
|
||||
private:
|
||||
LODManager();
|
||||
|
||||
bool _automaticLODAdjust = true;
|
||||
float _presentTime { 0.0f }; // msec
|
||||
float _engineRunTime { 0.0f }; // msec
|
||||
float _batchTime{ 0.0f }; // msec
|
||||
float _gpuTime { 0.0f }; // msec
|
||||
|
||||
float _smoothScale{ 8.0f };
|
||||
float _avgRenderTime { 0.0f }; // msec
|
||||
float _smoothRenderTime{ 0.0f };
|
||||
float _desktopMaxRenderTime { DEFAULT_DESKTOP_MAX_RENDER_TIME };
|
||||
float _hmdMaxRenderTime { DEFAULT_HMD_MAX_RENDER_TIME };
|
||||
float _presentTime{ 0.0f }; // msec
|
||||
float _engineRunTime{ 0.0f }; // msec
|
||||
float _batchTime{ 0.0f }; // msec
|
||||
float _gpuTime{ 0.0f }; // msec
|
||||
|
||||
float _nowRenderTime{ 0.0f }; // msec
|
||||
float _smoothScale{ 10.0f }; // smooth is evaluated over 10 times longer than now
|
||||
float _smoothRenderTime{ 0.0f }; // msec
|
||||
|
||||
float _lodQualityLevel{ LOD_DEFAULT_QUALITY_LEVEL };
|
||||
|
||||
float _desktopTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS };
|
||||
float _hmdTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS };
|
||||
|
||||
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
||||
int _boundaryLevelAdjust = 0;
|
||||
|
@ -270,9 +252,6 @@ private:
|
|||
glm::vec4 _pidCoefs{ 1.0f, 0.0f, 0.0f, 1.0f }; // Kp, Ki, Kd, Kv
|
||||
glm::vec4 _pidHistory{ 0.0f };
|
||||
glm::vec4 _pidOutputs{ 0.0f };
|
||||
|
||||
uint64_t _decreaseFPSExpiry { 0 };
|
||||
uint64_t _increaseFPSExpiry { 0 };
|
||||
};
|
||||
|
||||
#endif // hifi_LODManager_h
|
||||
|
|
|
@ -55,54 +55,6 @@ void setupPreferences() {
|
|||
// Graphics quality
|
||||
static const QString GRAPHICS_QUALITY { "Graphics Quality" };
|
||||
{
|
||||
/* static const float MAX_DESKTOP_FPS = 60;
|
||||
static const float MAX_HMD_FPS = 90;
|
||||
static const float MIN_FPS = 10;
|
||||
static const float LOW = 0.25f;
|
||||
static const float MEDIUM = 0.5f;
|
||||
static const float HIGH = 0.75f;
|
||||
auto getter = []()->float {
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
bool inHMD = qApp->isHMDMode();
|
||||
|
||||
float increaseFPS = 0;
|
||||
if (inHMD) {
|
||||
increaseFPS = lodManager->getHMDLODDecreaseFPS();
|
||||
} else {
|
||||
increaseFPS = lodManager->getDesktopLODDecreaseFPS();
|
||||
}
|
||||
float maxFPS = inHMD ? MAX_HMD_FPS : MAX_DESKTOP_FPS;
|
||||
float percentage = increaseFPS / maxFPS;
|
||||
|
||||
if (percentage >= HIGH) {
|
||||
return LOW;
|
||||
} else if (percentage >= LOW) {
|
||||
return MEDIUM;
|
||||
}
|
||||
return HIGH;
|
||||
};
|
||||
|
||||
auto setter = [](float value) {
|
||||
static const float THRASHING_DIFFERENCE = 10;
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
|
||||
bool isLowestValue = value == LOW;
|
||||
bool isHMDMode = qApp->isHMDMode();
|
||||
|
||||
float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS;
|
||||
float desiredFPS = maxFPS - THRASHING_DIFFERENCE;
|
||||
|
||||
if (!isLowestValue) {
|
||||
float calculatedFPS = (maxFPS - (maxFPS * value)) - THRASHING_DIFFERENCE;
|
||||
desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS;
|
||||
}
|
||||
|
||||
if (isHMDMode) {
|
||||
lodManager->setHMDLODDecreaseFPS(desiredFPS);
|
||||
} else {
|
||||
lodManager->setDesktopLODDecreaseFPS(desiredFPS);
|
||||
}
|
||||
};*/
|
||||
auto getter = []()->float {
|
||||
return DependencyManager::get<LODManager>()->getWorldDetailQuality();
|
||||
};
|
||||
|
|
|
@ -73,16 +73,16 @@ namespace render {
|
|||
Args(const gpu::ContextPointer& context,
|
||||
float sizeScale = 1.0f,
|
||||
int boundaryLevelAdjust = 0,
|
||||
float solidAngleHalfTan = 0.1f,
|
||||
float lodAngleHalfTan = 0.1f,
|
||||
RenderMode renderMode = DEFAULT_RENDER_MODE,
|
||||
DisplayMode displayMode = MONO,
|
||||
DebugFlags debugFlags = RENDER_DEBUG_NONE,
|
||||
gpu::Batch* batch = nullptr) :
|
||||
_context(context),
|
||||
_sizeScale(sizeScale),
|
||||
_solidAngleHalfTan(solidAngleHalfTan),
|
||||
_solidAngleHalfTanSq(solidAngleHalfTan * solidAngleHalfTan),
|
||||
_boundaryLevelAdjust(boundaryLevelAdjust),
|
||||
_lodAngleHalfTan(lodAngleHalfTan),
|
||||
_lodAngleHalfTanSq(lodAngleHalfTan * lodAngleHalfTan),
|
||||
_renderMode(renderMode),
|
||||
_displayMode(displayMode),
|
||||
_debugFlags(debugFlags),
|
||||
|
@ -111,8 +111,8 @@ namespace render {
|
|||
|
||||
float _sizeScale { 1.0f };
|
||||
int _boundaryLevelAdjust { 0 };
|
||||
float _solidAngleHalfTan{ 0.1f };
|
||||
float _solidAngleHalfTanSq{ _solidAngleHalfTan * _solidAngleHalfTan };
|
||||
float _lodAngleHalfTan{ 0.1f };
|
||||
float _lodAngleHalfTanSq{ _lodAngleHalfTan * _lodAngleHalfTan };
|
||||
|
||||
RenderMode _renderMode { DEFAULT_RENDER_MODE };
|
||||
DisplayMode _displayMode { MONO };
|
||||
|
|
|
@ -155,7 +155,7 @@ void FetchSpatialTree::run(const RenderContextPointer& renderContext, const Inpu
|
|||
// Octree selection!
|
||||
float threshold = 0.0f;
|
||||
if (queryFrustum.isPerspective()) {
|
||||
threshold = getPerspectiveAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust);
|
||||
threshold = args->_lodAngleHalfTan;
|
||||
if (frustumResolution.y > 0) {
|
||||
threshold = glm::max(queryFrustum.getFieldOfView() / frustumResolution.y, threshold);
|
||||
}
|
||||
|
|
|
@ -217,24 +217,19 @@ Item {
|
|||
valueUnit: "Hz"
|
||||
plots: [
|
||||
{
|
||||
prop: "lodIncreaseFPS",
|
||||
label: "LOD++",
|
||||
prop: "lodTargetFPS",
|
||||
label: "target",
|
||||
color: "#66FF66"
|
||||
},
|
||||
{
|
||||
prop: "fps",
|
||||
prop: "nowRenderFPS",
|
||||
label: "FPS",
|
||||
color: "#FFFF55"
|
||||
},
|
||||
{
|
||||
prop: "smoothFPS",
|
||||
prop: "smoothRenderFPS",
|
||||
label: "Smooth FPS",
|
||||
color: "#9999FF"
|
||||
},
|
||||
{
|
||||
prop: "lodDecreaseFPS",
|
||||
label: "LOD--",
|
||||
color: "#FF6666"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue