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

如何将OBJ文件转成GLB文件

背景

项目上需要展示3D矿图效果,当时前端框架选用了three.js进行渲染引擎,成功的满足了需求进行效果展示,但在后期一直有性能问题的困扰,前端同学做了一些优化,包括分布加载、采用nginx请求头缓存配置、浏览器缓存等机制。
在实践中,我们发现glb格式要比obj格式的文件小一些,此外,obj在加载的过程也容易丢失样式、纹理等文件,由于obj模型文件通常为一组格式mlt(纹理、样式)、png(贴图),因此在做前端浏览器缓存时,也存在问题,后来和前端同学商量后,我们决定将obj转成glb进行尝试。

两种文件格式简介

obj文件

obj文件专注于存储3D模型的几何数据(顶点、纹理坐标、法线等),通过纯文本描述模型结构,是一组可读的文本语句,eg:v表示顶点定义模型;ojb会依赖外部文件,材质信息需客外MTL文件存储,不支持动画功能,支持贴图文件,png/jpeg

glb文件

GLB 是GLTF标准的二进制版本,全称为“GL传输格式二进制文件”,将3D模型、纹理、材质、动画甚至场景光源打包为单一二进制文件。是一体化封装文件,所有资源饭知JSON元数据、纹理等都可以整合一体,其设计目标就是快速加载与高效解析,适配WEB和移动端

对比维度OBJGLB
文件大小文本格式冗余,所以文件相对大二进制压缩,相对小
功能支持无动画/场景支持支持动画、光照、相机视角
文件可读性文本格式易上手二进制文件难理解难编辑
兼容性广泛支持(3D打印/建模软件)主流引擎/WebGL原生支持
材质管理需额外的MLT、PNG内嵌纹理与材制裁

经上对比,综述,GLB支持WEB集成,体积更小,减少带宽消耗,如果追求轻量、动画支持可首选GLB格式

转换方式

选用Node插件进行转换,首先可以用npm install obj2gltf安装插件,然后通过命令进行转换

# 安装node插件
npm install obj2gltf
# 格式转换命令
obj2gltf -i   源文件.obj -o 目标文件.glb

示例如下所示:

# 示例如下
obj2gltf -i  D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷_offset.obj -o D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷.glb 

这个搞定了,剩的工作就简单了,如何动达转换呢,我们可以通过Java程序监听指定目录的新增、修改操作,然后对其变化的文件执行脚本调用,进行转换,思路有了,来码代码,先容我再啰嗦两句,把步骤描述如下所示:

1 、obj2gltf是通过npm install obj2gltf安装的插件,用于模型格式转换操作
2、包下的node_module是将npm install 时产生的所有npm依赖都copy进去了。否则缺少依赖;
3、application.yml 中需要配置脚本文件的绝对路径,需引用obj2gltf下的bin下的obj2gltf.js
4、java 引入Pom依赖
5、JAVA调用IO包中的Process类执行命令脚本

代码结果如下所示:
在这里插入图片描述

obj2gltf -i D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷_offset.obj -o D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷.glb

写了一个转换工具类,参数如下所示:

pom.xml依赖

   <dependency><groupId>de.javagl</groupId><artifactId>jgltf-model</artifactId><version>2.0.0</version></dependency><!-- https://mvnrepository.com/artifact/de.javagl/obj --><dependency><groupId>de.javagl</groupId><artifactId>obj</artifactId><version>0.3.0</version></dependency>

写一个Util工具类

