Three.js: 不支持 FBX 二进制格式?

创建于 2016-10-14  ·  100评论  ·  资料来源: mrdoob/three.js

问题描述

qq 20161014151051

FBXLoader 只支持 FBX 文本格式吗?

三.js版本
  • [ ] 开发
  • [x] r81
  • [ ] ...

    浏览器
  • [x] 所有这些

  • [ ] 铬合金
  • [ ] 火狐
  • [ ] IE浏览器

    操作系统
  • [x] 所有这些

  • [ ] 窗户
  • [ ] Linux
  • [ ] 安卓
  • [ ] IOS
    硬件要求(显卡、VR 设备……)
Enhancement

最有用的评论

从 4 月开始,我将再次开始研究 FBX 二进制解析器。
LMK,如果有人赶时间的话。

所有100条评论

是的。 目前FBXLoader仅支持版本 7 中的 ASCII 格式。

三.js 版本:r77

qq 20161014175807

为什么?

/ping @yamahigashi

为什么?

因为没有参考开源实现? 如果你知道一个,我会很想看看它。

啊,等等,我以为是关于二进制的。 对于低于 v7 的 ASCII FBX,我有代码在这里和一堆测试模型在我的硬盘驱动器的某个地方。

这里有人制作或正在制作二进制 FBX 解析器吗?
如果没有,我想尝试做到这一点......

你必须喜欢逆向工程才能做到这一点)而且,如果它是简单的标签,你可能很幸运,但如果它们唯一地序列化每种数据类型,你就很合适:你面临着为每个模型调整一个数字并保存它一次看看发生了什么变化。

感谢您的建议。
我现在通过查看这个站点已经实现了制作 FBX 二进制解析器。

https://code.blender.org/2013/08/fbx-binary-file-format-specification/

我会尝试制作 ObjectParser 来制作一个对象
来自接下来的二进制解析器的结果。

哦哇,有人已经经历了地狱,并且有规格)

@takahirox如果新解析器具有类似THREE.PLYLoader结构,那就太好THREE.BufferGeometry对象(请参阅方法handleElement用法)。

好,我会试试。 我在想我是否也可以将它用于MMDLoader

顺便说一句,这里有人知道即使在版本 7 以下 FBX 二进制格式是否保持不变吗?

我不知道。

也许@mrdoob知道?

@takahirox你有没有在任何地方分享过你的二进制 fbx 解析器?

还没有……我很快就会做的!

@takahirox任何更新:)? 谢谢!

对不起,我最近很忙……但很快!

@takahirox真棒\ o/

从 4 月开始,我将再次开始研究 FBX 二进制解析器。
LMK,如果有人赶时间的话。

@takahirox你有什么粗略的东西要分享吗? 我们将在本周末进行演示,并且可以真正使用 FBX 二进制加载进行演示。

@takahirox我真的很着急,这有什么更新吗? 我可以在力所能及的地方提供帮助,但这对我来说仍然是新的。

我刚刚开始重新开始工作。
至少,我还需要几周的时间来分享。

你觉得几周?

嗯,大概两三个星期?

出于好奇,如果我能够赞助一些开发工作,是否可以在一周左右的时间内完成?

好吧,我不能保证,但我会尝试。
你有什么具体的模型数据可以分享吗?
想和他们一起工作作为参考。

测试文件.fbx.zip
这与我们需要的类似,如果有帮助的话

同时...

对于https://with.in/watch/under-neon-lights/,我们使用纯文本 FBX,但我们将扩展名更改为 .fbx.txt,以便服务器对其进行 gzip。 我也优化了很多FBXLoader2 。 它最终成为一个相当不错的工作流程。

我想知道是否有任何FBXLoader支持FBXLoader2不支持的内容,或者我们已经可以替换它...

@凯尔拉森?

旁注:FBX示例也已经使用了FBXLoader2

@mrdoob FBXLoader 和 FBXLoader2 之间的唯一区别是索引缓冲区的使用。 FBXLoader2 不使用索引缓冲区。 除此之外,FBXLoader2 应该包括之前加载器的所有功能。

啊! 是时候更换它了👌

这家伙有更新吗? 乐于助人,尽我所能。

