|
@@ -2,23 +2,22 @@
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
|
|
|
<link rel="stylesheet" href="./coderay-asciidoctor.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.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/level_of_detail.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>Level of Detail (LOD) Optimization</h1><div class="details"><span class="author" id="author"></span><br><span id="revnumber">version ,</span> <span id="revdate">2016/03/17 20:48</span></div><div id="toc" class="toc2"><div id="toctitle">Table of Contents</div><ul class="sectlevel1"><li><a href="#usage">Usage</a></li><li><a href="#pick-reduction-methods-and-values">Pick Reduction Methods and Values</a></li><li><a href="#generate-lod">Generate LOD</a><ul class="sectlevel2"><li><a href="#generating-lods-in-the-sdk">Generating LODs in the SDK</a></li><li><a href="#generating-lods-in-code">Generating LODs in Code</a></li></ul></li><li><a href="#activate-the-lod-control">Activate the LOD Control</a></li><li><a href="#impact-on-quality-and-speed">Impact on Quality and Speed</a></li><li><a href="#see-also">See also</a></li></ul></div></div><div id="content"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>A mesh with a high level of detail has lots of polygons and looks good close up. But when the mesh is further away (and the detail is not visible), the high-polygon count slows down performance unnecessarily.</p></div>
|
|
|
<div class="paragraph"><p>One solution for this problem is to use high-detail meshes for objects close to the camera, and low-detail meshes for objects far from the camera. As the player moves through the scene, you must keep replacing close objects by more detailed meshes, and far objects by less detailed meshes. The goal is to keep few high-quality slow-rendering objects in the foreground, and many low-quality fast-rendering objects in the background. (Experienced users can compare this approach to <a href="../../jme3/advanced/terrain.html">JME’s TerraMonkey terrain system</a>, which internally uses the specialized GeoMipMapping algorithm to generate a terrain’s Levels of Detail.)</p></div>
|
|
|
-<div class="paragraph"><p>You see now why you may want to be able to generate Levels of Detail for complex Geometries automatically. JME3 supports a Java implementation of the Ogre engine’s LOD generator (originally by Péter Szücs and Stan Melax): You use <a href="https://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/tools/jme3tools/optimize/LodGenerator.java">jme3tools.optimize.LodGenerator</a> in conjunction with <a href="https://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/scene/control/LodControl.java">com.jme3.scene.control.LodControl</a>.</p></div>
|
|
|
-<div class="paragraph"><p>For a demo, run <a href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/stress/TestLodGeneration.java">TestLodGeneration.java</a> from <a href="../../sdk/sample_code.html">JmeTests</a>, then press +/- and spacebar to experiment. The following screenshots show a monkey model with three reduced Levels of Detail:</p></div>
|
|
|
+<div class="paragraph"><p>You see now why you may want to be able to generate Levels of Detail for complex Geometries automatically. JME3 supports a Java implementation of the Ogre engine’s LOD generator (originally by Péter Szücs and Stan Melax): You use <a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/tools/java/jme3tools/optimize/LodGenerator.java">jme3tools.optimize.LodGenerator</a> in conjunction with <a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/scene/control/LodControl.java">com.jme3.scene.control.LodControl</a>.</p></div>
|
|
|
+<div class="paragraph"><p>For a demo, run <a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java">TestLodGeneration.java</a> from <a href="../../sdk/sample_code.html">JmeTests</a>, then press +/- and spacebar to experiment. The following screenshots show a monkey model with three reduced Levels of Detail:</p></div>
|
|
|
<div style="text-align: center;" class="imageblock"><div class="content"><img src="../../jme3/advanced/jmonkey-lod.gif" alt="jmonkey-lod.gif" width="" height=""></div></div></div></div>
|
|
|
<div class="sect1"><h2 id="usage">Usage</h2><div class="sectionbody"><div class="paragraph"><p>To activate this optimization:</p></div>
|
|
|
<div class="olist arabic"><ol class="arabic"><li><p>Pick a reduction method and values for the Geometry. (Trial and error…)</p></li><li><p>Generate LODs for the Geometry, either in the SDK or in code.</p></li><li><p>Add an LOD control to the Geometry.</p></li></ol></div></div></div>
|
|
|
<div class="sect1"><h2 id="pick-reduction-methods-and-values">Pick Reduction Methods and Values</h2><div class="sectionbody"><div class="paragraph"><p>There are several reduction methods to generate a low-polygon version from a high-polygon model. Don’t worry, the reduction does not modify the original model.</p></div>
|
|
|
-<table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 33.3333%;"><col style="width: 33.3333%;"><col style="width: 33.3334%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">Reduction Method</th><th class="tableblock halign-left valign-top">Description</th><th class="tableblock halign-left valign-top">Reduction Value</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>LodGenerator.TriangleReductionMethod.COLLAPSE_COST</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Collapses polygon vertices from the mesh until the reduction cost (= amount of ugly artifacts caused) exceeds the given threshold.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>0.0f - 1.0f</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>LodGenerator.TriangleReductionMethod.PROPORTIONAL</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Removes the given percentage of polygons from the mesh.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>0.0f - 1.0f</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>LodGenerator.TriangleReductionMethod.CONSTANT</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Removes the given number of polygons from the mesh.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>integer</p></div></div></td></tr></tbody></table>
|
|
|
+<table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 35%;"><col style="width: 55%;"><col style="width: 10%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">Reduction Method</th><th class="tableblock halign-left valign-top">Description</th><th class="tableblock halign-left valign-top">Reduction Value</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>LodGenerator.TriangleReductionMethod.COLLAPSE_COST</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Collapses polygon vertices from the mesh until the reduction cost (= amount of ugly artifacts caused) exceeds the given threshold.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>0.0f - 1.0f</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>LodGenerator.TriangleReductionMethod.PROPORTIONAL</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Removes the given percentage of polygons from the mesh.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>0.0f - 1.0f</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>LodGenerator.TriangleReductionMethod.CONSTANT</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Removes the given number of polygons from the mesh.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>integer</p></div></div></td></tr></tbody></table>
|
|
|
<div class="paragraph"><p>If you don’t know which to choose, experiment. For example start by trying COLLAPSE_COST and .5f-.9f.</p></div></div></div>
|
|
|
<div class="sect2"><h3 id="generate-lod">Generate LOD</h3><div class="paragraph"><p>You must generate and cache several LODs for each mesh, ranging from many to few polygons. The LOD generator algorithm attempts to collaps vertices automatically, while avoiding ugly artifacts. The LOD generator doesn’t generate new meshes, it only creates separate reduced index buffers for the more highly reduced levels.</p></div>
|
|
|
<div class="ulist"><ul><li><p>If you create geometries manually (3D models), use the SDK to generate LODs.</p></li><li><p>If you create geometries programmatically, generate LODs from your Java code.</p></li></ul></div>
|
|
|
<div class="sect2"><h3 id="generating-lods-in-the-sdk">Generating LODs in the SDK</h3><div class="paragraph"><p>The SDK contains a user-friendly interface to generate LODs for a model (.j3o file).</p></div>
|
|
|
-<div class="olist arabic"><ol class="arabic"><li><p>Open the Projects or Files window.</p></li><li><p>Select the .j3o file in the Project Assets > Models directory.</p></li><li><p>Choose Window>SceneExplorer if the SceneExplorer is not open. Info about the selected model is now displayed in the SceneExplorer.</p></li><li><p>Right-click the model in SceneExplorer. Choose the “Tools > Generate Levels of Detail menu.<br>
|
|
|
-<span class="image"><img src="../../jme3/advanced/jme-sdk-generate-lod-menu.png" alt="The "Tools>Generate LOD" context menu in the SceneExplorer" width="300" height="180"></span></p></li><li><p>The “Generate LOD settings wizard opens:<br>
|
|
|
-<span class="image"><img src="../../jme3/advanced/jme-sdk-generate-lod-window.png" alt="The "Generate LOD" settings wizard" width="300" height="150"></span></p></li><li><p>Choose a reduction method and reduction values for one or more levels.<br>
|
|
|
-Tip: Enter higher reduction values for higher levels.</p></li><li><p>Click Finish to generate the LODs for this model.</p></li></ol></div>
|
|
|
+<div class="olist arabic"><ol class="arabic"><li><p>Open the Projects or Files window.</p></li><li><p>Select the .j3o file in the <code>Project Assets/Models</code> directory.</p></li><li><p>Choose <code><span class="menuseq"><span class="menu">Window</span> ▸ <span class="menuitem">Edit in SceneExplorer</span></span></code> if the SceneExplorer is not open. Info about the selected model is now displayed in the SceneExplorer.</p></li><li><p><b class="button">RMB</b> select the model in SceneExplorer. Choose the <code><span class="menuseq"><span class="menu">Tools</span> ▸ <span class="menuitem">Generate Levels of Detail</span></span></code> menu.<br>
|
|
|
+<span class="image"><img src="../../jme3/advanced/jme-sdk-generate-lod-menu.png" alt="The Tools Generate LOD context menu in the SceneExplorer" width="300" height="180"></span></p></li><li><p>The <code>Generate LOD</code> settings wizard opens:<br>
|
|
|
+<span class="image"><img src="../../jme3/advanced/jme-sdk-generate-lod-window.png" alt="The Generate LOD settings wizard" width="300" height="150"></span></p></li><li><p>Choose a reduction method and reduction values for one or more levels.</p><div class="admonitionblock tip"><table><tr><td class="icon"><i class="fa icon-tip" title="Tip"></i></td><td class="content"><div class="paragraph"><p>Enter higher reduction values for higher levels.</p></div></td></tr></table></div></li><li><p>Click <b class="button">Finish</b> to generate the LODs for this model.</p></li></ol></div>
|
|
|
<div class="paragraph"><p>The LODs are saved in the .j3o model file.</p></div>
|
|
|
-<div class="admonitionblock tip"><table><tr><td class="icon"><i class="fa icon-tip" title="Tip"></i></td><td class="content"><div class="paragraph"><p>Choose Window>Properties if the Properties window is not open. Choose the generated LODs from the dropdown in the Properties window, and verify their quality in the SceneComposer.</p></div></td></tr></table></div>
|
|
|
+<div class="admonitionblock tip"><table><tr><td class="icon"><i class="fa icon-tip" title="Tip"></i></td><td class="content"><div class="paragraph"><p>Choose <code><span class="menuseq"><span class="menu">Window</span> ▸ <span class="menuitem">Properties</span></span></code> if the Properties window is not open. Choose the generated LODs from the dropdown in the Properties window, and verify their quality in the SceneComposer.</p></div></td></tr></table></div>
|
|
|
<div style="text-align: center;" class="imageblock"><div class="content"><img src="../../jme3/advanced/jme-sdk-generate-lod-full.png" alt="jme-sdk-generate-lod-full.png" width="" height=""></div></div></div>
|
|
|
<div class="sect2"><h3 id="generating-lods-in-code">Generating LODs in Code</h3><div class="paragraph"><p>The <code>jme3tools.optimize.LodGenerator</code> utility class helps you generate LODs for an arbitrary mesh (a Geometry object) programmatically from your Java code. You create and bake one LodGenerator for each Geometry.</p></div>
|
|
|
<div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">LodGenerator lod = <span class="keyword">new</span> LodGenerator(geometry);
|
|
@@ -32,14 +31,13 @@ lod.bakeLods(LodGenerator.TriangleReductionMethod.PROPORTIONAL,<span class="floa
|
|
|
myPrettyGeo.addControl(lc);
|
|
|
rootNode.attachChild(myPrettyGeo);</code></pre></div></div>
|
|
|
<div class="paragraph"><p>The LodControl internally gets the camera from the game’s viewport to calculate the distance to this geometry. Depending on the distance, the LodControl selects an appropriate level of detail, and passes more (or less) detailed vertex data to the renderer.</p></div></div></div>
|
|
|
-<div class="sect1"><h2 id="impact-on-quality-and-speed">Impact on Quality and Speed</h2><div class="sectionbody"><table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 20%;"><col style="width: 20%;"><col style="width: 20%;"><col style="width: 20%;"><col style="width: 20%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">Level number</th><th class="tableblock halign-left valign-top">Purpose</th><th class="tableblock halign-left valign-top">Distance</th><th class="tableblock halign-left valign-top">Rendering Speed</th><th class="tableblock halign-left valign-top">Rendering Quality</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>“Level 0</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The original mesh is used automatically for close-ups, and it’s the default if no LODs have been generated.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Closest</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Slowest.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Best.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>“Level 1<br>
|
|
|
-“Level 2<br>
|
|
|
-“Level 3<br>
|
|
|
-…</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>If you generated LODs, JME3 uses them automatically as soon as the object moves into the background.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The higher the level,<br>
|
|
|
+<div class="sect1"><h2 id="impact-on-quality-and-speed">Impact on Quality and Speed</h2><div class="sectionbody"><table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 10%;"><col style="width: 45%;"><col style="width: 15%;"><col style="width: 15%;"><col style="width: 15%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">Level number</th><th class="tableblock halign-left valign-top">Purpose</th><th class="tableblock halign-left valign-top">Distance</th><th class="tableblock halign-left valign-top">Rendering Speed</th><th class="tableblock halign-left valign-top">Rendering Quality</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Level 0</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The original mesh is used automatically for close-ups, and it’s the default if no LODs have been generated.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Closest</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Slowest.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Best.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Level 1<br>
|
|
|
+Level 2<br>
|
|
|
+Level 3</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>If you generated LODs, JME3 uses them automatically as soon as the object moves into the background.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The higher the level,<br>
|
|
|
the further away.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The higher the level,<br>
|
|
|
the faster.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The higher the level,<br>
|
|
|
the lower the quality.</p></div></div></td></tr></tbody></table></div></div>
|
|
|
-<div class="sect1"><h2 id="see-also">See also</h2><div class="sectionbody"><div class="ulist"><ul><li><p><a href="http://hub.jmonkeyengine.org/forum/topic/brand-new-lod-generator/">http://hub.jmonkeyengine.org/forum/topic/brand-new-lod-generator/</a></p></li><li><p><a href="https://github.com/worldforge/ember/tree/master/src/components/ogre/lod">https://github.com/worldforge/ember/tree/master/src/components/ogre/lod</a></p></li><li><p><a href="http://www.melax.com/polychop">http://www.melax.com/polychop</a></p></li><li><p><a href="http://sajty.elementfx.com/progressivemesh/GSoC2012.pdf">http://sajty.elementfx.com/progressivemesh/GSoC2012.pdf</a></p></li><li><p><a href="../../jme3/advanced/terrain.html">JME3 TerraMonkey Terrain</a></p></li></ul></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2017-06-10 20:26:00 UTC</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
|
|
|
+<div class="sect1"><h2 id="see-also">See also</h2><div class="sectionbody"><div class="ulist"><ul><li><p><a href="https://hub.jmonkeyengine.org/t/brand-new-lod-generator/26341">https://hub.jmonkeyengine.org/t/brand-new-lod-generator/26341</a></p></li><li><p><a href="https://github.com/worldforge/ember/tree/master/src/components/ogre/lod">https://github.com/worldforge/ember/tree/master/src/components/ogre/lod</a></p></li><li><p><a href="http://www.melax.com/polychop">http://www.melax.com/polychop</a></p></li><li><p><a href="http://sajty.elementfx.com/progressivemesh/GSoC2012.pdf">http://sajty.elementfx.com/progressivemesh/GSoC2012.pdf</a></p></li><li><p><a href="../../jme3/advanced/terrain.html">JME3 TerraMonkey Terrain</a></p></li></ul></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2017-06-11 00:31:36 UTC</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
|
|
|
apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
|
|
|
indexName: 'jmonkeyengine',
|
|
|
inputSelector: '#doc-search',
|