写点什么

【Three.js】随着元宇宙开启 WEB3D 之路

作者:devpoint
  • 2021 年 11 月 19 日
  • 本文字数:3255 字

    阅读完需:约 11 分钟

【Three.js】随着元宇宙开启WEB3D之路

当视频游戏遇到 Web 2.0 时会发生什么? 当虚拟世界相遇地球的地理空间地图?当模拟变成现实,生活和商业变成虚拟?当你使用虚拟地球在物理地球上导航时,你的化身就变成了你的在线代理?这一切发生的就是元宇宙。


元宇宙设想了一个由虚拟世界和 3D 技术广泛应用重塑的未来。Three.js 是一个非常令人印象深刻的 JavaScript 3D 库,它也使用 WebGL(或 2d Canvas)进行渲染。随着 WebGL API 标准的改进,以及对 WebXR 的支持,Three.js 成为了一个可以用来营造沉浸式体验的主流工具。与此同时,浏览器对 3D 渲染和 WebXR 设备 API 的支持也得到提升,使得 web 成为一个越来越有吸引力的 3D 内容平台。

Three.js

Three.jsRicardo Cabello(@mrdoob) 在 2010 年开发的一个 JavaScript 库(如今它在 Github 上有许多贡献者)。这个令人难以置信的工具让用户可以在浏览器上处理 3D 图形,使用 WebGL 技术非常简单和直观的方式来实现。而 WebGL 技术已经非常普及和被浏览器广泛支持。



WebGL 在许多设备和浏览器中创建丰富的交互体验,点击查看浏览器支持程度。


开始

本文将以 Vue 为基础框架来构建 Three.js 示例,关于代码可以查阅 GitHub


首先安装依赖:


npm install three --save
复制代码

构建

现在开始添加代码到页面,如下:


<template>    <div id="app"></div></template>
<script>import * as THREE from "three";export default { name: "App", data() { return {}; }, mounted() { this.init(); }, methods: { init() { const scene = new THREE.Scene();
// 创建一个基本透视相机 camera const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 4;
// 创建一个抗锯齿渲染器 const renderer = new THREE.WebGLRenderer({ antialias: true });
// 配置渲染器清除颜色 renderer.setClearColor("#000000");
// 配置渲染器尺寸 renderer.setSize(window.innerWidth, window.innerHeight);
// 添加渲染器到DOM document.body.appendChild(renderer.domElement);
// 创建一个立方体网格 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshBasicMaterial({ color: "#433F81" }); const cube = new THREE.Mesh(geometry, material);
// 将立方体到场景中 scene.add(cube);
const render = function () { requestAnimationFrame(render);
cube.rotation.x += 0.01; cube.rotation.y += 0.01;
renderer.render(scene, camera); };
render(); }, },};</script>
复制代码


然后再添加简单的样式:


body {    margin: 0;}canvas {    width: 100%;    height: 100%;}
复制代码


执行脚本 yarn serve ,打开浏览器将看到如下效果:



这是每个 Three.js 应用程序一种常见模式,包括 WebGlRendererSceneCamera ,如下:


  1. 创建渲染器WebGlRenderer

  2. 创建 Scene

  3. 创建Camera


渲染器是放置场景结果的地方。在 Three.js 中,可以有多个场景,每个场景可以有不同的对象。



在示例中创建 WebGLRenderer,再将窗口的大小作为参数传递给它,然后将它附加到 DOM 中。


// 创建一个抗锯齿渲染器const renderer = new THREE.WebGLRenderer({ antialias: true });
// 配置渲染器清除颜色renderer.setClearColor("#000000");
// 配置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight);
// 添加渲染器到DOMdocument.body.appendChild(renderer.domElement);
复制代码


首先需要创建一个空场景,将在其中添加创建的立方体对象:


const scene = new THREE.Scene();
复制代码


最后创建一个相机 camera ,将 视野 、纵横比以及近平面和远平面作为参数:


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