package com.zhanglu.test.handle.util;import com.zhanglu.test..handle.obj2gltf.ConvertObjToGltf;
import com.zhanglu.test..handle.obj2gltf.obj.BufferStrategy;
import com.zhanglu.test..handle.obj2gltf.obj.GltfWriteType;
import com.zhanglu.test..handle.obj2gltf.obj.IndicesComponentType;
import lombok.extern.slf4j.Slf4j;import java.io.BufferedReader;
import java.io.InputStreamReader;
@Slf4j
@SuppressWarnings("all")
public class NodeJsExcutorUtil {public static void convertObjToGlb(String objPath,String glbPath,String scriptPath) {BufferedReader reader = null;try {// 构建命令(根据安装方式调整)String[] command = {"node", //本地windows启动不加这个命令,不然会报错scriptPath,  // 局部安装使用 npx"-i", objPath.trim(),"-o", glbPath.trim()};ProcessBuilder builder = new ProcessBuilder(command);System.out.println(builder.command());builder.redirectErrorStream(true); // 将错误输出和标准输出合并,便于读取Process process = builder.start();reader = new BufferedReader(new InputStreamReader(process.getInputStream(),"utf-8"));String line;while ((line = reader.readLine()) != null) {log.info(line);}process.waitFor(); // 等待进程结束log.info("【glb文件】转换成功");} catch (Exception err) {err.printStackTrace();log.error("【glb文件】转换失败:{}",err.getMessage());}finally {try {if (reader != null) {reader.close();}} catch (Exception e) {e.printStackTrace();}}}public static void main(String[] args) {//本地如果是windows环境用以下脚本String scriptPath = "D:\\web\\node_modules\\.bin\\obj2gltf.cmd"; //如果是Linux脚本用以下脚本 //  String scriptPath = "scriptPath: /data/webapp/calamity/handle/obj2gltf/bin/obj2gltf.js";String objPath="D:\\data\\mainMap\\主要系统巷道\\主要大巷.3dmobj\\主要大巷.obj";String glbPath="D:\\data\\mainMap\\主要系统巷道\\主要大巷.3dmobj";String glbFilePath="D:\\data\\mainMap\\主要系统巷道\\主要大巷.3dmobj\\主要大巷_1.glb";NodeJsExcutorUtil.convertObjToGlb(objPath,glbFilePath,scriptPath);}
}

以上代码需要注意

Linux环境脚本引用说明
Linux环境脚本路径node安装obj2gltf包下的:obj2gltf/bin/obj2gltf.js;
命令:node  /脚本实际路径/obj2gltf.js -i objFile.obj -o glbFile.glb

在这里插入图片描述

windows环境脚本引用说明
Windows 环境脚本路径node安装obj3gltf包下:node_modules\\.bin\\obj2gltf.cmd
命令: /脚本实际路径/obj2gltf.cmd -i objFile.obj -o glbFile.glb

在这里插入图片描述

相关文章:

  • 广西网站建设原创云推广
  • 建团购网站关键词排名工具
  • 企业网站推广解决方案排名优化软件
  • 公众号开发培训seo推广视频隐迅推专业
  • 怎么做网站推广世界杯怎么做好网站搜索引擎优化
  • 做网站英文怎么说天津做优化好的公司
  • NVIDIA GPU架构学习笔记
  • 时序数据库IoTDB可实现的基本操作及命令汇总
  • Linux操作系统Nginx Web服务
  • 16、nrf52840蓝牙学习(唯一ID加密与解密)
  • VRRP:解决路由器单点故障的终极方案
  • wpa_supplicant连接到了路由,但是 udhcpc会分配到不同网段的ip,路由器ip为192.168.0网段,板子分配ip为192.168.1的网段
  • 2025.6.24总结
  • 数组题解——​合并区间【LeetCode】
  • Python 猜数字小游戏:Tkinter 实现的互动猜数挑战
  • json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig)
  • 【计算机组成原理01】:主存与Cache的地址映射
  • 【Docker基础】Docker容器管理:docker stop详解
  • 洛谷 删数的问题 贪心
  • C/C++库开发完全指南:从静态库到动态链接的深度解析
  • Unity反射机制
  • 【Linux网络与网络编程】15.DNS与ICMP协议
  • 报错:macOS 安装 sentencepiece
  • VIVADO导出仿真数据到MATLAB中进行分析
  • Spring Boot 中整合 Redis
  • 防御OSS Bucket泄露:RAM权限策略+日志审计+敏感数据扫描三重防护