从 Blender 到 THREE.js:导出器的 BufferGeometry 和动画问题

Posted

技术标签:

【中文标题】从 Blender 到 THREE.js:导出器的 BufferGeometry 和动画问题【英文标题】:From Blender to THREE.js: BufferGeometry and Animation Problems with Exporter 【发布时间】:2017-12-21 06:02:14 【问题描述】:

我使用 THREE.js 已经有一段时间了,我真的很喜欢它,除了一件事:将 Blender 中的动画图形引入游戏场景。在尝试自己解决并搜索了一段时间之后,我在这里提出了我的问题。坦率地说,我只是一名编码员,不是图形专家,而且我自己也没有创建搅拌机内容。

1.在当前版本 86 中使用 THREE.js Blender 导出器导出 BufferGeometry 是否有什么特别需要了解(或损坏?)? 当使用 BufferGeometry 作为导出选项时,我的文件大小增加了 3 倍,但不包含动画在生成的 .json 文件中。使用除了“Geometry”而不是“BufferGeometry”之外的相同选项包含动画并提供更小的文件大小(导出器选项和示例文件如下)。

2。正确的可能是什么问题? .json 没有在 THREE.js 中播放动画? 我有一个可以导出、加载和动画的工作示例(Slimeblob)。使用相同的代码,我的大多数其他动画模型都已加载,但没有动画。例如,我有一个非常简单的立方体,它有一个短动画,它不在 THREE.js 中播放,而是在 .json 中(以及运行时环境中)有动画数据。 .blend 文件和代码如下。可以在控制台输出中看到动画以某种方式加载(至少在 chrome 浏览器中)。

示例演示:

<!doctype html>
<html lang="en">
<head>
    <title>Animation Test</title>
    <style> body  padding: 0; margin: 0; overflow: hidden;  </style>
</head>
<body>

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

var gameScene, gameCamera, renderer;
var clock = new THREE.Clock();
var delta;
var controls;

var jsonLoader = new THREE.JSONLoader();

var SlimeblobGeometry, SlimeblobGeometryAnimationMixer;
var AnimationExport, AnimationExportAnimationMixer;

init();

function init() 
    var windowHeight = window.innerHeight;
    var windowWidth = window.innerWidth;

    gameCamera = new THREE.PerspectiveCamera( 60, windowWidth / windowHeight, 1, 2100 );
    gameCamera.position.set( 0, 11, 11 );
    gameCamera.lookAt( new THREE.Vector3( 0, 0, 0 ) );

    gameScene = new THREE.Scene();

    renderer = new THREE.WebGLRenderer(  antialias: true  );
    renderer.setSize( windowWidth, windowHeight );
    renderer.setClearColor( 0xB2DFEE );
    document.body.appendChild( renderer.domElement );

    var light = new THREE.HemisphereLight( 0xffffff, 0x003300, 1 );
    light.position.set( -80, 500, 50 );
    gameScene.add( light );

    controls = new THREE.OrbitControls( gameCamera, renderer.domElement );

    jsonLoader.load( "SlimeblobGeometry.json",
                     function ( geometry, materials ) 
                         for ( var k in materials ) 
                             materials[ k ].skinning = true;
                         
                         SlimeblobGeometry = new THREE.SkinnedMesh( geometry, materials );
                         SlimeblobGeometry.position.x = 5;
                         gameScene.add( SlimeblobGeometry );
                         SlimeblobGeometryAnimationMixer = new THREE.AnimationMixer( SlimeblobGeometry );
                         SlimeblobGeometryAnimationMixer.clipAction( SlimeblobGeometry.geometry.animations[ 0 ] ).play();
                     
    );

    jsonLoader.load( "AnimationExport.json",
                     function ( geometry ) 
                         AnimationExport = new THREE.SkinnedMesh( geometry, new THREE.MeshLambertMaterial(  color: 0x436EEE  ) );
                         AnimationExport.position.x = -5;
                         gameScene.add( AnimationExport );
                         AnimationExportAnimationMixer = new THREE.AnimationMixer( AnimationExport );
                         AnimationExportAnimationMixer.clipAction( AnimationExport.geometry.animations[ 0 ] ).play();
                         console.log( AnimationExport.geometry.animations[ 0 ] ); /* Chrome Browser may be necessary for meaningful output */
                    
    );

    updateFrame();


function updateFrame() 
    requestAnimationFrame( updateFrame );
    delta = clock.getDelta();

    if ( SlimeblobGeometryAnimationMixer ) 
        SlimeblobGeometryAnimationMixer.update( delta );
    
    if ( AnimationExportAnimationMixer ) 
        AnimationExportAnimationMixer.update( delta );
    

    controls.update();

    renderer.render( gameScene, gameCamera );


</script>

</body>
</html>

代码运行没有错误,并且两个模型都已加载。粘液动画正确,立方体没有。我错过了什么?

The export settings (same for both)

环境详情:

THREE.js 修订版 86(此时是最新版本) 修订版 86 中的 THREE.js Blender 导出器 Blender 2.77 版

工作示例:上面的代码以及 .json 和 .blend 的代码(直接在本地工作,跨域策略块除外):

AnimationTest.7z

现在离我很远,谢谢和最好的问候!

【问题讨论】:

【参考方案1】:

skinning: true 分配给您的立方体材料,这为我解决了问题:

AnimationExport = new THREE.SkinnedMesh( geometry, new THREE.MeshLambertMaterial(  color: 0x436EEE, skinning: true  ) );

SkinnedMesh Animations 和threejs 处理起来很痛苦,但最近得到了一些喜爱。这也意味着动画系统 API 会不时更改,因此我建议您阅读 github 上的问题和 PR :-)

【讨论】:

是的,就是这样,你解决了我的问题,非常感谢!还没有想法告诉我的代码创建的关于动画的材料。我会等一下,然后接受你的分析器是正确的,这样也许有人也可以回答 BufferGeometry 的困惑。

以上是关于从 Blender 到 THREE.js:导出器的 BufferGeometry 和动画问题的主要内容,如果未能解决你的问题,请参考以下文章

将变形目标从 Blender 导出到 Three.js

将 Blender 粒子系统头发导出到 Three.JS

以 gltf 格式从 Blender 导出组到 Three.js

Blender 导出到 Three.js

Blender 导出到 JSON 以获取 THREE.js 缺少的材料

无法将从 Blender 导出的对象加载到 three.js 中?