Three.js: GLTF出口商

创建于 2017-08-15  ·  85评论  ·  资料来源: mrdoob/three.js

我想用这个问题来跟踪 GLTF2 导出器功能。 我已经复制了 PR https://github.com/mrdoob/three.js/pull/11917上讨论的功能的初始列表,随着我们在实施过程中的进展,我会不断更新列表。

特点 / 待办事项

  • [x] 导出选项

    • [x] trs导出 TRS 而不是矩阵

    • [x] input :

    • [x] 单场景

    • [x] 场景数组

    • [x] 单个对象

    • [x] 对象数组

    • [x] truncateDrawRange :强制仅导出由drawRange定义的属性值:

    • [x] 非索引缓冲区几何

    • [x] 索引缓冲区几何

  • [x] 在extras包含userData extras
  • [x]场景

    • [x] 支持多场景

  • [x]节点

    • [x] 网格

    • [x] 原始模式:



      • [x] 三角形


      • [x] TRIANGLE_STRIP


      • [x] TRIANGLE_SPAN


      • [x] 积分


      • [x] 线


      • [x] LINE_STRIP


      • [x] LINE_LOOP



    • [x] 几何类型:



      • [x] 缓冲区几何


      • [x] 几何



    • [x] 原始属性:



      • [x] 位置


      • [x] 正常


      • [x] TEXCOORD_0


      • [x] TEXCOORD_1


      • [x] 颜色_0


      • [x] 关节_0


      • [x] 重量_0


      • [x]切线



    • [x] 多材质网格作为基元

    • [x] 灯

    • [x] 相机

    • [x] 皮肤

  • [ ]材料

    • [x]如果使用默认材料,则忽略

    • [x] 如果material.wireframe === true导出为行

    • [x] pbrMetallicRoughnessMeshStandardMaterial

    • [x] 属性:



      • [x] baseColorFactor


      • [x] metallicFactor


      • [x] roughnessFactor


      • [x] baseColorTexture :支持( material.map )但texCoord始终设置为 0。



    • [x] doubleSided

    • [x] KHR_material_unlit

  • [x]采样器
  • [ ]图像

    • [x] uri使用map.image.src

    • [x] uri base64

    • [x] bufferView

    • [x] 处理flipY图像

    • [] 将通道合并为一个纹理

  • [ ]存取器

    • [ ] 对相同的 componentType 使用相同的bufferView而不是为每个属性创建一个新的 (WIP @takahirox)
    • [x]支持sparse吗?
    • []属性
    • [x] bufferView
    • [ ] byteOffset :目前它总是使用 0,因为我正在为每个访问器创建一个新的 bufferView。
    • [x] componentType
    • [x] count
    • [x] max
    • [x] min
    • [x] type :

      • [x] SCALAR

      • [x] VEC2

      • [x] VEC3

      • [x] VEC4

  • [] BufferViews :目前我正在为每个Accessor创建一个新的bufferView ,这应该固定为仅对这些共享相同componentType属性使用一个

    • [x] 属性:
    • [x] buffer
    • [x] byteOffset
    • [x] byteLength
    • [x] byteStride
    • [x] target
  • [x]缓冲区:目前我将所有内容都保存到一个缓冲区中,因此它只是缓冲区数组中的一个条目。

    • [x] 字节长度

    • [x] uri

  • [x]动画
  • [ ]杂项

    • [ ] 验证输出 (https://github.com/KhronosGroup/glTF-Validator)

    • [ ] 包括stats选项来记录导出的项目数量,也许是一些时间?

  • [x] GLB

例子

当前演示:
image

@donmccurdy的 gltf 查看器上加载导出的 gltf
image

GLTF: https ://gist.github.com/fernandojsg/0e86638d81839708bcbb78ab67142640

Enhancement

最有用的评论

希望多材料网格能尽快实现,因为大多数 3D 模型都使用多材料。

正如我在另一个线程中所说,我正在努力。

所有85条评论

这看起来真的很好!

顺便说一下,我们计划在不久的将来移除THREE.GLTFLoader并重命名GLTF2LoaderGLTFLoader *。 在 r87 登陆之前将导出器重命名为 GLTFExporter 可能是一个好主意,以避免任何混淆,因此在发布之间不需要更改名称。 哎呀,我想念你已经这样命名了..继续! 😆


* @mrdoob ,对什么时候应该发生任何偏好? 国际海事组织我们现在可以这样做,除非我们想在 r87 中保留GLTFLoader并只发出弃用警告,并在 r88 中将其删除?

我觉得越早越好。 只要新的GLTFLoader能够检测到 1.0 并警告用户我们只支持 2.0+。

正如我之前提到的,我们可以通过查看asset来检测 IIRC。

正如我之前提到的,我们可以通过查看资产来检测 IIRC。

✅ 没错! https://github.com/mrdoob/three.js/pull/11864

凉爽的! 但是我发现了一个小错误。 我现在正在做公关。 让我们在重命名之前合并。

我们可以在清单中指定某人正在处理的项目吗?

@takahirox确定! 人们可以在这里写评论,我可以更新列表并指向 PR 如果已经发生了某些事情

接下来我要做的是处理纹理,将它们转换为 base64 而不是仅使用 url

谢谢! 我想帮助制作 glTF 导出器。 我正在研究我可以在清单中提供什么帮助...

顺便说一句,你有没有故意让两个变量WEBGL_CONSTANTSTHREE_TO_WEBGL全局化?

@takahirox很酷!
关于这两个变量,这是我将在以下 PR 中解决的问题,使其成为WebGLUtils一部分,然后将其导入。 每个需要这些常量的人每次都需要重新定义它们是没有意义的。

@takahirox顺便说一句,当然可以随意向列表中提出新项目! ;)

