Three.js零基础入门教程|前端3D可视化实战案例附源码

Three.js零基础入门教程|前端3D可视化实战案例附源码 一

文章目录CloseOpen

Three.js基础入门:从环境搭建到核心概念

其实Three.js没你想的那么复杂,它就像一个“前端3D工具箱”,把复杂的WebGL底层代码封装好了,你不用写一堆矩阵运算,直接调用API就能实现3D效果。我去年带过一个实习生小林,他之前只会HTML/CSS/JS,学Three.js的时候,第一天就做出了一个旋转的立方体,兴奋地发了朋友圈。所以你看,入门真的不难,关键是找对方法。

环境搭建:5分钟跑通第一个3D场景

你可能觉得“环境搭建”很麻烦,其实用Vite随便建个项目就行,比配React环境还简单。我通常会推荐这样做:

  • 先新建一个前端项目,用Vite最快:npm create vite@latest threejs-demo -
  • template vanilla
  • ,选Vanilla JS模板(纯JS,没框架干扰)

  • 进入项目安装Three.js:cd threejs-demo && npm install three
  • 打开main.js,把默认代码清空,复制这段基础代码(我写的最简版本,你直接抄就行):
  • // 引入Three.js核心模块
    

    import as THREE from 'three';

    // 创建场景(你要展示的3D世界)

    const scene = new THREE.Scene();

    // 创建相机(相当于你的眼睛,决定看哪里、怎么看)

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

    camera.position.z = 5; // 把相机往后移5个单位,不然会贴在物体上看不见

    // 创建渲染器(把3D场景画到网页上)

    const renderer = new THREE.WebGLRenderer();

    renderer.setSize(window.innerWidth, window.innerHeight); // 渲染器大小等于窗口大小

    document.body.appendChild(renderer.domElement); // 把渲染器生成的canvas加到页面

    // 创建一个立方体(这是你要展示的物体)

    const geometry = new THREE.BoxGeometry(); // 立方体的形状

    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true }); // 绿色线框材质

    const cube = new THREE.Mesh(geometry, material); // 把形状和材质组合成物体

    scene.add(cube); // 把物体放进场景

    // 动画循环(让立方体转起来)

    function animate() {

    requestAnimationFrame(animate);

    cube.rotation.x += 0.01; // 绕X轴旋转

    cube.rotation.y += 0.01; // 绕Y轴旋转

    renderer.render(scene, camera); // 渲染场景

    }

    animate();

  • 运行项目:npm run dev,打开浏览器,你会看到一个绿色的旋转立方体——恭喜,你已经完成了第一个Three.js程序!
  • 小林当时做到这一步的时候,问我:“为什么立方体是线框?我想要实心的。” 你是不是也好奇?其实是MeshBasicMaterial这个材质的问题,它不会受光照影响,适合做线框。你可以把材质换成MeshLambertMaterial,再加个光源,立方体就有立体感了——这就是接下来要讲的核心概念。

    核心概念:用“拍照”类比理解Three.js的4个核心角色

    很多人学Three.js卡在“搞不懂那些概念”,其实你把它想象成“用手机拍3D照片”,一下子就明白了。我画个表格帮你对比:

    Three.js概念 拍照类比 作用
    场景(Scene) 你要拍的风景/人物 存放所有3D物体、光源、相机的“容器”
    相机(Camera) 你的手机 决定从哪个角度、多远看场景(就像手机的焦距、位置)
    物体(Mesh) 风景里的树/人 由“形状”(Geometry)和“材质”(Material)组成,是场景里的可见元素
    渲染器(Renderer) 手机屏幕 把相机“看到”的场景画到网页上(生成canvas元素)

    比如刚才的立方体例子,场景是放立方体的空间,相机在Z轴5的位置“看”立方体,渲染器把看到的画面显示在网页上。你可能会问:“那光源呢?” 就像拍照需要光线,3D场景也需要光源才能让物体有明暗效果。比如你把刚才的材质换成MeshLambertMaterial,再添加一个平行光:

    // 添加光源(平行光,像太阳一样从某个方向照过来)
    

    const light = new THREE.DirectionalLight(0xffffff, 1); // 白色光,强度1

    light.position.set(5, 5, 5); // 光源位置

    scene.add(light);

    // 把材质换成受光照影响的Lambert材质

    const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 });

    刷新页面,你会发现立方体有了阴影效果,看起来更“真实”了。我之前教朋友小张的时候,他一开始总记不住相机参数,后来我让他调camera.position.z的值,从1改到10,观察立方体大小变化,他突然就懂了:“哦!这个值越小,相机离物体越近,看到的物体越大!” 你也可以试试,改改参数,观察变化,比死记硬背效果好得多。

    前端3D可视化实战案例:从基础到进阶

    学会了基础,接下来就是实战了。我发现很多人学技术只看教程不动手,结果看完就忘。其实前端3D开发和做网页一样,多敲代码、多改参数,遇到问题解决问题,进步才快。我整理了3个前端高频场景的案例,每个案例都有完整步骤和源码片段,你跟着做,做完就能直接用到项目里。

    案例1:3D模型加载——让你的网页“站起来”

    现在很多电商网站都用3D模型展示商品,比如鞋子、家具,用户可以360度查看细节,转化率比图片高不少。加载3D模型其实不难,Three.js有专门的加载器,我去年帮一个家具品牌做官网时,就用这个方法实现了沙发的3D展示。

    步骤拆解

  • 准备3D模型:你可以从Sketchfab下载免费模型(选GLB格式,体积小兼容性好),或者让设计师导出。注意模型别太大, 压缩到5MB以内,不然加载太慢。
  • 安装加载器:npm install @tweenjs/tween.js three/addons/loaders/GLTFLoader.js(GLTFLoader是加载GLB/GLTF格式的工具)
  • 编写加载代码:
  • import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
    

    import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 轨道控制器,让用户能拖动旋转模型

    // 创建控制器(用户可以用鼠标拖动旋转模型)

    const controls = new OrbitControls(camera, renderer.domElement);

    controls.enableDamping = true; // 拖动时有惯性,更顺滑

    // 加载GLB模型

    const loader = new GLTFLoader();

    loader.load(

    '/models/sofa.glb', // 模型路径(放在public文件夹下)

    (gltf) => { // 加载成功回调

    scene.add(gltf.scene); // 把模型添加到场景

    gltf.scene.scale.set(0.5, 0.5, 0.5); // 缩放模型(根据模型大小调整)

    gltf.scene.position.set(0, -2, 0); // 调整位置,避免模型太靠上或靠下

    },

    (xhr) => { // 加载进度回调

    console.log(加载进度:${(xhr.loaded / xhr.total 100).toFixed(2)}%);

    },

    (error) => { // 加载错误回调

    console.error('模型加载失败:', error);

    }

    );

    // 动画循环里更新控制器

    function animate() {

    requestAnimationFrame(animate);

    controls.update(); // 让控制器的惯性生效

    renderer.render(scene, camera);

    }

    避坑经验

    :我一开始加载模型时,遇到过“模型显示不全”的问题,后来发现是相机的far参数设太小(默认1000,足够用),或者模型位置不在相机“视野”里。你可以在加载成功后,用console.log(gltf.scene.position)看看模型位置,调整camera.position让相机“对准”模型。 模型材质可能需要调整,比如有些模型自带的材质太暗,可以手动添加环境光:scene.add(new THREE.AmbientLight(0xffffff, 0.5))(环境光像室内灯光,均匀照亮所有物体)。

    案例2:交互式3D场景——让用户“玩”起来

    除了展示模型,你还可以做交互式场景,比如用户点击物体显示信息,或者拖拽物体移动。我之前帮一个博物馆做过“虚拟展厅”,用户点击展品就能弹出介绍,当时用的就是射线投射器(Raycaster)——你可以把它想象成“鼠标点哪里,就发射一条线检测有没有碰到物体”。

    核心代码片段

    // 创建射线投射器和鼠标向量(记录鼠标位置)
    

    const raycaster = new THREE.Raycaster();

    const mouse = new THREE.Vector2();

    // 监听鼠标点击事件

    window.addEventListener('click', (event) => {

    // 把鼠标位置转换成Three.js需要的坐标(-1到1之间)

    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) { // 如果有相交的物体

    const clickedObject = intersects[0].object; // 第一个相交的物体(离相机最近的)

    alert(你点击了:${clickedObject.name}); // 显示物体名称(需要给物体设置name属性)

    }

    });

    比如你可以给立方体设置cube.name = "myCube",点击时就会弹出“你点击了:myCube”。这个功能可以扩展成“点击3D按钮跳转页面”“拖拽物体到指定位置”等,非常实用。

    案例3:动态粒子效果——打造炫酷背景

    粒子效果是前端3D里的“氛围感神器”,比如首页背景的流动粒子、鼠标跟随的粒子群。其实粒子本质是很多小几何体(比如点、三角形)的集合,通过控制每个粒子的位置和运动实现效果。我之前给一个音乐节官网做背景时,用粒子效果模拟“音符流动”,用户反馈特别好。

    基础粒子效果实现

    // 创建粒子系统(点材质+缓冲区几何体,性能更好)
    

    const particlesGeometry = new THREE.BufferGeometry();

    const particlesCount = 1000; // 粒子数量

    // 创建粒子位置数组(每个粒子有x、y、z三个坐标)

    const posArray = new Float32Array(particlesCount 3);

    for (let i = 0; i < particlesCount 3; i++) {

    // 随机位置(范围-100到100,让粒子分布在一个立方体空间里)

    posArray[i] = (Math.random()

  • 0.5) 200;
  • }

    particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3));

    // 粒子材质(点材质,大小2,白色)

    const particlesMaterial = new THREE.PointsMaterial({ size: 2, color: 0x00ff00 });

    // 创建粒子系统并添加到场景

    const particlesMesh = new THREE.Points(particlesGeometry, particlesMaterial);

    scene.add(particlesMesh);

    // 让粒子动起来(在动画循环里更新位置)

    function animate() {

    requestAnimationFrame(animate);

    // 遍历所有粒子,让y轴位置缓慢变化(产生流动感)

    for (let i = 0; i < particlesCount; i++) {

    const i3 = i 3; // 每个粒子有3个坐标(x,y,z)

    posArray[i3 + 1] -= 0.1; // y轴位置减少0.1(向下移动)

    // 如果粒子移出屏幕下方,重置到上方

    if (posArray[i3 + 1] < -100) {

    posArray[i3 + 1] = 100;

    }

    }

    particlesGeometry.attributes.position.needsUpdate = true; // 告诉Three.js位置属性已更新

    renderer.render(scene, camera);

    }

    你可以调整粒子数量、大小、颜色,或者让粒子随鼠标移动(监听mousemove事件改变粒子位置)。我当时做音乐节背景时,还加了粒子颜色渐变,用THREE.AdditiveBlending让粒子重叠时更亮,效果很惊艳。

    如果你想深入学粒子效果,可以看看Three.js的官方粒子示例(链接带nofollow:https://threejs.org/examples/?q=particles),里面有各种炫酷效果的源码。

    其实Three.js入门真的不难,关键是多动手试——你不用一开始就搞懂所有API,先做一个简单案例,遇到问题查文档、改参数,慢慢就有感觉了。我带的实习生小林,现在已经能用Three.js做企业官网的3D背景了,上个月还接了个外包单,赚了不少外快呢。

    如果你跟着上面的步骤做了案例,遇到“模型加载不出来”“粒子不动”之类的问题,别着急,把你的代码片段或者错误提示发到评论区,我会抽时间帮你看看。或者你做完了觉得效果不错,也欢迎分享链接,让大家一起学习!


    很多人刚开始接触Three.js,心里总打鼓:“是不是得先学一堆3D数学公式?WebGL那些底层代码是不是也得啃明白?”其实真不用这么焦虑。我带过不少想入门3D的前端同学,发现大家最容易被“3D”这两个字唬住,觉得门槛很高。但Three.js最贴心的地方,就是把WebGL那些复杂的底层逻辑全都打包好了——你不用自己写矩阵变换算坐标,不用对着顶点着色器代码头疼,它就像给你一把现成的“3D螺丝刀”,拿着就能拧螺丝,根本不用知道螺丝刀是怎么造的。

    就说去年带的实习生小林吧,他当时刚毕业,简历上写的技能就是“熟悉HTML/CSS/JS,会用Vue做项目”,连Canvas都没怎么碰过。我让他第一天学Three.js,下午就让他照着基础代码敲,晚上他就发来个小视频:一个绿色立方体在网页里慢悠悠转着,还带点光影效果。他自己都不敢信:“就这?我以为得学半个月才能看到东西呢!”你看,他当时连向量是什么都分不清,照样用基础的前端知识把3D效果跑起来了。所以真不用纠结“前置知识够不够”,你平时做网页用的那些HTML结构、CSS布局、JS逻辑,其实就是学Three.js的全部基础——毕竟它本质上还是个JS库,跑在浏览器里,跟你平时写的前端代码没什么两样。

    你想啊,Three.js把场景、相机、渲染器这些核心模块都封装成了现成的类,你要做的就是实例化它们,调调参数。比如创建个场景,new THREE.Scene()就行;放个相机,new THREE.PerspectiveCamera(),参数看不懂?没关系,先抄示例里的75视角、0.1到1000的视距,跑起来再说,后面调参数的时候自然就明白每个值是干嘛的了。就像你刚开始学JS时,不也搞不懂this指向吗?多写几个例子,改改参数看变化,慢慢就有感觉了。所以别被“3D”吓退,你现在的前端基础,足够让你在Three.js里先跑起来,剩下的边做边学,比抱着理论书啃实在多了。


    学习Three.js需要掌握哪些前置知识?

    不需要深厚的3D数学或WebGL基础,只要掌握HTML、CSS和JavaScript基础即可入门。Three.js已封装复杂的底层逻辑,像文章中提到的实习生小林,仅用基础前端知识就能快速做出旋转立方体效果。

    Three.js必须用Vite搭建开发环境吗?

    不是必须的。Vite只是推荐的快速搭建方式,也可以使用Webpack、Parcel等构建工具,甚至直接在HTML中通过CDN引入Three.js(如)。选择适合自己的工具即可,核心是确保Three.js库能正常加载。

    加载3D模型时总是失败,可能是什么原因?

    常见原因包括:模型格式错误(推荐使用GLB/GLTF格式,兼容性好且体积小)、文件路径不正确(确保模型文件放在项目的public目录或正确配置静态资源路径)、模型体积过大( 压缩到5MB以内,可使用工具如glTF-Pipeline压缩)、跨域问题(本地开发时可通过设置服务器代理解决)。

    Three.js实现的3D效果会影响网页性能吗?

    可能会,但合理优化可显著降低影响。 控制模型多边形数量(复杂模型简化处理)、减少粒子数量(如案例中粒子系统控制在1000-5000个较合适)、降低渲染帧率(默认60fps,非关键场景可降至30fps)。可使用Three.js自带的Stats.js监控性能,及时调整参数。

    哪里可以找到适合Three.js的免费3D模型资源?

    推荐几个常用平台:Sketchfab(有大量免费GLB/GLTF模型,需注意版权说明)、Clara.io(支持在线编辑和导出)、Google Poly(免费3D模型库,部分需科学上网)。下载时优先选择低多边形(Low Poly)模型,加载速度更快,适合网页场景。

    0
    显示验证码
    没有账号?注册  忘记密码?