Three.js 3D人物漫游项目(上)

news2024/12/24 8:39:14

本文目录

  • 前言
  • 1、项目构建
    • 1.1 安装依赖
    • 1.2 初始化
    • 1.3 项目结构
    • 1.4 初始化的项目运行
  • 2、加载模型
    • 2.1 threejs三要素
      • 2.1.1 代码解读
    • 2.2 加载模型
      • 2.2.1 代码解读
    • 2.3 效果

前言

在数字技术的浪潮中,三维图形渲染技术以其独特的魅力,正逐步渗透到我们生活的方方面面,从电影特效的震撼呈现到游戏世界的沉浸式体验,再到虚拟现实(VR)与增强现实(AR)技术的蓬勃发展,三维图形技术无疑成为了连接现实与虚拟世界的桥梁。而在这众多技术中,Three.js作为一款轻量级、易于上手且功能强大的JavaScript 3D库,凭借其跨平台、高性能的特点,成为了前端开发者探索三维世界的重要工具。
本系列文章《Three.js 3D人物漫游项目(上)》,将带您深入Three.js的奇妙世界,通过构建一个生动的3D人物漫游场景,让您亲身体验从项目构建到模型加载,再到最终效果呈现的全过程。这不仅是一次技术实践的旅程,更是一次对三维图形艺术无限可能的探索。

1、项目构建

1.1 安装依赖

我们使用vite前端开发与构建工具,来进行构建与开发,首先我们新建一个文件夹roam3D,进入文件夹根目录,

  • 运行命令yarn init -y,效果如下:
    在这里插入图片描述

  • 接着再运行命令yarn add -D vite,效果如下:
    在这里插入图片描述

  • 接着运行命令yarn add three安装Three.js
    在这里插入图片描述

1.2 初始化

  • index.html:项目入口
    安装完必要的依赖后,我们在项目根目录下新建index.html并且写入如下代码进行初始化:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1.0">
    	<title>3D漫游项目</title>
    	<style>
        	html, body {
            	margin: 0;
            	padding: 0;
            	width: 100%;
            	height: 100%;
            	overflow: hidden;
        	}
    	</style>
    </head>
    <body>
    	<p>Roam 3D</p>
    </body>
    </html>
    

  • vite.config.jsvite配置入口
    我们在项目根目录下新建vite.config.js并且写入如下代码进行配置:

    import { defineConfig } from 'vite';
    
    export default defineConfig({
    server: {
        port: 8080
    }
    });
    

    这个配置更改运行的端口号。


  • package.json:项目配置
    我们在package.json写入脚本运行的配置:

     "scripts": {
    	"serve": "vite"
    },
    

    这个是脚本运行项目运行起来。


  • 模型
    我们在根目录下新建文件夹models将我们的模型放进去。
    在这里插入图片描述

  • src文件夹:存放一些逻辑代码。
    我们在根目录下新建文件夹src

1.3 项目结构

安装完依赖以及初始化后,我们的项目结构如下:

├── index.html
├── models
│   └── roamGirl.glb
├── node_modules
│   ├── @esbuild
│   ├── @rollup
│   ├── @types
│   ├── esbuild
│   ├── fsevents
│   ├── nanoid
│   ├── picocolors
│   ├── postcss
│   ├── rollup
│   ├── source-map-js
│   ├── three
│   └── vite
├── src
├── package.json
├── vite.config.js
└── yarn.lock

1.4 初始化的项目运行

我们现在进行初始化的项目运行,是为了看看项目是否正确的搭建,在项目根目录终端运行命令:yarn serve,可以看到如下图,说明成功:
在这里插入图片描述
浏览器访问http://localhost:8080/roam3D/index.html
在这里插入图片描述
说明项目已正常启动。接着我们可以着手准备下一步了。


2、加载模型

2.1 threejs三要素

我们在src文件夹下新建init.js写入如下代码:

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

// 场景
const scene = new THREE.Scene();

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

