I have a GLB files that I smashed down from 1.5G to 35mb using Draco compression and I’m trying to get it to load faster. I thought using the Draco loader might help but I don’t know how to load it. I’m new to Three.js and the instructions must be a bit advance for me to understand. I took a stab at it and my code is below. After adding the code I didn’t notice my model loading any faster.
I’d just like my model to load as fast as possible. Any information is appreciated. Thank you.
My project is linked below. It takes a while to load and the loading bar doesn’t seem to be showing up. Please be patient with it.
<!doctype html>
<html lang="en">
<head>
<title><model-viewer> template</title>
<meta charset="utf-8">
<meta name="description" content="<model-viewer> template">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link type="text/css" href="./styles.css" rel="stylesheet"/>
<!-- Include Three.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<!-- Include Draco decoder -->
<script src="https://cdn.jsdelivr.net/npm/three/examples/js/libs/draco/draco_decoder.js"></script>
<!-- Include Draco loader -->
<script src="https://cdn.jsdelivr.net/npm/three/examples/js/loaders/DRACOLoader.js"></script>
</head>
<body>
<!-- <model-viewer> HTML element -->
<model-viewer src="atv-1.gltf" ar ar-modes="webxr scene-viewer quick-look" camera-controls touch-action="pan-y" disable-pan tone-mapping="commerce" poster="poster.png" shadow-intensity="1.8" environment-image="-clarens_midday_1k.hdr" exposure="2" camera-orbit="24.04deg 84.85deg 9.837m" field-of-view="30deg">
<button class="Hotspot" slot="hotspot-1" id="hotspot-1" data-position="0.6689565723854323m 1.6544605146550801m 0.9353069082455452m" data-normal="0.8107748143522527m 0.0025009121046661318m 0.5853528387654023m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Auxiliary Front Sensors.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-2" id="hotspot-2" data-position="0.48340941571993584m 1.7489946734053206m 0.9089996688932045m" data-normal="0.003917392155032962m -0.17240132674140898m 0.9850190031550183m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Mine-hardened Tri-cameras.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-3" id="hotspot-3" data-position="0.6542449230858935m 0.9657232659198631m 1.9435799086709165m" data-normal="-0.0016062900459600635m 0.6756733487086103m 0.737199393432456m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Polaris Pro R4 Ultimate.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-7" id="hotspot-7" data-position="1.0022329080480814m 1.4644457644245366m -0.1531226408665525m" data-normal="0.0027045046512102003m 0.0013995088565950317m 0.9999953635040274m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Autonomy Computer.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-8" id="hotspot-8" data-position="1.1432403529183388m 1.1794797410704478m 0.915896420102363m" data-normal="0.7446811280326255m 0.6456696895238259m 0.16899902242990245m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Sensor Protection.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-9" id="hotspot-9" data-position="1.5749757950516305m 0.6502616260564937m -1.7494980168508585m" data-normal="0.9810055579164411m 0.172700125553546m -0.08833324386006633m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Capable DBW Retrofit.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-11" id="hotspot-11" data-position="0.7739309368785187m 1.7320756702581286m -1.3960181700116374m" data-normal="-0.0024744129783826102m -0.4073778600403854m -0.9132563475987062m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>lasers.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-12" id="hotspot-12" data-position="0.48300115474661803m 1.4216854021153018m -1.0922254388158366m" data-normal="-0.002704364653785577m -0.001399842799765007m -0.9999953634152289m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Reliable Cooling.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-13" id="hotspot-13" data-position="1.2153281525858806m 0.5419904616877063m -1.4079768611667498m" data-normal="-0.06808591953966726m 0.4202168904318171m -0.9048657759890427m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Ruggedization Kit.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-14" id="hotspot-14" data-position="0.4380011609612441m 0.49028111424493676m -1.6847507206820689m" data-normal="-0.03307149570457462m 0.44250846311157294m -0.8961543038151947m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Reliable Driveline Sensing.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<button class="Hotspot" slot="hotspot-15" id="hotspot-15" data-position="-0.123790090278318m 1.0914742537496784m -0.3988344909580315m" data-normal="-0.9945214839332801m -0.05462290660050085m -0.08912550740197588m" data-visibility-attribute="visible" z-index="1"><div class="HotspotAnnotation" style="color:black;font-size:15px;"><strong>Dual Fire Suppression.</strong></div>
<p align="left"><font color="black" face="sans-serif" size="1px" font-weight="100"></font></p></button>
<!-- <Three.js interface elements -->
<script src="script.js"></script>
<!-- Loads <model-viewer> for browsers: -->
<script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.2.0/model-viewer.min.js"></script>
<!-- This is one of 9 scripts I wrote (I don't know how do to an array) Clicking the button changes the class that includes the description/popup box
but it doesn't close when another button is clicked-->
<script>
function toggleHotspotAnnotation(event) {
var hotspotId = event.target.id;
var HotspotAnnotation = document.querySelectorAll("#" + hotspotId + " .HotspotAnnotation")
HotspotAnnotation[0].classList.toggle("HotspotAnnotation2");
// Remove the class from all other hotspots
var allHotspots = document.querySelectorAll(".Hotspot");
allHotspots.forEach(function (hotspot) {
if (hotspot.id !== hotspotId) {
var hotspotAnnotations = hotspot.querySelectorAll(".HotspotAnnotation");
hotspotAnnotations.forEach(function (annotation) {
annotation.classList.remove("HotspotAnnotation2");
});
}
});
}
document.addEventListener("click", function (event) {
if (event.target.classList.contains("Hotspot")) {
toggleHotspotAnnotation(event);
}
});
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
</script>
<div class="progress-bar show" slot="progress-bar">
<div class="update-bar"></div>
</div>
<!-- <button slot="ar-button" id="ar-button">
View in your space
</button>
<div id="ar-prompt">
<img src="ar_hand_prompt.png">
</div>-->
</model-viewer>
</body>
</html>
Here is the JS
// Handles loading the events for <model-viewer>'s slotted progress bar
const onProgress = (event) => {
const progressBar = event.target.querySelector('.progress-bar');
const updatingBar = event.target.querySelector('.update-bar');
updatingBar.style.width = `${event.detail.totalProgress * 100}%`;
if (event.detail.totalProgress === 1) {
progressBar.classList.add('hide');
event.target.removeEventListener('progress', onProgress);
} else {
progressBar.classList.remove('hide');
}
};
// Import necessary modules
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
// Create a new instance of DRACOLoader
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three/examples/js/libs/draco/');
// Create a new instance of GLTFLoader and set Draco loader
const gltfLoader = new GLTFLoader();
gltfLoader.setDRACOLoader(dracoLoader);
// Load the GLB model
gltfLoader.load(
'FINAL62.glb', // Replace 'FINAL62.glb' with the path to your GLB model
function(gltf) {
// Add the loaded model to the scene
scene.add(gltf.scene);
},
// Optional: onProgress callback
function(xhr) {
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
// Optional: onError callback
function(error) {
console.error('An error occurred while loading the model', error);
}
);
document.querySelector('model-viewer').addEventListener('progress', onProgress);