Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            jMonkeyEngine3: Привет мир, Обучающая Серия
                jmonkeyengine 3 Урок (6) — Hello Materials

jmonkeyengine 3 Урок (6) — Hello Materials

Опубликованно: 04.04.2017, 19:59
Последняя редакция, Andry: 01.10.2017 10:36

Предыдущий: Hello Input System, Следующий: Hello Animation

Термин Материал(Material) включает в себя все, что влияет на то, как поверхность 3D модели выглядит: цвет, текстуру, блеск и непрозрачность/прозрачность. Простая окраска показана в уроке Hello Node. Загрузка моделей, которые идут вместе с материалом показана в уроке Hello Asset. В этом уроке вы научитесь создавать и использовать пользовательские JME3 настройки Описания Материала(Material Definition).

beginner-materials

Для того, чтобы использовать примеры игровых ресурсов в вашем новом проекте в jMonkeyEngine SDK, щелкните [ПК мыши] ваш проект, выберите Свойства, перейдите в раздел Библиотеки, нажмите кнопку [Добавить библиотеку] и добавьте библиотеку jme3-test-data.

Пример кода

package jme3test.helloworld;

import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.texture.Texture;
import com.jme3.util.TangentBinormalGenerator;

/** Пример 6 - как дать поверхности объекта материал и текстуру.
* Как сделать объекты прозрачными. Как сделать поверхности с неровностями и блестящие поверхности. */
public class HelloMaterial extends SimpleApplication {

  public static void main(String[] args) {
    HelloMaterial app = new HelloMaterial();
    app.start();
  }

  @Override
  public void simpleInitApp() {

    /** Простой текстурированный куб - хорошее качество MIP текстурирования. */
    Box cube1Mesh = new Box( 1f,1f,1f);
    Geometry cube1Geo = new Geometry("My Textured Box", cube1Mesh);
    cube1Geo.setLocalTranslation(new Vector3f(-3f,1.1f,0f));
    Material cube1Mat = new Material(assetManager,
        "Common/MatDefs/Misc/Unshaded.j3md");
    Texture cube1Tex = assetManager.loadTexture(
        "Interface/Logo/Monkey.jpg");
    cube1Mat.setTexture("ColorMap", cube1Tex);
    cube1Geo.setMaterial(cube1Mat);
    rootNode.attachChild(cube1Geo);

    /** Полупрозрачная/прозрачная текстура, похожая на оконное стекло. */
    Box cube2Mesh = new Box( 1f,1f,0.01f);
    Geometry cube2Geo = new Geometry("window frame", cube2Mesh);
    Material cube2Mat = new Material(assetManager,
        "Common/MatDefs/Misc/Unshaded.j3md");
    cube2Mat.setTexture("ColorMap",
        assetManager.loadTexture("Textures/ColoredTex/Monkey.png"));
    cube2Mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
    cube2Geo.setQueueBucket(Bucket.Transparent);
    cube2Geo.setMaterial(cube2Mat);
    rootNode.attachChild(cube2Geo);

    /** Камень с неровностями и эффектом блеска при освещении.*/
    Sphere sphereMesh = new Sphere(32,32, 2f);
    Geometry sphereGeo = new Geometry("Shiny rock", sphereMesh);
    sphereMesh.setTextureMode(Sphere.TextureMode.Projected); // лучшее качество по сферам
    TangentBinormalGenerator.generate(sphereMesh); // для эффекта от освещения
    Material sphereMat = new Material(assetManager,
        "Common/MatDefs/Light/Lighting.j3md");
    sphereMat.setTexture("DiffuseMap",
        assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg"));
    sphereMat.setTexture("NormalMap",
        assetManager.loadTexture("Textures/Terrain/Pond/Pond_normal.png"));
    sphereMat.setBoolean("UseMaterialColors",true);
    sphereMat.setColor("Diffuse",ColorRGBA.White);
    sphereMat.setColor("Specular",ColorRGBA.White);
    sphereMat.setFloat("Shininess", 64f); // [0,128]
    sphereGeo.setMaterial(sphereMat);
    sphereGeo.setLocalTranslation(0,2,-2); // подвинуть
    sphereGeo.rotate(1.6f, 0, 0); // вращать
    rootNode.attachChild(sphereGeo);

    /** Нужно добавить свет, чтобы сделать объект видимым! */
    DirectionalLight sun = new DirectionalLight();
    sun.setDirection(new Vector3f(1,0,-2).normalizeLocal());
    sun.setColor(ColorRGBA.White);
    rootNode.addLight(sun);

  }
}

Вы должны увидеть

