Copy to Points и инстансинг: размещение множества объектов
core Скопировать объект на точки другой геометрии, управляя размером, ориентацией и вариантом через атрибуты, созданные в VEX, и выбрать copy или instance по требованиям к памяти
Copy to Points — узел с двумя ролями входов: геометрия-шаблон (то, что копируем) и геометрия-цели (точки, на которые копируем). Для каждой точки цели узел создаёт экземпляр шаблона и трансформирует его по атрибутам этой точки. По сути это for (p : target_points) instantiate(template, p) — но с важным отличием от обычного цикла: то, как трансформировать копию, определяется атрибутами точки, а не кодом узла.
Атрибуты точек, которые Copy to Points читает по соглашению об именах:
@P— позиция копии;@Nи@up— ориентация через пару «направление + верх» (аналогlookat), либо@orient— кватернион, если нужна полная свобода поворота (он приоритетнее@N/@up);@pscale— равномерный масштаб копии (или@scaleкак vector для неравномерного);- атрибут-«piece» (по умолчанию обычно называют
@variant) — выбор одного из нескольких вариантов шаблона на разных точках.
Второй ключевой момент — разница между реальным копированием и инстансингом через packed primitives. Копии создают независимые геометрические объекты, тогда как инстансы ссылаются на исходную геометрию и экономят память. Без упаковки узел разворачивает полную геометрию шаблона в каждой точке — точки, примитивы и атрибуты шаблона умножаются на количество целевых точек. С включённым «Pack and Instance» каждая копия становится packed-примитивом: лёгкой оболочкой с трансформом, ссылающейся на одно общее описание геометрии. Это прямая аналогия указателя на структуру против глубокого копирования структуры.
// без packing — глубокая копия
for each point p in target_points:
new_geo = deep_copy(template)
transform(new_geo, p.P, p.orient, p.pscale)
append(output, new_geo)
// с packing — общая ссылка + трансформ
for each point p in target_points:
instance = InstanceRef(template_id, p.P, p.orient, p.pscale)
append(output, instance)
Для геймдева (тысячи растений, камней, обломков) packing почти всегда предпочтителен — иначе память и время кука растут пропорционально числу копий × сложности шаблона. Реальные копии нужны тогда, когда каждый экземпляр потом редактируется индивидуально (не просто трансформом), например деформируется отдельно.
graph LR
A["Точки: @P @pscale @orient @variant"] --> B[Copy to Points]
C[Шаблон геометрии] --> B
B --> D{Pack and Instance?}
D -->|Нет| E["Полные копии: N × геометрия"]
D -->|Да| F["Packed instances: ссылка на 1 шаблон × N"]Разобранный пример
Нужно раскидать камни по террейну: 3 модели-варианта, случайный масштаб и поворот вокруг вертикальной оси.
- Scatter создаёт точки на поверхности террейна.
- Attribute Wrangle на точках:
@pscale = fit01(rand(@ptnum), 0.6, 1.4);
float ang = rand(@ptnum + 17) * 2 * PI;
@orient = quaternion(ang, {0,1,0});
@variant = int(rand(@ptnum * 3.1) * 3); // 0..2
- Три модели камней выбираются либо через Switch, управляемый значением
@variant, либо подаются одним входом как несколько отдельных кусков (packed), а нужный кусок выбирается по атрибуту-«piece». - Copy to Points с включённым Pack and Instance.
Рассуждение: @orient через кватернион полностью определяет поворот без явного @N/@up, @pscale даёт разброс размеров, @variant — визуальное разнообразие; packing держит память на уровне одного шаблона на вариант, независимо от числа точек.
Попробуй сейчас
Создайте Grid, разбросайте на нём точки (Scatter, ~2000 точек). В Attribute Wrangle задайте @pscale = fit01(rand(@ptnum), 0.5, 1.5) и @orient через случайный поворот вокруг Y. Скопируйте на них сферу через Copy to Points. Сравните геометрию в Geometry Spreadsheet и в Node Info при выключенном и включённом Pack and Instance — обратите внимание на число точек и примитивов.
Ожидаемый результат: без packing число примитивов ≈ 2000 × примитивы сферы; с packing — 2000 лёгких packed-примитивов, ссылающихся на одну сферу.
Получилось, если…
Вы поняли тему, если можете объяснить: почему при включении Pack and Instance число точек и примитивов на выходе резко падает (вместо N × геометрия шаблона остаётся N packed-примитивов), и в каком случае вам всё равно нужен реальный copy, а не instance.
Вывод
@pscale/@orient (или @N+@up)/@variant — единый интерфейс управления копиями через данные, а не код узла. Packed primitives = общая ссылка на геометрию + трансформ, реальный copy = дублирование данных; для больших количеств в играх и ТВ почти всегда нужен инстансинг.
AI-generated · source-grounded review
🛡 Fact-checked: 2 risky claims verified · 4 removed · confidence: medium · figures: 1
A second opinion has not checked this lesson.
On your own course these buttons answer instantly, quizzes track what you've mastered, and lessons adapt to your gaps. Write my course