hello_material.html 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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"><meta name="keywords" content="documentation, beginner, intro, model, material, color, texture, transparency"><title>jMonkeyEngine 3 Tutorial (6) - Hello Materials</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/beginner/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/beginner/hello_material.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/beginner/"><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>jMonkeyEngine 3 Tutorial (6) - Hello Materials</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="#sample-code">Sample Code</a></li><li><a href="#simple-unshaded-texture">Simple Unshaded Texture</a></li><li><a href="#transparent-unshaded-texture">Transparent Unshaded Texture</a></li><li><a href="#shininess-and-bumpiness">Shininess and Bumpiness</a></li><li><a href="#default-material-definitions">Default Material Definitions</a></li><li><a href="#exercises">Exercises</a><ul class="sectlevel2"><li><a href="#exercise-1-custom-j3m-material">Exercise 1: Custom .j3m Material</a></li><li><a href="#exercise-2-bumpiness-and-shininess">Exercise 2: Bumpiness and Shininess</a></li></ul></li><li><a href="#conclusion">Conclusion</a></li></ul></div></div><div id="content"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>Previous: <a href="../../jme3/beginner/hello_input_system.html">Hello Input System</a>,
  4. Next: <a href="../../jme3/beginner/hello_animation.html">Hello Animation</a></p></div>
  5. <div class="paragraph"><p>The term Material includes everything that influences what the surface of a 3D model looks like: The color, texture, shininess, and opacity/transparency. Plain coloring is covered in <a href="../../jme3/beginner/hello_node.html">Hello Node</a>. Loading models that come with materials is covered in <a href="../../jme3/beginner/hello_asset.html">Hello Asset</a>. In this tutorial you learn to create and use custom JME3 Material Definitions.</p></div>
  6. <div style="text-align: center;" class="imageblock"><div class="content"><img src="../../jme3/beginner/beginner-materials.png" alt="beginner-materials.png" width="320" height="240"></div></div>
  7. <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>To use the example assets in a new jMonkeyEngine SDK project, right-click your project, select “Properties, go to “Libraries, press “Add Library and add the “jme3-test-data library.</p></div></td></tr></table></div></div></div>
  8. <div class="sect1"><h2 id="sample-code">Sample Code</h2><div class="sectionbody"><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">package</span> <span class="namespace">jme3test.helloworld</span>;
  9. <span class="keyword">import</span> <span class="include">com.jme3.app.SimpleApplication</span>;
  10. <span class="keyword">import</span> <span class="include">com.jme3.light.DirectionalLight</span>;
  11. <span class="keyword">import</span> <span class="include">com.jme3.material.Material</span>;
  12. <span class="keyword">import</span> <span class="include">com.jme3.material.RenderState.BlendMode</span>;
  13. <span class="keyword">import</span> <span class="include">com.jme3.math.ColorRGBA</span>;
  14. <span class="keyword">import</span> <span class="include">com.jme3.math.Vector3f</span>;
  15. <span class="keyword">import</span> <span class="include">com.jme3.renderer.queue.RenderQueue.Bucket</span>;
  16. <span class="keyword">import</span> <span class="include">com.jme3.scene.Geometry</span>;
  17. <span class="keyword">import</span> <span class="include">com.jme3.scene.shape.Box</span>;
  18. <span class="keyword">import</span> <span class="include">com.jme3.scene.shape.Sphere</span>;
  19. <span class="keyword">import</span> <span class="include">com.jme3.texture.Texture</span>;
  20. <span class="keyword">import</span> <span class="include">com.jme3.util.TangentBinormalGenerator</span>;
  21. <span class="comment">/** Sample 6 - how to give an object's surface a material and texture.
  22. * How to make objects transparent. How to make bumpy and shiny surfaces. */</span>
  23. <span class="directive">public</span> <span class="type">class</span> <span class="class">HelloMaterial</span> <span class="directive">extends</span> SimpleApplication {
  24. <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> main(<span class="predefined-type">String</span><span class="type">[]</span> args) {
  25. HelloMaterial app = <span class="keyword">new</span> HelloMaterial();
  26. app.start();
  27. }
  28. <span class="annotation">@Override</span>
  29. <span class="directive">public</span> <span class="type">void</span> simpleInitApp() {
  30. <span class="comment">/** A simple textured cube -- in good MIP map quality. */</span>
  31. <span class="predefined-type">Box</span> cube1Mesh = <span class="keyword">new</span> <span class="predefined-type">Box</span>( <span class="float">1f</span>,<span class="float">1f</span>,<span class="float">1f</span>);
  32. Geometry cube1Geo = <span class="keyword">new</span> Geometry(<span class="string"><span class="delimiter">&quot;</span><span class="content">My Textured Box</span><span class="delimiter">&quot;</span></span>, cube1Mesh);
  33. cube1Geo.setLocalTranslation(<span class="keyword">new</span> Vector3f(-<span class="float">3f</span>,<span class="float">1.1f</span>,<span class="float">0f</span>));
  34. Material cube1Mat = <span class="keyword">new</span> Material(assetManager,
  35. <span class="string"><span class="delimiter">&quot;</span><span class="content">Common/MatDefs/Misc/Unshaded.j3md</span><span class="delimiter">&quot;</span></span>);
  36. Texture cube1Tex = assetManager.loadTexture(
  37. <span class="string"><span class="delimiter">&quot;</span><span class="content">Interface/Logo/Monkey.jpg</span><span class="delimiter">&quot;</span></span>);
  38. cube1Mat.setTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">ColorMap</span><span class="delimiter">&quot;</span></span>, cube1Tex);
  39. cube1Geo.setMaterial(cube1Mat);
  40. rootNode.attachChild(cube1Geo);
  41. <span class="comment">/** A translucent/transparent texture, similar to a window frame. */</span>
  42. <span class="predefined-type">Box</span> cube2Mesh = <span class="keyword">new</span> <span class="predefined-type">Box</span>( <span class="float">1f</span>,<span class="float">1f</span>,<span class="float">0.01f</span>);
  43. Geometry cube2Geo = <span class="keyword">new</span> Geometry(<span class="string"><span class="delimiter">&quot;</span><span class="content">window frame</span><span class="delimiter">&quot;</span></span>, cube2Mesh);
  44. Material cube2Mat = <span class="keyword">new</span> Material(assetManager,
  45. <span class="string"><span class="delimiter">&quot;</span><span class="content">Common/MatDefs/Misc/Unshaded.j3md</span><span class="delimiter">&quot;</span></span>);
  46. cube2Mat.setTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">ColorMap</span><span class="delimiter">&quot;</span></span>,
  47. assetManager.loadTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">Textures/ColoredTex/Monkey.png</span><span class="delimiter">&quot;</span></span>));
  48. cube2Mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
  49. cube2Geo.setQueueBucket(Bucket.Transparent);
  50. cube2Geo.setMaterial(cube2Mat);
  51. rootNode.attachChild(cube2Geo);
  52. <span class="comment">/** A bumpy rock with a shiny light effect.*/</span>
  53. Sphere sphereMesh = <span class="keyword">new</span> Sphere(<span class="integer">32</span>,<span class="integer">32</span>, <span class="float">2f</span>);
  54. Geometry sphereGeo = <span class="keyword">new</span> Geometry(<span class="string"><span class="delimiter">&quot;</span><span class="content">Shiny rock</span><span class="delimiter">&quot;</span></span>, sphereMesh);
  55. sphereMesh.setTextureMode(Sphere.TextureMode.Projected); <span class="comment">// better quality on spheres</span>
  56. TangentBinormalGenerator.generate(sphereMesh); <span class="comment">// for lighting effect</span>
  57. Material sphereMat = <span class="keyword">new</span> Material(assetManager,
  58. <span class="string"><span class="delimiter">&quot;</span><span class="content">Common/MatDefs/Light/Lighting.j3md</span><span class="delimiter">&quot;</span></span>);
  59. sphereMat.setTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">DiffuseMap</span><span class="delimiter">&quot;</span></span>,
  60. assetManager.loadTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">Textures/Terrain/Pond/Pond.jpg</span><span class="delimiter">&quot;</span></span>));
  61. sphereMat.setTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">NormalMap</span><span class="delimiter">&quot;</span></span>,
  62. assetManager.loadTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">Textures/Terrain/Pond/Pond_normal.png</span><span class="delimiter">&quot;</span></span>));
  63. sphereMat.setBoolean(<span class="string"><span class="delimiter">&quot;</span><span class="content">UseMaterialColors</span><span class="delimiter">&quot;</span></span>,<span class="predefined-constant">true</span>);
  64. sphereMat.setColor(<span class="string"><span class="delimiter">&quot;</span><span class="content">Diffuse</span><span class="delimiter">&quot;</span></span>,ColorRGBA.White);
  65. sphereMat.setColor(<span class="string"><span class="delimiter">&quot;</span><span class="content">Specular</span><span class="delimiter">&quot;</span></span>,ColorRGBA.White);
  66. sphereMat.setFloat(<span class="string"><span class="delimiter">&quot;</span><span class="content">Shininess</span><span class="delimiter">&quot;</span></span>, <span class="float">64f</span>); <span class="comment">// [0,128]</span>
  67. sphereGeo.setMaterial(sphereMat);
  68. sphereGeo.setLocalTranslation(<span class="integer">0</span>,<span class="integer">2</span>,-<span class="integer">2</span>); <span class="comment">// Move it a bit</span>
  69. sphereGeo.rotate(<span class="float">1.6f</span>, <span class="integer">0</span>, <span class="integer">0</span>); <span class="comment">// Rotate it a bit</span>
  70. rootNode.attachChild(sphereGeo);
  71. <span class="comment">/** Must add a light to make the lit object visible! */</span>
  72. DirectionalLight sun = <span class="keyword">new</span> DirectionalLight();
  73. sun.setDirection(<span class="keyword">new</span> Vector3f(<span class="integer">1</span>,<span class="integer">0</span>,-<span class="integer">2</span>).normalizeLocal());
  74. sun.setColor(ColorRGBA.White);
  75. rootNode.addLight(sun);
  76. }
  77. }</code></pre></div></div>
  78. <div class="paragraph"><p>You should see</p></div>
  79. <div class="ulist"><ul><li><p>Left – A cube with a brown monkey texture.</p></li><li><p>Right – A translucent monkey picture in front of a shiny bumpy rock.</p></li></ul></div>
  80. <div class="paragraph"><p>Move around with the WASD keys to have a closer look at the translucency, and the rock&#8217;s bumpiness.</p></div></div></div>
  81. <div class="sect1"><h2 id="simple-unshaded-texture">Simple Unshaded Texture</h2><div class="sectionbody"><div class="paragraph"><p>Typically you want to give objects in your scene textures: It can be rock, grass, brick, wood, water, metal, paper… A texture is a normal image file in JPG or PNG format. In this example, you create a box with a simple unshaded Monkey texture as material.</p></div>
  82. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> <span class="comment">/** A simple textured cube -- in good MIP map quality. */</span>
  83. <span class="predefined-type">Box</span> cube1Mesh = <span class="keyword">new</span> <span class="predefined-type">Box</span>( <span class="float">1f</span>,<span class="float">1f</span>,<span class="float">1f</span>);
  84. Geometry cube1Geo = <span class="keyword">new</span> Geometry(<span class="string"><span class="delimiter">&quot;</span><span class="content">My Textured Box</span><span class="delimiter">&quot;</span></span>, cube1Mesh);
  85. cube1Geo.setLocalTranslation(<span class="keyword">new</span> Vector3f(-<span class="float">3f</span>,<span class="float">1.1f</span>,<span class="float">0f</span>));
  86. Material cube1Mat = <span class="keyword">new</span> Material(assetManager,
  87. <span class="string"><span class="delimiter">&quot;</span><span class="content">Common/MatDefs/Misc/Unshaded.j3md</span><span class="delimiter">&quot;</span></span>);
  88. Texture cube1Tex = assetManager.loadTexture(
  89. <span class="string"><span class="delimiter">&quot;</span><span class="content">Interface/Logo/Monkey.jpg</span><span class="delimiter">&quot;</span></span>);
  90. cube1Mat.setTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">ColorMap</span><span class="delimiter">&quot;</span></span>, cube1Tex);
  91. cube1Geo.setMaterial(cube1Mat);
  92. rootNode.attachChild(cube1Geo);</code></pre></div></div>
  93. <div class="paragraph"><p>Here is what we did: to create a textured box:</p></div>
  94. <div class="olist arabic"><ol class="arabic"><li><p>Create a Geometry <code>cube1Geo</code> from a Box mesh <code>cube1Mesh</code>.</p></li><li><p>Create a Material <code>cube1Mat</code> based on jME3&#8217;s default <code>Unshaded.j3md</code> material definition.</p></li><li><p>Create a texture <code>cube1Tex</code> from the <code>Monkey.jpg</code> file in the <code>assets/Interface/Logo/</code> directory of the project.</p></li><li><p>Load the texture <code>cube1Tex</code> into the <code>ColorMap</code> layer of the material <code>cube1Mat</code>.</p></li><li><p>Apply the material to the cube, and attach the cube to the rootnode.</p></li></ol></div></div></div>
  95. <div class="sect1"><h2 id="transparent-unshaded-texture">Transparent Unshaded Texture</h2><div class="sectionbody"><div class="paragraph"><p><code>Monkey.png</code> is the same texture as <code>Monkey.jpg</code>, but with an added alpha channel. The alpha channel allows you to specify which areas of the texture you want to be opaque or transparent: Black areas of the alpha channel remain opaque, gray areas become translucent, and white areas become transparent.</p></div>
  96. <div class="paragraph"><p>For a partially translucent/transparent texture, you need:</p></div>
  97. <div class="ulist"><ul><li><p>A Texture with alpha channel</p></li><li><p>A Texture with blend mode of <code>BlendMode.Alpha</code></p></li><li><p>A Geometry in the <code>Bucket.Transparent</code> render bucket.<br>
  98. This bucket ensures that the transparent object is drawn on top of objects behind it, and they show up correctly under the transparent parts.</p></li></ul></div>
  99. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> <span class="comment">/** A translucent/transparent texture, similar to a window frame. */</span>
  100. <span class="predefined-type">Box</span> cube2Mesh = <span class="keyword">new</span> <span class="predefined-type">Box</span>( <span class="float">1f</span>,<span class="float">1f</span>,<span class="float">0.01f</span>);
  101. Geometry cube2Geo = <span class="keyword">new</span> Geometry(<span class="string"><span class="delimiter">&quot;</span><span class="content">window frame</span><span class="delimiter">&quot;</span></span>, cube2Mesh);
  102. Material cube2Mat = <span class="keyword">new</span> Material(assetManager,
  103. <span class="string"><span class="delimiter">&quot;</span><span class="content">Common/MatDefs/Misc/Unshaded.j3md</span><span class="delimiter">&quot;</span></span>);
  104. cube2Mat.setTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">ColorMap</span><span class="delimiter">&quot;</span></span>,
  105. assetManager.loadTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">Textures/ColoredTex/Monkey.png</span><span class="delimiter">&quot;</span></span>));
  106. cube2Mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); <span class="comment">// !</span>
  107. cube2Geo.setQueueBucket(Bucket.Transparent); <span class="comment">// !</span>
  108. cube2Geo.setMaterial(cube2Mat);
  109. rootNode.attachChild(cube2Geo);</code></pre></div></div>
  110. <div class="paragraph"><p>For non-transparent objects, the drawing order is not so important, because the z-buffer already keeps track of whether a pixel is behind something else or not, and the color of an opaque pixel doesn&#8217;t depend on the pixels under it, this is why opaque Geometries can be drawn in any order.</p></div>
  111. <div class="paragraph"><p>What you did for the transparent texture is the same as before, with only one added step for the transparency.</p></div>
  112. <div class="olist arabic"><ol class="arabic"><li><p>Create a Geometry <code>cube2Geo</code> from a Box mesh <code>cube2Mesh</code>. This Box Geometry is flat upright box (because z=0.01f).</p></li><li><p>Create a Material <code>cube2Mat</code> based on jME3&#8217;s default <code>Unshaded.j3md</code> material definition.</p></li><li><p>Create a texture <code>cube2Tex</code> from the <code>Monkey.png</code> file in the <code>assets/Textures/ColoredTex/</code> directory of the project. This PNG file must have an alpha layer.</p></li><li><p><strong>Activate transparency in the material by setting the blend mode to Alpha.</strong></p></li><li><p><strong>Set the QueueBucket of the Geometry to <code>Bucket.Transparent</code>.</strong></p></li><li><p>Load the texture <code>cube2Tex</code> into the <code>ColorMap</code> layer of the material <code>cube2Mat</code>.</p></li><li><p>Apply the material to the cube, and attach the cube to the rootnode.</p></li></ol></div>
  113. <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>Learn more about creating PNG images with an alpha layer in the help system of your graphic editor.</p></div></td></tr></table></div></div></div>
  114. <div class="sect1"><h2 id="shininess-and-bumpiness">Shininess and Bumpiness</h2><div class="sectionbody"><div class="paragraph"><p>But textures are not all. Have a close look at the shiny sphere – you cannot get such a nice bumpy material with just a plain texture. You see that JME3 also supports so-called Phong-illuminated materials:</p></div>
  115. <div class="paragraph"><p>In a lit material, the standard texture layer is refered to as <em>DiffuseMap</em>, any material can use this layer. A lit material can additionally have lighting effects such as <em>Shininess</em> used together with the <em>SpecularMap</em> layer and <em>Specular</em> color. And you can even get a realistically bumpy or cracked surface with help of the <em>NormalMap</em> layer.</p></div>
  116. <div class="paragraph"><p>Let&#8217;s have a look at the part of the code example where you create the shiny bumpy rock.</p></div>
  117. <div class="olist arabic"><ol class="arabic"><li><p>Create a Geometry from a Sphere shape. Note that this shape is a normal smooth sphere mesh.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> Sphere sphereMesh = <span class="keyword">new</span> Sphere(<span class="integer">32</span>,<span class="integer">32</span>, <span class="float">2f</span>);
  118. Geometry sphereGeo = <span class="keyword">new</span> Geometry(<span class="string"><span class="delimiter">&quot;</span><span class="content">Shiny rock</span><span class="delimiter">&quot;</span></span>, sphereMesh);</code></pre></div></div>
  119. <div class="olist loweralpha"><ol class="loweralpha" type="a"><li><p>(Only for Spheres) Change the sphere&#8217;s TextureMode to make the square texture project better onto the sphere.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> sphereMesh.setTextureMode(Sphere.TextureMode.Projected);</code></pre></div></div></li><li><p>You must generate TangentBinormals for the mesh so you can use the NormalMap layer of the texture.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> TangentBinormalGenerator.generate(sphereMesh);</code></pre></div></div></li></ol></div></li><li><p>Create a material based on the <code>Lighting.j3md</code> default material.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> Material sphereMat = <span class="keyword">new</span> Material(assetManager,
  120. <span class="string"><span class="delimiter">&quot;</span><span class="content">Common/MatDefs/Light/Lighting.j3md</span><span class="delimiter">&quot;</span></span>);</code></pre></div></div>
  121. <div class="olist loweralpha"><ol class="loweralpha" type="a"><li><p>Set a standard rocky texture in the <code>DiffuseMap</code> layer.</p><div style="text-align: right;" class="imageblock"><div class="content"><img src="https://github.com/jMonkeyEngine/jmonkeyengine/raw/445f7ed010199d30c484fe75bacef4b87f2eb38e/jme3-testdata/src/main/resources/Textures/Terrain/Pond/Pond.jpg" alt="Pond.jpg" width="64" height="64"></div></div>
  122. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> sphereMat.setTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">DiffuseMap</span><span class="delimiter">&quot;</span></span>,
  123. assetManager.loadTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">Textures/Terrain/Pond/Pond.jpg</span><span class="delimiter">&quot;</span></span>));</code></pre></div></div></li><li><p>Set the <code>NormalMap</code> layer that contains the bumpiness. The NormalMap was generated for this particular DiffuseMap with a special tool (e.g. Blender).</p><div style="text-align: right;" class="imageblock"><div class="content"><img src="https://github.com/jMonkeyEngine/jmonkeyengine/raw/445f7ed010199d30c484fe75bacef4b87f2eb38e/jme3-testdata/src/main/resources/Textures/Terrain/Pond/Pond_normal.png" alt="Pond_normal.png" width="64" height="64"></div></div>
  124. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> sphereMat.setTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">NormalMap</span><span class="delimiter">&quot;</span></span>,
  125. assetManager.loadTexture(<span class="string"><span class="delimiter">&quot;</span><span class="content">Textures/Terrain/Pond/Pond_normal.png</span><span class="delimiter">&quot;</span></span>));</code></pre></div></div></li><li><p>Set the Material&#8217;s Shininess to a value between 1 and 128. For a rock, a low fuzzy shininess is appropriate. Use material colors to define the shiny Specular color.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> sphereMat.setBoolean(<span class="string"><span class="delimiter">&quot;</span><span class="content">UseMaterialColors</span><span class="delimiter">&quot;</span></span>,<span class="predefined-constant">true</span>);
  126. sphereMat.setColor(<span class="string"><span class="delimiter">&quot;</span><span class="content">Diffuse</span><span class="delimiter">&quot;</span></span>,ColorRGBA.White); <span class="comment">// minimum material color</span>
  127. sphereMat.setColor(<span class="string"><span class="delimiter">&quot;</span><span class="content">Specular</span><span class="delimiter">&quot;</span></span>,ColorRGBA.White); <span class="comment">// for shininess</span>
  128. sphereMat.setFloat(<span class="string"><span class="delimiter">&quot;</span><span class="content">Shininess</span><span class="delimiter">&quot;</span></span>, <span class="float">64f</span>); <span class="comment">// [1,128] for shininess</span></code></pre></div></div></li></ol></div></li><li><p>Assign your newly created material to the Geometry.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> sphereGeo.setMaterial(sphereMat);</code></pre></div></div></li><li><p>Let&#8217;s move and rotate the geometry a bit to position it better.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> sphereGeo.setLocalTranslation(<span class="integer">0</span>,<span class="integer">2</span>,-<span class="integer">2</span>); <span class="comment">// Move it a bit</span>
  129. sphereGeo.rotate(<span class="float">1.6f</span>, <span class="integer">0</span>, <span class="integer">0</span>); <span class="comment">// Rotate it a bit</span>
  130. rootNode.attachChild(sphereGeo);</code></pre></div></div></li></ol></div>
  131. <div class="paragraph"><p>Remember that any Lighting.j3md-based material requires a light source, as shown in the full code sample above.</p></div>
  132. <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>To deactivate Shininess, do not set <code>Shininess</code> to 0, but instead set the <code>Specular</code> color to <code>ColorRGBA.Black</code>.</p></div></td></tr></table></div></div></div>
  133. <div class="sect1"><h2 id="default-material-definitions">Default Material Definitions</h2><div class="sectionbody"><div class="paragraph"><p>As you have seen, you can find the following default materials in <code>jme/core-data/Common/MatDefs/…</code>.</p></div>
  134. <table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 20%;"><col style="width: 40%;"><col style="width: 40%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">Default Definition</th><th class="tableblock halign-left valign-top">Usage</th><th class="tableblock halign-left valign-top">Parameters</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p><code>Misc/Unshaded.j3md</code></p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Colored: Use with mat.setColor() and ColorRGBA.<br>
  135. Textured: Use with mat.setTexture() and Texture.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Color : Color<br>
  136. ColorMap : Texture2D</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p><code>Light/Lighting.j3md</code></p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Use with shiny Textures, Bump- and NormalMaps textures.<br>
  137. Requires a light source.</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Ambient, Diffuse, Specular : Color<br>
  138. DiffuseMap, NormalMap, SpecularMap : Texture2D<br>
  139. Shininess : Float</p></div></div></td></tr></tbody></table>
  140. <div class="paragraph"><p>For a game, you create custom Materials based on these existing MaterialDefintions – as you have just seen in the example with the shiny rock&#8217;s material.</p></div></div></div>
  141. <div class="sect2"><h3 id="exercises">Exercises</h3><div class="sect2"><h3 id="exercise-1-custom-j3m-material">Exercise 1: Custom .j3m Material</h3><div class="paragraph"><p>Look at the shiny rocky sphere above again. It takes several lines to create and set the Material.</p></div>
  142. <div class="ulist"><ul><li><p>Note how it loads the <code>Lighting.j3md</code> Material definition.</p></li><li><p>Note how it sets the <code>DiffuseMap</code> and <code>NormalMap</code> to a texture path.</p></li><li><p>Note how it activates <code>UseMaterialColors</code> and sets <code>Specular</code> and <code>Diffuse</code> to 4 float values (RGBA color).</p></li><li><p>Note how it sets <code>Shininess</code> to 64.</p></li></ul></div>
  143. <div class="paragraph"><p>If you want to use one custom material for several models, you can store it in a .j3m file, and save a few lines of code every time.</p></div>
  144. <div class="paragraph"><p>You create a j3m file as follows:</p></div>
  145. <div class="olist arabic"><ol class="arabic"><li><p>Create a plain text file <code>assets/Materials/MyCustomMaterial.j3m</code> in your project directory, with the following content:</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code>Material My shiny custom material : Common/MatDefs/Light/Lighting.j3md {
  146. MaterialParameters {
  147. DiffuseMap : Textures/Terrain/Pond/Pond.jpg
  148. NormalMap : Textures/Terrain/Pond/Pond_normal.png
  149. UseMaterialColors : true
  150. Specular : 1.0 1.0 1.0 1.0
  151. Diffuse : 1.0 1.0 1.0 1.0
  152. Shininess : 64.0
  153. }
  154. }</code></pre></div></div>
  155. <div class="ulist"><ul><li><p>Note that <code>Material</code> is a fixed keyword.</p></li><li><p>Note that <code>My shiny custom material</code> is a String that you can choose to describe the material.</p></li><li><p>Note how the code sets all the same properties as before!</p></li></ul></div></li><li><p>In the code sample, comment out the eight lines that have <code>sphereMat</code> in them.</p></li><li><p>Below this line, add the following line:</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">sphereGeo.setMaterial((Material) assetManager.loadMaterial(
  156. <span class="string"><span class="delimiter">&quot;</span><span class="content">Materials/MyCustomMaterial.j3m</span><span class="delimiter">&quot;</span></span>));</code></pre></div></div></li><li><p>Run the app. The result is the same.</p></li></ol></div>
  157. <div class="paragraph"><p>Using this new custom material <code>MyCustomMaterial.j3m</code> only takes one line. You have replaced the eight lines of an on-the-fly material definition with one line that loads a custom material from a file. Using .j3m files is very handy if you use the same material often.</p></div></div>
  158. <div class="sect2"><h3 id="exercise-2-bumpiness-and-shininess">Exercise 2: Bumpiness and Shininess</h3><div class="paragraph"><p>Go back to the bumpy rock sample above:</p></div>
  159. <div class="olist arabic"><ol class="arabic"><li><p>Comment out the DiffuseMap line, and run the app. (Uncomment it again.)</p><div class="ulist"><ul><li><p>Which property of the rock is lost?</p></li></ul></div></li><li><p>Comment out the NormalMap line, and run the app. (Uncomment it again.)</p><div class="ulist"><ul><li><p>Which property of the rock is lost?</p></li></ul></div></li><li><p>Change the value of Shininess to values like 0, 63, 127.</p><div class="ulist"><ul><li><p>What aspect of the Shininess changes?</p></li></ul></div></li></ol></div></div></div>
  160. <div class="sect1"><h2 id="conclusion">Conclusion</h2><div class="sectionbody"><div class="paragraph"><p>You have learned how to create a Material, specify its properties, and use it on a Geometry. You know how to load an image file (.png, .jpg) as texture into a material. You know to save texture files in a subfolder of your project&#8217;s <code>assets/Textures/</code> directory.</p></div>
  161. <div class="paragraph"><p>You have also learned that a material can be stored in a .j3m file. The file references a built-in MaterialDefinition and specifies values for properties of that MaterialDefinition. You know to save your custom .j3m files in your project&#8217;s <code>assets/Materials/</code> directory.</p></div>
  162. <div class="paragraph"><p>Now that you know how to load models and how to assign good-looking materials to them, let&#8217;s have a look at how to animate models in the next chapter, <a href="../../jme3/beginner/hello_animation.html">Hello Animation</a>.</p></div>
  163. <hr>
  164. <div class="paragraph"><p>See also</p></div>
  165. <div class="ulist"><ul><li><p><a href="../../jme3/intermediate/how_to_use_materials.html">How to Use Materials</a></p></li><li><p><a href="../../sdk/material_editing.html">Material Editing</a></p></li><li><p><a href="https://hub.jmonkeyengine.org/t/jmonkeyengine3-material-system-full-explanation/12947">Materials</a> forum thread</p></li><li><p><a href="http://nbviewer.jupyter.org/github/jMonkeyEngine/wiki/blob/master/src/docs/resources/tutorials/material/jME3_materials.pdf">jME3 Materials documentation (PDF)</a></p></li><li><p><a href="http://www.youtube.com/watch?v=Feu3-mrpolc">Video Tutorial: Editing and Assigning Materials to Models in jMonkeyEngine SDK (from 2010, is there a newer one?</a></p></li><li><p><a href="https://www.blender.org/support/tutorials/">Creating textures in Blender</a></p></li><li><p><a href="http://www.shaders.co.uk/ifw2_textures/whatsin10.htm">Various Material screenshots</a> (Not done with JME3, this is just to show the fantastic range of Material parameters in the hands of an expert, until we have a JME3 demo for it.)</p></li></ul></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2020-04-29 14:53:30 +00:00</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
  166. apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
  167. indexName: 'jmonkeyengine',
  168. inputSelector: '#doc-search',
  169. debug: false // Set debug to true if you want to inspect the dropdown
  170. });</script></body></html>