尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

【Three.js教程】 创建场景:让你的第一个 3D 立方体转起来

【Three.js教程】 创建场景:让你的第一个 3D 立方体转起来 Three.js 创建场景让你的第一个 3D 立方体转起来原文出处Three.js Manual – 创建场景本文基于 three.js 官方手册创建场景章节整理用通俗的方式带你从零写出一个会旋转的 3D 立方体。写在前面上一篇我们搞定了安装项目能跑起来了页面却是空白的。这篇就来做点看得见的东西——一个旋转的立方体。别小看这个立方体它是 three.js 最经典的 “Hello World”。通过它你会接触到 three.js 的三个核心概念场景、相机、渲染器还会学到几何体、材质、网格最后再让它动起来。走完这一篇你就真正迈进了 3D 编程的大门。一、开始之前这篇假设你已经跟着安装指南搭好了项目结构——有index.html和main.js装好了 three.js而且能用构建工具或本地服务器 CDN 把页面跑起来。如果这些还没做先回去搞定再回来。二、三大件场景、相机、渲染器要用 three.js 在页面上显示任何东西你至少需要三样场景Scene就是你的 3D 世界所有物体都放进去相机Camera决定你从什么角度、什么位置看这个世界渲染器Renderer把相机看到的东西画到屏幕上在main.js里写下这段代码import*asTHREEfromthree;constscenenewTHREE.Scene();constcameranewTHREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);constrenderernewTHREE.WebGLRenderer();renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);看着有点长别急我们逐行拆解。场景constscenenewTHREE.Scene();这一行最简单——创建一个空场景。后面往里加东西就行。相机四个参数分别是什么意思three.js 提供了好几种相机这里用的是最常用的透视相机PerspectiveCamera它的成像效果和人眼类似——近大远小。它接受四个参数参数含义说明75视野范围FOV你能看到的场景有多宽单位是角度。75° 是个比较常见的值window.innerWidth / window.innerHeight宽高比用窗口宽度除以高度。不按实际比例来画面就会像宽屏电视放老电影一样被压扁0.1近裁剪面near离相机比这更近的东西不渲染1000远裁剪面far离相机比这更远的东西也不渲染近裁剪面和远裁剪面现在不用太纠结知道有这么回事就行。后面做实际项目时合理调整这两个值能提升渲染性能——毕竟看不到的东西就没必要画。渲染器把画面画到页面上constrenderernewTHREE.WebGLRenderer();renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);创建渲染器实例后要告诉它画多大。这里填的是浏览器窗口的宽高让 3D 画面铺满整个窗口。如果你对性能有要求也可以传小一点的值。比如setSize(window.innerWidth/2, window.innerHeight/2)渲染分辨率会缩小到四分之一宽高各减半但画面会变糊。还有个小技巧如果你想保持显示尺寸不变、只是降低渲染分辨率可以给setSize传第三个参数false// 画面还是铺满窗口但实际以一半分辨率渲染renderer.setSize(window.innerWidth/2,window.innerHeight/2,false);最后一行document.body.appendChild(renderer.domElement)——渲染器本质上是在往一个canvas元素上画东西这行代码把这个 canvas 塞到网页里你才看得见。三、加个立方体进来三个基本要素就位了但页面还是空的。说好的立方体呢别急这就来。constgeometrynewTHREE.BoxGeometry(1,1,1);constmaterialnewTHREE.MeshBasicMaterial({color:0x00ff00});constcubenewTHREE.Mesh(geometry,material);scene.add(cube);camera.position.z5;这段代码做了三件事对应 three.js 里物体的三个组成部分几何体GeometryBoxGeometry(1, 1, 1)定义了一个 1×1×1 的立方体。几何体本质上是顶点和面的集合描述了物体的形状。材质MaterialMeshBasicMaterial({ color: 0x00ff00 })给立方体上色。0x00ff00是十六进制绿色和 CSS、Photoshop 里的颜色写法一样。three.js 有很多种材质这是最基础的一种不受光照影响。网格Meshnew THREE.Mesh(geometry, material)把几何体和材质组合到一起变成一个可以放进场景、可以移动的 3D 对象。然后scene.add(cube)把它加进场景。最后一行camera.position.z 5很关键。默认情况下新加的物体会放在坐标原点(0, 0, 0)而相机也在原点。如果不把相机往后挪一点它就和立方体贴在一起了什么都看不见。往后移 5 个单位刚好能看清立方体的全貌。四、渲染场景得有个循环代码都写好了保存、刷新——还是什么都看不到。为什么因为我们还没让渲染器干活。three.js 需要一个渲染循环也叫动画循环不断地把场景画到屏幕上functionanimate(time){renderer.render(scene,camera);}renderer.setAnimationLoop(animate);setAnimationLoop会创建一个循环让渲染器在每次屏幕刷新时画一次场景——普通屏幕上是每秒 60 次。你可能会问“为什么不直接用setInterval” 技术上可以但setAnimationLoop底层用的是requestAnimationFrame有个很大的好处当用户切到其他标签页时它会自动暂停不会白白浪费 CPU 和电池。对移动端尤其友好。加了这段之后刷新页面——一个绿色立方体出现了五、让它转起来立方体能看到了但静止不动有点无聊。给它加个旋转动画在animate函数里、renderer.render之前加两行functionanimate(time){cube.rotation.xtime/2000;cube.rotation.ytime/1000;renderer.render(scene,camera);}animate函数会收到一个time参数毫秒用它来驱动旋转角度。X 轴转得慢一点除以 2000Y 轴转得快一点除以 1000看起来更有层次感。原理很简单动画循环每秒跑 60 次每次都更新立方体的旋转角度再重新渲染。只要每次的角度变化足够小肉眼看起来就是流畅的旋转。小贴士实际项目里动画循环里可能会塞很多逻辑——更新物体位置、处理碰撞、响应用户输入……建议把不同功能拆成单独的函数在animate里调用别让这个函数变成几百行。六、完整代码恭喜你的第一个 three.js 应用完成了虽然只是一个旋转的绿色立方体但万事开头难你已经跨过了最重要的那道坎。下面是完整代码也可以去 JSFiddle 在线示例 直接试玩改改参数感受一下。index.html!DOCTYPEhtmlhtmllangenheadmetacharsetutf-8titleMy first three.js app/titlestylebody{margin:0;}/style/headbodyscripttypemodulesrc/main.js/script/body/htmlmain.jsimport*asTHREEfromthree;constscenenewTHREE.Scene();constcameranewTHREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);constrenderernewTHREE.WebGLRenderer();renderer.setSize(window.innerWidth,window.innerHeight);renderer.setAnimationLoop(animate);document.body.appendChild(renderer.domElement);constgeometrynewTHREE.BoxGeometry(1,1,1);constmaterialnewTHREE.MeshBasicMaterial({color:0x00ff00});constcubenewTHREE.Mesh(geometry,material);scene.add(cube);camera.position.z5;functionanimate(time){cube.rotation.xtime/2000;cube.rotation.ytime/1000;renderer.render(scene,camera);}七、然后呢回顾一下这篇学到的核心概念概念作用对应代码场景Scene3D 世界的容器new THREE.Scene()相机Camera决定从哪看、看到什么new THREE.PerspectiveCamera(...)渲染器Renderer把场景画到屏幕上new THREE.WebGLRenderer()几何体Geometry定义物体形状new THREE.BoxGeometry(1,1,1)材质Material定义物体外观new THREE.MeshBasicMaterial({...})网格Mesh几何体 材质 可显示物体new THREE.Mesh(geometry, material)动画循环每帧更新并重新渲染renderer.setAnimationLoop(animate)这七个概念会贯穿你后续所有的 three.js 学习。接下来可以试试这些方向换个几何体试试SphereGeometry、CylinderGeometry看看不同形状换种材质MeshStandardMaterial支持光照效果立方体会有明暗变化加个光源DirectionalLight、PointLight让场景更有立体感响应式窗口缩放时怎么让画面跟着变官方手册的 Responsive Design 章节有答案加交互引入OrbitControls插件用鼠标拖拽旋转视角3D 编程的世界很大但起点就是这一个旋转的立方体。动手改改代码比看十遍文档都管用。
返回列表