以下是一些 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 实现鼠标拾取(点击选择物体)。通常步骤如下:
- 监听鼠标事件
- 使用
Raycaster
投射射线 - 计算与哪些对象相交
- 响应用户操作
🧱 几何与材质篇
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 项目中的集成示例,请告诉我即可提供。
发表回复