Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,32 @@
* @returns {JSX.Element} The returned JSX Element.
*/
export const controls = ({ observer, ReactPCUI, React, jsx, fragment }) => {
const { BindingTwoWay, LabelGroup, BooleanInput, Panel, Label } = ReactPCUI;
const { BindingTwoWay, LabelGroup, BooleanInput, Panel, SliderInput, Label } = ReactPCUI;
return fragment(
jsx(
Panel,
{ headerText: 'Settings' },
jsx(
LabelGroup,
{ text: 'Colorize' },
{ text: 'Hue Animation' },
jsx(BooleanInput, {
type: 'toggle',
binding: new BindingTwoWay(),
link: { observer, path: 'colorize' },
value: observer.get('colorize')
})
),
jsx(
LabelGroup,
{ text: 'Splat Budget' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'splatBudget' },
min: 0,
max: 10,
precision: 1,
step: 0.1
})
)
),
jsx(
Expand Down
21 changes: 10 additions & 11 deletions examples/src/examples/gaussian-splatting/lod-instances.example.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -210,19 +210,10 @@ assetListLoader.load(() => {
// allow rendering with lower LOD quality when optimal is not yet loaded
app.scene.gsplat.lodUnderfillLimit = 10;

// internal LOD preset based on platform (7 LOD levels: 0-6)
const isMobile = pc.platform.mobile;
app.scene.gsplat.splatBudget = isMobile ? 1000000 : 3000000;
data.set('splatBudget', pc.platform.mobile ? 1 : 3);

// create grid of instances centered around origin on XZ plane
const half = (GRID_SIZE - 1) * 0.5;
/**
* Compute per-LOD distances from a base value.
* @param {number} base - The base distance in world units.
* @returns {number[]} The array of distances for LODs 0..6.
*/
const lodBase = 1.2;
const lodDistances = [lodBase, lodBase * 2, lodBase * 3, lodBase * 4, lodBase * 5, lodBase * 6, lodBase * 7];

// Create a grid of playbot instances using unified gsplat component
let componentIndex = 0;
Expand All @@ -239,13 +230,21 @@ assetListLoader.load(() => {
entity.setLocalEulerAngles(180, 0, 0);
app.root.addChild(entity);
const gs = /** @type {any} */ (entity.gsplat);
gs.lodDistances = lodDistances;
gs.lodBaseDistance = 1.2;
gs.setParameter('uComponentId', componentIndex);
gs.setWorkBufferModifier(workBufferModifier);
componentIndex++;
}
}

const applySplatBudget = () => {
const millions = data.get('splatBudget');
app.scene.gsplat.splatBudget = Math.round(millions * 1000000);
};

applySplatBudget();
data.on('splatBudget:set', applySplatBudget);

// Create a camera with fly controls
const camera = new pc.Entity('camera');
camera.addComponent('camera', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @returns {JSX.Element} The returned JSX Element.
*/
export const controls = ({ observer, ReactPCUI, React, jsx, fragment }) => {
const { BindingTwoWay, LabelGroup, BooleanInput, Panel, SelectInput, Label } = ReactPCUI;
const { BindingTwoWay, LabelGroup, BooleanInput, Panel, SelectInput, SliderInput, Label } = ReactPCUI;
return fragment(
jsx(
Panel,
Expand Down Expand Up @@ -43,6 +43,40 @@ export const controls = ({ observer, ReactPCUI, React, jsx, fragment }) => {
{ v: 'mobile', t: 'Mobile (2-5)' }
]
})
),
jsx(
LabelGroup,
{ text: 'LOD Base Dist' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'lodBaseDistance' },
min: 1,
max: 50,
precision: 1
})
),
jsx(
LabelGroup,
{ text: 'LOD Multiplier' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'lodMultiplier' },
min: 1.2,
max: 10,
precision: 1
})
),
jsx(
LabelGroup,
{ text: 'Splat Budget' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'splatBudget' },
min: 0,
max: 10,
precision: 1,
step: 0.1
})
)
),
jsx(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,23 +63,23 @@ const config = {
};

// LOD preset definitions with customizable distances
/** @type {Record<string, { range: number[], lodDistances: number[] }>} */
/** @type {Record<string, { range: number[], lodBaseDistance: number }>} */
const LOD_PRESETS = {
'desktop-max': {
range: [0, 5],
lodDistances: [15, 30, 80, 250, 300]
lodBaseDistance: 15
},
'desktop': {
range: [0, 2],
lodDistances: [15, 30, 80, 250, 300]
lodBaseDistance: 15
},
'mobile-max': {
range: [1, 2],
lodDistances: [15, 30, 80, 250, 300]
lodBaseDistance: 15
},
'mobile': {
range: [2, 5],
lodDistances: [15, 30, 80, 250, 300]
lodBaseDistance: 15
}
};

Expand Down Expand Up @@ -119,6 +119,7 @@ assetListLoader.load(() => {
data.set('debugLod', false);
data.set('colorizeSH', false);
data.set('lodPreset', pc.platform.mobile ? 'mobile' : 'desktop');
data.set('splatBudget', pc.platform.mobile ? 1 : 3);

app.scene.gsplat.colorizeLod = !!data.get('debugLod');
app.scene.gsplat.colorizeColorUpdate = !!data.get('colorizeSH');
Expand Down Expand Up @@ -148,12 +149,31 @@ assetListLoader.load(() => {
const presetData = LOD_PRESETS[preset] || LOD_PRESETS.desktop;
app.scene.gsplat.lodRangeMin = presetData.range[0];
app.scene.gsplat.lodRangeMax = presetData.range[1];
gs.lodDistances = presetData.lodDistances;
gs.lodBaseDistance = presetData.lodBaseDistance;
data.set('lodBaseDistance', presetData.lodBaseDistance);
};

applyPreset();
data.on('lodPreset:set', applyPreset);

data.set('lodMultiplier', 4);
gs.lodMultiplier = 4;

data.on('lodBaseDistance:set', () => {
gs.lodBaseDistance = data.get('lodBaseDistance');
});
data.on('lodMultiplier:set', () => {
gs.lodMultiplier = data.get('lodMultiplier');
});

const applySplatBudget = () => {
const millions = data.get('splatBudget');
app.scene.gsplat.splatBudget = Math.round(millions * 1000000);
};

applySplatBudget();
data.on('splatBudget:set', applySplatBudget);

// Create a camera with fly controls
const camera = new pc.Entity('camera');
camera.addComponent('camera', {
Expand Down
80 changes: 53 additions & 27 deletions examples/src/examples/gaussian-splatting/lod-streaming.controls.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,34 @@
* @returns {JSX.Element} The returned JSX Element.
*/
export const controls = ({ observer, ReactPCUI, React, jsx, fragment }) => {
const { BindingTwoWay, LabelGroup, BooleanInput, Panel, SelectInput, Label } = ReactPCUI;
const { BindingTwoWay, LabelGroup, BooleanInput, Panel, SelectInput, SliderInput, Label } = ReactPCUI;
const isWebGPU = observer.get('isWebGPU');
return fragment(
jsx(
Panel,
{ headerText: 'Camera' },
jsx(
LabelGroup,
{ text: 'FOV' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'cameraFov' },
min: 10,
max: 120,
precision: 0
})
),
jsx(
LabelGroup,
{ text: 'High Res' },
jsx(BooleanInput, {
type: 'toggle',
binding: new BindingTwoWay(),
link: { observer, path: 'highRes' },
value: observer.get('highRes') || false
})
)
),
jsx(
Panel,
{ headerText: 'Settings' },
Expand All @@ -29,16 +54,6 @@ export const controls = ({ observer, ReactPCUI, React, jsx, fragment }) => {
value: observer.get('culling') || false
})
),
jsx(
LabelGroup,
{ text: 'High Res' },
jsx(BooleanInput, {
type: 'toggle',
binding: new BindingTwoWay(),
link: { observer, path: 'highRes' },
value: observer.get('highRes') || false
})
),
jsx(
LabelGroup,
{ text: 'Compact' },
Expand Down Expand Up @@ -75,27 +90,38 @@ export const controls = ({ observer, ReactPCUI, React, jsx, fragment }) => {
]
})
),
jsx(
LabelGroup,
{ text: 'LOD Base Dist' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'lodBaseDistance' },
min: 1,
max: 50,
precision: 1
})
),
jsx(
LabelGroup,
{ text: 'LOD Multiplier' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'lodMultiplier' },
min: 1,
max: 5,
precision: 1
})
),
jsx(
LabelGroup,
{ text: 'Splat Budget' },
jsx(SelectInput, {
type: 'string',
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'splatBudget' },
value: observer.get('splatBudget') || '4M',
options: [
{ v: 'none', t: 'No limit' },
{ v: '1M', t: '1M' },
{ v: '2M', t: '2M' },
{ v: '3M', t: '3M' },
{ v: '4M', t: '4M' },
{ v: '5M', t: '5M' },
{ v: '6M', t: '6M' },
{ v: '7M', t: '7M' },
{ v: '8M', t: '8M' },
{ v: '9M', t: '9M' },
{ v: '10M', t: '10M' }
]
min: 0,
max: 10,
precision: 1,
step: 0.1
})
)
),
Expand Down
Loading
Loading