@fernandojsg当然! 关于变量,如果它们被故意声明为全局变量,我想建议将它们移动到某个地方,所以很高兴知道你这样做了。

我想在共享缓冲区视图上工作。

BufferViews:目前我正在为每个 Accessor 创建一个新的 bufferView,这应该修复为仅对这些共享相同 componentType 的属性使用一个

之所以对共享相同componentType的属性一个,而不是所有属性一个,是为了数据对齐,对吗?

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data -alignment

酷,我刚刚将您添加到列表中👍 是的,基本上您想为相同类型的组件共享相同的缓冲区视图,例如,如果您有位置和正常,您将有两个 VEC3 访问器,但它们会指向到同一个缓冲区视图。 这可能是一个很好的起点;)

我的意思是,我们不让缓冲区视图在不同的组件类型(例如:float 和 short)之间共享的原因是为了保持良好的数据对齐,对吗?

我相信你可以在同一个缓冲区视图中存储不同的组件类型,只要它们具有相同的target ,例如normal (Vec3)position (Vec3)uv (Vec2)可能在同一个缓冲区视图中,但indices不在。 @donmccurdy你能确认一下吗?

是的,同意了。 正如这个 glTF 规范所提到的

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data -alignment

访问器到bufferView的偏移量(即accessor.byteOffset)和访问器到缓冲区的偏移量(即accessor.byteOffset + bufferView.byteOffset)必须是访问器组件类型大小的倍数。

为了简单起见,我们在不同的 componentType(=数据类型,如 float 和 short,而不是 vec2 或 vec3)之间分离缓冲区视图是一个好主意。 如果我们在不同数据长度的 componentType 之间将它们分开,则会更加优化。

顺便说一句,当前导出器仅支持accessor.componentType float、uint 和 ushort 有什么特殊原因吗? 除了它们之外,glTF 2.0 还可以处理 char、uchar 和 short。

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#accessorcomponenttype -white_check_mark

@takahirox不是真的,我现在只是定义了这些,因为它们用于我们现在支持的属性类型(位置、法线、颜色、uvs、索引......)。
我正在处理的下一步是纹理,所以我们需要其他的,例如uchar

好的,所以我首先将处理accessor.componentType s,除非您已经开始实施。

几乎准备好了,但我的 PR 应该与 #11978 冲突。
所以我在#11978 合并后发送我的,我解决了冲突。

