当前位置: 首页 > news >正文

Three.js高级应用--利用Three.js+WebGL实现fbx和obj格式模型的自定义加载

通过对webgl和three.js的不断学习与实践,在三维应用场景建设过程中,利用Three.js与webgl配合可以实现大部分三维场景的应用需求,这一篇主要讲述如何利用Three.js加载已有的模型,支持的三维模型格式有.fbx和.obj,同时.obj格式记得将对应的mtl文件放在与obj文件同目录下,名称一致即可。这样就可以加载我们已经建设好的各类三维模型,目前100M之内的模型加载都没问题。Three.js的基础代码请参考其他三篇文章,一般利用Three.js实现三维场景的代码主要内容有:

1.获取canvas元素

2.创建场景scene

3.创建相机camera

4.添加相机控件OrbitControls

5.添加灯光-环境光AmbientLight

6.创建渲染器renderer并设置像素比和场景背景色

7.添加三维物体,一般在另一个js中完成。

8.添加动画函数实现场景的动态循环渲染、添加浏览器窗口变化事件,用于设置随着浏览器窗口大小进行画布大小的调整。

开发环境:vue-2.5.2,Three.js-0.142.0,开发工具webstorm2021.2.3, 前端用chrome109.0.5414.120,其他默认。

以下是实现三维模型加载示例的功能描述和关键代码。

一、功能简述:在浏览器中实现已有三维模型文件的动态加载,不需要安装插件,支持旋转、放大缩小、移动,场景扫描和烟雾预警等。

二、实现效果:

三、关键代码如下(相机platform下的src/enter目录下的index.js和addComponent.js文件):

1.index.js文件中需要引入加载各个三维组件对应的js。

import { AddComponent } from './addComponent.js'
export const initPlatform = () => {//添加三维场景的各个组件,相当于加载各种三维模型const plat = new AddComponent(scene, camera, controls);const clock = new THREE.Clock();const start = () => {plat.start(clock.getDelta());//记得更新相机位置controls.update();// 渲染场景renderer.render(scene, camera)requestAnimationFrame(start)}start();//设置随着浏览器窗口大小进行画布大小的调整window.addEventListener('resize', () => {// 更新宽高比camera.aspect = window.innerWidth / window.innerHeight// 更新相机的投影矩阵camera.updateProjectionMatrix()renderer.setSize(window.innerWidth, window.innerHeight)// 设置像素比renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))})
}

 2.addComponent.js文件中引入加载模型后的处理js和加载fbx和obj文件的js,每个组件是一个类。

import { SurroundLine } from '../effect/surroundLine.js'
import { loadFBX } from '../utils'
import { loadOBJ } from '../utils'
export class AddComponent {constructor(scene, camera, controls) {this.scene = scene;this.camera = camera;this.controls = controls;this.loadModel('fbx');}// 加载模型,并且渲染到画布上loadModel(fileType) {if(fileType=='fbx'){loadFBX('/src/model/NB352-3D.fbx').then(object => {object.rotation.z = Math.PI / 2;//模型旋转90度object.traverse((child) => {if (child.isMesh) {new SurroundLine(this.scene, child, this.height, this.time);}})this.initEffect();})}else if(fileType=='obj'){loadOBJ('/src/model/factory.obj').then(object => {object.traverse((child) => {if (child.isMesh) {new SurroundLine(this.scene, child, this.height, this.time);}})// this.initEffect();})}}
}

3.surroundLine.js完整文件如下:

