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

Вклад

Опубликованно: 16.02.2019, 19:12
Последняя редакция, Andry: 15.04.2019 19:49

Это система частиц для jME3, выложена для обзора и обсуждения. Это даст возможность для людей комментировать и запрашивать изменения в API или внутренних функций системы. Код для этой системы частиц может быть найден jMonkeyEngine-Contributions

Извиняюсь за небольшое дрожание в некоторых видео, VideoRecorderState, кажется, вызывает некоторые проблемы, которые отсутствуют, когда приложение работает нормально.

Титры

На эти излучатели частиц я был вдохновлён излучателем частиц t0neg0ds, и использую часть кода оттуда.

Он же, в свою очередь, были основаны на оригинальной системе частиц jME3 Кирилла Вайнера

Большая картина

Ядром всех Излучателей Частиц является ParticleController. Который используется для управления всеми частицами, хотя поведение самих частиц контролируется через ряд других классов, которые подключаете к ParticleController для обеспечения требуемой функциональности. Вы можете думать о ParticleController как о центральном концентраторе, к которому вы подключаете все модули, необходимые для получения желаемого поведения.

Простой способ увидеть, что вам нужно, — это создать новый ParticleController, а затем посмотреть на конструктор, вы можете увидеть какие параметры необходимо там указать.

Название  Название, используемое для геометрии в графе сцены
mesh  Используемая сетка (обычно это PointMesh или QuadMesh)
maxParticles  Максимальное количество частиц, которые могут быть активны в любой момент
lifeMin  Минимальное количество времени (в секундах), в течение которого живет каждая частица
lifeMax  Максимальное количество времени (в секундах), в течение которого живет каждая частица
source  Источник, из которого появляются частицы
emissionController  Частота и время появления частиц. Если ноль, то никакие частицы автоматически не создаются, и их нужно запускать вручную, используя emitNextParticle() или emitAllParticles()
influencers  Ноль или более ParticleInfluencers, каждый из которых меняет поведение частиц.

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

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

Полный список доступных стандартных опций смотрите на странице ссылок.

Простой огонь

public class HelloParticles1_SimpleFire extends SimpleApplication {

public static void main(String[] args){
HelloParticles1_SimpleFire app = new HelloParticles1_SimpleFire();
app.start(); // старт игры
}

@Override
public void simpleInitApp() {

// Создадим новый ParticleController
ParticleController pCtrl = new ParticleController(
// Назовём излучатель
"SimpleFire",
// Используем простую point mesh (самый быстрый, но наиболее ограниченный тип сетки) с заданным
// изображением (из jME3-testdata). Изображение на самом деле содержит сетку спрайтов 2х2.
new PointMesh(assetManager, "Effects/Explosion/flame.png", 2, 2),
// Разрешим не более 32 частиц в любой момент времени
32,
// Частицы существую не менее 2 секунд
2,
// И максимум 3 секунды
3,
// Точечные источники всегда генерируют частицы в месте расположения источника,
// частицам даётся случайная скорость между двумя заданными значениями.
new PointSource(new Vector3f(-3, 0, -3), new Vector3f(3, 0, 3)),
// Испускать частицы через равные промежутки времени, 10 частиц каждую секунду
new RegularEmission(10),
// ** Influencers начинаются здесь
// Выберите случайный спрайт из 4 доступных для каждой частицы
new RandomSpriteInfluencer(),
// Частицы начинаются с размера 0,5 единиц и заканчиваются радиусом 0,1
new SizeInfluencer(0.5f, 0.1f),
// Частицы начинаются желтого цвета и полностью непрозрачными и исчезают с красным
// с очень низкой непрозрачностью
new ColorInfluencer(new ColorRGBA(1,1,0.2f,1), new ColorRGBA(1,0,0,0.1f)),
// Независимо от того, с какой скоростью запускаются частицы, они начнут двигаться вверх.
new PreferredDirectionInfluencer(new Vector3f(0, 1, 0), 0.25f));

// Наконец, прикрепите геометрию к rootNode, чтобы запустить частицы в вашу сцену
rootNode.attachChild(pCtrl.getGeometry());
}
}

Запустите этот код, и результат должен выглядеть примерно так:

particles1

Простой огонь и дым

    @Override
public void simpleInitApp() {

// Создадим новый ParticleController
ParticleController pCtrl = new ParticleController(
// Назовём излучатель
"SimpleFire",
// Используем простую point mesh (самый быстрый, но наиболее ограниченный тип сетки) с заданным
// изображением (из jME3-testdata). Изображение на самом деле содержит сетку спрайтов 2х2.
new PointMesh(assetManager, "Effects/Explosion/flame.png", 2, 2),
// Разрешим не более 32 частиц в любой момент времени, частицы теперь будут живить дольше
// опому что нам их надо будет больше на экране
50,
// Частицы существую не менее 4 секунд
4,
// И максимум 5 секунд
5,
// Точечные источники всегда генерируют частицы в месте расположения источника,
// частицам даётся случайная скорость между двумя заданными значениями.
new PointSource(new Vector3f(-3, 0, -3), new Vector3f(3, 0, 3)),
// Испускать частицы через равные промежутки времени, 10 частиц каждую секунду
new RegularEmission(10),
// ** Influencers начинаются здесь
// Выберите случайный спрайт из 4 доступных для каждой частицы
new RandomSpriteInfluencer(),
// Частицы начинаются с размера 0,5 единиц и заканчиваются радиусом 0,1
new SizeInfluencer(0.5f, 0.25f),
// Частицы начинаются желтого цвета и полностью непрозрачными и исчезают с красным
// с очень низкой непрозрачностью
new MultiColorInfluencer(
new MultiColorInfluencer.Stage(0, new ColorRGBA(1, 1, 0.1f, 1)),
new MultiColorInfluencer.Stage(0.15f, new ColorRGBA(1, 0, 0, 0.25f)),
new MultiColorInfluencer.Stage(0.3f, new ColorRGBA(1f, 1f, 1f, 0.5f)),
new MultiColorInfluencer.Stage(1, new ColorRGBA(1f,1f,1f,0f))
),
// Независимо от того, с какой скоростью запускаются частицы, они начнут двигаться вверх.
new PreferredDirectionInfluencer(new Vector3f(0, 1, 0), 0.25f));

// Наконец, прикрепите геометрию к rootNode, чтобы запустить частицы в вашу сцену
rootNode.attachChild(pCtrl.getGeometry());
}