// 渲染器
const renderer = new THREE.WebGLRenderer({
    antialias: true,
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);

// 加载glb模型方法
export const glbLoader = (url) => {
    const loaderGLTF = new GLTFLoader();
    return new Promise((resolve) => {
        loaderGLTF.load(url, (glb) => {
            resolve(glb);
        });
    });
};

export { scene, camera, renderer };

2.1.1 代码解读

  1. 我们将三要素独立出来一个文件,避免所有代码写在一个文件里过于冗长。这样可能会导致文件难以管理,还可能降低代码的可读性和可维护性。
  2. 我们使用了Promise,它是一种用于异步计算的对象,使得我们封装异步变得更加方便,使得代码更加简洁、易于理解和维护,避免回调地狱,更好的状态管理,提高代码的可读性和可维护性。(我们不仅要会写,还要尽量将代码写的优雅。)

2.2 加载模型

我们在index.html 中导入模型,写入代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D漫游项目</title>
    <style>
        html, body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <script type="module">
        import * as THREE from 'three';
        import {scene, camera, renderer, glbLoader} from './src/init.js';

        renderer.render(scene, camera);

        // 设置背景色
        scene.background = new THREE.Color(0xFFFAFA);
        camera.position.set(0,5,30);

        // 环境光
        const ambientLight = new THREE.AmbientLight(0x404040, 100); // 柔和的白光
        scene.add(ambientLight);

        // 平行光
        const directionalLight = new THREE.DirectionalLight(0xffffff, 3);
        directionalLight.position.set(5,5,5);
        directionalLight.castShadow = true; // 光源开启阴影投射
        scene.add(directionalLight);

        // 加载模型
        const loadModel = async () => {
            const model = await glbLoader('../models/roamGirl.glb');
            console.log(model);
            model.scene.scale.set(8,8,8);

            scene.add(model.scene);
        };

        loadModel();

        // 动画循环渲染函数
        const animate = () => {
            renderer.render(scene, camera);
            window.requestAnimationFrame(animate);
        };
        window.requestAnimationFrame(animate);

    </script>
</body>
</html>

2.2.1 代码解读

  1. 我们在环境中设置了场景的背景色scene.background = new THREE.Color(0xFFFAFA);
  2. 添加了两个光源,一个ambientLight环境光(不会产生阴影),一个平行光directionalLight会产生阴影需要开启castShadowtrue
  3. 我们添加了动画循环渲染函数animate为什么后续的模型动画铺垫。
  4. 我们使用了es6asyncawait关键字,极大地简化了异步编程的复杂性和提高了代码的可读性。更好的错误处理,改进的流程控制。

2.3 效果

我们在项目根目录下运行命令yarn serve,效果如下:
在这里插入图片描述
可以看到我们将我们模型加载进来了。

在学习的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2151630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于无人机影像的可见光单木分割数据集-json格式

基于无人机影像的可见光单木分割数据集&#xff0c;共1700张影像&#xff0c;数据集大小3.6GB&#xff0c;分割标注采用标准json格式。 该数据集是一个专门用于基于无人机可见光影像进行单木分割的数据集&#xff0c;旨在帮助研究人员和开发者训练和评估基于深度学习的图像分割…

4.5 pandas 实战 分析抖音播放数据(1)

课程目标 基于pandas对抖音播放数据做数据分析 数据准备 点此去下载 课程内容 导包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns plt.rcParams["font.family"] "SimHei" plt.rcParams["ax…

道路坑洞分割数据集/道路裂纹分割数据集

1.道路坑洞,道路裂纹分割数据集&#xff0c;包含5790张坑洞分割图像数据&#xff08;默认分割标注png图片&#xff0c;850MB&#xff09;2.10000余张道路裂纹图像数据&#xff08;默认分割标注png图片&#xff0c;3.7GB&#xff09;3。道路坑洞&#xff0c;道路 道路坑洞与裂纹…

关于“华为杯”第二十一届中国研究生数学建模竞赛赛题下载及提交作品的重要提醒

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 各参赛队伍&#xff1a; “华为杯”第二十一届中国研究生数学建模竞赛即将于2024年…

零基础玩转实在Agent -- 基础篇|实在Agent研究

前言 实在Agent是什么 实在Agent&#xff08;智能体&#xff09;是实在智能基于RPA和自研屏幕语义理解技术&#xff0c;结合最前沿的Al大模型打造的自动化智能体产品。 它能像朋友一样聊天&#xff0c;并通过对话的方式理解你的任务需求&#xff0c;自动规划任务的实现方式&…

Qt clicked()、clicked(bool)、toggled(bool)信号的区别和联系

clicked() 信号 所属控件&#xff1a;clicked()信号是QAbstractButton类&#xff08;及其子类&#xff0c;如QPushButton、QRadioButton、QCheckBox等&#xff09;的一个信号。clicked信号可以说是许多控件&#xff08;特别是按钮类控件&#xff0c;如QPushButton&#xff09;…

后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0920)

十三、文章分类页面 - [element-plus 表格] Git仓库&#xff1a;https://gitee.com/msyycn/vue3-hei-ma.git 基本架子 - PageContainer 功能需求说明&#xff1a; 基本架子-PageContainer封装文章分类渲染 & loading处理文章分类添加编辑[element-plus弹层]文章分类删除…

Vue3DevTools7是如何在vscode定位指定文件位置的?

Vue3DevTools7是如何在vscode定位指定文件位置的&#xff1f; 背景 今天在使用vue脚手架创建项目的时候&#xff0c;并发现一个新的&#xff08;实验中的新功能&#xff09;&#xff0c;可以直接在我们的项目中集成Vue DevTools插件&#xff0c;浏览器插件devtools即将成为历史…

第十三周:机器学习笔记

第十三周周报 摘要Abstract一、机器学习——Transformer&#xff08;上&#xff09;1. Sequence to Sequence(Seq 2 Seq&#xff0c;序列到序列模型) 的应用2. Transformer的结构2.1 Transformer encoder&#xff08;Transformer 编码器&#xff09; 二、Pytorch学习1. 网络模型…

python爬虫初体验(一)

文章目录 1. 什么是爬虫&#xff1f;2. 为什么选择 Python&#xff1f;3. 爬虫小案例3.1 安装python3.2 安装依赖3.3 requests请求设置3.4 完整代码 4. 总结 1. 什么是爬虫&#xff1f; 爬虫&#xff08;Web Scraping&#xff09;是一种从网站自动提取数据的技术。简单来说&am…

BandiView 7.03 看图软件

BandiView 加入了大量现代化功能特性&#xff0c;比如支持 HDR 照片高动态范围效果、支持 HEIC / RAW / 漫画模式、免解压直接看图、查看 AI 图片提示词等 BandiView 是一款非常值得推荐的电脑全能看图浏览工具软件&#xff0c;软件的兼容性非常强&#xff0c;可以一站式满足用…

java通过org.eclipse.milo实现OPCUA客户端进行连接和订阅

前言 之前写过一篇关于MQTT的方式进行物理访问的文章&#xff1a;SpringBoot集成MQTT&#xff0c;WebSocket返回前端信息_springboot mqtt websocket-CSDN博客 最近又接触到OPCUA协议&#xff0c;想通过java试试看能不能实现。 软件 在使用java实现之前&#xff0c;想着有没…

欠款管理代码———未来之窗行业应用跨平台架构

一、欠款管理代码 function fun_会员_还款操作(会员卡信息id,MainID){var 未来之窗vos对话框_内容 ";var title"test";var 未来之窗vos对话框_id"hjksgfjkkhkj_child";CyberWin_Dialog.layer(未来之窗vos对话框_内容,{type:"url",title:&…

windows下,用docker部署xinference,为什么老是提示localhost无法访问?

部署xinference有两种方式&#xff1a; 一、本地部署 &#xff08;略&#xff09; 二、使用Docker部署&#xff08;与运行&#xff09; 其中又包括&#xff1a; 1&#xff09;使用CPU的方式&#xff1a;&#xff08;略&#xff09; 1&#xff09;使用GPU的方式&#xff1…

LeetCode_sql_day30(1264.页面推荐)

描述 1264.页面推荐 朋友关系列表&#xff1a; Friendship ------------------------ | Column Name | Type | ------------------------ | user1_id | int | | user2_id | int | ------------------------ (user1_id, user2_id) 是这张表具有唯一值的…

低代码可视化工具--vue条件判断v-if可视化设置-代码生成器

在Vue UniApp中&#xff0c;条件判断通常是通过指令v-if、v-else-if、v-else来实现的。这些机制允许你根据表达式的真假值来决定是否渲染某个元素或元素组&#xff0c;或者执行特定的逻辑。 条件判断说明 v-if 是惰性的&#xff1a;如果在初始渲染时条件为假&#xff0c;则什么…

mac os x 找不到钥匙串访问

昨天手贱更新了最新的mac系统&#xff0c;结果在实用工具中找不到钥匙串访问APP了。。。 最新mac系统为 15.0 (24A335) 真是醉了。。。 那就得想办法把他给呼出来&#xff0c;在开发者中心下载了一个.cer文件&#xff0c;然后双击打开&#xff0c;此时钥匙串打开了&#xff…

猿大师办公助手在线编辑Office为什么要在客户端电脑安装插件微软Office或金山WPS?

猿大师办公助手作为一款专业级的网页编辑Office方案&#xff0c;与在线云文档方案&#xff08;飞书、腾讯文档等&#xff09;不同&#xff0c;需要在客户端电脑安装猿大师办公助手插件及微软Office或者金山WPS软件&#xff0c;很多客户不理解为什么要这么麻烦&#xff0c;能否客…

从虚拟到现实:数字孪生与数字样机的进化之路

数字化技术高速发展的当下&#xff0c;计算机辅助技术已成为产品设计研发中不可或缺的一环&#xff0c;数字样机&#xff08;Digital Prototype, DP&#xff09;与数字孪生技术便是产品研发数字化的典型方法。本文将主要介绍数字样机与数字孪生在国内外的发展&#xff0c;并针对…