{"id":1,"date":"2013-09-30T16:29:52","date_gmt":"2013-09-30T16:29:52","guid":{"rendered":"http:\/\/localhost\/apsentorno\/instances\/5215cbee16caf\/htdocs\/?p=1"},"modified":"2015-02-11T23:05:54","modified_gmt":"2015-02-11T23:05:54","slug":"hello-world","status":"publish","type":"post","link":"http:\/\/blog.restemeier.com\/?p=1","title":{"rendered":"Unity3D and Blender"},"content":{"rendered":"<p>Many people are using <a href=\"http:\/\/www.blender.org\">Blender <\/a>to create 3D assets to use in <a href=\"http:\/\/unity3d.com\/\">Unity3D<\/a>, but the conversion doesn&#8217;t always go smoothly. I decided to spend some time researching and documenting the process and to provide solutions for key problems.<\/p>\n<h2>Model orientation<\/h2>\n<div id=\"attachment_31\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/Blender.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-31\" class=\"size-medium wp-image-31 \" alt=\"\" src=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/Blender-300x168.png\" width=\"300\" height=\"168\" \/><\/a><p id=\"caption-attachment-31\" class=\"wp-caption-text\">A simple test model in Blender<\/p><\/div>\n<p>The first problem people often report is the orientation of models. Blender and Unity3D are using different coordinate systems and every model moving between them has to go through a conversion. To visualise this I made a simple test model in Blender, with arrow models aligned with the coordinate axes.\u00a0The first thing to note is that Z is up and Blender is using a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Right_hand_rule#Right-handed_and_left-handed_coordinates\">right handed coordinate<\/a> system.<\/p>\n<div id=\"attachment_28\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/Unity.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-28\" class=\"size-medium wp-image-28\" alt=\"\" src=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/Unity-300x168.png\" width=\"300\" height=\"168\" srcset=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/Unity-300x168.png 300w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/Unity-624x350.png 624w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/Unity.png 1020w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-28\" class=\"wp-caption-text\">The axes model in Unity<\/p><\/div>\n<p>This model is easily imported into Unity and shown here with the camera rotated so that the model has the same orientation as in Blender. The model is imported once as a .blend file, once as a FBX file and once as a Collada DAE file. \u00a0The axes don&#8217;t match at all, so we need to have a look for the reasons.<\/p>\n<p>The easiest change to explain is the change to Y and Z: Unity3D works with the Y axis up, so Blender rotates the model by 90 degree around the X axis. The other change is a bit more complicated: Unity3D uses a left handed coordinate system, so the model has to be mirrored during import to make sure it looks the same as in Blender.<\/p>\n<div id=\"attachment_32\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/decodefbx.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-32\" class=\"size-medium wp-image-32\" alt=\"decodefbx\" src=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/decodefbx-300x174.png\" width=\"300\" height=\"174\" srcset=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/decodefbx-300x174.png 300w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/decodefbx-624x363.png 624w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/decodefbx.png 881w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-32\" class=\"wp-caption-text\">The model in a different FBX viewer.<\/p><\/div>\n<p>A quick look in a different FBX viewer shows that this must be done during import into Unity3D and not export from Blender. Annoyingly unintuitive, but this seems to match the Blender exporter code. We can use this information to predict how a model will be oriented when imported into Unity3D: up will stay up, positive Y in Blender will point towards negative Z in Unity3D and positive X in Blender will point towards negative X in Unity3D.<\/p>\n<div id=\"attachment_29\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/axes_bake.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-29\" class=\"size-medium wp-image-29\" alt=\"axes_bake\" src=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/axes_bake-300x164.png\" width=\"300\" height=\"164\" srcset=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/axes_bake-300x164.png 300w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/axes_bake-624x341.png 624w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/axes_bake.png 960w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-29\" class=\"wp-caption-text\">Example model with baked space transform.<\/p><\/div>\n<p>Unfortunately this is not the whole story: Blender bakes the rotation around X only into the transforms, so if a model is used for example as a terrain tree model it will be drawn sideways.\u00a0I made a change to the exporter to bake this change into the actual mesh data, which solves this kind of problem. It will need some testing before it can be applied to the official Blender distribution, but now you can use Blender models in a terrain without having too much of a headache about which axis is up.<\/p>\n<div id=\"attachment_41\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/forest_of_axes.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-41\" class=\"size-medium wp-image-41\" alt=\"Test model on terrain.\" src=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/forest_of_axes-300x164.png\" width=\"300\" height=\"164\" srcset=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/forest_of_axes-300x164.png 300w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/forest_of_axes-624x341.png 624w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/forest_of_axes.png 960w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-41\" class=\"wp-caption-text\">Test model on terrain.<\/p><\/div>\n<p>This is a model exported with baked space transform used as a &#8220;tree&#8221; in a terrain.<\/p>\n<h2>Model materials<\/h2>\n<div id=\"attachment_35\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_beforeafter.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-35\" class=\"size-medium wp-image-35\" alt=\"Material problems with current fbx exporter.\" src=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_beforeafter-300x164.png\" width=\"300\" height=\"164\" srcset=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_beforeafter-300x164.png 300w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_beforeafter-624x341.png 624w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_beforeafter.png 960w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-35\" class=\"wp-caption-text\">Material problems with current FBX exporter.<\/p><\/div>\n<p>The other big problem people are having is with material export. This shows a <a href=\"http:\/\/opengameart.org\/content\/dwarf-fixed\">dwarf model<\/a> exported with the original exporter, which fails to assign materials even remotely close to the Blender scene. This is no surprise because the shading systems in Unity3D and Blender are very different: Blender&#8217;s shading system is meant for offline rendering, and Unity3D&#8217;s shading system is meant for efficient hardware rendering on many devices. It is still disappointing that the materials are not even close within the limitations of the two systems. This can be explained by the system that the Blender FBX exporter uses to select textures: You can assign textures directly to the UV data in a mesh, and the exporter combines those textures with the meshes&#8217; material settings.<\/p>\n<div id=\"attachment_37\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_material.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-37\" class=\"size-medium wp-image-37\" alt=\"Fixed materials.\" src=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_material-300x164.png\" width=\"300\" height=\"164\" srcset=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_material-300x164.png 300w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_material-624x341.png 624w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_material.png 960w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-37\" class=\"wp-caption-text\">Fixed materials.<\/p><\/div>\n<p>I changed the system so that it goes through a material&#8217;s texture slots and writes out the textures. Unity3D is able to pick the correct diffuse and normal maps from that.<\/p>\n<p>There doesn&#8217;t seem to be a way for FBX files to specify exactly which UV map has to be used for a texture, so the UV settings in a texture are ignored for now. Unity3D uses only the first two UV maps anyway (one for textures, one for lightmaps), so this shouldn&#8217;t be a big problem.\u00a0I think it would be possible to handle some cases by rebuilding UV data during export, but that may never be able to handle all cases and cause more problems and unpredictable behaviour down the line.<\/p>\n<div id=\"attachment_40\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/fallback.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-40\" class=\"size-medium wp-image-40\" alt=\"Fallback for meshes with no materials\" src=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/fallback-300x164.png\" width=\"300\" height=\"164\" srcset=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/fallback-300x164.png 300w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/fallback-624x341.png 624w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/fallback.png 960w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-40\" class=\"wp-caption-text\">Fallback for meshes without materials.<\/p><\/div>\n<p>The old system is still useful as a fallback, so it is used for meshes that have no material assigned. The textures in this example come from the OpenGameArt models\u00a0<a href=\"http:\/\/opengameart.org\/content\/benny-the-rottweiler\">benny\u00a0<\/a>and <a href=\"http:\/\/opengameart.org\/content\/low-poly-rigged-skeleton\">skeleton<\/a>.<\/p>\n<p><span style=\"font-size: 1.285714286rem; line-height: 1.6;\">General Problems<\/span><\/p>\n<div id=\"attachment_36\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_envelope_off.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-36\" class=\"size-medium wp-image-36\" alt=\"Skinning problem.\" src=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_envelope_off-300x164.png\" width=\"300\" height=\"164\" srcset=\"http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_envelope_off-300x164.png 300w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_envelope_off-624x341.png 624w, http:\/\/blog.restemeier.com\/wp-content\/uploads\/2013\/10\/dwarf_envelope_off.png 960w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-36\" class=\"wp-caption-text\">Skinning problem with bone envelopes disabled.<\/p><\/div>\n<p>There are often problems in models that are not easily visible in a modelling application, but show up in a realtime engine. In this case there are a few vertices near the boots that have no bone attached to them. These don&#8217;t show up in Blender because bone envelopes are enabled, but show up in Unity3D because the realtime skinning only uses vertex groups. There is a <a href=\"http:\/\/wiki.blender.org\/index.php\/Extensions:2.6\/Py\/Scripts\/Modeling\/Show_Vertex_Group_Weights\">useful third party script<\/a> to show vertex weights in Blender that makes it is easy to find misbehaving vertices and to add or remove them from vertex groups.<\/p>\n<p>Blender can embed textures into a .blend file. That is very handy for sharing scenes, but Unity3D has no way to access those textures and the FBX exporter doesn&#8217;t write them out. The menu option &#8220;File\/External Data\/Unpack into Files&#8221; can be used to extract most textures, though textures that were created inside Blender, for example with the texture paint tool, may need to be saved manually. This can be done in the UV\/Image Editor with menu option &#8220;Image\/Save Image&#8221;.<\/p>\n<h2>Beta test the new exporter<\/h2>\n<p>You can beta-test the new version of the Blender FBX exporter so that more problems can be caught before it goes into Blender officially. I developed my changes with Blender 2.68a, but there is a good chance that the script will work with earlier versions.<\/p>\n<ul>\n<li>The space transform from Z-up to Y-up is baked into the whole model including the geometry.\n<ul>\n<li>This MAY break models that have been imported and posed into Unity3D already, so it shouldn&#8217;t be changed in the middle of a project.<\/li>\n<\/ul>\n<\/li>\n<li>Textures are now taken from the material&#8217;s texture slots instead of the uv layers. This means that normal maps transfer over correctly. The code falls back to uvlayer textures only if no material is set.\n<ul>\n<li>This MAY break models that rely on the old behaviour. If your textures are set on the material you should be fine.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Please remember that this is a beta version and you should be careful with it in production work. Mixing models exported with the new and old exporter is most likely going to cause problems at some point.\u00a0If you are in a team then please discuss it with team mates or leads before using it, and try it out on a separate copy of the project first.<\/p>\n<p>It is very important that you make a backup of the existing exporter script before installing this, in case you want to return to the old version.<\/p>\n<h2>Installation<\/h2>\n<p>This code replaces Blender&#8217;s original export scripts. On Windows they are in\u00a0%PROGRAMFILES%\\Blender Foundation\\Blender\\&lt;version&gt;\\scripts\\addons\\io_scene_fbx<br \/>\nOn OSX they are in the application bundle, in<br \/>\nContents\/MacOS\/&lt;version&gt;\/scripts\/addons\/io_scene_fbx<\/p>\n<p>You can disable baking the space transform if you export an FBX file manually from Blender. The option is the last at the bottom called\u00a0&#8220;Bake Space Transform&#8221;. To change the default you have to modify the code:<\/p>\n<pre class=\"brush: python; first-line: 199; highlight: [202]; title: __init__.py; notranslate\" title=\"__init__.py\">\r\nbake_space_transform = BoolProperty(\r\n            name=&quot;Bake Space Transform&quot;,\r\n            description=&quot;Bake the transform from Blender's space into target space into all transforms and the mesh data&quot;,\r\n            default=False,\r\n            )\r\n<\/pre>\n<p>Change the default to False. The settings that Unity3D uses for importing .blend files are hardcoded in the other file:<\/p>\n<pre class=\"brush: python; first-line: 3118; highlight: [3129]; title: export_fbx.py; notranslate\" title=\"export_fbx.py\">\r\ndef defaults_unity3d():\r\n\treturn dict(global_matrix=Matrix.Rotation(-math.pi \/ 2.0, 4, 'X'),\r\n\t\t    use_selection=False,\r\n\t\t    object_types={'ARMATURE', 'EMPTY', 'MESH'},\r\n\t\t    use_mesh_modifiers=True,\r\n\t\t    use_armature_deform_only=True,\r\n\t\t    use_anim=True,\r\n\t\t    use_anim_optimize=False,\r\n\t\t    use_anim_action_all=True,\r\n\t\t    batch_mode='OFF',\r\n\t\t    use_default_take=True,\r\n\t\t    bake_space_transform=False\r\n\t\t    )\r\n<\/pre>\n<p>Change bake_space_transform to False. Unfortunately the changes to the material system were too extensive to make an option to switch to the old system,<\/p>\n<p>Here is the script for download:<\/p>\n<p><a href=\"http:\/\/www.restemeier.com\/blog\/io_scene_fbx.zip\" target=\"_blank\">http:\/\/www.restemeier.com\/blog\/io_scene_fbx.zip<\/a><\/p>\n<p>Please let me know about your results!<\/p>\n<p><em>Update: From what I&#8217;ve heard there will be a significant rewrite of the FBX exporter in one of the next versions of Blender. If you&#8217;re visiting this from the future, this was tested on Blender 2.68a, and I&#8217;ll try to re-test this on the new exporter as soon as it arrives.<\/em><\/p>\n<p><em>Update 2: My patch was accepted into Blender, so Blender 2.71 will come with the &#8220;Bake Space Transform&#8221; option available.<\/em><\/p>\n<p><em>I had to disable comments again thanks to spam. You can reach me on Twitter and Google Plus.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many people are using Blender to create 3D assets to use in Unity3D, but the conversion doesn&#8217;t always go smoothly. I decided to spend some time researching and documenting the process and to provide solutions for key problems. Model orientation The first problem people often report is the orientation of models. Blender and Unity3D are [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,6],"tags":[],"class_list":["post-1","post","type-post","status-publish","format-standard","hentry","category-blender","category-unity3d"],"_links":{"self":[{"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=\/wp\/v2\/posts\/1","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1"}],"version-history":[{"count":27,"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":276,"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions\/276"}],"wp:attachment":[{"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.restemeier.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}