你有 testfile.fbx.zip 的文本文件版本吗?
我想比较。

二进制解析器进度...

image

@亚当克莱里

能分享一下模型截图吗?
甚至文本文件也无法在 Three.js 上加载。

另一个模型的截图....

image

模型: https :

看起来不错! 😀

谢谢你们!

我会尽快尝试上传屏幕截图。 基本上我的用例能够将材质图像和模型捆绑到一个文件中

块.fbx.zip
screen shot 2017-05-05 at 15 19 12

这是一个简单的块,将图像材料烘焙到 fbx 中,并附有它在搅拌机中的外观的图像

你的意思是,纹理图像数据应该在 fbx 文件中?

是的。 我可能错误地导出了那个模型

我在fbx二进制数据中找不到图像数据...
如果有人知道烘焙纹理图像数据规范,请告诉我。

也许试试这个
block2.fbx.zip

还是找不到...
这些文件是否可以加载到其他查看器上?

如果有人知道烘焙纹理图像数据规范,请告诉我。

我只是尝试用搅拌机和 3ds max 打开block2.fbx.zip 。 两者都只显示文件名,但不显示图像。 文件中似乎只有.../Users/adamclarey/Documents/burger-screen.jpg的引用。

是的,我的解析器提取文件名但没有图像数据。

好的。 我显然做错了什么。 Blender 不是最直观的应用程序。 我会试试别的

我从来没有听说过图像数据可以被烘焙成 3D 导出​​/导入格式(但只能是资源的相对路径)。

这甚至可能吗?

我刚刚注意到:这是可能的。

我将创建一个这样的测试文件并将其张贴在这里。

好东西。

此 FBX 是在 3ds max 中创建的,并使用“嵌入媒体”选项导出:
TestcubeWithImage.zip

3ds max 的截图:

testcubescreenshot

在搅拌机中打开(在另一台机器上):

screenshot_blender

到目前为止,在搅拌机中,我没有发现导出带有烘焙图像的 FBX 的选项。 也许在出口之前必须进行烘焙? - 我没有使用搅拌机的经验。

@takahirox这是同一个文件,也是在 3ds max 中创建的,但导出时没有“嵌入媒体”选项:

测试立方体.zip

用于比较目的可能会很有趣。

如果您需要其他文件进行测试,请随时在此处发布。

我发现数据看起来像 TestcubeWithImage.fbx 的 Video.ID.properties.Content 属性下的图像数据。
这在该线程中发布的其他二进制文件中不存在。

我再仔细看看...

image

进步...😄

image

所以,嵌入的纹理现在看起来没问题。
如果你有,任何人都可以分享包括动画在内的二进制 fbx 吗?

以下是具有不同类型关键帧动画的 3 个测试文件:

动画翻译.zip
动画变形.zip
动画骨头.zip

但不幸的是,我没有设法生成在不同程序中以相同方式运行的文件。

它们都是用 3ds max 创建的。

  • 重新导入到 3ds max 时一切正常。
  • AnimationTranslate 示例在 Blender 和 Clara.io 中没有问题。
  • AnimationMorph 示例在 Blender 中没问题,但动画在 Clara.io 中不起作用。
  • AnimationBones 示例在 Clara.io 中没问题,但在 Blender 中动画不太好。

@takahirox我们的团队一直在寻找一个 Three.js 二进制 FBX 解析器有一段时间了,这看起来很棒! 你有没有在任何地方提供源代码? 出于我们的目的,我们需要能够从 FBX 中提取网格、法线、UV 和视觉场景,这似乎工作正常。

如果源可用,如果您能指出它的位置,那就太好了。

感谢您做的伟大工作!

https://github.com/takahirox/three.js/blob/FixLoaderBinaryParser/examples/js/loaders/FBXLoader2.js

请注意,这是非常临时的。
我需要清理和优化代码。
并且功能现在可能会被破坏。

@takahirox请注意:在不同程序中进行了一些测试后,我更新了我之前的评论。

@jostschmithals

谢谢。
Translate 和 Bone 现在似乎可以工作了。
即使使用 ascii 文件,FBXLoader 也不支持 Morph 动画。
这将是我们的下一个工作......

