Summary of common problems encountered in Three.js development and performance optimization

Summary of some problems encountered in Three.js development

1. Loading external model files cannot be displayed in the scene:

(1) Make sure whether the current file content can be read, search for errors in the Javascript console, and make sure that when you call .load(), you use the onError callback function to output the result. If err is output, it means the current glb file The content cannot be read. Try changing to a new glb file.

	const loader = new GLTFLoader()
	loader.load('/three/1.glb', (result) => {
    
    
			 console.log(result)
			}, () => {
    
    
			}, (err) => {
    
    
				console.log(err)
		})

(2) Try to enlarge or reduce the model to 1000 times its original size. Many models scale differently, and large models may not display if the camera is inside the model. Or you can set the appropriate scaling value according to the model scale after the model is loaded.

		//设置模型位置
		this.model.updateMatrixWorld()
		const box = new THREE.Box3().setFromObject(this.model);
		const size = box.getSize(new THREE.Vector3());
		const center = box.getCenter(new THREE.Vector3());
		// 计算缩放比例
		const maxSize = Math.max(size.x, size.y, size.z);
		const targetSize = 2.5; // 目标大小
		const scale = targetSize / (maxSize > 1 ? maxSize : .5);
		this.model.scale.set(scale, scale, scale)
	     // 设置控制器最小缩放值
		this.controls.maxDistance = size.length() * 10
		// 设置相机位置
		this.camera.position.set(0, 2, 6)
		// 设置相机坐标系
		this.camera.lookAt(center)
		this.camera.updateProjectionMatrix();

(3) Increase the value far of the far end surface of the camera . If the value of the far end surface of the camera frustum is set too small when creating the camera, the model will not be displayed correctly.

this.camera = new THREE.PerspectiveCamera(45, clientWidth / clientHeight, 0.25, 100)
this.camera.far = 2000
this.camera.updateProjectionMatrix()

(4) Try adding a light source and changing its position. Models may be hidden in darkness.

       // 创建一个平行光
		this.directionalLight = new THREE.DirectionalLight('#1E90FF', 1)
		this.directionalLight.position.set(-1.44, 2.2, 1)
		this.directionalLight.castShadow = true
		this.scene.add(this.directionalLight)

2. The glow effect of the model material affects the normal display of the background image

(1) Process the background image separately in scene animation frame rendering

	sceneAnimation() {
    
    
		this.renderAnimation = requestAnimationFrame(() => this.sceneAnimation())
		// 将不需要处理辉光的材质进行存储备份
		this.scene.traverse((v) => {
    
    
			if (v instanceof THREE.Scene) {
    
    
				this.materials.scene = v.background
				v.background = null
			}
			if (!this.glowMaterialList.includes(v.name) && v.isMesh) {
    
    
				this.materials[v.uuid] = v.material
				v.material = new THREE.MeshBasicMaterial({
    
     color: 'black' })
			}
		})
		this.glowComposer.render()
		// 在辉光渲染器执行完之后在恢复材质原效果
		this.scene.traverse((v) => {
    
    
			if (this.materials[v.uuid]) {
    
    
				v.material = this.materials[v.uuid]
				delete this.materials[v.uuid]
			}
			if (v instanceof THREE.Scene) {
    
    
				v.background = this.materials.scene
				delete this.materials.scene
			}
		})

		this.effectComposer.render()
	}

3. When the window size changes, the scene pixels become blurred.

Update camera, renderer and other related information in the window listening method

	window.addEventListener("resize", this.onWindowResize.bind(this))
				// 监听窗口变化
	onWindowResize() {
    
    
		const {
    
     clientHeight, clientWidth } = this.container
		//调整屏幕大小
		this.camera.aspect = clientWidth / clientHeight //摄像机宽高比例
		this.camera.updateProjectionMatrix() //相机更新矩阵,将3d内容投射到2d面上转换
		this.renderer.setSize(clientWidth, clientHeight)
		this.effectComposer.setSize(clientWidth, clientHeight)
		this.glowComposer.setSize(clientWidth, clientHeight)
	}
			

4. Modifying the position (x, y, z) of the material has no actual effect

Materials with model material type Mesh support position modification.

	const mesh = this.model.getObjectByName(name)
	if(mesh.type == 'Mesh){
    
    
        mesh.position.set(1,10,1)
   }

5. In the material setting grid, transparency and color have no actual effect or cause the material display to be incorrect?

The six materials that three.js supports to modify the mesh, transparency and color are:
MeshBasicMaterial, MeshLambertMaterial, MeshPhongMaterial, MeshStandardMaterial, MeshPhysicalMaterial, MeshToonMaterial

6. Mouse (click, drag, zoom, move) and other operations do not affect the scene content

// 启用或禁用摄像机平移,默认为true。
this.controls.enablePan = false
// 当设置为false时,控制器将不会响应用户的操作。默认值为true。
thsi.controls.enabled =false
// 启用或禁用摄像机水平或垂直旋转。默认值为true。
thsi.controls.enableRotate  =false
// 启用或禁用摄像机的缩放。
thsi.controls.enableZoom =false

7. Convert three.js color values ​​into ordinary css values

const colot = new THREE.Color(colorRGB).getStyle()

8. When adjusting the camera angle, some material contents of the model are incompletely displayed or not displayed.

Setting the frustumCulled value to false will render regardless of whether it is in the camera view frustum.

   this.model.traverse(item => {
    
    
        if (item.isMesh && item.material) {
    
    
            item.frustumCulled = false  
        }
    })

About performance optimization in Three.js development

Clear timers , event listeners , animation frames and other related methods in the code when the page is closed, destroyed and jumped away . Release the material memory in the scene and clear the scene and model related information

   // 清除模型数据
	onClearModelData(){
    
    
		cancelAnimationFrame(this.rotationAnimationFrame)
		cancelAnimationFrame(this.renderAnimation)
		cancelAnimationFrame(this.animationFrame)
		this.container.removeEventListener('click', this.onMouseClickModel)
		this.container.removeEventListener('mousedown', this.onMouseDownModel)
		this.container.removeEventListener('mousemove', this.onMouseMoveModel)
		window.removeEventListener("resize", this.onWindowResize)
		// 材质释放内存
	 	this.scene.traverse((v) => {
    
    
			  if (v.type === 'Mesh') {
    
    
						v.geometry.dispose();
						v.material.dispose();
		    	}
		  })
		  // 清除场景和模型相关信息
	    this.model.clear()
        this.scene.clear()
	}

For the complete code, please refer to: https://gitee.com/ZHANG_6666/Three.js3D develops a 3D model visual editor based on three.js

Insert image description here

Guess you like

Origin blog.csdn.net/weixin_43835425/article/details/132665897