五分钟掌握threejs面试高频考点与实战技巧
1. Three.js基础概念与核心组件第一次接触Three.js时我被它强大的3D渲染能力震撼到了。简单来说Three.js就是一个能让网页轻松展示3D效果的JavaScript库。想象一下你正在玩网页版的3D游戏或者浏览一个可以360度旋转的产品展示页面背后很可能就是Three.js在发挥作用。Three.js的核心架构就像拍电影一样需要几个关键角色场景(Scene)相当于拍摄场地所有3D物体都在这里相机(Camera)好比导演的取景器决定观众能看到什么渲染器(Renderer)就是摄影机负责把画面拍出来创建一个基础场景的代码示例// 创建场景 const scene new THREE.Scene(); // 创建相机透视相机 const camera new THREE.PerspectiveCamera( 75, // 视野角度 window.innerWidth / window.innerHeight, // 宽高比 0.1, // 近裁剪面 1000 // 远裁剪面 ); // 创建渲染器 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.MeshBasicMaterial({ color: 0x00ff00 }); const cube new THREE.Mesh(geometry, material); scene.add(cube); // 设置相机位置 camera.position.z 5; // 渲染循环 function animate() { requestAnimationFrame(animate); cube.rotation.x 0.01; cube.rotation.y 0.01; renderer.render(scene, camera); } animate();2. 面试必考的光照与材质系统在实际项目中我发现光照设置是让3D场景活起来的关键。Three.js提供了6种光源类型每种都有独特用途环境光(AmbientLight)像阴天的光线均匀照亮所有物体平行光(DirectionalLight)模拟太阳光所有光线平行点光源(PointLight)像灯泡向四周均匀发光聚光灯(SpotLight)类似手电筒有锥形光照范围半球光(HemisphereLight)模拟天空和地面的自然光矩形区域光(RectAreaLight)平面发光源适合LED屏幕效果材质决定了物体表面的视觉效果。常用的材质包括MeshBasicMaterial基础材质不受光照影响MeshPhongMaterial有光泽的塑料质感MeshLambertMaterial哑光材质MeshStandardMaterial基于物理渲染(PBR)的标准材质// 创建带纹理的PBR材质 const textureLoader new THREE.TextureLoader(); const texture textureLoader.load(textures/brick_diffuse.jpg); const normalMap textureLoader.load(textures/brick_normal.jpg); const material new THREE.MeshStandardMaterial({ map: texture, normalMap: normalMap, roughness: 0.8, metalness: 0.2 });3. 模型加载与性能优化实战处理3D模型时我踩过不少性能坑。GLTF格式是目前Three.js中最推荐的模型格式它专为Web设计体积小、加载快。使用GLTFLoader的典型流程import { GLTFLoader } from three/examples/jsm/loaders/GLTFLoader; const loader new GLTFLoader(); loader.load( models/scene.gltf, function (gltf) { scene.add(gltf.scene); }, undefined, function (error) { console.error(加载出错:, error); } );性能优化是面试必问的重点我总结了几条实战经验模型压缩使用gltf-pipeline工具压缩模型实例化渲染对重复物体使用InstancedMeshLOD技术根据距离显示不同精度的模型视锥剔除只渲染相机视野内的物体合并几何体减少绘制调用次数// 实例化渲染示例 const geometry new THREE.BoxGeometry(); const material new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const count 100; const mesh new THREE.InstancedMesh(geometry, material, count); for (let i 0; i count; i) { const matrix new THREE.Matrix4(); matrix.setPosition(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50); mesh.setMatrixAt(i, matrix); } scene.add(mesh);4. 高级特性与交互实现Three.js的交互功能让3D场景真正活起来。Raycaster(射线投射)是实现物体点击检测的核心技术const raycaster new THREE.Raycaster(); const mouse new THREE.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); } } window.addEventListener(click, onMouseClick, false);动画系统是另一个亮点。Three.js提供了多种动画实现方式直接修改属性简单但不够灵活Tween.js库适合补间动画AnimationMixer处理骨骼动画Shader动画最高性能但最复杂// 使用AnimationMixer播放骨骼动画 const mixer new THREE.AnimationMixer(model); const action mixer.clipAction(gltf.animations[0]); action.play(); function animate() { requestAnimationFrame(animate); const delta clock.getDelta(); mixer.update(delta); renderer.render(scene, camera); }后期处理能为场景添加电影级特效。常见的后期效果包括抗锯齿(SMAA)景深(Depth of Field)辉光(Bloom)色彩校正(Color Correction)// 创建后期处理效果链 const composer new THREE.EffectComposer(renderer); composer.addPass(new THREE.RenderPass(scene, camera)); const bloomPass new THREE.BloomPass( 1.5, // 强度 25, // 内核大小 4, // 采样数 256 // 渲染目标分辨率 ); composer.addPass(bloomPass); function animate() { requestAnimationFrame(animate); composer.render(); }