Run-time expression для номера используемого частицей спрайта не сложен и основывается на велечине угла между направлениями оси Z и проекцией вектора, соединяющего местоположение частицы и камеры на плоскость XY. Собственно, это целая часть от половины такого угла, измеренного в градусах.
В конечном виде сам runtime expression выглядит следующим образом:
float $pos [] =position; vector $axis,$vect;
$axis=<<0,0,1>> ;
$vect=<< ($pos [0] - camX) ,0, ($pos[2]-camZ)>>; float $angle;
$angle=rad_to_deg(angle($axis,$vect)); if ($vect.x<0) $angle=360-$angle; spriteNumPP=floor ($angle/2 .) +1; Комментарии. Вектор $axis - направление оси 2. Вектор $vect - это пресловутая проекция вектора, соединяющего местоположение частицы и камеры на плоскость XZ. Для определения угла используется функция angle (следует помнить, что, во-первых, функция angle возвращает значение угла в радианах, а не в градусах, и во-вторых, angle возвращает минимальный из двух возможных углов между векторами). Нумерация спрайтов всегда начинается с 1, независимо от нумерации используемых файлов, поэтому в последней строке после вычисления целой части к результату прибавляется единица.
Чтобы не было сбоев в поведении нашего «леса» в первом кадре не забудем копию написанного выше выражения присвоить нашим частицам и в качестве creation expression.
Теперь можно «побродить» камерой по получившемуся «лесу», наслаждаясь полученным результатом.
Замечание. Несмотря на достигнутый эффект объемности ( хотя правильнее, вероятно, говорить о псевдообъемности) созданный нами лес навевает уныние абсолютной идентичностью растущих в нем деревьев. Можно (и нужно!), конечно, поварьировать размер и местоположение спрайтов, это придаст некоторое разнообразие, но можно пойти и дальше - каждому спрайту добавить индивидуальные цветовые свойства. Для решения этой задачи воспользуемся следующим трюком.
1. Добавим нашей системе частиц per-particle атрибут цвета - rgbPP.
2. Определим значение этого атрибута с помощью creation expression, например:
rgbPP=<<rand(l) , rand(l) , rand(l)>>;
3 a Поварьируем значения атрибутов Color Gain и Color Offset файловой ноды текстуры наших спрайтов.
Результат покажется несколько неожиданным, но по зрелому размышлению вполне закономерным: индивидуальный цвет частиц rgbPP смешивается с цветом текстуры в пропорциях, задаваемых значениями атрибутов Color Gain и Color Offset:
Таким образом, деревья в лесу приобрели индивидуальность. Остается лиш заметить, что значение индивидуального цвета частиц rgbPP может быть связано, например, с расстоянием до камеры, что позволит создать эффект воздушной перспективы, атмосферы, тумана и так далее.
Задача 2. Неподвижная камера и движущиеся объекты.
Описанную выше технологию можно применить и к созданию большого числа движущихся объектов
- колонна войск, стадо бегущих животных, толпы людей и так далее. Однако нужно иметь ввиду два существенных отличия: во-первых, чтобы получить правдивый по освещенности результат, при «изготовлении» текстур спрайта придется вращать сам объект, а не камеру вокруг объекта; во-вторых, при каждом угле поворота объекта по отношению к камере необходимо будет отрендерить не одну картинку, а весь цикл анимации, то есть количество текстурных файлов, необходимых для создания толны анимируемых объектов будет существенно больше, чем в предыдущем примере. Давайте создадим толпу шагающих циркулей: