Skip to content

Commit 2631686

Browse files
authored
Streaming & lod update (#121)
1 parent a9a301c commit 2631686

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

src/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
noui: url.searchParams.has('noui'),
2929
noanim: url.searchParams.has('noanim'),
3030
ministats: url.searchParams.has('ministats'),
31+
colorize: url.searchParams.has('colorize'),
3132
unified: url.searchParams.has('unified'),
3233
aa: url.searchParams.has('aa')
3334
};

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
EventHandler,
66
type Texture,
77
type AppBase,
8+
platform,
89
revision as engineRevision,
910
version as engineVersion
1011
} from 'playcanvas';
@@ -89,7 +90,7 @@ const main = (app: AppBase, camera: Entity, settingsJson: any, config: Config) =
8990

9091
const state = observe(events, {
9192
readyToRender: false,
92-
hqMode: true,
93+
hqMode: !platform.mobile,
9394
progress: 0,
9495
inputMode: 'desktop',
9596
cameraMode: 'orbit',

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type Config = {
1616
noui: boolean;
1717
noanim: boolean;
1818
ministats: boolean;
19+
colorize: boolean; // render with LOD colorization
1920
unified: boolean; // force unified rendering mode
2021
aa: boolean; // render with antialiasing
2122
};

src/viewer.ts

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ import {
2020
TONEMAP_ACES2,
2121
TONEMAP_NEUTRAL,
2222
Vec3,
23-
GSplatComponent,
24-
platform
23+
GSplatComponent
2524
} from 'playcanvas';
2625

2726
import { Annotations } from './annotations';
@@ -332,13 +331,22 @@ class Viewer {
332331

333332
const { gsplat } = app.scene;
334333

335-
// lod ranges
336-
const low = [2, 5];
337-
const high = [0, 2];
334+
// quality ranges
335+
const quality = {
336+
low: {
337+
range: [2, 8],
338+
splatBudget: 1
339+
},
340+
high: {
341+
range: [0, 8],
342+
splatBudget: 4
343+
}
344+
};
338345

339-
// in unified mode, for now we hard-code LOD range on mobile vs desktop
340-
gsplat.lodRangeMin = low[0];
341-
gsplat.lodRangeMax = low[1];
346+
// start in low quality mode so we can get user interacting asap
347+
gsplat.lodRangeMin = quality.low.range[0];
348+
gsplat.lodRangeMax = quality.low.range[1];
349+
gsplat.splatBudget = quality.low.splatBudget * 1000000;
342350

343351
// these two allow LOD behind camera to drop, saves lots of splats
344352
gsplat.lodUpdateAngle = 90;
@@ -349,23 +357,30 @@ class Viewer {
349357

350358
const eventHandler = app.systems.gsplat;
351359

352-
// force render empty frames otherwise unified rendering doesn't update
360+
// we must force continuous rendering with streaming & lod system
353361
this.forceRenderNextFrame = true;
354362

355363
let current = 0;
356364
let watermark = 1;
357365
const readyHandler = (camera: CameraComponent, layer: Layer, ready: boolean, loading: number) => {
358-
if (ready && !loading) {
366+
if (ready && loading === 0) {
359367
// scene is done loading
360-
361368
eventHandler.off('frame:ready', readyHandler);
362369

363-
this.forceRenderNextFrame = false;
364370
state.readyToRender = true;
365371

366-
const range = platform.mobile ? low : high;
367-
gsplat.lodRangeMin = range[0];
368-
gsplat.lodRangeMax = range[1];
372+
// handle quality mode changes
373+
const updateLod = () => {
374+
const settings = state.hqMode ? quality.high : quality.low;
375+
gsplat.lodRangeMin = settings.range[0];
376+
gsplat.lodRangeMax = settings.range[1];
377+
gsplat.splatBudget = settings.splatBudget * 1000000;
378+
};
379+
events.on('hqMode:changed', updateLod);
380+
updateLod();
381+
382+
// debug colorize lods
383+
gsplat.colorizeLod = config.colorize;
369384

370385
// wait for the first valid frame to complete rendering
371386
app.once('frameend', () => {
@@ -376,18 +391,13 @@ class Viewer {
376391
});
377392
}
378393

379-
if (ready) {
380-
app.renderNextFrame = true;
381-
}
382-
383394
// update loading status
384395
if (loading !== current) {
385396
watermark = Math.max(watermark, loading);
386397
current = watermark - loading;
387398
state.progress = Math.trunc(current / watermark * 100);
388399
}
389400
};
390-
391401
eventHandler.on('frame:ready', readyHandler);
392402
}
393403
});

0 commit comments

Comments
 (0)