mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-07 03:32:42 +02:00
Merge pull request #663 from overte-org/feature/new_LOD
Added distance-based LOD
This commit is contained in:
commit
b6f148576a
8 changed files with 127 additions and 22 deletions
|
@ -144,7 +144,7 @@ Flickable {
|
|||
|
||||
HifiStylesUit.RalewayRegular {
|
||||
id: worldDetailHeader
|
||||
text: "World Detail"
|
||||
text: "Target frame rate"
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
width: 130
|
||||
|
@ -157,13 +157,13 @@ Flickable {
|
|||
id: worldDetailModel
|
||||
|
||||
ListElement {
|
||||
text: "Low World Detail"
|
||||
text: "High Frame Rate/Low Detail"
|
||||
}
|
||||
ListElement {
|
||||
text: "Medium World Detail"
|
||||
text: "Medium Frame Rate/Medium Detail"
|
||||
}
|
||||
ListElement {
|
||||
text: "Full World Detail"
|
||||
text: "Low Frame Rate/High Detail"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6829,7 +6829,8 @@ void Application::updateRenderArgs(float deltaTime) {
|
|||
_viewFrustum.calculate();
|
||||
}
|
||||
appRenderArgs._renderArgs = RenderArgs(_graphicsEngine.getGPUContext(), lodManager->getVisibilityDistance(),
|
||||
lodManager->getBoundaryLevelAdjust(), lodManager->getLODHalfAngleTan(), RenderArgs::DEFAULT_RENDER_MODE,
|
||||
lodManager->getBoundaryLevelAdjust(), lodManager->getLODFarHalfAngleTan(), lodManager->getLODNearHalfAngleTan(),
|
||||
lodManager->getLODFarDistance(), lodManager->getLODNearDistance(), RenderArgs::DEFAULT_RENDER_MODE,
|
||||
RenderArgs::MONO, RenderArgs::DEFERRED, RenderArgs::RENDER_DEBUG_NONE);
|
||||
appRenderArgs._renderArgs._scene = getMain3DScene();
|
||||
|
||||
|
|
|
@ -172,7 +172,8 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
_pidOutputs.w = output;
|
||||
|
||||
// And now add the output of the controller to the LODAngle where we will guarantee it is in the proper range
|
||||
setLODAngleDeg(oldLODAngle + output);
|
||||
float newLODAngle = std::min(oldLODAngle + output, glm::degrees(_farMaxAngle));
|
||||
setLODAngleDeg(newLODAngle);
|
||||
|
||||
if (oldLODAngle != getLODAngleDeg()) {
|
||||
auto lodToolsDialog = DependencyManager::get<DialogsManager>()->getLodToolsDialog();
|
||||
|
@ -185,6 +186,16 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
float LODManager::getLODHalfAngleTan() const {
|
||||
return tan(_lodHalfAngle);
|
||||
}
|
||||
float LODManager::getLODFarHalfAngleTan() const {
|
||||
return tan(std::min(_lodHalfAngle, _farMaxAngle / 2.0f));
|
||||
}
|
||||
float LODManager::getLODNearHalfAngleTan() const {
|
||||
if (_farMaxAngle > 0) {
|
||||
return tan(std::min(_lodHalfAngle / (_farMaxAngle / 2.0f) * (_nearMaxAngle / 2.0f), _nearMaxAngle / 2.0f));
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
float LODManager::getLODAngle() const {
|
||||
return 2.0f * _lodHalfAngle;
|
||||
}
|
||||
|
@ -192,6 +203,37 @@ float LODManager::getLODAngleDeg() const {
|
|||
return glm::degrees(getLODAngle());
|
||||
}
|
||||
|
||||
void LODManager::setLODFarDistance(float value) {
|
||||
_farDistance = value;
|
||||
updateLODAfterSettingsChange();
|
||||
}
|
||||
|
||||
void LODManager::setLODNearDistance(float value) {
|
||||
_nearDistance = value;
|
||||
updateLODAfterSettingsChange();
|
||||
}
|
||||
|
||||
void LODManager::setLODFarMaxAngleDeg(float value) {
|
||||
_farMaxAngle = glm::radians(value);
|
||||
updateLODAfterSettingsChange();
|
||||
}
|
||||
|
||||
float LODManager::getLODFarMaxAngleDeg() const {
|
||||
return glm::degrees(_farMaxAngle);
|
||||
}
|
||||
|
||||
void LODManager::setLODNearMaxAngle(float value) {
|
||||
_nearMaxAngle = glm::radians(value);
|
||||
updateLODAfterSettingsChange();
|
||||
}
|
||||
|
||||
void LODManager::updateLODAfterSettingsChange() {}
|
||||
|
||||
float LODManager::getLODNearMaxAngle() const {
|
||||
return glm::degrees(_nearMaxAngle);
|
||||
}
|
||||
|
||||
|
||||
float LODManager::getVisibilityDistance() const {
|
||||
float systemDistance = getVisibilityDistanceFromHalfAngle(_lodHalfAngle);
|
||||
// Maintain behavior with deprecated _boundaryLevelAdjust property
|
||||
|
@ -274,9 +316,19 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
|||
// 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.
|
||||
|
||||
// TODO: maybe include own avatar size in calculating near and far distance?
|
||||
|
||||
// Tangent Adjacent side is eye to bound center vector length
|
||||
auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter();
|
||||
auto halfTanAdjacentSq = glm::dot(pos, pos);
|
||||
auto distSq = halfTanAdjacentSq;
|
||||
|
||||
if (distSq <= args->_lodNearDistSq) {
|
||||
return true;
|
||||
}
|
||||
|
||||
float farNearRatio = (distSq > args->_lodFarDistSq) ? 1.0f : (distSq - args->_lodNearDistSq)/(args->_lodFarDistSq - args->_lodNearDistSq);
|
||||
float lodAngleHalfTanSq = (farNearRatio * (args->_lodFarAngleHalfTanSq - args->_lodNearAngleHalfTanSq)) + args->_lodNearAngleHalfTanSq;
|
||||
|
||||
// Tangent Opposite side is the half length of the dimensions vector of the bound
|
||||
auto dim = bounds.getDimensions();
|
||||
|
@ -286,7 +338,7 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
|||
// isVisible = halfTanSq >= lodHalfTanSq = (halfTanOppositeSq / halfTanAdjacentSq) >= lodHalfTanSq
|
||||
// which we express as below to avoid division
|
||||
// (halfTanOppositeSq) >= lodHalfTanSq * halfTanAdjacentSq
|
||||
return (halfTanOppositeSq >= args->_lodAngleHalfTanSq * halfTanAdjacentSq);
|
||||
return (halfTanOppositeSq >= lodAngleHalfTanSq * halfTanAdjacentSq);
|
||||
};
|
||||
|
||||
void LODManager::setOctreeSizeScale(float sizeScale) {
|
||||
|
|
|
@ -29,15 +29,15 @@
|
|||
class ScriptEngine;
|
||||
|
||||
/*@jsdoc
|
||||
* <p>The world detail quality rendered.</p>
|
||||
* <p>The balance between target framerate and world detail quality rendered.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>Low world detail quality.</td></tr>
|
||||
* <tr><td><code>1</code></td><td>Medium world detail quality.</td></tr>
|
||||
* <tr><td><code>2</code></td><td>High world detail quality.</td></tr>
|
||||
* <tr><td><code>0</code></td><td>High frame rate / Low detail quality.</td></tr>
|
||||
* <tr><td><code>1</code></td><td>Medium frame rate / Medium detail quality.</td></tr>
|
||||
* <tr><td><code>2</code></td><td>Low frame rate / High detail quality.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {number} LODManager.WorldDetailQuality
|
||||
|
@ -49,7 +49,7 @@ enum WorldDetailQuality {
|
|||
};
|
||||
Q_DECLARE_METATYPE(WorldDetailQuality);
|
||||
|
||||
const bool DEFAULT_LOD_AUTO_ADJUST = false; // true for auto, false for manual.
|
||||
const bool DEFAULT_LOD_AUTO_ADJUST = true; // true for auto, false for manual.
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
const float DEFAULT_LOD_QUALITY_LEVEL = 0.2f; // default quality level setting is High (lower framerate)
|
||||
|
@ -120,6 +120,17 @@ class AABox;
|
|||
* @property {number} lodAngleDeg - The minimum angular dimension (relative to the camera position) of an entity in order for
|
||||
* it to be rendered, in degrees. The angular dimension is calculated as a sphere of radius half the diagonal of the
|
||||
* entity's AA box.
|
||||
|
||||
* @property {number} lodFarMaxAngleDeg - The maximum angular size (relative to the camera position)
|
||||
* of an entity that is allowed to be culled by LOD Manager, in degrees at distance specified by lodFarDistance. The angular dimension is
|
||||
* calculated as a sphere of radius half the diagonal of the entity's AA box.
|
||||
* @property {number} lodNearMaxAngleDeg - The maximum angular size (relative to the camera position)
|
||||
* of an entity that is allowed to be culled by LOD Manager, in degrees at distance specified by lodNearDistance. The angular dimension is
|
||||
* calculated as a sphere of radius half the diagonal of the entity's AA box.
|
||||
|
||||
* @property {number} lodFarDistance - Distance for which lodFarMaxAngleDeg limit is applied
|
||||
* @property {number} lodNearDistance - Distance for which lodNearMaxAngleDeg limit is applied
|
||||
|
||||
*
|
||||
* @property {number} pidKp - <em>Not used.</em>
|
||||
* @property {number} pidKi - <em>Not used.</em>
|
||||
|
@ -157,6 +168,11 @@ class LODManager : public QObject, public Dependency {
|
|||
|
||||
Q_PROPERTY(float lodAngleDeg READ getLODAngleDeg WRITE setLODAngleDeg)
|
||||
|
||||
Q_PROPERTY(float lodFarMaxAngleDeg READ getLODFarMaxAngleDeg WRITE setLODFarMaxAngleDeg)
|
||||
Q_PROPERTY(float lodNearMaxAngleDeg READ getLODNearMaxAngle WRITE setLODNearMaxAngle)
|
||||
Q_PROPERTY(float lodFarDistance READ getLODFarDistance WRITE setLODFarDistance)
|
||||
Q_PROPERTY(float lodNearDistance READ getLODNearDistance WRITE setLODNearDistance)
|
||||
|
||||
Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp)
|
||||
Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi)
|
||||
Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd)
|
||||
|
@ -292,7 +308,8 @@ public:
|
|||
|
||||
float getLODAngleDeg() const;
|
||||
void setLODAngleDeg(float lodAngle);
|
||||
float getLODHalfAngleTan() const;
|
||||
float getLODFarHalfAngleTan() const;
|
||||
float getLODNearHalfAngleTan() const;
|
||||
float getLODAngle() const;
|
||||
float getVisibilityDistance() const;
|
||||
void setVisibilityDistance(float distance);
|
||||
|
@ -311,6 +328,15 @@ public:
|
|||
float getPidOd() const;
|
||||
float getPidO() const;
|
||||
|
||||
void setLODFarDistance(float value);
|
||||
float getLODFarDistance() const { return _farDistance; }
|
||||
void setLODNearDistance(float value);
|
||||
float getLODNearDistance() const { return _nearDistance; }
|
||||
void setLODFarMaxAngleDeg(float value);
|
||||
float getLODFarMaxAngleDeg() const;
|
||||
void setLODNearMaxAngle(float value);
|
||||
float getLODNearMaxAngle() const;
|
||||
|
||||
signals:
|
||||
|
||||
/*@jsdoc
|
||||
|
@ -354,7 +380,9 @@ signals:
|
|||
private:
|
||||
LODManager();
|
||||
|
||||
float getLODHalfAngleTan() const;
|
||||
void setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode);
|
||||
void updateLODAfterSettingsChange();
|
||||
|
||||
std::mutex _automaticLODLock;
|
||||
bool _automaticLODAdjust = DEFAULT_LOD_AUTO_ADJUST;
|
||||
|
@ -364,6 +392,11 @@ private:
|
|||
float _batchTime{ 0.0f }; // msec
|
||||
float _gpuTime{ 0.0f }; // msec
|
||||
|
||||
float _farDistance{ 200.0f };
|
||||
float _nearDistance{ 4.0f };
|
||||
float _farMaxAngle{ 15.0f / 180.f * (float)M_PI };
|
||||
float _nearMaxAngle{ 1.0f / 180.f * (float)M_PI };
|
||||
|
||||
float _nowRenderTime{ 0.0f }; // msec
|
||||
float _smoothScale{ 10.0f }; // smooth is evaluated over 10 times longer than now
|
||||
float _smoothRenderTime{ 0.0f }; // msec
|
||||
|
|
|
@ -99,7 +99,7 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP
|
|||
RenderScriptingInterface::getInstance()->setShadowsEnabled(true);
|
||||
qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::REALTIME);
|
||||
|
||||
DependencyManager::get<LODManager>()->setWorldDetailQuality(WORLD_DETAIL_HIGH);
|
||||
DependencyManager::get<LODManager>()->setWorldDetailQuality(WORLD_DETAIL_MEDIUM);
|
||||
|
||||
break;
|
||||
case PerformancePreset::MID:
|
||||
|
|
|
@ -99,7 +99,7 @@ public slots:
|
|||
/*@jsdoc
|
||||
* Sets graphics performance to a preset.
|
||||
* @function Performance.setPerformancePreset
|
||||
* @param {Performance.PerformancePreset} performancePreset - The graphics performance preset to to use.
|
||||
* @param {Performance.PerformancePreset} performancePreset - The graphics performance preset to use.
|
||||
*/
|
||||
void setPerformancePreset(PerformancePreset performancePreset);
|
||||
|
||||
|
|
|
@ -76,7 +76,11 @@ namespace render {
|
|||
Args(const gpu::ContextPointer& context,
|
||||
float sizeScale = 1.0f,
|
||||
int boundaryLevelAdjust = 0,
|
||||
float lodAngleHalfTan = 0.1f,
|
||||
float lodFarAngleHalfTan = 0.1f,
|
||||
float lodNearAngleHalfTan = 0.01f,
|
||||
//float lodAngleHalfTan = 0.1f,
|
||||
float lodFarDist = 200.0f,
|
||||
float lodNearDist = 4.0f,
|
||||
RenderMode renderMode = DEFAULT_RENDER_MODE,
|
||||
DisplayMode displayMode = MONO,
|
||||
RenderMethod renderMethod = DEFERRED,
|
||||
|
@ -85,8 +89,14 @@ namespace render {
|
|||
_context(context),
|
||||
_sizeScale(sizeScale),
|
||||
_boundaryLevelAdjust(boundaryLevelAdjust),
|
||||
_lodAngleHalfTan(lodAngleHalfTan),
|
||||
_lodAngleHalfTanSq(lodAngleHalfTan * lodAngleHalfTan),
|
||||
_lodFarAngleHalfTan(lodFarAngleHalfTan),
|
||||
_lodFarAngleHalfTanSq(lodFarAngleHalfTan * lodFarAngleHalfTan),
|
||||
_lodNearAngleHalfTan(lodNearAngleHalfTan),
|
||||
_lodNearAngleHalfTanSq(lodNearAngleHalfTan * lodNearAngleHalfTan),
|
||||
_lodFarDist(lodFarDist),
|
||||
_lodNearDist(lodNearDist),
|
||||
_lodFarDistSq(lodFarDist * lodFarDist),
|
||||
_lodNearDistSq(lodNearDist * lodNearDist),
|
||||
_renderMode(renderMode),
|
||||
_displayMode(displayMode),
|
||||
_renderMethod(renderMethod),
|
||||
|
@ -116,8 +126,14 @@ namespace render {
|
|||
|
||||
float _sizeScale { 1.0f };
|
||||
int _boundaryLevelAdjust { 0 };
|
||||
float _lodAngleHalfTan{ 0.1f };
|
||||
float _lodAngleHalfTanSq{ _lodAngleHalfTan * _lodAngleHalfTan };
|
||||
float _lodFarAngleHalfTan{ 0.1f };
|
||||
float _lodFarAngleHalfTanSq{ _lodFarAngleHalfTan * _lodFarAngleHalfTan };
|
||||
float _lodNearAngleHalfTan{ 0.01f };
|
||||
float _lodNearAngleHalfTanSq{ _lodNearAngleHalfTan * _lodNearAngleHalfTan };
|
||||
float _lodFarDist { 200.0f };
|
||||
float _lodNearDist { 4.0f };
|
||||
float _lodFarDistSq { _lodFarDist * _lodFarDist };
|
||||
float _lodNearDistSq { _lodNearDist * _lodNearDist };
|
||||
|
||||
RenderMode _renderMode { DEFAULT_RENDER_MODE };
|
||||
DisplayMode _displayMode { MONO };
|
||||
|
|
|
@ -127,7 +127,10 @@ void FetchSpatialTree::run(const RenderContextPointer& renderContext, const Inpu
|
|||
// Octree selection!
|
||||
float threshold = 0.0f;
|
||||
if (queryFrustum.isPerspective()) {
|
||||
threshold = args->_lodAngleHalfTan;
|
||||
// TODO: Before our LOD took distance into account it used:
|
||||
// threshold = args->_lodAngleHalfTan;
|
||||
// We should make it dependent on distance in the future.
|
||||
threshold = args->_lodFarAngleHalfTan;
|
||||
if (frustumResolution.y > 0) {
|
||||
threshold = glm::max(queryFrustum.getFieldOfView() / frustumResolution.y, threshold);
|
||||
}
|
||||
|
@ -423,4 +426,4 @@ void ClearContainingZones::run(const RenderContextPointer& renderContext) {
|
|||
// of the next frame
|
||||
CullTest::_prevContainingZones = CullTest::_containingZones;
|
||||
CullTest::_containingZones.clear();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue