You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用document.getElementById时Three.js地球模型程序卡顿,求优化方案

Three.js地球模型嵌入容器后卡顿的优化方案

问题背景

刚接触Three.js,制作的地球模型程序直接在窗口运行时速度很快,但通过document.getElementById获取容器嵌入后运行极慢,怀疑是贴图使用方式有误,相关代码如下:

JS代码

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/Addons.js';
import getStarField from './getStarfield.js';
import {getFresnelMat} from './getFresnelMat.js';

export function initializeThreeJS(){
var container = document.getElementById('world');

// a scene 

const scene = new THREE.Scene();
scene.background = new THREE.Color( 'gainsboro' );

var camera = new THREE.PerspectiveCamera( 30, container.clientWidth/ container.clientHeight );
    camera.position.set( 2, 5, 10 );
    camera.position.z = 25;


var renderer = new THREE.WebGLRenderer( {antialias: true} );
renderer.setSize( container.clientWidth, container.clientHeight);
renderer.setAnimationLoop( animate );
container.appendChild( renderer.domElement );

const earthGroup = new THREE.Group();
scene.add(earthGroup);

/* 
* Starfield tb implemented
*/

/*
* temporary lighting
*/
var controls = new OrbitControls( camera, renderer.domElement );
    controls.enableDamping = true;

var ambientLight = new THREE.AmbientLight( 'white', 0.5 );
    scene.add( ambientLight );

var light = new THREE.DirectionalLight( 'white', 0.5 );
    light.position.set( 1, 1, 1 );
    scene.add( light );
/* 
* Orbit Controls tb implemented
*/
const loader = new THREE.TextureLoader();
/* 
* Earth Geometry
*/
const geometry = new THREE.IcosahedronGeometry(1, 12);
const material = new THREE.MeshPhongMaterial({
    map: loader.load("./textures/00_earthmap1k.jpg"),
    specularMap: loader.load("./textures/02_earthspec1k.jpg"),
    bumpMap: loader.load("./textures/01_earthbump1k.jpg"),
    bumpScale: 0.04,
  });

const earthMesh = new THREE.Mesh(geometry, material);
earthGroup.add(earthMesh);


/* 
* Function Loop 
*/
function animate() {
    requestAnimationFrame(animate);

    // Rotate the cube
    // Render the scene
    renderer.render(scene, camera);
}

}

HTML代码

<body>
  <div id="container">
    <div id="world" ></div>
</div>
</body>

优化提速方案

1. 修复重复渲染的核心问题

你同时使用了renderer.setAnimationLoop(animate)和requestAnimationFrame(animate),这会让渲染函数每帧被调用两次,直接翻倍消耗GPU资源。删掉其中一个即可,推荐保留renderer.setAnimationLoop(Three.js官方推荐的现代写法):

function animate() {
    // 删掉 requestAnimationFrame(animate);
    renderer.render(scene, camera);
}

2. 优化贴图加载与配置

  • 统一管理资源加载:当前贴图异步加载时直接创建材质,可能导致渲染异常和额外开销。用LoadingManager确保所有贴图加载完成后再初始化地球网格:
const manager = new THREE.LoadingManager();
manager.onLoad = function() {
    // 所有资源加载完成后再创建网格
    const earthMesh = new THREE.Mesh(geometry, material);
    earthGroup.add(earthMesh);
};

const loader = new THREE.TextureLoader(manager);
const earthMap = loader.load("./textures/00_earthmap1k.jpg");
const specularMap = loader.load("./textures/02_earthspec1k.jpg");
const bumpMap = loader.load("./textures/01_earthbump1k.jpg");

const material = new THREE.MeshPhongMaterial({
    map: earthMap,
    specularMap: specularMap,
    bumpMap: bumpMap,
    bumpScale: 0.04,
});
  • 优化纹理采样:给贴图设置滤波参数,减少不必要的计算:
// 对所有加载的贴图设置
earthMap.minFilter = THREE.LinearMipmapLinearFilter;
earthMap.magFilter = THREE.LinearFilter;
specularMap.minFilter = THREE.LinearMipmapLinearFilter;
specularMap.magFilter = THREE.LinearFilter;
bumpMap.minFilter = THREE.LinearMipmapLinearFilter;
bumpMap.magFilter = THREE.LinearFilter;

3. 确保容器尺寸正确

  • 给#world添加明确的CSS样式,避免容器宽高为0导致相机比例异常:
#world {
    width: 100%;
    height: 800px; /* 或使用100vh占满视口高度 */
}
  • 添加窗口 resize 监听,动态调整相机和渲染尺寸,避免渲染分辨率过大:
window.addEventListener('resize', () => {
    camera.aspect = container.clientWidth / container.clientHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(container.clientWidth, container.clientHeight);
});

4. 降低几何体复杂度

IcosahedronGeometry(1, 12)的细分级别12会生成大量顶点,视觉提升有限但性能消耗大。降低到6左右即可平衡效果与性能:

const geometry = new THREE.IcosahedronGeometry(1, 6);

5. 按需关闭抗锯齿

antialias: true会增加GPU负担,如果容器尺寸不大,可暂时关闭测试性能,或根据设备能力自适应开启:

var renderer = new THREE.WebGLRenderer( {antialias: false} );

内容的提问来源于stack exchange,提问作者Jack Holly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 03:43:12