Skip to content

Commit d67297b

Browse files
committed
Added mode to render only when needed
1 parent 6298b67 commit d67297b

File tree

5 files changed

+88
-11
lines changed

5 files changed

+88
-11
lines changed

src/RenderMode.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const RenderMode = {
2+
Always: 0,
3+
OnChange: 1,
4+
Never: 2
5+
};

src/SceneHelper.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ export class SceneHelper {
129129
this.meshCursor.visible = visible;
130130
}
131131

132+
getMeschCursorVisibility() {
133+
return this.meshCursor.visible;
134+
}
135+
132136
setMeshCursorPosition(position) {
133137
this.meshCursor.position.copy(position);
134138
}

src/SplatMesh.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export class SplatMesh extends THREE.Mesh {
7272
this.maxRadius = 0;
7373
this.visibleRegionRadius = 0;
7474
this.visibleRegionFadeStartRadius = 0;
75+
this.visibleRegionChanging = false;
7576

7677
this.disposed = false;
7778
}
@@ -921,6 +922,7 @@ export class SplatMesh extends THREE.Mesh {
921922
this.material.uniforms.currentTime.value = performance.now();
922923
this.material.uniforms.fadeInComplete.value = fadeInComplete;
923924
this.material.uniformsNeedUpdate = true;
925+
this.visibleRegionChanging = !fadeInComplete;
924926
}
925927

