以下是一些 Three.js 相关的前端面试题及其参考答案,涵盖了基础概念、常用 API、渲染原理、性能优化等方面,适合用于准备初中高级面试。


🧠 基础篇

1. Three.js 是什么?有什么应用场景?

参考答案:
Three.js 是一个基于 WebGL 封装的 JavaScript 3D 渲染库,用于在网页中创建和展示 3D 图形。应用场景包括:

  • 产品展示(如汽车、家具)
  • 可视化数据分析
  • 游戏开发
  • 虚拟现实(VR)/增强现实(AR)
  • 数字孪生、建筑可视化等

2. 使用 Three.js 创建一个基本的 3D 场景需要哪些核心元素?

参考答案:
一个基本的 Three.js 场景包含以下元素:

  • Scene:场景容器
  • Camera:相机(常用 PerspectiveCamera)
  • Renderer:渲染器(如 WebGLRenderer)
  • Mesh:包含几何体(Geometry)+ 材质(Material)
  • Light:光源(如 DirectionalLight、AmbientLight)
  • 渲染循环(animation loop)
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(...);
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
renderer.render(scene, camera);

3. 如何在 Three.js 中添加交互功能?

参考答案:
Three.js 本身不处理交互,但可结合 Raycaster 实现鼠标拾取(点击选择物体)。通常步骤如下:

  1. 监听鼠标事件
  2. 使用 Raycaster 投射射线
  3. 计算与哪些对象相交
  4. 响应用户操作

🧱 几何与材质篇

4. 常见的几何体有哪些?如何自定义几何体?

参考答案:
常见几何体:

  • BoxGeometry(立方体)
  • SphereGeometry(球体)
  • PlaneGeometry(平面)
  • CylinderGeometry(圆柱体)
  • TorusGeometry(圆环)
    自定义可使用 BufferGeometry 并设置 position、normal、uv 等属性。

5. MeshBasicMaterial 和 MeshStandardMaterial 有什么区别?

参考答案:

  • MeshBasicMaterial:不受光照影响,性能好,常用于调试。
  • MeshStandardMaterial:基于物理光照模型(PBR),可实现真实光影效果,受光照影响。

🔧 渲染与优化篇

6. 如何实现模型动画?

参考答案:

  • 关键帧动画:使用 THREE.AnimationMixer + .fbx / .gltf 动画数据
  • 骨骼动画:支持 SkinnedMesh 骨骼蒙皮
  • 手动动画:在 requestAnimationFrame 中更新对象的位置/旋转

7. 如何提高 Three.js 性能?

参考答案:

  • 合理使用 BufferGeometry 和 InstancedMesh
  • 降低面数,多用低模模型
  • 使用 LOD(Level of Detail)
  • 使用贴图代替几何细节
  • 合理开启 frustum culling(视锥剔除)
  • 减少灯光数量或使用 lightmap
  • 对纹理进行压缩、缓存

🎨 进阶篇

8. Three.js 如何实现加载外部模型?

参考答案:
使用加载器(Loaders)加载外部格式,例如:

const loader = new GLTFLoader();
loader.load('model.gltf', (gltf) => {
  scene.add(gltf.scene);
});

常用格式:

  • .glb / .gltf(推荐)
  • .obj
  • .fbx

9. 如何实现环境光、阴影和反射?

参考答案:

  • 环境光:THREE.AmbientLight
  • 阴影:设置 castShadow 和 receiveShadow,启用 renderer.shadowMap.enabled = true
  • 反射:
    • 环境贴图(envMap
    • 使用 CubeCamera 实时反射
    • 使用 PMREMGenerator 生成模糊反射贴图

10. 如何在项目中集成 Three.js?

参考答案:

  • 通过 <script src="three.min.js"> 引入
  • 使用 npm 安装:npm install three
  • 配合 bundler(如 Webpack/Vite)
  • 可结合 React(如使用 react-three-fiber

以下是配合 Three.js 前端面试题 的一些典型代码示例,涵盖基础场景搭建、模型加载、鼠标拾取、动画等方面,便于理解每个知识点在实际项目中的应用。


✅ 1. 创建基础 3D 场景

import * as THREE from 'three';

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 添加一个立方体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 添加光源
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
scene.add(light);

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  cube.rotation.y += 0.01;
  renderer.render(scene, camera);
}

animate();

✅ 2. 加载外部 .glb/.gltf 模型

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const loader = new GLTFLoader();
loader.load('model.gltf', (gltf) => {
  scene.add(gltf.scene);
}, undefined, (error) => {
  console.error(error);
});

确保你已经安装了:

npm install three

✅ 3. 实现鼠标拾取(点击物体)

import { Raycaster, Vector2 } from 'three';

const raycaster = new Raycaster();
const mouse = new Vector2();

function onMouseClick(event) {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObjects(scene.children);

  if (intersects.length > 0) {
    console.log('点击了:', intersects[0].object);
    intersects[0].object.material.color.set(0xff0000);
  }
}

window.addEventListener('click', onMouseClick, false);

✅ 4. 添加阴影效果

renderer.shadowMap.enabled = true;

light.castShadow = true;
cube.castShadow = true;
cube.receiveShadow = true;

// 添加地面
const planeGeometry = new THREE.PlaneGeometry(10, 10);
const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x999999 });
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add(plane);

✅ 5. 创建环境贴图反射(立方体天空盒)

const loader = new THREE.CubeTextureLoader();
const texture = loader.load([
  'px.jpg', 'nx.jpg',
  'py.jpg', 'ny.jpg',
  'pz.jpg', 'nz.jpg',
]);
scene.background = texture;

const reflectiveMaterial = new THREE.MeshStandardMaterial({
  envMap: texture,
  metalness: 1,
  roughness: 0
});

const sphere = new THREE.Mesh(
  new THREE.SphereGeometry(1, 32, 32),
  reflectiveMaterial
);
scene.add(sphere);

✅ 6. 创建骨骼动画 / 动画混合器(GLTF)

let mixer;
loader.load('animated_model.glb', (gltf) => {
  const model = gltf.scene;
  scene.add(model);

  mixer = new THREE.AnimationMixer(model);
  gltf.animations.forEach((clip) => {
    mixer.clipAction(clip).play();
  });
});

const clock = new THREE.Clock();
function animate() {
  requestAnimationFrame(animate);
  const delta = clock.getDelta();
  if (mixer) mixer.update(delta);
  renderer.render(scene, camera);
}

如需我整理成一份完整的 PDF / Markdown 文件(包含面试题+代码+答案),或希望包含 Vue、React、Webpack/Vite 项目中的集成示例,请告诉我即可提供。