我尝试在我的 Three.js 项目中加载 testcube 文件,但没有加载任何内容。
我在图像文件上得到一个 404,在检查 FBXTree 对象后,我可以看到它仍然包含对绝对文件路径的引用。

screen shot 2017-05-07 at 15 01 23
screen shot 2017-05-07 at 14 59 00

我刚刚测试了它(在原始 jpg 不可用的机器上),它工作正常。

注意:您必须使用
https://github.com/takahirox/three.js/blob/FixLoaderBinaryParser/examples/js/loaders/FBXLoader2.js
但是加载器被简单地称为THREE.FBXLoader (没有版本号 2)。

这就是我正在使用的。 我会进一步调查

试试 TestcubeWithImage.fbx
Testcube.fbx 不包含图像数据,所以你应该得到 404

@ 在我的测试中,我得到了与 @adam-clarey 完全相同的控制台输出 - 除了GET ... 404消息。

顺便说一句:我在 Windows 10 上测试过。

进步...
动画现在看起来很好用 😄

image

你能粘贴你用来加载模型的代码吗? 出于某种原因,它只是不适合我。

我已经尝试将 Testcube 文件替换为 webgl_loader_fbx.html 示例(也交换了 FBXLoader2.js 文件),但它仍然没有呈现模型。

@adam-clarey 这正是我所做的(当然,停用动画),并且无需任何其他更改即可工作。

多么奇怪……

screen shot 2017-05-08 at 09 50 40

并且确定您正在使用TestcubeWithImage.fbx (正如@takahirox指出的那样)?
任何进一步的错误信息?
您使用的是哪个操作系统?
所有浏览器都一样吗?

啊哈,我真是个笨蛋! 我只是向上滚动,直到找到第一个 testcube 文件。

我的错

你好! 尝试加载从 Autodesk 导出的外部 .fbx 模型时,我也遇到此错误。 谁能给我一个解决方案

谢谢!

https://github.com/takahirox/three.js/blob/FixLoaderBinaryParser/examples/js/loaders/FBXLoader2.js
请注意,这是非常临时的。
我需要清理和优化代码。
并且功能现在可能会被破坏。

@hmtri1011

@RicoLiu这是我使用 THREE.FBXLoader 时得到的。 我通过替换模型的 URL 实现了 loader_fbx 示例。

当我使用 THREE.FBXLoader2 时,我收到错误THREE.FBXLoader2 is not a constructor

image

您可以使用 webgl_loader_fbx.example:

  1. 加载https://github.com/takahirox/three.js/blob/FixLoaderBinaryParser/examples/js/loaders/FBXLoader2.js
    而不是当前threejs分支的FBXLoader2.js,
  2. 使用THREE.FBXLoader没有版本号 2 ! ),
  3. (停用动画,如果您的模型中没有动画),

它应该工作。

@jostschmithals我按照你的步骤然后得到一个新的错误Zlib is not defined

好像你的模型文件被压缩了?

image
我得到的完全错误

在您的示例中添加此行。

    <script src="js/libs/zlib_and_gzip.min.js"></script>