Вы можете видеть, что единственное изменение состояло в том, чтобы заставить частицы жить немного дольше и изменить ColorInfluencer для MultiColorInfluencer, и все же результат выглядят совершенно иным:

Это еще не очень убедительный огонь, но его очень легко получить и запустить. Одна из проблем этого подхода состоит в том, что частицы сделаны с использованием альфа-аддитивного материала, то есть они могут делать вещи только освещёнными, но не могут их затенять. Это не идеально для дыма, который должен делать вещи затенёнными. Мы еще вернемся к этому позже, но сейчас перейдем к различным типам сеток(mesh).

Quad Meshes и Billboarding

Point Meshe(Точечные сетки) очень быстрые, но у них есть ряд ограничений. Основные из них заключаются в том, что спрайты всегда должны быть направлены к экрану, а на некоторых видеокартах максимальное количество пикселей, которое спрайт может занимать на экране, ограничено.

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

Изображение пламени которое мы создавали ранее будет использоваться для второго излучателя, а первый излучатель будет использовать изображение ниже, которое вы можете скачать для использования в своём коде:
runecircle
    @Override
public void simpleInitApp() {

// Создадим новый ParticleController чтобы обеспечить сам эффект рунного заклинания
ParticleController pCtrl = new ParticleController(
// Назовём излучатель
"SpellRunes",
// Use a Quad Mesh, this image is available for download on this page. The texture file contains
// a single image so there are no sprite columns and rows to set up. The BillboardStrategy is how
// the particles should be oriented, in this case it uses the particle rotation.
new QuadMesh(QuadMeshBillboardStrategy.USE_PARTICLE_ROTATION, assetManager, "Textures/runeCircle.png"),
// Allow at most 9 particles at any time
9,
// Particles always last for 4 seconds
4,
4,
// We want to generate all particles from the same location with the same velocity.
new PointSource(new Vector3f(0, 1f, 0), new Vector3f(0, 1f, 0)),
// Emit particles at regular intervals, 4 particles every second
new RegularEmission(2),
// ** Influencers start here
// These particles should be size 3 and stay the same size
new SizeInfluencer(3, 3),
// Start the particles at full opacity blue and then fade them out to 0 opacity cyan.
new ColorInfluencer(ColorRGBA.Blue, new ColorRGBA(0, 1, 1, 0)),
// Rotate all particles by the same amount. The units are radians-per-second
new RotationInfluencer(
new Vector3f(0, FastMath.QUARTER_PI, 0),
new Vector3f(0, FastMath.QUARTER_PI, 0), false));

// Finally attach the geometry to the rootNode in order to start the particles running
rootNode.attachChild(pCtrl.getGeometry());

// Construct a new ParticleController to provide the central glow effect
pCtrl = new ParticleController(
// The name of the emitter
"SpellBase",
// Use a simple point mesh (the fastest but most limitted mesh type) with the specified
// image (from jME3-testdata). The image actually contains a 2x2 grid of sprites.
new PointMesh(assetManager, "Textures/flame.png", 2, 2),
// Allow at most 76 particles at any time
76,
// Particles last for at least 5 seconds
5,
// And at most 5 seconds
5,
// Point sources always generate particles at the location of the source, the particles
// are given a random velocity between the two given.
new PointSource(new Vector3f(-1f, 0, -1f), new Vector3f(1f, 0.5f, 1f)),
// Emit particles at regular intervals, 15 particles every second
new RegularEmission(15),
// ** Influencers start here
// Select a random sprite from the 4 available for each particle
new RandomSpriteInfluencer(),
// Particles start red with some blue and green and fade towards blue zero opacity
// Because particles are rendered using an additive blend then any area where a lot
// of particles overlap will end up white.
new ColorInfluencer(new ColorRGBA(1,0.25f,0.25f,0.25f), new ColorRGBA(0,0,1,0f)));

// Finally attach the geometry to the rootNode in order to start the particles running
rootNode.attachChild(pCtrl.getGeometry());

cam.setLocation(new Vector3f(0, 10, -10));
cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
}

Результат должен выглядеть примерно так:

Видео: Пример 1 излучателя частиц

Использование сетки в качестве источника частиц

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

    @Override
public void simpleInitApp() {

Node monkey = (Node) assetManager.loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml");
rootNode.attachChild(monkey);

DirectionalLight dl = new DirectionalLight();
dl.setDirection(new Vector3f(-0.1f,-0.7f,-1).normalizeLocal());
dl.setColor(new ColorRGBA(0.88f, 0.60f, 0.60f, 1.0f));
rootNode.addLight(dl);

AmbientLight al = new AmbientLight();
al.setColor(ColorRGBA.White);
rootNode.addLight(al);

Результат должен выглядеть примерно так:

Теперь давайте подожжем обезьяну! (Никакие

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