926928
/**

src/Viewer.js

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ import { VRButton } from './webxr/VRButton.js';
2020
import { ARButton } from './webxr/ARButton.js';
2121
import { delayedExecute } from './Util.js';
2222
import { LoaderStatus } from './loaders/LoaderStatus.js';
23-
23+
import { RenderMode } from './RenderMode.js';
2424

2525
const THREE_CAMERA_FOV = 50;
2626
const MINIMUM_DISTANCE_TO_NEW_FOCAL_POINT = .75;
2727
const MIN_SPLAT_COUNT_TO_SHOW_SPLAT_TREE_LOADING_SPINNER = 1500000;
2828
const FOCUS_MARKER_FADE_IN_SPEED = 10.0;
2929
const FOCUS_MARKER_FADE_OUT_SPEED = 2.5;
30+
const CONSECUTIVE_RENDERED_FRAMES_FOR_FPS_CALCULATION = 60;
3031

3132
/**
3233
* Viewer: Manages the rendering of splat scenes. Manages an instance of SplatMesh as well as a web worker
@@ -121,6 +122,8 @@ export class Viewer {
121122
this.gpuAcceleratedSort = false;
122123
}
123124

125+
this.renderMode = options.renderMode || RenderMode.Always;
126+
124127
this.controls = null;
125128

126129
this.showMeshCursor = false;
@@ -147,6 +150,7 @@ export class Viewer {
147150

148151
this.currentFPS = 0;
149152
this.lastSortTime = 0;
153+
this.consecutiveRenderFrames = 0;
150154

151155
this.previousCameraTarget = new THREE.Vector3();
152156
this.nextCameraTarget = new THREE.Vector3();
@@ -283,6 +287,10 @@ export class Viewer {
283287
}
284288
}
285289

290+
setRenderMode(renderMode) {
291+
this.renderMode = renderMode;
292+
}
293+
286294
onKeyDown = function() {
287295

288296
const forward = new THREE.Vector3();
@@ -941,6 +949,7 @@ export class Viewer {
941949
this.sortPromiseResolver();
942950
this.sortPromise = null;
943951
this.sortPromiseResolver = null;
952+
this.forceRenderNextFrame();
944953
if (sortCount === 0) {
945954
this.runAfterFirstSort.forEach((func) => {
946955
func();
@@ -1088,13 +1097,60 @@ export class Viewer {
10881097
this.requestFrameId = requestAnimationFrame(this.selfDrivenUpdateFunc);
10891098
}
10901099
this.update();
1091-
this.render();
1100+
if (this.shouldRender()) {
1101+
this.render();
1102+
this.consecutiveRenderFrames++;
1103+
} else {
1104+
this.consecutiveRenderFrames = 0;
1105+
}
1106+
this.renderNextFrame = false;
10921107
}
10931108

1109+
forceRenderNextFrame() {
1110+
this.renderNextFrame = true;
1111+
}
1112+
1113+
shouldRender = function() {
1114+
1115+
let renderCount = 0;
1116+
const lastCameraPosition = new THREE.Vector3();
1117+
const lastCameraOrientation = new THREE.Quaternion();
1118+
const changeEpsilon = 0.0001;
1119+
1120+
return function() {
1121+
let shouldRender = false;
1122+
let cameraChanged = false;
1123+
if (this.camera) {
1124+
const cp = this.camera.position;
1125+
const co = this.camera.quaternion;
1126+
cameraChanged = Math.abs(cp.x - lastCameraPosition.x) > changeEpsilon ||
1127+
Math.abs(cp.y - lastCameraPosition.y) > changeEpsilon ||
1128+
Math.abs(cp.z - lastCameraPosition.z) > changeEpsilon ||
1129+
Math.abs(co.x - lastCameraOrientation.x) > changeEpsilon ||
1130+
Math.abs(co.y - lastCameraOrientation.y) > changeEpsilon ||
1131+
Math.abs(co.z - lastCameraOrientation.z) > changeEpsilon ||
1132+
Math.abs(co.w - lastCameraOrientation.w) > changeEpsilon;
1133+
}
1134+
1135+
shouldRender = this.renderMode !== RenderMode.Never && (renderCount === 0 || this.splatMesh.visibleRegionChanging ||
1136+
cameraChanged || this.renderMode === RenderMode.Always || this.dynamicMode === true || this.renderNextFrame);
1137+
1138+
if (this.camera) {
1139+
lastCameraPosition.copy(this.camera.position);
1140+
lastCameraOrientation.copy(this.camera.quaternion);
1141+
}
1142+
1143+
renderCount++;
1144+
return shouldRender;
1145+
};
1146+
1147+
}();
1148+
10941149
render = function() {
10951150

10961151
return function() {
10971152
if (!this.initialized || !this.splatRenderingInitialized) return;
1153+
10981154
const hasRenderables = (threeScene) => {
10991155
for (let child of threeScene.children) {
11001156
if (child.visible) return true;
@@ -1141,14 +1197,18 @@ export class Viewer {
11411197
let frameCount = 0;
11421198

11431199
return function() {
1144-
const currentTime = getCurrentTime();
1145-
const calcDelta = currentTime - lastCalcTime;
1146-
if (calcDelta >= 1.0) {
1147-
this.currentFPS = frameCount;
1148-
frameCount = 0;
1149-
lastCalcTime = currentTime;
1200+
if (this.consecutiveRenderFrames > CONSECUTIVE_RENDERED_FRAMES_FOR_FPS_CALCULATION) {
1201+
const currentTime = getCurrentTime();
1202+
const calcDelta = currentTime - lastCalcTime;
1203+
if (calcDelta >= 1.0) {
1204+
this.currentFPS = frameCount;
1205+
frameCount = 0;
1206+
lastCalcTime = currentTime;
1207+
} else {
1208+
frameCount++;
1209+
}
11501210
} else {
1151-
frameCount++;
1211+
this.currentFPS = null;
11521212
}
11531213
};
11541214

@@ -1227,6 +1287,7 @@ export class Viewer {
12271287
this.sceneHelper.setFocusMarkerOpacity(newFocusMarkerOpacity);
12281288
this.sceneHelper.updateFocusMarker(this.nextCameraTarget, this.camera, renderDimensions);
12291289
wasTransitioning = true;
1290+
this.forceRenderNextFrame();
12301291
} else {
12311292
let currentFocusMarkerOpacity;
12321293
if (wasTransitioning) currentFocusMarkerOpacity = 1.0;
@@ -1237,6 +1298,7 @@ export class Viewer {
12371298
this.sceneHelper.setFocusMarkerOpacity(newFocusMarkerOpacity);
12381299
if (newFocusMarkerOpacity === 0.0) this.sceneHelper.setFocusMarkerVisibility(false);
12391300
}
1301+
if (currentFocusMarkerOpacity > 0.0) this.forceRenderNextFrame();
12401302
wasTransitioning = false;
12411303
}
12421304
};
@@ -1250,6 +1312,7 @@ export class Viewer {
12501312

12511313
return function() {
12521314
if (this.showMeshCursor) {
1315+
this.forceRenderNextFrame();
12531316
this.getRenderDimensions(renderDimensions);
12541317
outHits.length = 0;
12551318
this.raycaster.setFromCameraAndScreenPosition(this.camera, this.mousePosition, renderDimensions);
@@ -1261,6 +1324,7 @@ export class Viewer {
12611324
this.sceneHelper.setMeshCursorVisibility(false);
12621325
}
12631326
} else {
1327+
if (this.sceneHelper.getMeschCursorVisibility()) this.forceRenderNextFrame();
12641328
this.sceneHelper.setMeshCursorVisibility(false);
12651329
}
12661330
};
@@ -1279,7 +1343,7 @@ export class Viewer {
12791343
const meshCursorPosition = this.showMeshCursor ? this.sceneHelper.meshCursor.position : null;
12801344
const splatRenderCountPct = this.splatRenderCount / splatCount * 100;
12811345
this.infoPanel.update(renderDimensions, this.camera.position, cameraLookAtPosition,
1282-
this.camera.up, meshCursorPosition, this.currentFPS, splatCount,
1346+
this.camera.up, meshCursorPosition, this.currentFPS || 'N/A', splatCount,
12831347
this.splatRenderCount, splatRenderCountPct, this.lastSortTime);
12841348
};
12851349

src/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { OrbitControls } from './OrbitControls.js';
1313
import { AbortablePromise } from './AbortablePromise.js';
1414
import { SceneFormat } from './loaders/SceneFormat.js';
1515
import { WebXRMode } from './webxr/WebXRMode.js';
16+
import { RenderMode } from './RenderMode.js';
1617

1718
export {
1819
PlyParser,
@@ -29,5 +30,6 @@ export {
2930
OrbitControls,
3031
AbortablePromise,
3132
SceneFormat,
32-
WebXRMode
33+
WebXRMode,
34+
RenderMode
3335
};

0 commit comments

Comments
 (0)