Render.ru

Попытка создания снега maxscript'ом

Александр Якушев

Активный участник
Рейтинг
7
#1
Пытаюсь автоматизировать создание снега с помощью максскрипта. Что-то получается, но очень долго обсчитывает. Посмотрите код, пожалуйста, может удастся как-то ускорить.

Сам код состоит из двух частей - сам скрипт и BirthScript для PF Source

скрипт:
Создает массив лучей(с произвольными позиция по плоскости XY) над поверхностью, направленных вниз, затем находит пересечение с поверхностью и если уклон меньше 20 градусов, то точка пересечения записывается в глобальную переменную global ArrayPoints, которую потом использует скриптовой оператор BirthScript в PF Source

Код:
(
--vvedem funkciy polucheniya ugla mejdu vectorami:
	fn GetVectorsAngle v1 v2 = (  theAngle = acos(dot (normalize v1) (normalize v2))  )	

	theGeomObj = snapshot $   -- snimok geometrii kak mesh objekta

	global ArrayPoints = #() -- globalnaya peremennaya dlya sozdaniya chasticw
	
	ArrayRay = #() -- massiv dlya luchey
	RayCount = 1000000 -- kolichestvo luchikov ili "snejinok"
	Uklon = 20.0 -- uklon poverhnosti zaderjanoya snejinok 
		
	progressstart "Generating snowflakes..."  -- add progress
		
-- sozdanie massiva luchey po razmera objecta 	
	for i = 1 to RayCount do
	(
		local rayX = random theGeomObj.min.x theGeomObj.max.x
		local rayY = random theGeomObj.min.y theGeomObj.max.y
		local rayZ = theGeomObj.max.z + 100.0
		local ThePosRay = [rayX, rayY, rayZ]
		local TheDirRay = [0.0, 0.0, -1.0]
		local TheRay = ray ThePosRay TheDirRay
		append  ArrayRay TheRay
		)	
--dlya kajdogo luchika naydem peresechenie s geometriey i vichislim ugol 
-- esli ugol > 170 to zapisat point v massiv 	ArrayPoints dlya  Birth Scripts
for i = 1 to RayCount do
(
	theIntRay = intersectRay theGeomObj ArrayRay[i]	-- intersection ray with geom Obj
	
	progressupdate (i as float /RayCount *100) -- update progressbar
	
	if theIntRay != undefined do
	(
		local theAngle = GetVectorsAngle theIntRay.dir ArrayRay[i].dir -- ugol mejdu vektorami
		if theAngle >= (180.0 - Uklon) do  append ArrayPoints  theIntRay.pos
		)		
	)
	progressend () -- end progressbar
	
	delete theGeomObj
	)
-------------------------------------
скрипт для BirthScript оператора:
Использует глобальную переменную global ArrayPoints для создания частиц

Код:
on ChannelsUsed pCont do
(
pCont.useTime = true
pCont.useAge = true
pCont.usePosition = true
pCont.useSpeed = true
)

on Init pCont do
(

)

on Proceed pCont do
(
t1 = pCont.getTimeEnd() as float

if t1 == 0 do
(
		 for i in ArrayPoints do
		(
			pCont.AddParticle()
			pCont.particleIndex = pCont.NumParticles() -- last particle that was added
			pCont.particlePosition = i
		) 
)

)
Порядок теста был таков:
1. Создаеть plane 500x500 сегметнов 100x100 сверху нойз с силой ~100 по оси Z
2. При выделенном плэйне запустить скрипт - будет создана глобальная переменная с массивом точек для PF Source
3. Создать, соответственно, PF Source, - вместо оператора Birth - оператор BirthScript с вышеприведенным вторым скриптом. Из остальных операторов оставить только Display (не забудьте в свойствах PF Source поднять Upper Limit хотя бы до миллиона)
Для создания геометрии снега на частицы применяется PWrapper.

Собственно, суть проблемы:
1. Если параметр RayCount (количество лучиков) увеличить допустим до 5 000 000, очень замедляется процесс.
2. Также если согментов Plane поднять до 1000х1000 (2 000 000 треугольников, что очень даже может быть, особенно на деревьях) при RayCount = 100 000 - процесс опять надолго зависает.
3. Ну и если и RayCount увеличить и использовать высокополигональный объект , то вообще улетает.

Можно ли как-то упростить, ускорить весь процесс? Уж больно долго считает, проще ручками повыделять полики и посадить на них частицы.
 

Вложения

maiden666

Мастер
Рейтинг
112
#2
я не понимаю в скриптах, но занимаюсь частицами и алгоритмами
Если я правильно понял мысль, идея в том, чтобы частицы образовывались на склонах определённой крутизны?
В SoftimageICE я бы реализовал это так: у вертексов и поверхностей имеется атрибут Tangent ( касательная), если он меньше или больше определённого значения, то... ( по вашему выбору)
Думаю, в МаксСкрипт должен быть доступ к подобноиу атрибуту
 

Александр Якушев

Активный участник
Рейтинг
7
#3
В принципе почти правильно, за небольшим исключением. Если у нас, к примеру, елка или сложное дерево - одним склоном определенной крутизны не отделаетесь). Тут важно еще учитывать пересечение траектории снежинки (произвольного вектора) именно с первым полигоном. На нижние ярусы снег не должен проникать. Грубо говоря, если просто крутизну полика учитывать, то внутри елки тоже снега насыпет.
 
Сверху