你会把动画添加到列表中吗?

@takahirox当然,添加动画可能很棒。 我只是没有添加它,因为我对three.js 上的动画功能的当前状态不够熟悉,但是如果您想接管它,那就太好了;)

您是否计划支持 BufferGeometry 组?
GLTF 规范是否涵盖了这一点,还是会导致为每个组创建一个新的网格?
这还必须注意,网格的材质属性是一组材质。

@marcatec glTF 规范确实有“网格”与“原始”的区别,这将允许您创建每个可以引用不同材料的 BufferGeometry 组。 目前 THREE.GLTFLoader 没有优化加载原语——它创建了单独的网格——但可以实现。

很棒的工作,很棒的列表,很高兴知道格式已经得到了很多支持! 与 gltf blender exporter 一起也能很好地工作。 迫不及待地等待灯光支持! 继续伟大的工作。

我同意,伟大的工作!

除了标准材料之外,是否有计划增加对其他材料的支持?

谢谢!

@homerjam与 MeshStandardMaterial 共享的任何材质属性都将被保留——例如,使用mapnormalMap MeshPhongMaterial 将导出这些纹理完好无损,但是当您将其导入回 Three.js 时将是 MeshStandardMaterial。 出口商目前为此做了一个简单的 PBR 转换。

往返支持(从 GLTFExporter 导出 Phong,从 GLTFLoader 加载 Phong)将需要对 glTF 格式进行正在进行的工作: https :

baseColorTexture : 支持 (material.map) 但 texCoord 总是设置为 0

@fernandojsg你能澄清一下这里缺少什么吗? 由于.map始终是three.js 中的第一个UV 集,这听起来像是在glTF 中表示它的正确方法?

同样提醒一下,我在清单上划掉了三个项目。 推理如下:

  • 切线

    • Three.js 只在 GPU 上计算它们; 添加仅用于导出器的实现听起来并不理想。

  • 稀疏存取器
  • 检查材料是否与 glTF 默认匹配并忽略它

    • 感觉就像一个边缘案例/混乱,如果有人感觉强烈,请随意实施

通过从编辑器导出到 GLB,我注意到alphaMaproughnessMapmetalnessMap不会被导出。

在#13397 中,我说normalMap都没有导出,但似乎我错了。

通过从编辑器导出到 GLB,我注意到 alphaMap、roughnessMap 和 metalnessMap 不会被导出。

除非有人已经开始,否则我今天将致力于此。

@donmccurdy

稀疏存取器
我认为这最好留给后导出优化,比如 mattdesl 的脚本。

感觉就像让导出器支持变形的稀疏访问器一样。 我稍后试试。

@takahirox很酷! 前进!

是的,我担心.... metalnessMaproughnessMap呢?

我现在正在研究它们!

13415

关于图像格式。 glTF 2.0 仅支持 .png 和 .jpg 作为外部图像文件。 我正在考虑如何在非embedImages模式下处理不受支持的图像格式文件(例如:.bmp)。

  1. 转换为 .png 或 .jpg 并嵌入
  2. 别管。 导出为原始图像文件
  3. 不出口

我更喜欢 1. 有什么想法吗?

哇,真的很欣赏你们的作品。

希望Multi-material meshes尽快实现,因为大多数3D模型都使用多材料。

  1. 转换为 .png 或 .jpg 并嵌入
  2. 别管。 导出为原始图像文件
  3. 不出口

我投了 3 票并在控制台中记录了警告。

希望多材料网格能尽快实现,因为大多数 3D 模型都使用多材料。

同意,对我来说,这是阻止使用出口商的首要问题。

希望多材料网格能尽快实现,因为大多数 3D 模型都使用多材料。

正如我在另一个线程中所说,我正在努力。

  1. 转换为 .png 或 .jpg 并嵌入
  2. 别管。 导出为原始图像文件
  3. 不出口

我投了 3 票并在控制台中记录了警告

是的,我开始认为 3. 会更简单,不会让用户感到困惑。 在非emedImages模式下获取嵌入图像会有点混乱。

