UpPetto

This is a real course generated by UpPetto — unedited.

AI-generated. Two models wrote it, a third checked every risky claim against sources, a fourth re-checked.

Create my own course

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"]
Поток данных Copy to Points: атрибуты точки управляют трансформом, флаг packing переключает между реальным копированием и инстансингом.

Разобранный пример

Нужно раскидать камни по террейну: 3 модели-варианта, случайный масштаб и поворот вокруг вертикальной оси.

  1. Scatter создаёт точки на поверхности террейна.
  2. 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
  1. Три модели камней выбираются либо через Switch, управляемый значением @variant, либо подаются одним входом как несколько отдельных кусков (packed), а нужный кусок выбирается по атрибуту-«piece».
  2. 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
[verified] Copy to Points читает @P, @N/@up, @orient, @pscale/@scale для трансформа копий, @orient приоритетнее @N/@up
стандартное соглашение об именах атрибутов Houdini; база знаний подтверждает управление трансформациями через атрибуты (@P и др.)
[verified] Инстансы (packed primitives) ссылаются на общую геометрию и экономят память, реальные копии дублируют данные
прямо подтверждено разделом о copy vs instancing в базе знаний
[removed] Варианты шаблона можно подавать как несколько входов Copy to Points
механизм не подтверждён; заменён на Switch по атрибуту либо атрибут-piece на packed-кусках
[removed] При включении Pack and Instance число точек не меняется, падает только число примитивов/память
неверно: относительно небакованных копий падает и число точек; формулировка исправлена
[softened] Память и время кука растут линейно с числом копий × сложность шаблона
точная линейность не подтверждена базой; заменено на «пропорционально»
[removed] «либо подаются как несколько входов в Copy to Points, если узел это поддерживает напрямую» — заменено на корректный механизм выбора варианта (Switch по атрибуту либо атрибут-piece на packed-кусках)
[removed] «при включении Pack and Instance число точек не меняется» — фактически неверно относительно небакованных копий; переформулировано (падает и число точек, и примитивов)
[removed] «память и время кука растут линейно» — смягчено до «пропорционально», без утверждения о строгой линейности
[removed] «@variant — атрибут, который вы связываете со Switch/множеством входов» — уточнено как атрибут-piece с именем по умолчанию

A second opinion has not checked this lesson.

Key concepts: Copy to Points инстансинг и packed primitives @pscale/@orient/@N оптимизация памяти
Tell me more 🔒 Didn't understand — explain simply 🔒 Show examples 🔒 Sources 🔒

On your own course these buttons answer instantly, quizzes track what you've mastered, and lessons adapt to your gaps. Write my course

Check yourself

1. Какой атрибут точки задаёт равномерный масштаб копии в Copy to Points?
2. Что происходит с памятью при включении Pack and Instance по сравнению с обычным копированием?
3. В каком случае реальный copy предпочтительнее инстансинга?
On your own course, these are marked as you answer