无法使用 Three.js 加载从搅拌机导出的纹理 Collada

Posted

技术标签:

【中文标题】无法使用 Three.js 加载从搅拌机导出的纹理 Collada【英文标题】:Unable to load textured Collada exported from blender using Three.js 【发布时间】:2015-06-01 19:21:39 【问题描述】:

我正在使用 Three.js,版本 71。我正在使用 Blender,2.73 版

我使用 Blender 创建了一个带纹理的 collada 对象(.dae 文件),现在我想将它加载到我的 three.js 场景中。到目前为止,我只能加载从搅拌机导出的没有纹理的模型。

以下是我创建带纹理的 collada 对象的方法: 在搅拌机中,我只是使用默认立方体。使用右侧的设置,我为立方体添加了纹理。这是我放在立方体上的纹理(注意:它是 2048 X 2048,所以它是 2 的幂):

这是渲染模式下立方体的图像,以证明纹理在其上:

以下是我从 Blender 将立方体导出为 collada 时使用的导出设置:

这是我用来尝试加载带纹理的 collada 的一些代码:

var loader = new THREE.ColladaLoader();
var localObject;
loader.options.convertUpAxis = true;
loader.load( './models/test_texture.dae', function ( collada ) 
  localObject = collada.scene;
  localObject.scale.x = localObject.scale.y = localObject.scale.z = 32;
  localObject.updateMatrix();
  game.scene.add(localObject);
 );

这是我得到的错误:

[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 2

然后我用谷歌搜索了那个错误信息,有人说我需要计算切线。这是我的尝试以及我得到的错误:

var loader = new THREE.ColladaLoader();
var localObject;
loader.options.convertUpAxis = true;
loader.load( './models/test_texture.dae', function ( collada ) 
  localObject = collada.scene;
  localObject.scale.x = localObject.scale.y = localObject.scale.z = 32;
  localObject.updateMatrix();

  for (var i = collada.scene.children.length - 1; i >= 0; i--) 
    var child = collada.scene.children[i];

    // child.children[0] will give us the THREE.Mesh of the collada
    if ( child.colladaId == "Cube" ) 

      // ATTEMPT 1: Just tried computing tangets based on answer from neoRiley here: http://***.com/questions/21200386/webgl-gl-error-gl-invalid-operation-gldrawelements-attempt-to-access-out-of
      // child.children[0].geometry.computeTangents();

      // ATTEMPT 2: Got this suggestion from Popov here: http://***.com/questions/15717468/three-lod-and-normalmap-shader-fail
      // child.children[0].geometry[ 0 ][ 0 ].computeTangents();
      // child.children[0].geometry[ 1 ][ 0 ].computeTangents();

      // ATTEMPT 3: Tried setting some update flags based on answer from Sayris here: http://***.com/questions/13988615/webglrenderingcontext-error-loading-texture-maps
      // child.children[0].geometry.buffersNeedUpdate = true;
      // child.children[0].geometry.uvsNeedUpdate = true;
      // child.children[0].material.needsUpdate = true;
      // child.children[0].geometry.computeTangents();
    
  ;
  game.scene.add(localObject);
 );

尝试 1 错误:

Uncaught TypeError: Cannot read property '0' of undefined
// Stack trace
three.js:9935 handleTriangle
three.js:9974 THREE.Geometry.computeTangents
myCode.js:116 (anonymous function)
ColladaLoader.js:204 parse
ColladaLoader.js:84 request.onreadystatechange

尝试 2 错误:

Uncaught TypeError: Cannot read property '0' of undefined

这来自自己的代码。我不认为THREE.Mesh的几何是二维的,但我还是试过了。

尝试 3 错误:(与尝试 1 错误相同)

Uncaught TypeError: Cannot read property '0' of undefined
// Stack trace
three.js:9935 handleTriangle
three.js:9974 THREE.Geometry.computeTangents
myCode.js:116 (anonymous function)
ColladaLoader.js:204 parse
ColladaLoader.js:84 request.onreadystatechange

【问题讨论】:

【参考方案1】:

我决定改用 JSON 加载程序,因为我无法让 collada 工作。我做的第一件事是将 JSON 导出器插件安装到 Blender 中。我从我的 three.js 下载的 .zip 文件中获得了插件。在里面 three.js-r71/utils/exporters/blender/addons,它被称为 io_three。您只需复制该文件夹并将其粘贴到您的 Blender 安装目录中的 Blender Foundation/Blender/2.73/scripts/addons

然后您必须在 Blender 中启用它。为此:

    点击文件->用户首选项... 点击插件 在搜索字段中输入三个 一直向右,点击复选框启用 点击左下角的保存用户设置,这样您就无需再次执行此操作了。如果您在单击 File->Export 时看到 Three.js (.json),您就会知道它正在工作。

我按照该网站的大部分说明来帮助我创建和导出模型:http://graphic-sim.com/B_basic_export.html

这是我用来创建和导出模型的步骤(我从网站上稍微调整了它们)

    启动 Blender。 查看属性编辑器(右侧)。 按世界上下文按钮。在 World 面板中点击 Ambient Color 并将其从黑色更改为中灰色。 按材料上下文按钮。在 Diffuse 面板上,将 Intensity 更改为 1.0。在 Specular 面板上执行相同的操作。在 Shading 面板中,勾选 Shadeless 框。 按纹理上下文按钮。在Type下拉框顶部附近,选择Image or Movie。在图片面板中,浏览到您的图片(确保图片的尺寸是 2 的幂)。 选择 UV 编辑 屏幕布局(顶部帮助菜单右侧的下拉框)。 在 3D 编辑器中使用鼠标光标,进入编辑模式(Tab 键)。 展开(按 U 键)。选择智能 UV 项目。点击确定接受默认值。 在 UV 编辑屏幕中,使用左下角的菜单选择您的图像(见屏幕截图) 选择图像->另存为图像。此图片需要位于您要导出的 JSON 文件旁边。 点击文件->导出->Three.js (.json)。 在左侧,选择更多导出选项(请参阅我使用的截图,这是我通过反复试验找到的)。我想我只添加了 Face MaterialsMaterialsTextures。然后您也可以点击保存设置来保存这些设置。 将您之前保存的 JSON 文件和图像文件放入项目文件夹中。

    使用下面的代码来加载它:

    var object;
    var loader = new THREE.JSONLoader();          
    loader.load( "./models/test_texture.json", function(geometry, materials) 
      object = new THREE.Mesh(geometry, materials[0]);
      object.scale.set(32, 32, 32);
      game.scene.add(object);
    );
    

【讨论】:

以上是关于无法使用 Three.js 加载从搅拌机导出的纹理 Collada的主要内容,如果未能解决你的问题,请参考以下文章

THREE.JS 从搅拌机中导出 JSON 模型(包括纹理)

如何正确加载three.js中的json模型?

THREE.JS GLTFLoader,使用工作灯加载搅拌机场景

为three.js导出json的搅拌机

three.js如何使纹理“生成”纹理坐标,就像搅拌器循环一样

将模型从 Blender 导出到 Three.js 时没有纹理