Three.js实战02-react+ts+threejs 开发三维IT机房

eact+ts 是我当前所知的大部分企业开发三维项目的标配,所以我着这里就选择了react+ts。

当然,若大家擅长vue,用vue+ts 开发three 项目也可以。

1-准备一份IT机房模型

注:此机房布局仅供参考,不具专业效益,具体布局需考虑产品、环境和企业需求等。

1-1-建模思路

简化模型,能用贴图表现的细节,就用贴图。这样可提高渲染速度。将光效融入贴图中,即模型贴图后便具备光效和体感。这样在three 中就无需打灯,即可提高开发速度,亦可提高渲染效率。

1-2-建模软件

现在市面上可以3d建模的软件有很多,3dsMax、Blender、C4D 都可以。

3dsMax 相对更复杂一些,不过因为我大学就是学的这个,所以就用3dsMax建模了。

我当前用的3dsMax 版本是2018,无法导出gltf 文件,所以还需要安装一个gltf 文件导出插件

具体的建模和导出gltf 的过程,我先不做具体讲解,因为一般公司都是有专门的建模师。

等实战案例结束后,我会作为扩展内容,在视频里给大家演示一下建模和导出gltf 的过程。

1-3-模型文件

GLTF 模型文件包含了整个场景的数据,比如几何体、材质、动画、相机等。

GLTF 模型在使用起来,要比传统的obj 模型方便很多。

在导出GLTF模型后,一般会包含以下文件:

gltf 模型文件bin文件贴图文件

1-4-规范模型的结构和命名

在建模软件中,同一类型的模型文件可以放入一个数组里,数组可以多层嵌套。

当前的机房模型比较简单,我就没有使用数组,所有的Mesh对象都是平展开的。

为了便于访问和区分模型,需要对模型进行规范命名,如机房中的IT机柜都是按照cabinet-001、cabinet-002、cabinet-003 命名的。

假设IT机柜的名称都是唯一的,那我们便可以基于这个名称从后端获取相应机柜的详细信息。

2-构建项目

1.使用create-react-app 构建项目

Create React App 是React 官方支持的创建单页应用程序的工具,使用它可以快速构建一个react 项目。

npx create-react-app 02-machineroom –template typescript 复制代码

官方链接:create-react-app.bootcss.com/docs/gettin…

2.运行项目,package.json 里已经提供了start开发模式、build生产模式、test测试模式等。

我们可以先使用开发模式运行项目:

npm run start 复制代码

页面效果如下:

3.安装three 相关的依赖

npm install three @types/three –save 复制代码

4.调整一下ts的配置文件,取消strict 模式。因为如果strict为true,用threejs 写程序时,会比较麻烦。

tsconfig.json

{ “compilerOptions”: { …… // “strict”: true, …… }, …… } 复制代码

5.调整index.tsx首页,我们现在先不考虑项目测试,所以其中有些东西可以删掉,最终首页代码如下:

import React from react; import ReactDOM from react-dom; import ./index.css; import App from ./App; ReactDOM.render( , document.getElementById(root) ); 复制代码

注:

当前的vscode编辑器还无法对tsx 文件做格式化,可以安装一个Prettier – Code formatter 插件。react 18 对react 做了更新,index.tsx需要这样写:

import { createRoot } from “react-dom/client”; import “./index.css”; import App from “./App”; const container = document.getElementById(“root”); const root = createRoot(container); root.render(); 复制代码

详情参考官方链接:reactjs.org/blog/2022/0…

6.在src 文件夹里建立一个models 文件夹,将之前的模型文件放进去。同理,在public文件夹里放一份。

7.在App.tsx中建立canvas画布。

App.tsx

import React from react; import ./App.css; class App extends React.Component { // 建立canvas 画布 render() { return

} } export default App; 复制代码

8.设置css样式,让App组件充满窗口。

index.css

html{ height: 100%; } body{ height: 100%; margin: 0; } #root{ height: 100%; } 复制代码

App.css

.App { height: 100%; overflow: hidden; }

3-建立机房对象-MachineRoom.ts

机房对象会把所有图形相关的对象都封装进去,对模型进行统一管理和渲染。

src/component/MachineRoom.ts

import { MeshBasicMaterial,MeshStandardMaterial, Mesh, PerspectiveCamera,Raycaster, Scene,Texture,TextureLoader, WebGLRenderer, Vector2 } from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls import { GLTFLoader } from three/examples/jsm/loaders/GLTFLoader // GLTF 模型加载器 const gltfLoader=new GLTFLoader() export default class MachineRoom{ // 渲染器 renderer: WebGLRenderer // 场景 scene: Scene // 相机 camera: PerspectiveCamera // 轨道控制器 controls: OrbitControls // 存放模型文件的目录 modelPath: string // 初始化场景 constructor(canvas: HTMLCanvasElement,modelPath: string = ./models/) { this.renderer = new WebGLRenderer({ canvas }) this.scene=new Scene() this.camera = new PerspectiveCamera( 45, canvas.width / canvas.height, 0.1, 1000 ) this.camera.position.set(0, 10, 15) this.camera.lookAt(0, 0, 0) this.controls = new OrbitControls( this.camera, this.renderer.domElement ); this.modelPath=modelPath } // 加载GLTF模型 loadGLTF(modelName: string = ) { gltfLoader.load(this.modelPath + modelName, ({ scene: { children } }) => { this.scene.add(…children); }) } // 连续渲染 animate() { this.renderer.render(this.scene, this.camera) requestAnimationFrame(() => { this.animate() }) } } 复制代码

4-实例化机房对象

App.tsx

import React from react; import ./App.css; import MachineRoom from ./component/MachineRoom //机房对象 let room: MachineRoom //canvas画布 let canvas:HTMLCanvasElement class App extends React.Component { componentDidMount() { if (!canvas) { return } canvas.width = window.innerWidth canvas.height = window.innerHeight room=new MachineRoom(canvas) room.loadGLTF(machineRoom.gltf) room.animate() } // 建立canvas 画布,并通过ref 获取其HTMLCanvasElement对象 render() { return

canvas = ele} >
} } export default App; 复制代码

终效果如下:

现在,我们已经完成了GLTF 模型的导入、渲染和相机变换。

然而,把这个图和之前的3dsmax 图片对比一下,就会发现一个问题:three里的贴图颜色变深了。

接下来咱们分析一下这个问题。

    THE END
    喜欢就支持一下吧
    点赞13 分享
    评论 抢沙发
    头像
    欢迎您留下宝贵的见解!
    提交
    头像

    昵称

    取消
    昵称表情代码图片

      暂无评论内容