gsplat
This commit is contained in:
parent
7bb499656f
commit
14b14f09e3
3 changed files with 143 additions and 0 deletions
39
content/posts/gsplat.md
Normal file
39
content/posts/gsplat.md
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
+++
|
||||||
|
title = "GSplat Demo"
|
||||||
|
date = "2024-02-24"
|
||||||
|
author = "Brooke"
|
||||||
|
description = "Messing around with gsplat.js from huggingface.co"
|
||||||
|
TOC = false
|
||||||
|
+++
|
||||||
|
|
||||||
|
# What is all of this?
|
||||||
|
|
||||||
|
I've been interested in [photogrammetry](https://en.wikipedia.org/wiki/Photogrammetry) and projection scanning for quite a while, but I've never really had a good way of capturing things a bit more artistically. GSplatting, or [3D Gaussian Splatting](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/), is a form of capturing scenes in a way that preserves the visual quality but doesn't provide an actual [polygonal](https://en.wikipedia.org/wiki/Polygonal_modeling) model.
|
||||||
|
|
||||||
|
Unlike photogrammetry, GSplatting provides a fairly realistic gaussian of the captured scene that can be viewed using very little computational resources, this is a big reason why Nvidia is investing time into NeRF (actually something completely different but they're similar in output).
|
||||||
|
|
||||||
|
Anyways, here's a quick demo that allows you to view models in a browser, I may add a few different gaussians that I've been working on, but currently I'm borrowing `bonsai-7k-mini.splat`. You can check out the code [here](https://git.myco.systems/mycosystems/coop.myco.systems/src/branch/main/content/posts/gsplat.md), and [here](https://git.myco.systems/mycosystems/coop.myco.systems/src/branch/main/static/posts/gsplat).
|
||||||
|
|
||||||
|
{{< rawhtml >}}
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="container">
|
||||||
|
<div id="progress-container">
|
||||||
|
<dialog open id="progress-dialog">
|
||||||
|
<p>
|
||||||
|
<label for="progress-indicator">Waiting</label>
|
||||||
|
</p>
|
||||||
|
<progress max="100" id="progress-indicator"></progress>
|
||||||
|
</dialog>
|
||||||
|
</div>
|
||||||
|
<canvas id="canvas"></canvas>
|
||||||
|
<script type="module" src="index.js"></script>
|
||||||
|
</div>
|
||||||
|
<button id="load-button">Load Scene</button>
|
||||||
|
<a class="gsplat-js" href="https://github.com/huggingface/gsplat.js/">gsplat.js</a><a class="gsplat-js"> left click <strong>rotate</strong>, right click <strong>pan</strong></a>
|
||||||
|
</body>
|
||||||
|
{{< /rawhtml >}}
|
||||||
|
|
39
static/posts/gsplat/index.js
Normal file
39
static/posts/gsplat/index.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import * as SPLAT from "https://cdn.jsdelivr.net/npm/gsplat@latest";
|
||||||
|
|
||||||
|
const canvas = document.getElementById("canvas");
|
||||||
|
const progressDialog = document.getElementById("progress-dialog");
|
||||||
|
const progressIndicator = document.getElementById("progress-indicator");
|
||||||
|
const loadButton = document.querySelector("#load-button");
|
||||||
|
const loadingLabel = document.querySelector('#progress-dialog label');
|
||||||
|
|
||||||
|
const renderer = new SPLAT.WebGLRenderer(canvas);
|
||||||
|
const scene = new SPLAT.Scene();
|
||||||
|
const camera = new SPLAT.Camera();
|
||||||
|
const controls = new SPLAT.OrbitControls(camera, canvas);
|
||||||
|
|
||||||
|
loadButton.addEventListener('click', () => {
|
||||||
|
loadingLabel.textContent = 'Loading...';
|
||||||
|
main();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const url = "https://huggingface.co/datasets/dylanebert/3dgs/resolve/main/bonsai/bonsai-7k-mini.splat";
|
||||||
|
await SPLAT.Loader.LoadAsync(url, scene, (progress) => (progressIndicator.value = progress * 100));
|
||||||
|
progressDialog.close();
|
||||||
|
|
||||||
|
const handleResize = () => {
|
||||||
|
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
|
||||||
|
};
|
||||||
|
|
||||||
|
const frame = () => {
|
||||||
|
controls.update();
|
||||||
|
renderer.render(scene, camera);
|
||||||
|
|
||||||
|
requestAnimationFrame(frame);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleResize();
|
||||||
|
window.addEventListener("resize", handleResize);
|
||||||
|
|
||||||
|
requestAnimationFrame(frame);
|
||||||
|
}
|
65
static/posts/gsplat/style.css
Normal file
65
static/posts/gsplat/style.css
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#container {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
gap: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gsplat-js {
|
||||||
|
font-size: 12px !important;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvas {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #EE72F1;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#load-button {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dialog {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 20em;
|
||||||
|
color: white;
|
||||||
|
background-color: #000;
|
||||||
|
border: none;
|
||||||
|
position: relative;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
/* transform: translate(-50%, -50%); */
|
||||||
|
}
|
||||||
|
|
||||||
|
#progress-container {
|
||||||
|
position: absolute;
|
||||||
|
/* top: 50%;
|
||||||
|
left: 50%; */
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
width: 100%;
|
||||||
|
height: 1em;
|
||||||
|
border: none;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress::-webkit-progress-bar {
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress::-webkit-progress-value {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress::-moz-progress-bar {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue