Hello! I’m currently working with three.js to load OBJ files. I’ve encountered an issue where the 3D model doesn’t render correctly and appears broken when viewed in Chrome. However, when I check the same URL in Firefox, everything looks fine. Any insights on how to resolve this?
I used svelte with three.js
Here’s my code.
let scene: THREE.Scene;
let camera: THREE.PerspectiveCamera;
let renderer: THREE.WebGLRenderer;
onMount(async () => {
const url = new URLSearchParams(window.location.search);
const ratio = 0.5833;
const browserHeight = window.innerHeight;
modelHeight = Math.floor(browserHeight * ratio) + 'px';
scene = initScene();
camera = initCamera();
renderer = initRenderer(container);
const controls: OrbitControls = initControls(camera, renderer.domElement);
controls.enableDamping = true;
camera.position.z = 70;
loadObj(scene);
window.addEventListener('resize', onWindowResize, false);
function animate(): void {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
renderer.setSize(container.offsetWidth, container.offsetHeight);
animate();
updateCameraAndRenderer();
});
function initScene(): THREE.Scene {
const scene: THREE.Scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
const ambientLight: THREE.AmbientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
const directionalLight: THREE.DirectionalLight = new THREE.DirectionalLight(
0xffffff,
0.5
);
directionalLight.position.set(0, 1, 1);
scene.add(directionalLight);
return scene;
}
let initialCameraState = {
position: new THREE.Vector3(),
rotation: new THREE.Euler(),
zoom: 1,
};
function initCamera(): THREE.PerspectiveCamera {
const cam: THREE.PerspectiveCamera = new THREE.PerspectiveCamera(
50,
window.innerWidth / window.innerHeight,
0.1,
1000
);
cam.position.z = 5;
cam.position.y = 10;
initialCameraState.position.copy(cam.position);
initialCameraState.rotation.copy(cam.rotation);
initialCameraState.zoom = cam.zoom;
return cam;
}
function resetCameraToInitialState() {
camera.position.copy(initialCameraState.position);
camera.rotation.copy(initialCameraState.rotation);
camera.zoom = initialCameraState.zoom;
camera.position.z = 70;
camera.updateProjectionMatrix();
}
function initRenderer(container: HTMLElement): THREE.WebGLRenderer {
const rend: THREE.WebGLRenderer = new THREE.WebGLRenderer({
antialias: true,
});
if (container) {
rend.setSize(window.innerWidth, window.innerHeight);
container.appendChild(rend.domElement);
return rend;
}
}
function getContainerSize() {
return {
width: container.clientWidth,
height: container.clientHeight,
};
}
function updateCameraAndRenderer() {
const { width, height } = getContainerSize();
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
}
function onWindowResize(): void {
updateCameraAndRenderer();
}
function initControls(
camera: THREE.PerspectiveCamera,
rendererElement: HTMLElement
): OrbitControls {
const controls: OrbitControls = new OrbitControls(camera, rendererElement);
controls.enableDamping = true;
return controls;
}
function loadObj(scene: THREE.Scene): void {
const objLoader: OBJLoader = new OBJLoader();
objLoader.load($mesh_url, (object: THREE.Object3D) => {
const box: THREE.Box3 = new THREE.Box3().setFromObject(object);
const size = box.getSize(new THREE.Vector3());
const center = box.getCenter(new THREE.Vector3());
object.position.x += object.position.x - center.x;
object.position.y += object.position.y - center.y;
object.position.z += object.position.z - center.z;
const maxDim = Math.max(size.x, size.y, size.z);
const fov = camera.fov * (Math.PI / 180);
let cameraZ = Math.abs((maxDim / 2) * Math.tan(fov * 2));
cameraZ *= 1.1;
const minZ = box.min.z;
const cameraToFarEdge = minZ < 0 ? -minZ + cameraZ : cameraZ - minZ;
const far = camera.position.z + cameraToFarEdge * 3;
camera.far = far;
camera.updateProjectionMatrix();
scene.add(object);
updateCameraAndRenderer();
});
}