import * as THREE from "three";export class SurroundLine {constructor(scene, child, height, time) {this.height = height;this.scene = scene;this.child = child;this.time = time;this.createMesh();}computedMesh() {this.child.geometry.computeBoundingBox();this.child.geometry.computeBoundingSphere();}createMesh() {this.computedMesh();const { max, min } = this.child.geometry.boundingBox// 高度差const size = max.z - min.z//利用webgl原始的顶点和片元着色器对模型进行设置。const material = new THREE.ShaderMaterial({uniforms: {// 当前扫描的高度u_height: this.height,// 扫描线条的颜色是什么u_up_color: {value: new THREE.Color({color:'#5588AA'}),},u_city_color: {// 得需要一个模型颜色 最底部显示的颜色value: new THREE.Color(color.mesh)},u_head_color: {// 要有一个头部颜色 最顶部显示的颜色value: new THREE.Color(color.head)},u_size: {value: size,},u_time: this.time,},//顶点着色器vertexShader: `uniform float u_time;varying vec3 v_position;void main() {// 变化的时间float uMax = 4.0;v_position = position;// 变化的比例float rate = u_time / uMax * 2.0;// 边界条件if (rate > 1.0) {rate = 1.0;}float z = position.z * rate;gl_Position = projectionMatrix * modelViewMatrix * vec4(vec2(position), z, 1.0);}`,//片元着色器fragmentShader: `varying vec3 v_position;uniform vec3 u_city_color;uniform vec3 u_head_color;uniform float u_size;uniform vec3 u_up_color;uniform float u_height;void main() {vec3 base_color = u_city_color;base_color = mix(base_color, u_head_color, v_position.z / u_size);// 上升线条的高度是多少if (u_height > v_position.z && u_height < v_position.z + 6.0) {float f_index = (u_height - v_position.z) / 3.0;base_color = mix(u_up_color, base_color, abs(f_index - 1.0));}gl_FragColor = vec4(base_color, 1.0);}`,})const mesh = new THREE.Mesh(this.child.geometry, material);// 让mesh 继承 child 的旋转、缩放、平移mesh.position.copy(this.child.position)mesh.rotation.copy(this.child.rotation)mesh.scale.copy(this.child.scale)this.scene.add(mesh);}
}

相关文章:

Three.js高级应用--利用Three.js+WebGL实现fbx和obj格式模型的自定义加载

通过对webgl和three.js的不断学习与实践&#xff0c;在三维应用场景建设过程中&#xff0c;利用Three.js与webgl配合可以实现大部分三维场景的应用需求&#xff0c;这一篇主要讲述如何利用Three.js加载已有的模型&#xff0c;支持的三维模型格式有.fbx和.obj&#xff0c;同时.o…...

Go struct

每个无名结构体类型的字面形式均由struct关键字开头&#xff0c;后面跟着用一对大括号{}&#xff0c;其中包裹着的一系列字段&#xff08;field&#xff09;声明。 一般来说&#xff0c;每个字段声明由一个字段名和字段类型组成。一个结构体类型的字段数目可以为0。struct {tit…...

Redis多线程模型源码解析

1. 配置启用多线程 默认情况下多线程是默认关闭的&#xff0c;如果想要启动多线程&#xff0c;需要在配置文件中做适当的修改。 修改redis.conf 文件如下 io-threads 4 #启用的 io 线程数量 io-threads-do-reads yes #读请求也使用io线程2 源码解析 进入到Redis的main入口函…...

搭建zabbix4.0监控服务实例

一.Zabbix服务介绍 1.1服务介绍 Zabbix是基于WEB界面的分布式系统监控的开源解决方案&#xff0c;Zabbix能够监控各种网络参数&#xff0c;保证服务器系统安全稳定的运行&#xff0c;并提供灵活的通知机制让SA快速定位并解决存在的各种问题。 1.2 Zabbix优点 Zabbix分布式监…...

Xcode 系统崩溃问题01

参考链接&#xff1a;https://www.5axxw.com/questions/content/x2zlpx 问题&#xff1a;崩溃提示&#xff1a; Message from debugger: The LLDB RPC server has crashed. You may need to manually terminate your process. The crash log is located in ~/Library/Logs/Dia…...

SpringMVC文件上传、下载、国际化配置

Java知识点总结&#xff1a;想看的可以从这里进入 目录3.6、文件上传、下载3.6.1、文件上传3.6.2、文件下载3.7、国际化配置3.6、文件上传、下载 3.6.1、文件上传 form 表单想要具有文件上传功能&#xff0c;其必须满足以下 3 个条件。 form 表单的 method 属性必须设置为 p…...

计算机图形学07:有效边表法的多边形扫描转换

作者&#xff1a;非妃是公主 专栏&#xff1a;《计算机图形学》 博客地址&#xff1a;https://blog.csdn.net/myf_666 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录专栏推荐专栏系列文章序一、算法原理二、…...

UNIX编程--Makefile入门

Makefile 文件命名和规则 文件命名 makefile 或者 Makefile Makefile 规则 一个 Makefile 文件中可以有一个或者多个规则目标 ... &#xff1a; 依赖 ...命令 (shell 命令)...目标&#xff1a;最终要生成的文件&#xff0c;伪目标除外依赖&#xff1a;生成目标所需的文件或是目…...

【数据结构初阶】手撕单链表

目录一.链表概念和结构二.单链表功能的实现1.打印单链表内容2.申请单链表节点3.头插和尾插4.头删和尾删5.单链表查找6.pos位置前后插入7.pos位置删除三.链表面试题剖析一.链表概念和结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素…...

angular中http请求和传值

有关angular传值的相关内容 <number-info[subTitle]"customTitle"[total]"item.ENERGY_RATE %"[subTotal]"item.ENERGY_RATE_DIFF %"[status]"item.ENERGY_RATE_DIFF > 0 ? up : down">在number-info上面,会是一个delon/c…...

VSCode问题记录

20230304 - 0. 引言 这几年的编程方式还真是各种变化&#xff0c;从一开始直接VIM&#xff0c;到后面使用jupyter进行机器学习相关&#xff0c;然后再过渡到vim的形式并加以tmux批量化&#xff0c;最后去年使用了vscode作为IDE。随着工具的变化&#xff0c;那么很多习惯也都随…...

html基础学习

初识HTML HTML: 超文本标记语言 一.HTML的基本结构 根控制标记(头) ​ 头控制标记(头) ​ 标题 标题标记 ​ 头控制标记(尾) ​ 网页显示区域(一般要实现的代码都在这里写) </body> 根控制标记(尾) 二.网页的基本标签 标题标签 <h1> 一级标题</h1> <…...

leetcode_贪心算法

贪心算法相关题简单题目455.分发饼干1005.K次取反后最大化的数组和860.柠檬水找零序列问题376.摆动序列法一&#xff1a;贪心法法二&#xff1a;动态规划单调递增的数字简化版本有点难度53.最大子序和贪心算法动态规划134.加油站968.监控二叉树两个维度权衡问题分发糖果406.根据…...

C语言每日一题】——杨氏矩阵

【C语言每日一题】——倒置字符串&#x1f60e;前言&#x1f64c;杨氏矩阵&#x1f64c;总结撒花&#x1f49e;&#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#xff1a;全神贯注的上吧&#xff01;&#xff01;&#xff01; &#x1f60a;作者简介…...

最佳iOS设备管理器imazing 2.16.9官网Mac/Windows下载电脑版怎么下载安装

imazing 2.16.9官网Mac/Windows下载电脑版是款针对苹果设备所打造的管理工具。iMazing为用户提供多种设备管理功能&#xff0c;每一位用户都能以自己的形式管理苹果设备。iMazing与苹果设备连接后&#xff0c;用户就可以轻松传输文件&#xff0c;浏览保存信息等。 应用介绍 iM…...

八大排序算法之堆排序的实现+经典TopK问题

目录 一.堆元素的上下调整接口 1.前言 2.堆元素向上调整算法接口 3.堆元素向下调整算法接口 二.堆排序的实现 1.空间复杂度为O(N)的堆排序(以排升序为例) 思路分析: 代码实现: 排序测试: ​时空复杂度分析: 2. 空间复杂度为O(1)的堆排序(以排降序为例) 将数组arr调…...

使用AppSmith(PagePlug )低代码平台快速构建小程序应用实践

文章目录一、入门&#xff08;一&#xff09;介绍&#xff08;二&#xff09;功能特性&#xff08;三&#xff09;体验一下&#xff08;四&#xff09;参考教程二、使用Appsmith构建商城微信小程序&#xff08;一&#xff09;说明&#xff08;二&#xff09;应用配置&#xff0…...

第52章 短信验证服务和登录的后端定义实现

1 Services.Messages.SmsValidate using Core.Domain.Messages; using Data; using Microsoft.EntityFrameworkCore; namespace Services.Messages { /// <summary> /// 【短信验证服务--类】 /// <remarks> /// 摘要&#xff1a; /// 通过类中的方法成员实…...

谷歌验证码的使用

1. 表单重复提交之验证码 1.1 表单重复提交三种常见情况 提交完表单。服务器使用请求转来进行页面跳转。这个时候&#xff0c;用户按下功能键 F5&#xff0c;就会发起最后一次的请求。造成表单重复提交问题。解决方法&#xff1a;使用重定向来进行跳转用户正常提交服务器&…...

Git学习入门(1)- git的安装与配置

title: git学习&#xff08;1&#xff09; - git的安装与配置CSDN: https://blog.csdn.net/jj6666djdbbd?typeblogBlog: https://helloylh.comGithub: https://github.com/luumodtags: gitabbrlink: 12001description: 本文主要讲解了git的安装&#xff0c;配置基本工作date: …...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...