我更喜欢 1. 的原因是为了从其他格式转换为 glTF。 一些(或许多)其他格式没有图像格式限制。

出口商在embedImages模式下进行转换。 因此,在控制台警告中添加“如果您想转换,请使用 embedImages 选项”会很好,我在想。

我也会去3。 由于从其他格式转换可能很乏味,无论如何您都需要将某些格式与其他格式进行优先级排序。 现在可能值得做 3,然后等着看 gltf 是否添加对新纹理格式(如 ktx 左右)的支持,然后我们可以重新审视实现。

正如https://github.com/mrdoob/three.js/pull/13415#issuecomment -369022383 中所讨论的,如果导出器能够为用户组合ambientRoughnessMetalness纹理,那就太好了。 不过,最好将该代码放在ImageUtils

我已经用最新的变化更新了清单。 我已将@takahirox添加到multimaterial项目中,我将自己完成图像撰写任务。
我还添加了 material_unlit 扩展,虽然仍在草稿中我相信它非常接近发布并且不会改变太多(/cc @donmccurdy)

希望多材料网格能尽快实现,因为大多数 3D 模型都使用多材料。

正如我在另一个线程中所说,我正在努力。

WIP...(Miku有多种材料)

image

关于不支持的图像格式,好吧,让我们去 3。

@takahirox看起来不错! 👍

顺便说一句,你们对 zip 存档支持感兴趣吗? .glTF + 外部 .bin 和纹理将适合其他创作工具(也许),但很难做到非存档。 所以 zip 存档是必要的。 我们可以减少导出的文件大小。

我想要它并之前在我当地的分支机构尝试过,如果您有兴趣,我可以稍后分享。

这不是与 gzip 压缩 glb 几乎相同吗?

.glTF + 外部 .bin 和纹理将适合其他创作工具(也许)

我希望创作工具不需要单独的文件; 我们鼓励每个人默认使用 GLB。 但当然,如果没有嵌入图像,手动编辑图像会更容易。

