Процедурная генерация гальки на мобильном устройстве

Соло, почасовая оплата. Unity, URP, PCG in runtime, iOS, Android, UnityasaLibrary (React Native, iOS).

Процедурная генерация гальки на мобильном устройстве: её формы, рисунков на поверхности и других особенностей (например, цвета подповерхностного рассеяния). Результат случаен, но (при равном значении seed) одинаков на любом устройстве. После пары секунд на генерацию полученную гальку можно вращать пальцем. Эта Unity-сцена встраивается в React Native приложение на iOS.

Около 90 часов ушло чисто на то, что видно на скриншотах. Около 90 часов ушло на то, что не видно на них: встраивание в React Native, оптимизация под мобильные, обход проявляющихся только на телефонах багов в Unity, мобильный ввод, внутренние инструменты.

Проект был приостановлен в пользу более критичных приоритетов головного проекта. О последнем я ничего не знаю, потому что этот компонент просто должен создавать случайные аватарки, что полностью изолировано от необходимости знать контекст, то есть не было смысла прибегать к NDA.

Реализация

Рисунок на поверхности работает не через UV-развёртку, а опирается напрямую на 3D координату точки поверхности. Для неконтрастного (едва заметного) базового шума используется трипланарная проекция.

Контрастные (более заметные) рисунки (полосы и пятна) работают через изменённый (подробности ниже) под нужды проекта 2D Signed Distance Field. Двумерное поле с полосами проецируется напрямую, с применением шума к параметрам. Двумерное поле с пятнами повторяется многократно, с применением шума к параметрам каждого повторения.

Чтобы можно было использовать 2D поле в роли 3D поля, и при этом без искажений, пришлось расстояния в поле считать от центров/середин, а не границ. То есть, более точно было назвать такое поле «Central Distance Field». (Недостаток в том, что для этого центр/середины должны существовать, но большинство рисунков гальки можно сгенерировать через добавление шума к имеющим центр/середину фигурам: кругам и линиям.)

Наибольший «подводный камень»

Два бага в нодах Shader Graph (другими словами, в библиотеке функций для шейдеров), проявляющийся только при запуске на телефоне. Для обоих багов, чтобы найти конкретную ноду, выдающую неожиданный результат, пришлось многократно ждать медленный процесс построения проекта с последующим запуском на телефоне. Также пришлось сделать интерфейс (для себя), позволяющий отключать отдельные шейдеры непосредственно на телефоне, чтобы ждать меньше перезапусков.

Долгие ожидания я не считал как время работы, если не работал над чем-то другим в этом же проекте параллельно. (Если бы я засчитал эти часы, то к упомянутым выше 180 часам добавилось бы ещё где-то 30.)