到此 Three.js 应用程序的 3 个基本元素已经完成了。

几何、材料和网格

第二种常见模式是向场景添加对象:


  1. 创建几何

  2. 创建材质

  3. 创建网格

  4. 将网格添加到场景中。


在 Three.js 中,网格是几何体与材质的组合。



几何是对象的数学公式,在 Three.js 中有很多几何,将在以后的章节中探索它,几何体提供了要添加到场景中的对象的顶点。



材质可以定义为对象的属性及其与场景光源的行为。如下图所示,有不同类型的材料。



现在知道了网格、几何体和材质是什么,将把它们添加到场景中。在示例中,使用基本材质创建一个立方体:


// 创建一个立方体网格const geometry = new THREE.BoxGeometry(1, 1, 1);const material = new THREE.MeshBasicMaterial({ color: "#1b55e3" });const cube = new THREE.Mesh(geometry, material);
// 将立方体到场景中scene.add(cube);
复制代码

请求动画帧

最后一段代码是为场景设置动画,使用 requestAnimationFrame,它允许有一个以每秒 60 帧(最多)运行的函数。


const render = () => {    requestAnimationFrame(render);    renderer.render(scene, camera);};
render();
复制代码

立方体动画

为了在渲染循环中为立方体设置动画,需要更改它的属性。当创建一个网格时,可以访问一组在动画制作时非常有用的属性。


// Rotation (XYZ)  弧度cube.rotation.x;cube.rotation.y;cube.rotation.z;
// Position (XYZ)cube.position.x;cube.position.y;cube.position.z;
// Scale (XYZ)cube.scale.x;cube.scale.y;cube.scale.z;
复制代码


在示例中,为立方体设置 X 和 Y 旋转动画:


cube.rotation.x += 0.01;cube.rotation.y += 0.01;
复制代码

控制台

作为前端,控制台是最好的调试工具。当使用 Three.js 时,控制台是必不可少的工具。

效果增持

现在理解了示例的逻辑,将向场景中添加更多片段,目的是生成更复杂的片段。


/** * 创建材质的方法 */const createMesh = (boxOptions, meshOptions) => {    const geometry = new THREE.BoxGeometry(...boxOptions);    const material = new THREE.MeshBasicMaterial(meshOptions);    return new THREE.Mesh(geometry, material);};
const cube01 = createMesh([1, 1, 1], { color: "#A49FEF", wireframe: true, transparent: true,});scene.add(cube01);
const cube01_wireframe = createMesh([3, 3, 3], { color: "#433F81", wireframe: true, transparent: true,});scene.add(cube01_wireframe);
const cube02 = createMesh([1, 1, 1], { color: "#A49FEF",});scene.add(cube02);
const cube02_wireframe = createMesh([3, 3, 3], { color: "#433F81", wireframe: true, transparent: true,});
scene.add(cube02_wireframe);
const bar01 = createMesh([10, 0.05, 0.5], { color: "#00FFBC",});bar01.position.z = 0.5;scene.add(bar01);
const bar02 = createMesh([10, 0.05, 0.5], { color: "#ffffff",});bar02.position.z = 0.5;scene.add(bar02);
const render = () => { requestAnimationFrame(render);
cube01.rotation.x += 0.01; cube01.rotation.y += 0.01;
cube01_wireframe.rotation.x += 0.01; cube01_wireframe.rotation.y += 0.01;
cube02.rotation.x -= 0.01; cube02.rotation.y -= 0.01;
cube02_wireframe.rotation.x -= 0.01; cube02_wireframe.rotation.y -= 0.01;
bar01.rotation.z -= 0.01; bar02.rotation.z += 0.01;
renderer.render(scene, camera);};
render();
复制代码


运行后效果如图:



发布于: 2 小时前阅读数: 8
用户头像

devpoint

关注

细节的追求者 2011.11.12 加入

专注前端开发,用技术创造价值!

评论

发布
暂无评论
【Three.js】随着元宇宙开启WEB3D之路