
В уроке 4 мы выпустили коралл тремя слоями geo, mtl и xform. Теперь собираем из них риф на всю секвенцию, сотни кораллов на земле. Если скопировать геометрию на каждую точку, файл будет весить как все копии вместе. Поэтому геометрию в файл рифа не пишем.

В файле рифа нет ни одного меша. Только точки, а кораллы приходят из своих слоев.
1. Ссылки и инстансы
SubLayer из урока 4 ставит коралл туда же, где он записан в файлах, в /World/env/corals. А для рифа он нужен в /protos, где лежат образцы для копий. Это умеет ссылка.
Ссылка (reference) ставит в нашу сцену один прим из другого файла, по любому пути. В наш файл пишется только адрес этого прима. Это буква R в LIVERPS из урока 1.

В примере пять видов кораллов, а на рифе их много много. Каждый вид ставим один раз, ссылками на его слои, а риф собираем из копий. USD держит каждый вид в памяти один раз, сколько бы копий ни стояло.
Образец, с которого делают копии, называется прототипом, а копия инстансом. Место, поворот и размер у инстанса свои, а геометрия и материал общие.
Инстансы расставляет PointInstancer. Весь риф в нем записан массивами чисел, поэтому файл легкий даже на тысячах копий. Но отдельный коралл уже не прим, в дереве его не выбрать.
PointInstancer это один прим на все копии. В нем точки, и у каждой номер прототипа, место, поворот и размер.
2. Сетап по нодам
Сцена рифа собрана в /stage, цифры показывают порядок нод.
1. SubLayer со скелетом и Reference с землей.
2. Layer Break. Все, что выше, в файл рифа не попадет.
3. Primitive делает ветку /World/env/reef с kind group.
4. Reference ставит прототипы кораллов.
5. PointInstancer собирает риф по точкам из SOP.
6. USD ROP пишет файл рифа. Свет на отдельной ветке, только для просмотра.
Точки готовим в SOP, цифры показывают порядок нод.
1. LOP Import берет землю из /stage, Unpack USD делает из нее полигоны.
2. Grid делает поле рифа над землей.
3. Ray опускает поле на землю.
4. Normal и Scatter and Align раскладывают точки по склону.
5. Attribute Randomize задает размер коралла.
6. Attribute Randomize задает вид коралла.
7. Null отдает точки в PointInstancer.
Grid задает поле рифа, Ray кладет его на землю из второго входа.
1. В Size размер поля, в примере 120×120 м.
2. Center ставим выше земли, в примере 20 по Y.
3. Rows и Columns ставим погуще, чтобы сетка легла по рельефу.
4. В Direction Source ставим Vector, иначе луч летит по нормали сетки, а не вниз.
5. В Direction пишем 0, -1, 0, строго вниз.
Scatter and Align сыплет точки с orient, по нему коралл встанет по склону и повернется.
1. В Point Count Method ставим Number of Points, в Total Points число кораллов.
2. Orientation › Rotation › Max Random Cone Angle дает легкий наклон, в примере 6.
3. Там же в Rotation Around Normal › Max Angle ставим 360.
Remove Overlapping Points не включаем, иначе точек станет меньше.
Attribute Randomize дает каждой точке свой размер коралла.
1. В Attribute Name пишем pscale, его PointInstancer прочитает как размер.
2. Dimensions ставим 1, размер одним числом.
3. Min Value и Max Value задают разброс, в примере от 8 до 14. Сами ассеты кораллов 15‑30 см и на таком поле потерялись бы, а так вырастают до нескольких метров.
Вторая Attribute Randomize выбирает вид коралла на каждой точке, без VEX и кучи кода бебебе.
1. В Attribute Name пишем protoname.
2. В Distribution ставим Custom Discrete.
3. Type ставим String, Number of Values по числу видов.
4. В Value имя прототипа, coral_mushroom и другие, в Weight доля этого вида. Имена те же, что у примов в /protos.
В SOP нет ни одного коралла. Только точки, а на них размер, поворот и имя коралла.
Reference ставит прототипы в ветку /protos. PointInstancer скопирует их к себе, а сама ветка в файл не попадет.
1. Number of References ставим по две на коралл (mtl, geo).
2. В Primitive Path у обеих /protos/coral_mushroom.
3. В File Pattern geo‑слой в первой, mtl‑слой во второй.
4. В Reference Primitive ставим Reference Specific Primitive и путь к самому кораллу, а не к /World.
PointInstancer ставит прототипы на точки из SOP.
1. В Primitive Path пишем /World/env/reef/corals.
2. Primitive Kind ставим Group, иначе порвется цепочка моделей.
3. В Prototypes › Source › Primitives все прототипы из второго входа.
4. SOP Source ставим External SOP, в SOP Path последний Null сети точек.
5. Point Attributes to Copy очищаем, иначе атрибуты точек попадут в файл как primvars.
6. Prototype Index ставим String Attribute, в поле рядом уже protoname.



