Started a new thread with a link to the app that is now live:
@dllb is reporting some very troubling statistics though. For them it takes a whopping 15-22 seconds in firefox to load the scene after downloading.
Since last posting on this thread I managed to get it down to around 2 seconds on Firefox and 0.5 on Chrome by following @Fyrestar’s advice and essentially make it so every material uses the same constants, resulting in far fewer shaders, I run the following code on the gltf resource before adding to the scene:
var create_color_texture = (col)=>{
/** @type {HTMLCanvasElement} */
var canvas = document.createElement("CANVAS");
canvas.width = canvas.height = 2;
/** @type {CanvasRenderingContext2D } */
var ctx = canvas.getContext("2d");
ctx.fillStyle = col;
ctx.fillRect(0,0,canvas.width, canvas.height);
var tex = new THREE.CanvasTexture(canvas);
tex.format = THREE.RGBAFormat;
tex.wrapS = THREE.ClampToEdgeWrapping;
tex.wrapT = THREE.ClampToEdgeWrapping;
return tex;
};
var black_tex = create_color_texture("black");
var white_tex = create_color_texture("white");
var normal_tex = create_color_texture("#8080ff");
/** @param {THREE.ColorRepresentation} c */
var is_black = (c)=>{
return c.r == 0 && c.g == 0 && c.b == 0;
}
/** @param {THREE.MeshPhysicalMaterialParameters} m */
var get_material = (m)=>{
/** @type {THREE.MeshPhysicalMaterialParameters} */
var props = {
color: m.color,
map: m.map || white_tex,
normalMap: m.normalMap || normal_tex,
normalScale: m.normalScale,
emissive: m.emissive,
emissiveMap: m.emissiveMap || (is_black(m.emissive) ? black_tex : white_tex),
emissiveIntensity: m.emissiveIntensity,
roughnessMap: m.roughnessMap || white_tex,
roughness: m.roughness,
metalnessMap: m.metalnessMap || white_tex,
metalness: m.metalness,
envMap: this.env_map || null,
envMapIntensity: m.metalness ? 1 : 0,
side: THREE.DoubleSide,
transparent: m.transparent,
opacity: m.opacity,
vertexColors: true,
flatShading:false,
};
var hash = JSON.stringify(Object.values(props).map(v=>{
if (v && v.uuid) return v.uuid
return v;
}));
if (!new_materials[hash]) {
var type = (props.transmission) ? THREE.MeshPhysicalMaterial : THREE.MeshStandardMaterial;
new_materials[hash] = new type(props);
}
return new_materials[hash];
}
gltf.scenes.forEach(s=>s.traverse((o)=>{
if (o.material) {
o.material = get_material(o.material);
}
if (o.geometry) {
/** @type {THREE.BufferGeometry} */
var geom = o.geometry;
var attrib = geom.getAttribute('color');
if (!attrib) {
geom.setAttribute("color", new THREE.BufferAttribute(new Float32Array(3 * geom.attributes.position.count).fill(1), 3));
}
}
}));
On every machine I’ve tested it on since optimizing the shader compilation it’s been initializing much faster, so what’s going on with @dllb I have no idea.