blender_gltf.html 15 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="Asciidoctor 1.5.4"><title>Exporting scenes from Blender 2.8 to jME using glTF</title><link rel="stylesheet" href="./asciidoctor.css">
  2. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
  3. <link rel="stylesheet" href="./coderay-asciidoctor.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css"><link rel="stylesheet" href="/home/travis/build/jMonkeyEngine/wiki/build/asciidoc/html5/jme3/advanced/twemoji-awesome.css"></head><body class="article toc2 toc-left"><div id="header"><div id="toolbar"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/src/docs/asciidoc/jme3/advanced/blender_gltf.adoc"><i class="fa fa-pencil-square" aria-hidden="true"></i></a><a href="https://github.com/jMonkeyEngine/wiki/new/master/src/docs/asciidoc/jme3/advanced/"><i class="fa fa-plus-square" aria-hidden="true"></i></a><input dir="auto" style="position: relative; vertical-align: top;" spellcheck="false" autocomplete="off" class="searchbox__input aa-input" id="doc-search" name="search" placeholder="Search in the doc" required="required" type="search"></div><h1>Exporting scenes from Blender 2.8 to jME using glTF</h1><div class="details"><span class="author" id="author"></span><br><span id="revnumber">version ,</span> <span id="revdate">2019/08/11 20:48</span></div><div id="toc" class="toc2"><div id="toctitle">Table of Contents</div><ul class="sectlevel1"><li><a href="#background">Background</a></li><li><a href="#creating-models">Creating Models</a></li><li><a href="#animations">Animations</a></li><li><a href="#materials">Materials</a></li><li><a href="#shape-keys">Shape Keys</a></li><li><a href="#export-options">Export options</a></li><li><a href="#import-structure">Import structure</a></li><li><a href="#additional-reading">Additional Reading</a></li></ul></div></div><div id="content"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>This section discusses how to export scenes from Blender (2.8+) in glTF format appropriate for use by <code>AssetManager.loadModel</code>.</p></div></div></div>
  4. <div class="sect1"><h2 id="background">Background</h2><div class="sectionbody"><div class="paragraph"><p>glTF (GL Transmission Format) is a specification for transmitting 3D scenes between applications. The specification is owned by Khronos Group but is publicly available and can be used royalty free. It is growing in popularity as a robust and efficient transmission mechanism.</p></div>
  5. <div class="paragraph"><p>jME3 introduced a loader for glTF in 2017 (written by nehon) and it has since been included as a standard part of the <code>jme3-plugins</code> target. There are some limitations of the importer which can be avoided by following the guidelines below.</p></div>
  6. <div class="paragraph"><p>Ultimately all jME projects should use the <code>.j3o</code> format for storing assets. However during development a format is required to export scenes from Blender in a format suitable for conversion (either through the SDK or directly through code).</p></div>
  7. <div class="paragraph"><p>Use of glTF (or another standard format) has a significant advantage over direct import of <code>.blend</code> files: new versions of Blender with significant enhancements are released fairly regularly. Using a standard format allows new features to be used without requiring updates to the Blender importer.</p></div>
  8. <div class="admonitionblock note"><table><tr><td class="icon"><i class="fa icon-note" title="Note"></i></td><td class="content">Blender 2.7 had a number of problems in exporting glTF; these notes refer exclusively to Blender 2.8+</td></tr></table></div></div></div>
  9. <div class="sect1"><h2 id="creating-models">Creating Models</h2><div class="sectionbody"><div class="paragraph"><p>Details of how to create models in Blender that are compatible with jME are given at <a href="#jme3/external/blender">[jme3/external/blender]</a>. Follow all details on that page for creating models before attempting an export.</p></div>
  10. <div class="paragraph"><p>Before exporting a model all transforms need to be applied. This performs the required transforms on the vertices in a mesh to reset the transforms on the object. To apply all transforms in Blender 2.8, select each object (in object mode, not edit mode) then choose from the <code>Object</code> menu <code>Apply/All Transforms</code>.</p></div></div></div>
  11. <div class="sect1"><h2 id="animations">Animations</h2><div class="sectionbody"><div class="olist arabic"><ol class="arabic"><li><p>Blender supports non-linear transitions using F-Curves. However the glTF importer only supports linear transitions. There are 2 ways to ensure all transitions are linear:</p><div class="olist loweralpha"><ol class="loweralpha" type="a"><li><p>In Blender 2.8, go to the graph editor, select all keys (menu select/all) and then change to linear interpolation (menu key/interpolation mode/linear).</p></li><li><p>At export time, force the export to create interpolated keyframes using sampling. This can be done in Python using <code>export_force_sampling=True</code> or selecting <code>Always Sample Animations</code> in the <code>Animation</code> tab of the export function. By default a sample is created from each frame of the animation. This can be changed in Python using <code>export_frame_step=n</code> where n is number of frames between samples or changing the sampling rate in the <code>Animation</code> tab of the export function.</p></li></ol></div></li><li><p>Blender has a powerful tool to allow bones to be posed by just specifying the position of the final bone in a chain and allowing Blender to work out where to position attached bones. This tool is a bone constraint called IK (Inverse Kinematics) and it can save a lot of time in building animations. However jME does not support IK constraints so any use of IK needs to be "baked" before the export. To do this, select the appropriate bone, go to the bone contraints tab and apply the IK constraint. A useful workflow is to save the file, bake the constrain, export to glTF then revert to the saved file to restore the IK constraint.</p></li><li><p>All actions in Blender will be added as animations to the <code>Node</code> corresponding to the armature. In addition, the action last tweaked within Blender will also be added as an animation to the object&#8217;s node. This is just an artifact of the organisation of actions within Blender and should be ignored within jME.</p></li><li><p>glTF models loaded using jME 3.3 will create animations that use the new animation system introduced in jME 3.3. see <a class="bare" href="https://hub.jmonkeyengine.org/t/monkanim-v2/39877">https://hub.jmonkeyengine.org/t/monkanim-v2/39877</a> for more info about the new animation system.</p></li></ol></div></div></div>
  12. <div class="sect1"><h2 id="materials">Materials</h2><div class="sectionbody"><div class="paragraph"><p>All of the rules associated with defining materials in Blender suitable for use in jME apply when glTF is used as the import/export format.</p></div>
  13. <div class="olist arabic"><ol class="arabic"><li><p>Blender supports lots of different types of shaders and complex materials with several different renderers. glTF supports a relatively basic set of PBR attributes. If the primary purpose of the materials is to produce glTF exported models use a simple <code>Principled BSDF</code> node in your materials with the following settings:</p><div class="olist loweralpha"><ol class="loweralpha" type="a"><li><p>Metalling and roughness values</p></li><li><p>Base color</p></li><li><p>Diffuse and Normal (bump) textures</p></li></ol></div></li></ol></div></div></div>
  14. <div class="sect1"><h2 id="shape-keys">Shape Keys</h2><div class="sectionbody"><div class="paragraph"><p>Shape keys in Blender are used to apply a deformation to a mesh without changing the underlying vertices. The glTF exporter ignores shape keys unless they are part of an animation. To include shape keys in the export, select the <code>Shape Keys</code> option in the <code>Animation</code> tab of the glTF export options.</p></div>
  15. <div class="admonitionblock note"><table><tr><td class="icon"><i class="fa icon-note" title="Note"></i></td><td class="content">Shape keys are only supported in jME 3.3</td></tr></table></div></div></div>
  16. <div class="sect1"><h2 id="export-options">Export options</h2><div class="sectionbody"><div class="paragraph"><p>Blender 2.8 supports many options when exporting in glTF format. Most of the default options work fine.</p></div>
  17. <div class="paragraph"><p>You have 3 options of the format to export,
  18. . <code>GLB</code>: a single file in binary format (the default)
  19. . <code>GLTF_EMBEDDED</code>: a single file in JSON format
  20. . <code>GLTF_SEPERATE</code>: multiple files for separate objects, textures etc.</p></div>
  21. <div class="paragraph"><p>The <code>GLB</code> format is the most efficient so use it unless you need to debug the output or edit it prior to import for any reason.</p></div>
  22. <div class="paragraph"><p>The export can be performed manually (File/Export/GLTF 2.0) or via a Python script. If using a script to export, the following command will export the entire scene to the current directory in <code>.glb</code> format with recommended options.</p></div>
  23. <div class="paragraph"><p><code>bpy.ops.export_scene.gltf(filepath=filename, export_materials=False, export_force_sampling=True, check_existing=False)</code></p></div></div></div>
  24. <div class="sect1"><h2 id="import-structure">Import structure</h2><div class="sectionbody"><div class="paragraph"><p>The structure of the nodes following import will roughly match their structure in Blender. Note the following exceptions:
  25. . There is no equivalent in glTF to Blender collections. These will not be represented in the imported structure.
  26. . If an object has no material, a default material will be created for it.
  27. . If an object has a single material, the corresponding node in the imported structure will have type <code>Geometry</code> with the object&#8217;s mesh and the associated material.
  28. . If an object has more than one material, the corresponding node will have type <code>Node</code> with 1 child per material. Each of these children will be a <code>Geometry</code> with the associated material and a mesh containing the vertices assigned to the material.</p></div>
  29. <div class="paragraph"><p>For example, if a blender scene has the following structure</p></div>
  30. <div class="literalblock"><div class="content"><pre>Scene collection
  31. Collection A
  32. Tree (Object)
  33. Tree_Mesh (Mesh)
  34. Car (Object)
  35. Car_Mesh (Mesh)
  36. Body (Material)
  37. House (Object)
  38. House_Mesh (Mesh)
  39. Walls (Material)
  40. Roof (Material)
  41. Collection B
  42. Person_Armature (Armature)
  43. Root (Bone)
  44. Head (Bone)
  45. Animations
  46. Walk (Action)
  47. NLA Tracks
  48. NLA Track
  49. Run (Action)
  50. Person (Object)
  51. Animation
  52. Walk (Action link)
  53. Person_Mesh</pre></div></div>
  54. <div class="paragraph"><p>Then after export to glTF format and import to jME it will look like:</p></div>
  55. <div class="literalblock"><div class="content"><pre>Scene (Node)
  56. Tree (Geometry)
  57. Default (Material)
  58. Car (Geometry)
  59. Body (Material)
  60. House (Node)
  61. House_1 (Geometry)
  62. Walls (Material)
  63. House_1 (Geometry)
  64. Roof (Material)
  65. Person_Armature (Node)
  66. Animations (AnimControl)
  67. Walk (Animation)
  68. Run (Animation)
  69. Person (Geometry)
  70. Animations (AnimControl)
  71. Walk (Animation)</pre></div></div>
  72. <div class="paragraph"><p>For example, the animated person could be loaded with a custom material assigned as follows:</p></div>
  73. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">ModelKey key = <span class="keyword">new</span> ModelKey(<span class="string"><span class="delimiter">&quot;</span><span class="content">Models/model.glb</span><span class="delimiter">&quot;</span></span>);
  74. Node scene = (Node)assetManager.loadModel(key);
  75. Node person = scene.getChild(<span class="string"><span class="delimiter">&quot;</span><span class="content">Person_Armature</span><span class="delimiter">&quot;</span></span>);
  76. Geometry geometry = (Geometry)person.getChild(<span class="string"><span class="delimiter">&quot;</span><span class="content">Person</span><span class="delimiter">&quot;</span></span>);
  77. geometry.setMaterial(customMaterial);
  78. root.attachChild(person);</code></pre></div></div>
  79. <div class="paragraph"><p>And an animation for the model could be run as follows:</p></div>
  80. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">AnimControl animControl = person.getControl(AnimControl.class);
  81. AnimChannel animChannel = animControl.createChannel();
  82. animChannel.setAnim(<span class="string"><span class="delimiter">&quot;</span><span class="content">Run</span><span class="delimiter">&quot;</span></span>);</code></pre></div></div>
  83. <div class="paragraph"><p>If you import the model with the SDK, you can explore the scene graph using the Scene Explorer. See <a href="#sdk/scene_explorer">[sdk/scene_explorer]</a> and <a href="#jme3/advanced/traverse_scenegraph">[jme3/advanced/traverse_scenegraph]</a> for more details.</p></div>
  84. <div class="paragraph"><p>See <a href="#jme3/advanced/animation">[jme3/advanced/animation]</a> for further details on using animations in your code.</p></div></div></div>
  85. <div class="sect1"><h2 id="additional-reading">Additional Reading</h2><div class="sectionbody"><div class="paragraph"><p>Thread announcing glTF support: <a class="bare" href="https://hub.jmonkeyengine.org/t/jme-gltf-support/39174">https://hub.jmonkeyengine.org/t/jme-gltf-support/39174</a></p></div>
  86. <div class="paragraph"><p>Documentation for the python export functions <a class="bare" href="https://docs.blender.org/api/current/bpy.ops.export_scene.html">https://docs.blender.org/api/current/bpy.ops.export_scene.html</a></p></div>
  87. <div class="paragraph"><p>glTF specification <a class="bare" href="https://github.com/KhronosGroup/glTF/tree/master/specification/2.0">https://github.com/KhronosGroup/glTF/tree/master/specification/2.0</a></p></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2019-12-20 23:30:51 +00:00</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
  88. apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
  89. indexName: 'jmonkeyengine',
  90. inputSelector: '#doc-search',
  91. debug: false // Set debug to true if you want to inspect the dropdown
  92. });</script></body></html>