  • Слева — Куб с текстурой коричневой обезьяны.
  • Справа — полупрозрачный рисунок обезьяны перед блестящей неравной каменной сферой.

Перемещайтесь с помощью клавиш WASD, чтобы поближе взглянуть на полупрозрачность куба и неровности камня.


Простая не затененная текстура

Обычно вы хотите дать объектам на вашей сцене текстуры: это может быть камень, трава, кирпич, дерево, вода, металл, бумага … Текстура это обычный файл изображения в формате JPG или PNG. В этом примере, вы создаете куб с простой не затененной текстуру обезьяны в качестве материала.

    /** Простой текстурированный куб - хорошее качество MIP текстурирования. */
    Box cube1Mesh = new Box( 1f,1f,1f);
    Geometry cube1Geo = new Geometry("My Textured Box", cube1Mesh);
    cube1Geo.setLocalTranslation(new Vector3f(-3f,1.1f,0f));
    Material cube1Mat = new Material(assetManager,
        "Common/MatDefs/Misc/Unshaded.j3md");
    Texture cube1Tex = assetManager.loadTexture(
        "Interface/Logo/Monkey.jpg");
    cube1Mat.setTexture("ColorMap", cube1Tex);
    cube1Geo.setMaterial(cube1Mat);
    rootNode.attachChild(cube1Geo);

Вот что мы сделали: для создания текстурированного куба:

  1. Создали Геометрию cube1Geo из сетки cubeMesh являющеёся Box.
  2. Создали Материал cube1Mat, основанный на jME3 описании материала по умолчанию Unshaded.j3md.
  3. Создали текстуры cube1Tex из файла Monkey.jpg в папке проекта assets/Interface/Logo/.
  4. Загрузили текстуру cube1Tex в слой ColorMap материала cube1Mat.
  5. Применили материал к кубу, и прикрепите куб к RootNode.

Прозрачность не затененной текстуры

Monkey.png та же самая текстура, что и Monkey.jpg, но с добавлением альфа-канала. Альфа-канал позволяет указать, какие области текстуры вы хотите сделать, прозрачными или непрозрачными: Черные области альфа канала остаются непрозрачными, серые зоны становятся полупрозрачными, и белые области становятся прозрачными.

Для частично полупрозрачной/прозрачной текстуры, вам понадобится:

  • Текстура с альфа-каналом
  • Текстура с режимом наложения BlendMode.Alpha
  • Геометрия в Bucket.Transparent режиме «бакет» (render bucket).
    Этот bucket гарантирует, что прозрачный объект рисуется поверх объектов что идут позади него, и они показывают правильно через прозрачные части.
    /** Полупрозрачная/прозрачная текстура, похожая на оконное стекло. */
    Box cube2Mesh = new Box( 1f,1f,0.01f);
    Geometry cube2Geo = new Geometry("window frame", cube2Mesh);
    Material cube2Mat = new Material(assetManager,
        "Common/MatDefs/Misc/Unshaded.j3md");
    cube2Mat.setTexture("ColorMap",
        assetManager.loadTexture("Textures/ColoredTex/Monkey.png"));
    cube2Mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
    cube2Geo.setQueueBucket(Bucket.Transparent);  
    cube2Geo.setMaterial(cube2Mat);
    rootNode.attachChild(cube2Geo);

Для непрозрачных объектов, порядок рисования не так важен, потому что z-буфер уже отслеживает находятся ли пиксели за чем-то другим или нет, а цвет из непрозрачного пикселя не зависит от пикселей под ним, вот почему непрозрачные геометрии могут быть сделаны в любом порядке.

То же, что вы сделали для прозрачной текстуры, то же, что и было раньше, но только с одним добавленным шагом, для прозрачности.