image
完成,出现另一个错误....:(

正如我上面写的,如果您将示例代码与不包含任何动画的模型文件一起使用,则必须停用动画代码(在加载部分和渲染循环中)。

我遇到了一个不同的问题,我确定与材料有关。 我的问题是,在某些条件下,某些 fbx 模型会呈现,而有些则不会。

重现:
在 webgl_loader_fbx.html 示例文件中,在 init() 中放置以下代码以创建环境

 var loadSkyDomeAndGroundBowl = function(scene, onLoad, onProgress, onError) {
                var pathtop="path/to/top.jpg";
                var pathbot="path/to/bottom.jpg";
                var radius=40;
                var bottomtopfactor=0.1;
                var sinkin=0.05;

                var texturetop;
                var texturebot;

                var onTextureLoadTop=function(texture) {
                  console.log('onTextureLoadTop');
                  texturetop=texture;
                  onTextureLoaded();
                };
                var onTextureLoadBot=function(texture) {
                  console.log('onTextureLoadBot');
                  texturebot=texture;
                  onTextureLoaded();
                };

                var onTextureProgress=function(xhr) {
                  console.log('onTextureProgress');
                  if(onProgress)
                    onProgress('Loading sky dome / ground bowl texture');
                };
                var onTextureError=function(xhr) {
                  console.log('onTextureError');
                  if(onError)
                    onError('Error loading sky dome / ground bowl texture');
                };

                var onTextureLoaded=function() {
                  console.log('onTextureLoaded');
                  if(texturetop && texturebot) {
                    console.log('onTextureLoaded 2');
                    var geometrytop = new THREE.SphereGeometry( radius*10, 600, 400, 0, Math.PI*2, 0, Math.PI*0.5);
                    var materialtop = new THREE.MeshBasicMaterial();

                    materialtop.map = texturetop;
                    materialtop.side = THREE.BackSide;
                    var skydome = new THREE.Mesh( geometrytop, materialtop );
                    skydome.position.y=bottomtopfactor*radius+sinkin;
                    scene.add( skydome );

                    var geometrybot = new THREE.SphereGeometry( radius, 60, 40, 0, Math.PI*2, Math.PI*0.5, Math.PI*0.5);
                    var materialbot = new THREE.MeshBasicMaterial();
                    materialbot.map = texturebot;
                    materialbot.side = THREE.BackSide;
                    var groundbowl = new THREE.Mesh( geometrybot, materialbot );
                    groundbowl.scale.set(1,bottomtopfactor,1);
                    groundbowl.position.y=bottomtopfactor*radius+sinkin;
                    scene.add( groundbowl );

                    if(onLoad)
                      onLoad();
                  }
                };

                var loader=new THREE.TextureLoader();
                loader.load(pathtop, onTextureLoadTop, onTextureProgress, onTextureError);
                loader.load(pathbot, onTextureLoadBot, onTextureProgress, onTextureError);
              }

这基本上只是添加了一个带有 2 个图像的天穹和地面。

然后在场景初始化之后,运行: loadSkyDomeAndGroundBowl(scene);

您将看到 2 个 fbx 模型在这个新环境中加载和渲染良好。

现在,如果您将 xsi_man_skinning.fbx 引用替换为 TestcudeWithImages.fbx(同时注释掉动画代码),您将看到该代码根本没有渲染。

我在其他 fbx 文件中也注意到了这一点。 二进制 fbx 文件似乎与环境不兼容。

或者我可能只是做错了什么......
(是的,它使用最新的 FBXLoader2 文件)

这是我的示例代码:
`



三.js - FBXLoader 测试
<script src="../build/three.js"></script>

<script src="js/controls/OrbitControls.js"></script>

<script src="js/curves/NURBSCurve.js"></script>
<script src="js/curves/NURBSUtils.js"></script>
<script src="js/loaders/FBXLoader2.js"></script>

<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/libs/zlib_and_gzip.min.js"></script>
<script>
    if (!Detector.webgl) Detector.addGetWebGLMessage();

    var container, stats, controls;
    var camera, scene, renderer, light;

    var clock = new THREE.Clock();

    var mixers = [];

    init();

    function init() {

        container = document.createElement('div');
        document.body.appendChild(container);

        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);

        scene = new THREE.Scene();

        // grid
        var gridHelper = new THREE.GridHelper(28, 28, 0x303030, 0x303030);
        gridHelper.position.set(0, - 0.04, 0);
        scene.add(gridHelper);

        // stats
        stats = new Stats();
        container.appendChild(stats.dom);

        // model
        var manager = new THREE.LoadingManager();
        manager.onProgress = function (item, loaded, total) {

            console.log(item, loaded, total);

        };

        var onProgress = function (xhr) {

            if (xhr.lengthComputable) {

                var percentComplete = xhr.loaded / xhr.total * 100;
                console.log(Math.round(percentComplete, 2) + '% downloaded');

            }

        };

        var onError = function (xhr) {

            console.error(xhr);

        };

        var loader = new THREE.FBXLoader(manager);
        loader.load('models/fbx/accient_2_full.fbx', function (object) {

            //object.mixer = new THREE.AnimationMixer(object);
            //mixers.push(object.mixer);

            //var action = object.mixer.clipAction(object.animations[0]);
            //action.play();

            scene.add(object);


        }, onProgress, onError);

        loader.load('models/fbx/nurbs.fbx', function (object) {

            scene.add(object);

        }, onProgress, onError);

        renderer = new THREE.WebGLRenderer();
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0x000000);
        container.appendChild(renderer.domElement);

        // controls, camera
        controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.target.set(0, 12, 0);
        camera.position.set(2, 18, 28);
        controls.update();

        window.addEventListener('resize', onWindowResize, false);

        light = new THREE.HemisphereLight(0xffffff, 0x444444, 1.0);
        light.position.set(0, 1, 0);
        scene.add(light);

        light = new THREE.DirectionalLight(0xffffff, 1.0);
        light.position.set(0, 1, 0);
        scene.add(light);

        //animate();

    }

    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        renderer.setSize(window.innerWidth, window.innerHeight);

    }

    //

    function animate() {

        requestAnimationFrame(animate);

        if (mixers.length > 0) {

            for (var i = 0; i < mixers.length; i++) {

                mixers[i].update(clock.getDelta());

            }

        }

        stats.update();

        render();

    }

    function render() {

        renderer.render(scene, camera);

    }
</script>

`

@jostschmithals你能给我一个正确的解决方案吗? 我也停用了动画代码

@adam-clarey 我已经测试过了,你看不到立方体的原因是它位于地平面下方(如果你用相机绕它运行,你应该看到它)。 除此之外,您的代码对我来说一切正常。

@takahirox :由 FBXLoader 创建的组内的网格被平移和旋转,因此枢轴点不像在原始模型中那样位于立方体的中心,而是位于其上侧的中心。 这似乎是一个小错误?

(虽然图像正确显示在顶部......)

@hmtri1011您已停用 animate() 函数。 因此你的场景根本没有被渲染😉

(在这种情况下,仅停用您已注释掉的行就足够了。)

@jostschmithals tks :D 现在可以使用了

好地方@jostschmithals ,谢谢。

文件是什么二进制版本应该重要吗? 我有版本为 7400 的 fbx 文件呈现良好,但版本为 7500 的 fbx 文件出错了。

“FBXLoader:未知的属性类型”
其中变量 'type' 是一个空字符串

@adam-clarey 我对 fbx 没有详细的了解。 我只是加入了这个线程,因为我发现这个问题很有趣,是否/如何将图像数据烘焙到模型文件中。 所以我想把这个问题转发给@takahirox。

我知道 >=7500 的规格与 < 7500 有点不同,并且
我正在努力支持> = 7500。
能否分享一下7500版本的二进制模型数据供测试使用?

所以经过更多的测试,7200和7500似乎没问题。

但是,6100 和 7300 不渲染。
house_fs.fbx.zip
荷兰之家.FBX.zip

你会分享ascii版本文件吗?
我们可以澄清问题是否是二进制特定的。

我希望我们关闭这个问题,因为FBXLoader现在支持二进制(可能还不完美)。
让我们为FBXLoader改进提出另一个问题。

@takahirox听起来不错!

@亚当克莱里
我想我得到了这个错误。

“FBXLoader:未知的属性类型”
其中变量 'type' 是一个空字符串

在 FBXLoader.js 中
改成

            while ( ! this.endOfContent( reader ) ) {

                var node = this.parseNode( reader, version );
                if ( node !== null ) 
                    allNodes.add( node.name, node );
                else
                    break;

            }

11956

大家好,
我注意到 FBXLoader 只支持 FBX 文件 >= 7.0。
现在我想加载7.0以下的fbx文件,请问怎么做?
这是我的 fbx 文件https://github.com/nxhoang/Three.js-Fxb-and-Textures/tree/master/models/fbx
非常感谢。

@nxhoang正如我们在此处讨论的,我们仅支持 6100(二进制)或 7000(ASCII)以上的 FBX 版本。

如果您需要使用较旧的 FBX 文件,则需要更新它们(最好将它们加载到 3ds max 或 Maya 中以执行此操作),或将它们转换为其他格式。

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

相关问题

makc picture makc  ·  3评论

fuzihaofzh picture fuzihaofzh  ·  3评论

filharvey picture filharvey  ·  3评论

jlaquinte picture jlaquinte  ·  3评论

ghost picture ghost  ·  3评论