从 Blender 到 THREE.js:Exporter 的 BufferGeometry 和动画问题
From Blender to THREE.js: BufferGeometry and Animation Problems with Exporter
我现在使用 THREE.js 有一段时间了,我真的很喜欢它,除了一件事:将动画图形从 Blender 带到游戏场景中。在尝试自己解决并搜索了一段时间之后,我在这里提出我的问题。坦率地说,我只是一个编码员,不是图形专家,我也不是自己创建 blender-contents。
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(目前是最新的 2)
- THREE.js 修订版 86 的 Blender 导出器
- Blender 版本 2.77
工作示例:上面的代码以及 .json 和 .blend(除跨源策略块外直接在本地工作):
暂时离我很远,谢谢并致以最诚挚的问候!
将 skinning: true
分配给你的多维数据集 material,这为我解决了这个问题:
AnimationExport = new THREE.SkinnedMesh( geometry, new THREE.MeshLambertMaterial( { color: 0x436EEE, skinning: true } ) );
SkinnedMesh 动画和 threejs 处理起来很痛苦,但最近得到了一些爱。这也意味着动画系统 API 会不时发生变化,因此我建议通读 github 上的问题和 PR :-)
我现在使用 THREE.js 有一段时间了,我真的很喜欢它,除了一件事:将动画图形从 Blender 带到游戏场景中。在尝试自己解决并搜索了一段时间之后,我在这里提出我的问题。坦率地说,我只是一个编码员,不是图形专家,我也不是自己创建 blender-contents。
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(目前是最新的 2)
- THREE.js 修订版 86 的 Blender 导出器
- Blender 版本 2.77
工作示例:上面的代码以及 .json 和 .blend(除跨源策略块外直接在本地工作):
暂时离我很远,谢谢并致以最诚挚的问候!
将 skinning: true
分配给你的多维数据集 material,这为我解决了这个问题:
AnimationExport = new THREE.SkinnedMesh( geometry, new THREE.MeshLambertMaterial( { color: 0x436EEE, skinning: true } ) );
SkinnedMesh 动画和 threejs 处理起来很痛苦,但最近得到了一些爱。这也意味着动画系统 API 会不时发生变化,因此我建议通读 github 上的问题和 PR :-)