  1. Создали Геометрии cube2Geo из сетки cube2Mesh являющеёся Box. Эта Геометрия куба плоский вертикальный квадрат (потому что z = 0.01f).
  2. Создали материал cube2Mat, основанный на jME3 описании материала по умолчанию Unshaded.j3md
  3. Создали текстуру cube2Tex из файла Monkey.png в папке проекта assets/Textures/ColoredTex/. Этот файл PNG должен иметь альфа-слой.
  4. Активировали прозрачность материала, установив режим смешивания в Alpha.
  5. Установили QueueBucket Геометрии, в Bucket.Transparent.
  6. Загрузили текстуру cube2Tex в слой ColorMap материала cube2Mat.
  7. Применили материал к кубу, и присоединили куб к RootNode.
Подробнее о создании PNG изображений с альфа слоем в справочной системе вашего графического редактора.

Блеск и шероховатость

Но текстуры это еще не все. Внимательно посмотрите на блестящую сферу — вы не сможете получить такой ​​хороший материал с неровностями только из обычной текстуры. Как вы можете увидеть, JME3 также поддерживает так называемую Фонг-подсветку(Phong-illuminated) материалов:

В освещенном материале, стандартный слой текстуры называется DiffuseMap, любой материал может использовать этот слой. Освещенный материал дополнительно иметь световые эффекты, такие как Shininess(Блеск), используемые вместе со слоем SpecularMap и Specular(Зеркальным) цветом. И вы даже можете получить реалистичные неровности или трещины на поверхности с помощью слоя NormalMap.

Давайте посмотрим на участок примера кода, где вы создаете поверхность из блестящих неровных камней.

  1. Создаем Геометрию с фигурой Сферы. Заметим, что эта фигура является обычной гладкой сеткой сферы.
        Sphere sphereMesh = new Sphere(32,32, 2f);
        Geometry sphereGeo = new Geometry("Shiny rock", sphereMesh);
    
    • (Только для сфер) Измените TextureMode сферы что бы сделать квадратную текстуру лучше выглядящей на сфере.
    •     sphereMesh.setTextureMode(Sphere.TextureMode.Projected);
      
    • Вы должны создать TangentBinormal для сетки, что бы вы могли использовать слой текстуры NormalMap.
    •     TangentBinormalGenerator.generate(sphereMesh);
      
  2. Создаём материал на основе материала по умолчанию Lighting.j3md.
        Material sphereMat = new Material(assetManager,
            "Common/MatDefs/Light/Lighting.j3md");
    
    1. Установим стандартную текстуру с камнями в слой DiffuseMap.
    2. Pond

