Parts of GLB object disappear in certain angles and zoom

Hello, as Im new to Three.js I still dont know how specific things are named, Im sure that the thing is really primitive to find and either to fix, but I just dont know how its named and even how to fix it.
So, Im using OrbitControls to zoom and rotate. However, sometimes when I zoom pretty close (like 50, which is around a half of the entire model), some parts disappear, for example the head of the model. Id like to prevent this from happening. Im using GLTFLoader. Any suggestions?

1 Like

This usually happens because the near value of your camera is too high. Try to lower it to a value like e.g. 0.01.

I have my camera set like this:

camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 2000);

As far as I know, the 3rd value is near, but still, as I zoom in and rotate to some angles, the objects simply disappear (I have single model and sometimes the head disappears. Creepy)

Another possible reason is that certain model parts are discarded by the renderer because of view frustum culling. Try to traverse through your glTF asset and set frustumCulled to false for all objects.

gltf.scene.traverse( function( object ) {

    object.frustumCulled = false;

} );
10 Likes

Once again, thank you very much for your time and help!
For those who might come here afterwards, I applied the solution like this:
(Before):

		const loader = new GLTFLoader();
	loader.load("agents/model_" + skin + ".glb", function(gltf) {
		const model = gltf.scene;
		scene.add(model);
		model.position.y = -50;
		const animations = gltf.animations;
		mixer = new THREE.AnimationMixer(model);
		$("._3dcontent h1").fadeOut();
		mixer.clipAction(animations[0]).play();
	}, onProgress, onError);

(After):

		const loader = new GLTFLoader();
	loader.load("agents/model_" + skin + ".glb", function(gltf) {
		const model = gltf.scene;
		scene.add(model);
		model.position.y = -50;
		model.traverse(function(obj) { obj.frustumCulled = false; });
		const animations = gltf.animations;
		mixer = new THREE.AnimationMixer(model);
		$("._3dcontent h1").fadeOut();
		mixer.clipAction(animations[0]).play();
	}, onProgress, onError);

Anyways, thanks, @Mugen87

2 Likes

I registered account only to say thank you! You literally saved my life because I was about to abort the project, delete repository, delete react, everything, throw my computer and go to monastery and pray to all gods to keep sanity, I was dealing with this issue for weeks and I just absolutely happy I finally found this solution OMG.

And since I can’t reply without improving conversation on these forums, I’ll leave a code for react-three-fiber with useState and frustumCulled:

import React, { useState } from 'react'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

function ModelComponent(props) {
   const loader = new GLTFLoader()
   const [model, setModel] = useState()
   loader.load('/url/to.glb', function(gltf) {
       let gltfModel = gltf.scene
       gltfModel.traverse(function(obj) { obj.frustumCulled = false; });
       setModel(gltfModel)
   });
   return model ? <primitive object={model} dispose={null} /> : null
}
5 Likes

That’s really helpful. Thanks!!

Just came across this topic but also saw this PR and the linked discussion:

I think @Mugen87 provided a better solution there :slight_smile: