Skip to content

Commit

Permalink
Merge pull request #169 from mkkellogg/dev
Browse files Browse the repository at this point in the history
v0.3.5: Various small bug fixes and updates
  • Loading branch information
mkkellogg authored Mar 20, 2024
2 parents e5846bd + 865cdb0 commit bdf7b1c
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 23 deletions.
37 changes: 31 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ const viewer = new GaussianSplats3D.Viewer({
'integerBasedSort': true,
'dynamicScene': false,
'webXRMode': GaussianSplats3D.WebXRMode.None,
'renderMode': GaussianSplats3D.RenderMode.OnChange
'renderMode': GaussianSplats3D.RenderMode.OnChange,
'sceneRevealMode': GaussianSplats3D.SceneRevealMode.Instant
});
viewer.addSplatScene('<path to .ply, .ksplat, or .splat file>')
.then(() => {
Expand Down Expand Up @@ -291,6 +292,7 @@ Advanced `Viewer` parameters
| `dynamicScene` | Tells the viewer to not make any optimizations that depend on the scene being static. Additionally all splat data retrieved from the viewer's splat mesh will not have their respective scene transform applied to them by default.
| `webXRMode` | Tells the viewer whether or not to enable built-in Web VR or Web AR. Valid values are defined in the `WebXRMode` enum: `None`, `VR`, and `AR`. Defaults to `None`.
| `renderMode` | Controls when the viewer renders the scene. Valid values are defined in the `RenderMode` enum: `Always`, `OnChange`, and `Never`. Defaults to `Always`.
| `sceneRevealMode` | Controls the fade-in effect used when the scene is loaded. Valid values are defined in the `SceneRevealMode` enum: `Default`, `Gradual`, and `Instant`. `Default` results in a nice, slow fade-in effect for progressively loaded scenes, and a fast fade-in for non progressively loaded scenes. `Gradual` will force a slow fade-in for all scenes. `Instant` will force all loaded scene data to be immediately visible.
<br>

### Creating KSPLAT files
Expand All @@ -301,8 +303,7 @@ import * as GaussianSplats3D from '@mkkellogg/gaussian-splats-3d';

const compressionLevel = 1;
const splatAlphaRemovalThreshold = 5; // out of 255
const plyLoader = new GaussianSplats3D.PlyLoader();
plyLoader.loadFromURL('<path to .ply or .splat file>', compressionLevel, splatAlphaRemovalThreshold)
GaussianSplats3D.PlyLoader.loadFromURL('<path to .ply or .splat file>', compressionLevel, splatAlphaRemovalThreshold)
.then((splatBuffer) => {
GaussianSplats3D.KSplatLoader.downloadFile(splatBuffer, 'converted_file.ksplat');
});
Expand Down Expand Up @@ -333,19 +334,43 @@ response.setHeader("Cross-Origin-Opener-Policy", "same-origin");
response.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
```

If you're using Apache, you can edit the `.htaccess` file to do that by adding the lines:
#### CORS with Apache

For Apache, you can edit the `.htaccess` file to allow CORS by adding the lines:

```
Header add Cross-Origin-Opener-Policy "same-origin"
Header add Cross-Origin-Embedder-Policy "require-corp"
```

For other web servers, these headers most likely can be set in a similar fashion.

Additionally you may need to require a secure connection to your server by redirecting all access via `http://` to `https://`. In Apache this can be done by updating the `.htaccess` file with the following lines:

```
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
```

#### CORS with Vite

For Vite, one popular option is to install the [vite-plugin-cross-origin-isolation](https://github.com/chaosprint/vite-plugin-cross-origin-isolation) plugin via `npm` and then add the following to your `vite.config.js` file.

```javascript
import { defineConfig } from "vite";

export default defineConfig({
plugins: [
{
name: "configure-response-headers",
configureServer: (server) => {
server.middlewares.use((_req, res, next) => {
res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
next();
});
},
},
],
});
```
There are other ways to configure Vite to handle this referenced in issue [#41](https://github.com/mkkellogg/GaussianSplats3D/issues/41).
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "git",
"url": "https://github.com/mkkellogg/GaussianSplats3D"
},
"version": "0.3.4",
"version": "0.3.5",
"description": "Three.js-based 3D Gaussian splat viewer",
"module": "build/gaussian-splats-3d.module.js",
"main": "build/gaussian-splats-3d.umd.cjs",
Expand Down
5 changes: 5 additions & 0 deletions src/SceneRevealMode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const SceneRevealMode = {
Default: 0,
Gradual: 1,
Instant: 2
};
21 changes: 15 additions & 6 deletions src/SplatMesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import { WebGLExtensions } from './three-shim/WebGLExtensions.js';
import { WebGLCapabilities } from './three-shim/WebGLCapabilities.js';
import { uintEncodedFloat, rgbaArrayToInteger } from './Util.js';
import { Constants } from './Constants.js';
import { SceneRevealMode } from './SceneRevealMode.js';

const dummyGeometry = new THREE.BufferGeometry();
const dummyMaterial = new THREE.MeshBasicMaterial();

const COVARIANCES_ELEMENTS_PER_SPLAT = 6;
const CENTER_COLORS_ELEMENTS_PER_SPLAT = 4;

const SCENE_FADEIN_RATE_FAST = 0.012;
const SCENE_FADEIN_RATE_GRADUAL = 0.003;

/**
* SplatMesh: Container for one or more splat scenes, abstracting them into a single unified container for
* splat data. Additionally contains data structures and code to make the splat data renderable as a Three.js mesh.
Expand Down Expand Up @@ -591,7 +595,6 @@ export class SplatMesh extends THREE.Mesh {
this.visibleRegionRadius = 0;
this.visibleRegionFadeStartRadius = 0;
this.firstRenderTime = -1;
this.finalBuild = false;
this.lastBuildScenes = [];
this.lastBuildSplatCount = 0;
this.lastBuildMaxSplatCount = 0;
Expand Down Expand Up @@ -911,16 +914,22 @@ export class SplatMesh extends THREE.Mesh {
this.updateVisibleRegionFadeDistance();
}

updateVisibleRegionFadeDistance() {
const fadeInRate = this.finalBuild ? 0.01 : 0.003;
updateVisibleRegionFadeDistance(sceneRevealMode = SceneRevealMode.Default) {
const fastFadeRate = SCENE_FADEIN_RATE_FAST;
const gradualFadeRate = SCENE_FADEIN_RATE_GRADUAL;
const defaultFadeInRate = this.finalBuild ? fastFadeRate : gradualFadeRate;
const fadeInRate = sceneRevealMode === SceneRevealMode.Default ? defaultFadeInRate : gradualFadeRate;
this.visibleRegionFadeStartRadius = (this.visibleRegionRadius - this.visibleRegionFadeStartRadius) *
fadeInRate + this.visibleRegionFadeStartRadius;
const fadeInComplete = (this.visibleRegionFadeStartRadius / this.maxRadius) > 0.99 ? 1 : 0;
fadeInRate + this.visibleRegionFadeStartRadius;
const fadeInPercentage = (this.visibleRegionFadeStartRadius / this.maxRadius);
const fadeInComplete = fadeInPercentage > 0.99;
const shaderFadeInComplete = (fadeInComplete || sceneRevealMode === SceneRevealMode.Instant) ? 1 : 0;

this.material.uniforms.visibleRegionFadeStartRadius.value = this.visibleRegionFadeStartRadius;
this.material.uniforms.visibleRegionRadius.value = this.visibleRegionRadius;
this.material.uniforms.firstRenderTime.value = this.firstRenderTime;
this.material.uniforms.currentTime.value = performance.now();
this.material.uniforms.fadeInComplete.value = fadeInComplete;
this.material.uniforms.fadeInComplete.value = shaderFadeInComplete;
this.material.uniformsNeedUpdate = true;
this.visibleRegionChanging = !fadeInComplete;
}
Expand Down
16 changes: 11 additions & 5 deletions src/Viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ARButton } from './webxr/ARButton.js';
import { delayedExecute } from './Util.js';
import { LoaderStatus } from './loaders/LoaderStatus.js';
import { RenderMode } from './RenderMode.js';
import { SceneRevealMode } from './SceneRevealMode.js';

const THREE_CAMERA_FOV = 50;
const MINIMUM_DISTANCE_TO_NEW_FOCAL_POINT = .75;
Expand Down Expand Up @@ -122,8 +123,16 @@ export class Viewer {
this.gpuAcceleratedSort = false;
}

// if 'renderMode' is RenderMode.Always, then the viewer will rrender the scene on every update. If it is RenderMode.OnChange,
// it will only render when something in the scene has changed.
this.renderMode = options.renderMode || RenderMode.Always;

// SceneRevealMode.Default results in a nice, slow fade-in effect for progressively loaded scenes,
// and a fast fade-in for non progressively loaded scenes.
// SceneRevealMode.Gradual will force a slow fade-in for all scenes.
// SceneRevealMode.Instant will force all loaded scene data to be immediately visible.
this.sceneRevealMode = options.sceneRevealMode || SceneRevealMode.Default;

this.controls = null;

this.showMeshCursor = false;
Expand Down Expand Up @@ -1170,7 +1179,7 @@ export class Viewer {
if (this.dropInMode) this.updateForDropInMode(renderer, camera);
if (!this.initialized || !this.splatRenderingInitialized) return;
if (this.controls) this.controls.update();
this.splatMesh.updateVisibleRegionFadeDistance();
this.splatMesh.updateVisibleRegionFadeDistance(this.sceneRevealMode);
this.updateSplatSort();
this.updateForRendererSizeChanges();
this.updateSplatMesh();
Expand Down Expand Up @@ -1488,8 +1497,6 @@ export class Viewer {
return tempMax.copy(node.max).sub(node.min).length();
};

const MaximumDistanceToRender = 125;

return function(gatherAllNodes = false) {

this.getRenderDimensions(renderDimensions);
Expand Down Expand Up @@ -1533,8 +1540,7 @@ export class Viewer {
const ns = nodeSize(node);
const outOfFovY = cameraAngleYZDot < (cosFovYOver2 - .6);
const outOfFovX = cameraAngleXZDot < (cosFovXOver2 - .6);
if (!gatherAllNodes && ((outOfFovX || outOfFovY ||
distanceToNode > MaximumDistanceToRender) && distanceToNode > ns)) {
if (!gatherAllNodes && ((outOfFovX || outOfFovY) && distanceToNode > ns)) {
continue;
}
splatRenderCount += node.data.indexes.length;
Expand Down
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { AbortablePromise } from './AbortablePromise.js';
import { SceneFormat } from './loaders/SceneFormat.js';
import { WebXRMode } from './webxr/WebXRMode.js';
import { RenderMode } from './RenderMode.js';
import { SceneRevealMode } from './SceneRevealMode.js';

export {
PlyParser,
Expand All @@ -33,5 +34,6 @@ export {
AbortablePromise,
SceneFormat,
WebXRMode,
RenderMode
RenderMode,
SceneRevealMode
};
6 changes: 4 additions & 2 deletions src/splattree/SplatTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ class SplatSubTree {
let splatTreeWorker;
function createSplatTreeWorker(self) {

let WorkerSplatTreeNodeIDGen = 0;

class WorkerBox3 {

constructor(min, max) {
Expand Down Expand Up @@ -112,7 +114,7 @@ function createSplatTreeWorker(self) {
}

class WorkerSplatTreeNode {
static idGen = 0;

constructor(min, max, depth, id) {
this.min = [min[0], min[1], min[2]];
this.max = [max[0], max[1], max[2]];
Expand All @@ -122,7 +124,7 @@ function createSplatTreeWorker(self) {
this.depth = depth;
this.children = [];
this.data = null;
this.id = id || WorkerSplatTreeNode.idGen++;
this.id = id || WorkerSplatTreeNodeIDGen++;
}

}
Expand Down

0 comments on commit bdf7b1c

Please sign in to comment.