Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество

Простая Вода

Опубликованно: 26.06.2017, 12:39
Последняя редакция, Andry: 26.06.2017 14:35

JMonkeyEngine предлагает SimpleWaterProcessor, который превращает любой
четырехугольник(quad) (плоский прямоугольник) в отражающую водную поверхность с волнами. Вы можете использовать этот четырехугольник(quad) для простых ограниченных водных поверхностей, таких как водные желоба, мелкие фонтаны, лужи, мелкая вода в каналах. SimpleWaterProcessor имеет меньшее влияние на вашу игру, чем полнофункциональный SeaMonkey WaterFilter; Основное отличие состоит в том, что SimpleWaterProcessor не включает в себя эффекты под водой.

Вот некоторая справочная информация для базовой реализации воды JME3:

SimpleWaterProcessor

Сцена JME3 с водой может использовать com.jme3.water.SimpleWaterProcessor (который реализует интерфейс SceneProcessor).

Для достижения эффекта воды JME3 использует шейдеры и специальный материал Common/MatDefs/Water/SimpleWater.j3md. Поверхность воды представляет собой четырехугольники(quad), и мы используем карты нормалей и dU/dV карты текстурированные для имитации волн.

  1. Каждый кадр мы визуализируем на трех текстурных картах:
    • Для поверхности воды (отражения) мы берем снимок окружающей среды, переворачиваем ее вверх ногами и закрепляем его на видимой поверхности воды. Обратите внимание, что мы на самом деле не используем «текстуру воды color map(карта цветов)»: «Текстура воды является исключительно искаженным отражением.
    • Для «волнообразного искажения (преломления) мы используем производную карту нормалей, dU/dV map.
    • Для затуманивания воды (глубина) мы используем карту глубин(depth map) от terrains z-buffer.
  2. В шейдерах мы добавляем все карты текстур вместе.
    • Для «ухабистого смещения волн» мы используем карту нормалей и dU/dV map, которые смещаются относительно друг друга с течением времени для создания эффекта волна..
    • Для векторов отражения света на поверхности воды мы используем формулу Френеля вместе с векторами нормали.
    • Мы добавляем зеркальное освещение.
  3. (Для подводного эффекта каустики мы используем текстуры брызг. — WIP/TODO)

Применение

simplewater

  1. Создадим узла mainScene
    1. Присоедините узел MainScene к rootNode
  2. Загрузите свою scene Spatial
    1. Добавить источник света на Spatial scene
    2. Прикрепите scene Spatial к Улу mainScene
  3. Загрузите вашу Геометрию неба
    1. Прикрепите вашу Геометрию неба к узлу mainScene
  4. Создайте SimpleWaterProcessor WaterProcessor
    • Установите processor ReflectionScene в Spatial mainScene (!)
    • Установите processor Plane туда, где вы хотите, чтобы была поверхность вашей воды
    • Установите processor WaterDepth, DistortionScale, и WaveSpeed
    • Присоедините processor к viewPort
  5. Создайте Quad quad
    • Установите четырехугольнику(quad) TextureCoordinates, чтобы указать размер волн
  6. Создайте Геометрию water из Quad
    • Установите перемещение и вращение воды (то же значение Y, Plane что и выше)!
    • Установите материал воды на выходной материал processor
    • Присоедините Геометрию water к rootNode. (Не mainScene!)

Пример кода

Код примера можно найти в TestSimpleWater.java и TestSceneWater.java.

Вот самая важная часть кода:

// мы создаете water processor
SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
waterProcessor.setReflectionScene(mainScene);

// мы задаете water plane
Vector3f waterLocation=new Vector3f(0,-6,0);
waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
viewPort.addProcessor(waterProcessor);

// мы устанавливаем свойства волны
waterProcessor.setWaterDepth(40);         // прозрачность волн
waterProcessor.setDistortionScale(0.05f); // сила волн
waterProcessor.setWaveSpeed(0.05f);       // скорость волн

// Мы определяем размер волны, задавая размер координатами текстур
Quad quad = new Quad(400,400);
quad.scaleTextureCoordinates(new Vector2f(6f,6f));

// мы создаем геометрию воды из quad
Geometry water=new Geometry("water", quad);
water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
water.setLocalTranslation(-200, -6, 250);
water.setShadowMode(ShadowMode.Receive);
water.setMaterial(waterProcessor.getMaterial());
rootNode.attachChild(water);

Настройки

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

waterProcessor.setRenderSize(128,128);

Чем глубже вода, тем прозрачнее. (?)

waterProcessor.setWaterDepth(40);

Более высокий масштаб искажений делает большие волны.

waterProcessor.setDistortionScale(0.05f);

Более низкая скорость волны делает более спокойную воду.

waterProcessor.setWaveSpeed(0.05f);

Если в вашей сцене нет источника света, вы можете установить направление света для воды:

waterProcessor.setLightDirection( new Vector3f(0.55f, -0.82f, 0.15f));

Вместо того, чтобы создавать quad и задавать plane, вы можете получить waterplane по умолчанию от processor:

Geometry waterPlane = waterProcessor.createWaterGeometry(10, 10);
waterPlane.setLocalTranslation(-5, 0, 5);
waterPlane.setMaterial(waterProcessor.getMaterial());

Вы можете предоставить возможность переключать материал воды на статическую текстуру — для пользователей с медленными ПК.


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

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

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