关于我们是否想将该功能直接放入THREE.GLTFExporter没有强烈的意见......但我几乎认为我们不应该有太多的选项,而是可以在 glTF 上进行后优化。 另一个例子,Draco 有点复杂,需要几个外部文件,所以也许最好让专门的 glTF-to-glTF 工具来做优化? 同样,如果我们发现人们需要它,我们可以制作一个 glb-unpacker(与 http://glb-packer.glitch.me/ 相对)来帮助人们将文件从 GLB 解压缩到 ZIP。

来自https://github.com/KhronosGroup/glTF/issues/1256

... gltf-pipeline 的初衷 - 以及一般的 glTF - 使导出器尽可能简单,并将优化推向通用工具。 当然,它也有助于解决碎片化问题。

也就是说,我所知道的还没有 glb-unpacker 存在......

@mrdoob

我希望纹理图像是外部的,而不是 .glTF 与 .glb。

@donmccurdy

我跟进了https://github.com/KhronosGroup/glTF/issues/1117 的讨论,并同意现在鼓励 .glb + 嵌入式文件和管道方法。 一个 .glb 有利于数据传输,特别是对于 Web 和管道方法,可以使导出器和工具保持简单和可重用。 (我也喜欢 UNIX/Linux 命令管道方法!)

所以我认为出口商现在不需要 zip 存档支持。 也许由于同样的原因,它也不需要稀疏访问器和 draco 支持。

关于 glb-unpacker,我可能会在空闲时间完成。 我认为有些艺术家喜欢 .glTF + 外部文件,因为它们在没有任何 glTF 特定工具的情况下是可读的。 有时由于并行加载文件,外部文件可以减少加载时间,因此它可以用于优化目的。

关于管道/优化工具,我想指出我们不想通过网络传输大量数据。 用户希望在~转换~传输数据之前优化/压缩。 因此,glTF 优化 Web 服务有时不适用于大数据,因为用户需要将大文件发送到服务器。

另外,对于 Three.js 和其他基于 JavaScript 浏览器的引擎,如果我们有在浏览器上运行的 glTF 优化工具,我们会很高兴。 我们可以在数据传递给用户之前进行优化/压缩。 如果没有它们,由于浏览器的限制,用户需要手动下载导出的数据,然后将其传递给管道工具。

从这个角度来看,我希望一个工具能够在任何地方运行,在浏览器上、在服务器上、在 CUI 上等等,让它更通用和可重用。 我们不想为不同的平台制作两次或更多次相同目的的工具。 那么基于 node.js 的工具会好吗? glTF(管道)团队有什么建议吗? (也许这个讨论应该在 glTF 中完成,而不是在这里。)

以防万一,在GLTFLoader二进制支持是作为扩展实现的,但 .glb 是 glTF 2.0 的核心规范,对吗?

以防万一,在 GLTFLoader 中,二进制支持是作为扩展实现的,但 .glb 是 glTF 2.0 的核心规范,对吗?

是的,它是 glTF 1.0 中的一个扩展,在它成为核心 glTF 2.0 规范的一部分后,我从未重新定位或重命名该代码。

从这个角度来说,我想要一个【优化工具】能够在任何地方运行,在浏览器上,在服务器上,在CUI上等等,让它更通用和可重用。 那么基于 node.js 的工具会好吗? glTF(管道)团队有什么建议吗? (也许这个讨论应该在 glTF 中完成,而不是在这里。)

值得询问glTF-Pipeline 路线图......不确定他们希望 glTF-Pipeline 有多普遍,或者它是否主要用于 Cesium 用途,或者它是否只是开发人员时间有限的问题。 glTF-Toolkit看起来也很相关,但(目前)仅在 Windows 上运行。 我个人喜欢 Node.js,但 C++ 或 Rust 可能是编译为 WASM 的合理选择。

哦,我错过了 WASM 的编译。 指定一些推荐的开发平台对优化开发人员很有好处。 所以我建议一个合适的线程。

我同意@donmccurdy 的观点,因为我觉得管道上的这些优化可以存在于与three.js 不同的存储库中,因此每个人都可以从中受益。 我仍然需要检查 gltf 管道和工具包工具之间的差异,但我希望它们包含此类功能。
我也同意,只要我们有一个 WASM,源语言其实并不重要,但如果它是用 node.js 编写的,那么围绕 3d 网络引擎的许多社区可能会帮助改进它们也是事实。无论如何,现在是这种文件格式的主要目标。

我不确定我是否理解“转换前优化”……管道可能对模型进行多种类型的转换,而优化可能是最常见的转换类型?

同意除此之外。 最好有低级、集中的工具,可用于构建其他工具或插入更用户友好的 GUI。

哎呀,打错字了。 不是转化而是转移。 我的意思是,大多数用户希望在通过网络发送数据之前进行优化/压缩。 我已经更新了帖子,让它们更清晰。

嗨,大家好

我正在使用 THREE.js GLTF 导出器将整个 aframe 场景导出为 gltf 对象。
如何让 aframe 上定义的 a-animation 标签成为 gltf 对象中动画的一部分?

@donmccurdy @fernandojsg @mrdoob

@siddhartpaiTHREE.GLTFExporter仅将THREE.AnimationClip对象转换为 glTF 动画,而 A-Frame 的动画系统使用 TweenJS。 所以目前这是不可能的。 您可能想在 A-Frame 或 A-Frame Inspector 上打开一个问题,它们也使用GLTFExporter ,以请求将其作为未来功能。

多材料支持 #13536

我刚刚注意到验证器会在未规范化的缓冲区视图上的每个普通元素上引发错误。 例如,如果我存储了像 [0,0,0] 这样的未初始化值,它会抛出那个错误。
因为这是一个错误而不是警告/通知,所以我认为修复很敏感。 你认为如何确保正常的缓冲区视图元素被规范化? 即便如此,对于无法归一化的值,例如 [0,0,0],我们是否应该使用有效的单位向量? /cc @donmccurdy

似乎NORMAL应该标准化。

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#meshes

正常 | “VEC3” | 5126 (浮动) | 标准化的 XYZ 顶点法线

同意确保,因为 Three.js normal 没有这样的限制。

是的,但是当您没有实际的法线(例如 [0,0,0] 的未使用值)时该怎么办,只需创建一个有效的就可以了? 让我们说 [1,0,0]。 因此,我们应该修改 bufferview 代码以检测我们正在解析一个普通属性,并在将其保存到数据视图之前对每个属性进行规范化。

当您没有实际法线时该怎么办,例如未使用的 [0,0,0] 值

嗯.... 用有效的替换并显示警告?

因此,我们应该修改 bufferview 代码以检测我们正在解析一个普通属性,并在将其保存到数据视图之前对每个属性进行规范化。

我更喜欢在processMesh()这样做,因为它会更简单,比如

var originalNormal = geometry.attributes.normal;

if ( hasNonNormalizedValues( originalNormal ) ) {

    geometry.attributes.normal = createNormalizedAttribute( originalNormal );

}

processAccessorHere();

geometry.attributes.normal = originalNormal;

如果我们在processBufferView()这样做,代码会变得有点复杂,因为我们需要关心数据是否在不同属性之间共享,例如位置和法线。 (我知道这是非常罕见的用例,但 Three.js 不限制。)

是的,我喜欢这种方法,我害怕在导出后修改法线,但是如果我们保存参考并在完成后将它们放回去应该没问题。 :+1: 你介意通过这些变化来推动 PR 吗? 还是要我做?

好的,我会。 (你急着解决这个问题吗?)

@takahirox很酷,谢谢! 但不着急,我只是在审查出口商的状态 ^_^

好的,那我~明天~这周就做。

是的,glTF 不允许省略特定顶点上的法线,但不允许在单个基元中省略其他顶点。 我们需要提供某种值、剥离这些顶点或抛出错误。

我更愿意让用户更轻松,所以我的投票是创建一个新的法线数组,对它们进行规范化,并为空数组添加一个 (0,1,0) 值。

看起来不错。 如果大型模型的速度很慢,我们可能需要checkNormals选项或类似的选项,因此不需要此选项的用户可以选择退出,而不是扫描每个顶点。

是的,我正要写同样的东西! :D

如果大型模型的速度很慢,我们可能需要 checkNormals 选项或类似的选项,因此不需要此选项的用户可以选择退出,而不是扫描每个顶点。

我将首先在没有该选项的情况下进行 PR。 让我们在必要时添加。 我个人认为这项检查不会减慢多少。

我将首先在没有该选项的情况下进行 PR。 让我们在必要时添加。 我个人认为这项检查不会减慢多少。

在 a-painter 上加载每个笔画时,我正在标准化整个缓冲区,而且速度很慢

即使只是检查它们是否正常化?

@takahirox 无论如何您都需要计算长度,所以我想它不会有太大变化

嗯,好的。 我会用 PR 来评估。

这是我们引入的第一个 GLTFExporter 功能,它对每个顶点进行任何计算(相对/绝对变形目标转换除外),所以是的,可能会更慢......无论如何。

做得好! 恕我直言,应该合并到核心three.js 中,而不是在“示例”中。
希望看到KHR_lights_punctual支持!

PR https://github.com/mrdoob/three.js/pull/15519 添加了 KHR_lights_punctual。 :)

我认为这个问题可能可以关闭 - 其余项目不太重要的便利或优化,可以在其他地方跟踪:

  • [] 重用缓冲区视图
  • [] 自动合并金属/粗糙/AO 纹理

嘿伙计们,有谁知道如何通过应用变形并将其从最终对象中删除的变形更改导出自定义形状的网格?
像这个问题https://stackoverflow.com/questions/57423471/how-to-export-morph-changed-meshes-from-threejs-application
提前致谢!

@vini-guerrero 请使用论坛 (https://discourse.threejs.org/) 或 Stack Overflow 寻求帮助,而不是 GitHub 问题。

此页面是否有帮助?
0 / 5 - 0 等级