          sphereMat.setTexture("DiffuseMap",
              assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg"));
      
    3. Установим слой NormalMap, содержащий неровности. NormalMap должен быть создан для нужной DiffuseMap с помощью специального инструмента (например Blender).
    4. Pond_normal

          sphereMat.setTexture("NormalMap",
              assetManager.loadTexture("Textures/Terrain/Pond/Pond_normal.png"));
      
    5. Установите Shininess(блеск) материала в диапазоне от 1 до 128. Для камня, низкий нечеткий блеск будет уместнее. Используйте материалы цвета, чтобы определить блестящий Specular(зеркальный) цвет.
    6.     sphereMat.setBoolean("UseMaterialColors",true);
          sphereMat.setColor("Diffuse",ColorRGBA.White);  // минимальный цвет материала
          sphereMat.setColor("Specular",ColorRGBA.White); // для блеска
          sphereMat.setFloat("Shininess", 64f);           // [1,128] для блеска
      
  3. Назначьте вновь созданный материал Геометрии.
  4.     sphereGeo.setMaterial(sphereMat);
    
  5. Давайте немного переместим и повернем Геометрию что бы расположить ее лучше.
  6.     sphereGeo.setLocalTranslation(0,2,-2); // немного сдвинем
        sphereGeo.rotate(1.6f, 0, 0);          // немного её повернем 
        rootNode.attachChild(sphereGeo);
    

Помните, что любому материалу на основе Lighting.j3md требуется источник света, как показано в полном примере кода выше.

Что бы отключить Shininess(Блеск), не устанавливайте Shininess на 0, а вместо этого установите Specular цвет такой ColorRGBA.Black.

Описания материалов идущие по умолчанию

Как вы видели, вы можете найти следующие стандартные материалы jme/core-data/Common/MatDefs/….

  По умолчанию Применение Параметры
 Common/MatDefs/Misc/Unshaded.j3md Окрас: используйте с mat.setColor() и ColorRGBA.

Текстурирование: используйте с mat.setTexture() и Texture.

Color : Color
ColorMap : Texture2D
 Common/MatDefs/Light/Lighting.j3md Используйте блестящие Texture, Bump- и NormalMap текстуры.

Требуется источник света.

Ambient, Diffuse, Specular : Color
DiffuseMap, NormalMap, SpecularMap : Texture2D
Shininess : Float

Для игры, создавайте пользовательские материалы на основе этих существующих MaterialDefintion(Описаний материалов) — как вы только что видели в примере с материалом блестящих камней.


Упражнения

Упражнение 1: Пользовательский .j3m материал

Взгляните еще раз на блестящую каменную сферу из примера выше. Вам понадобится всего несколько строк, чтобы создать и настроить материал.

  • Обратите внимание, как загружается описание материала Lighting.j3md.
  • Обратите внимание, как задавать путик к текстурам DiffuseMap и NormalMap.
  • Обратите внимание, как активируется UseMaterialColors и устанавливает Specular и Diffuse с помощью 4 float значений (RGBA цвета).
  • Обратите внимание, как устанавливается Shininess до 64.

Если вы хотите использовать один пользовательский материал для нескольких моделей, вы можете сохранить его в файле .j3m, и сохранить несколько строк кода в любое время.

Вы создаете файл j3m следующим образом:

  1. Создаете в своей папке проекта assets/Materials/MyCustomMaterial.j3m простой текстовый файл, со следующим содержанием:
    Material My shiny custom material : Common/MatDefs/Light/Lighting.j3md {
         MaterialParameters {
            DiffuseMap : Textures/Terrain/Pond/Pond.jpg
            NormalMap : Textures/Terrain/Pond/Pond_normal.png
            UseMaterialColors : true
            Specular : 1.0 1.0 1.0 1.0
            Diffuse : 1.0 1.0 1.0 1.0
            Shininess : 64.0
         }
    }
    
    • Обратите внимание, что Material является фиксированным ключевым словом.
    • Обратите внимание, что My shiny custom material представляет собой Строку, которую можно использовать, чтобы описать материал.
    • Обратите внимание, как код устанавливает все те же свойства, как и раньше!
  2. В примере кода, закомментируйте восемь строк, где есть sphereMat в них.
  3. Ниже этих строк, добавьте следующую строку:
  4. sphereGeo.setMaterial((Material) assetManager.loadMaterial(
        "Materials/MyCustomMaterial.j3m"));
    
  5. Запустите приложение. Результат тот же.

Использование этого нового пользовательского материала MyCustomMaterial.j3m, занимает всего одну строку. Вы заменили восемь строк описывающих материал на лету всего в одну строку, которая загружает пользовательский материал из файла. Использовать .j3m файлы очень удобно, если вы используете часто один и тот же материал.

Упражнение 2: Неровность и Блеск

Вернемся к образцу неровного камня, рассмотренного выше:

  1. Закомментируйте строку с DiffuseMap, и запустить приложение. (Раскомментируем его снова.)
    • Какое свойство каменной поверхности теряется?
  2. Закомментируйте строку с NormalMap, и запустить приложение. (Раскомментируем его снова.)
    • Какое свойство каменной поверхности теряется?
  3. Измените значение Shininess на значения как 0, 63, 127.
    • Какой аспект блеска изменился?

Вывод

Вы узнали, как создать материал, задать его свойства, и использовать его на Геометрии. Вы знаете, как загрузить файл изображения (PNG, .jpg) в качестве текстуры в материал. Теперь вы знаете, что можете сохранить файлы текстур в подпапке assets/Textures вашего проекта.

Вы также узнали, что материал может быть сохранен в файле .j3m. Этот файл ссылается на встроенный MaterialDefinition и определяет значения для свойств этого MaterialDefinition. Теперь вы знаете, что можете сохранять пользовательские .j3m файлы в assets/Materials/ директории вашего проекта.

Теперь, когда вы знаете, как загрузить модели и как назначить ей красивый материал, давайте посмотрим, как анимировать модели в следующей главе, Hello Animation.


Смотрите также:


Переведено для jmonkeyengine.ru, оригинал
Автор перевода: BuGaGa

Добавить комментарий

Содержание

jMonkeyEngine.ru © 2017. Все права сохранены.