Skip to content

feat: Gaussians LOD #189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c7fab8f
start integration
Apr 8, 2025
dc481e4
integrating
Apr 8, 2025
95651ae
testing mobile version
Apr 9, 2025
f6b0583
setting up a way to define if the harmonics should be loaded
Apr 11, 2025
8c1368d
setup a way to check if it is IOS, define a way to see if the renderi…
Apr 11, 2025
e03f2e9
testing memory, defining parameters
Apr 11, 2025
d70ba47
remove flickering
Apr 11, 2025
5ad1005
using a defer function to check the next frame so the data is updated…
Apr 11, 2025
77c0d40
cleaning
Apr 11, 2025
5bc9c9a
refactoring the delay function
Apr 12, 2025
fe641f4
remove splats scenes
Apr 15, 2025
cd3afe1
setup the decoding worker for the splats to work without Three
Apr 16, 2025
e07bd85
updates for the shader to test harmonics
Apr 22, 2025
9c7144b
changes from Thibault requests
Apr 23, 2025
2e789b2
inserting the splats into the octree from Potree
Apr 24, 2025
54a0382
include the splats mesh into the octree
Apr 25, 2025
bd69f09
testing Thibault requests
Apr 28, 2025
b1b4df8
testing
Apr 28, 2025
a640039
solving the loading issue for the new decoder refactoring
Apr 29, 2025
c87bc09
level of detail for the splats size implementation
Apr 29, 2025
f7b382a
adding the sorter as base64 and implement the splats scale based on t…
Apr 30, 2025
fdb835e
modify the splats to be adaptive to the LOD and the camera distance
May 4, 2025
e2cdc7a
yarn lock as master
May 4, 2025
57f4973
updates from Thibault
May 5, 2025
5e9aebd
Delete example/.DS_Store
HectorArellanoDev May 5, 2025
b63c50c
Delete .DS_Store
HectorArellanoDev May 5, 2025
4dcc8cc
fix the example to load V1, V2 and splats
May 12, 2025
2fbe25a
fix issue with DS_Store
May 12, 2025
733af0b
Delete .DS_Store
HectorArellanoDev May 12, 2025
0911020
setup the depth mode for the point cloud material
May 13, 2025
8d0c444
modify the example to remove ths splats
Jun 4, 2025
aa0f516
Merge branch 'gaussians-lod' of github.com:pnext/three-loader into ga…
Jun 4, 2025
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
12 changes: 12 additions & 0 deletions example/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,22 @@ body,
left: 20px;
}

.btn-container-splats {
position: absolute;
bottom: 80px;
left: 20px;
}

.btn-container-v1 button {
margin-right: 10px;
}

.btn-container-v2 button {
margin-right: 10px;
}

.btn-container-splats button {
margin-right: 10px;
}


65 changes: 48 additions & 17 deletions example/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Vector3 } from 'three';
import { ClipMode, PointCloudOctree } from '../src';
import { Viewer } from './viewer';

Expand All @@ -14,18 +13,19 @@ viewer.initialize(targetEl);
interface PointCloudsConfig {
file: string;
url: string;
version: 'v1' | 'v2';
version: 'v1' | 'v2' | 'splats';
}

const examplePointClouds: PointCloudsConfig[] = [
{
file: 'cloud.js',
url: 'https://raw.githubusercontent.com/potree/potree/develop/pointclouds/lion_takanawa/',
version: 'v1'
}, {
version: 'v1',
},
{
file: 'metadata.json',
url: 'https://test-pix4d-cloud-eu-central-1.s3.eu-central-1.amazonaws.com/lion_takanawa_converted/',
version: 'v2'
version: 'v2',
}
];

Expand All @@ -39,15 +39,17 @@ interface LoadedState {

const pointClouds: PointClouds = {
v1: undefined,
v2: undefined
v2: undefined,
splats: undefined
};

const loaded: LoadedState = {
v1: false,
v2: false
v2: false,
splats: false
};

function createButton(text: string, onClick: () => void): HTMLButtonElement {
function createButton(text: string, onClick: (e: MouseEvent) => void): HTMLButtonElement {
const button: HTMLButtonElement = document.createElement('button');
button.textContent = text;
button.addEventListener('click', onClick);
Expand All @@ -58,45 +60,67 @@ function createSlider(version: string): HTMLInputElement {
const slider: HTMLInputElement = document.createElement('input');
slider.type = 'range';
slider.min = '10000';
slider.max = '500000';
slider.max = '1000000';
slider.value = '1000000';
slider.className = 'budget-slider';
slider.addEventListener('change', () => {
const cloud = pointClouds[version];
if (!cloud) {
return;
}
cloud.potree.pointBudget = parseInt(slider.value, 10);
viewer.update(0);
console.log(cloud.potree.pointBudget);
});
return slider;
}

function setupPointCloud(version: 'v1' | 'v2', file: string, url: string): void {
function setupPointCloud(version: 'v1' | 'v2' | 'splats', file: string, url: string): void {
if (loaded[version]) {
return;
}
loaded[version] = true;

viewer.load(file, url, version)
//TODO: check for mobile, not noly IOS
function isIOS() {
const ua = navigator.userAgent;
return ua.indexOf('iPhone') > 0 || ua.indexOf('iPad') > 0;
}

viewer.load(file, url, version == 'splats' ? 'v2' : version, !isIOS())
.then(pco => {
pointClouds[version] = pco;
pco.rotateX(-Math.PI / 2);
pco.material.size = 1.0;

pco.material.pointColorType = 0;

pco.material.clipMode = ClipMode.CLIP_HORIZONTALLY;
pco.material.clipExtent = [0.0, 0.0, 1.0, 1.0];
pco.position.set(0, 0, 0);

const camera = viewer.camera;
camera.up.set(0, 0, 1);
camera.far = 1000;
camera.updateProjectionMatrix();
camera.position.set(0, 0, 10);
camera.lookAt(new Vector3());
camera.position.set(-4, 4, 16);

viewer.add(pco);
})
.catch(err => console.error(err));
}

function setupUI(cfg: PointCloudsConfig): void {

const updateBtn = createButton("Update", (e: MouseEvent) => {
e.stopPropagation();
viewer.enableUpdate = !viewer.enableUpdate;
updateBtn.style.backgroundColor = viewer.enableUpdate ? "#00ff00" : "#ff0000";
})

updateBtn.style.backgroundColor ="#00ff00";

const slider = createSlider(cfg.version);

const unloadBtn = createButton('Unload', () => {
if (!loaded[cfg.version]) {
return;
Expand All @@ -109,18 +133,25 @@ function setupUI(cfg: PointCloudsConfig): void {
viewer.disposePointCloud(pointCloud);
loaded[cfg.version] = false;
pointClouds[cfg.version] = undefined;
});

const loadBtn = createButton('Load', () => setupPointCloud(cfg.version, cfg.file, cfg.url));
viewer.enableUpdate = true;
updateBtn.style.backgroundColor ="#00ff00";
});

const slider = createSlider(cfg.version);
const loadBtn = createButton('Load', (e: MouseEvent) => {
e.stopPropagation();
setupPointCloud(cfg.version, cfg.file, cfg.url)
}
);

const btnContainer: HTMLDivElement = document.createElement('div');
btnContainer.className = 'btn-container-' + cfg.version;
document.body.appendChild(btnContainer);
btnContainer.appendChild(unloadBtn);
btnContainer.appendChild(loadBtn);
btnContainer.append(updateBtn);
btnContainer.appendChild(slider);

}

examplePointClouds.forEach(setupUI);
Binary file added example/sorter_test.wasm
Binary file not shown.
Loading