Three.js: Запрос функции: повысить производительность обнаружения столкновений raycaster с помощью деревьев пространственного поиска.

Созданный на 11 дек. 2017  ·  36Комментарии  ·  Источник: mrdoob/three.js

Я создал VR-приложение, похожее на WebVR-Vive-Dragging , которое позволяет взаимодействовать с многочисленными 3D-объектами с помощью VR-контроллеров. Это означает, что пользователь может захватить объект с помощью VR-контроллера и может перемещать или масштабировать его.

Проблема : Когда в сцене есть сложные 3D-объекты, т.е. объекты THREE.Mesh , имеющие геометрию с очень большим количеством вершин, то рейкастинг во время обнаружения столкновений становится очень медленным. Значит, проблема в сложности геометрии одного объекта.

Существуют древовидные структуры данных для быстрого пространственного поиска, такие как Octree или R-Tree . Я нашел threeocttree , который позволяет разбивать геометрию на более мелкие фрагменты, но кажется, что он немного устарел (Three.js r60).

Насколько я вижу, в методе THREE.Mesh объекта raycast уже есть некоторые оптимизации производительности (сначала проверка ограничивающей рамки и сферы перед выполнением фактического raycast). Может быть, имеет смысл сделать еще один такой этап проверки с помощью деревьев пространственного поиска?! Как вы думаете?

С уважением

Enhancement

Самый полезный комментарий

В прошлом я предлагал включить пространственный индекс в threejs. В этом направлении была проведена некоторая работа, и существующий пример октодерева является одним из них. В конечном счете, я думаю, что это отсутствие интереса со стороны основного сообщества в отношении того, чтобы иметь эту функциональность как первоклассного гражданина из трех.

Я был бы рад пожертвовать свой код BVH проекту, если будет достаточный интерес и намерение включить его в основной дистрибутив (не в примеры).
Мой код фокусируется на двух аспектах:

  • динамичные сцены

    • быстрая вставка

    • быстрое удаление

    • переоснащение (способность узлов менять форму без повторной установки)

  • скорость запроса

У меня есть 2 реализации:

  • ДвоичныйBVH

    • очень компактный, с использованием ByteBuffer

    • сочетание типов UintX и FloatX через DataView

    • отлично подходит для сериализации

    • может быть сжат с помощью стандартных инструментов, таких как библиотека lzma

    • неизменный

    • скорость сборки оптимизирована

    • работает только для BufferGeometry

    • оптимизация SAH

    • лучевые запросы

  • БВХ

    • Дерево объектов, как следствие, намного больше, чем бинарная реализация.

    • изменчивый

    • быстрая объемная вставка

    • быстрая вставка одного элемента

    • переоборудование

    • стековая, рекурсивная и бесстековая реализации обхода (разные характеристики производительности)

    • оптимизация SAH

    • Усеченные запросы

    • Рэй запросы

Лично я не могу жить без пространственного индекса, это разница между производительностью n^2 и log(n). Например, в моем текущем проекте следующие части полагаются на пространственный индекс:

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

http://server1.lazy-kitty.com/komrade

Terrain имеет около 1 м полигонов, и размещение тысяч деревьев и запуск raycasts в реальном времени на нем просто недопустимо, особенно для младших устройств.

Все 36 Комментарий

Рискуя констатировать очевидное, но пробовали ли вы версию threeocttree , которая уже есть в репозитории ( examples/js/Octree.js )?

Я не поддерживаю аппаратное использование деревьев пространственного поиска в three.js . Накладные расходы/сложность таких алгоритмов перевешивают выигрыш в производительности во многих приложениях.

сначала проверьте ограничивающую рамку и сферу, прежде чем делать фактический raycast

Это разумно и должно быть достаточно. Если пользователям требуется более высокая производительность в контексте более сложных вариантов использования, они могут использовать упомянутый пример в качестве отправной точки. Octree может быть хорошим выбором. Но я никогда не видел решения R-Tree в интерактивных 3D-приложениях, потому что его подход довольно сложен (алгоритм выполняет данные вместо разделения пространства).

Здравствуйте и спасибо за ваши ответы,
@ Mugen87 Mugen87 Я согласен, что многие варианты использования не требуют такого быстрого поиска. Однако, имея механизм для взаимодействия с 3D-объектами (и я предполагаю, что это тот случай, для которого он в основном используется), шаг THREE.Raycaster от проверки ограничивающей рамки/сферы в первую очередь (что я полностью согласен с тем, что это разумно ) в скажем, от постоянного времени до линейного времени, когда выполнение фактического raycast довольно велико. Я мог бы представить своего рода «дерево поиска по геометрии» вместо одного глобального дерева поиска. Пока геометрия не изменяется (часто преобразования более вероятны, чем изменения геометрии), дерево поиска не нужно обновлять.

Вот почему я подумал, что такая оптимизация с использованием деревьев пространственного поиска может быть более неотъемлемой частью three.js . Но я также понимаю, что это вызывает дополнительную сложность и накладные расходы.

@moraxy Я посмотрю примерную версию. Я просто хотел знать, будет ли такая функция иметь смысл.

Еще раз спасибо и с уважением

Возможно, в THREE.BufferGeometry можно было бы интегрировать более простое дерево поиска. Например, вызов computeBoundingBox также может построить своего рода дерево поиска только для чтения, ссылающееся на соответствующие вершины. Так как THREE.BufferGeometry

лучше всего подходит для статических объектов, где вам не нужно много манипулировать геометрией после ее создания

это дерево поиска не нужно изменять после его инициализации. Это уменьшит некоторые накладные расходы на обновление/удаление. Octree будет хорошей отправной точкой ( аналогичная концепция в BabylonJS ).

лучше всего подходит для статических объектов, где вам не нужно много манипулировать геометрией после ее создания

FWIW, я не верю, что это верное утверждение.

@WestLangley Цитата из документации THREE.BufferGeometry

Документация THREE.BufferGeometry

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

Наверное надо удалить

Вероятнее всего.

Я только что реализовал лучший метод рейкастинга в PlaneBufferGeometry. Я использую параметр far и нахожу первую и последнюю позиции индекса. Это работает в planebuffer, потому что массив индексов находится в порядке x/y. После выхода за ограничительную рамку x/y все столкновения должны происходить за пределами дальнего диапазона. Есть ли желание это где-то зафиксировать? Текущая реализация специфична для моего варианта использования, но я хотел бы попытаться сделать ее более общей, если это необходимо. Мне удалось значительно снизить производительность рейкастинга на большом плоском буфере (от 2,5 секунд до 10 мс).

@kpetrow Я думаю, что примеров октодерева three.js достаточно. Вы, конечно, можете поделиться своим кодом на GitHub, если считаете, что он будет полезен другим.

В прошлом я предлагал включить пространственный индекс в threejs. В этом направлении была проведена некоторая работа, и существующий пример октодерева является одним из них. В конечном счете, я думаю, что это отсутствие интереса со стороны основного сообщества в отношении того, чтобы иметь эту функциональность как первоклассного гражданина из трех.

Я был бы рад пожертвовать свой код BVH проекту, если будет достаточный интерес и намерение включить его в основной дистрибутив (не в примеры).
Мой код фокусируется на двух аспектах:

  • динамичные сцены

    • быстрая вставка

    • быстрое удаление

    • переоснащение (способность узлов менять форму без повторной установки)

  • скорость запроса

У меня есть 2 реализации:

  • ДвоичныйBVH

    • очень компактный, с использованием ByteBuffer

    • сочетание типов UintX и FloatX через DataView

    • отлично подходит для сериализации

    • может быть сжат с помощью стандартных инструментов, таких как библиотека lzma

    • неизменный

    • скорость сборки оптимизирована

    • работает только для BufferGeometry

    • оптимизация SAH

    • лучевые запросы

  • БВХ

    • Дерево объектов, как следствие, намного больше, чем бинарная реализация.

    • изменчивый

    • быстрая объемная вставка

    • быстрая вставка одного элемента

    • переоборудование

    • стековая, рекурсивная и бесстековая реализации обхода (разные характеристики производительности)

    • оптимизация SAH

    • Усеченные запросы

    • Рэй запросы

Лично я не могу жить без пространственного индекса, это разница между производительностью n^2 и log(n). Например, в моем текущем проекте следующие части полагаются на пространственный индекс:

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

http://server1.lazy-kitty.com/komrade

Terrain имеет около 1 м полигонов, и размещение тысяч деревьев и запуск raycasts в реальном времени на нем просто недопустимо, особенно для младших устройств.

Я хотел бы увидеть что-нибудь, что оптимизирует raycast. Есть ли место для оптимизации без усложнения? Для Octree требуется вся новая библиотека со всеми новыми дополнениями, обновлениями и т. д.

Я заметил одну вещь: как только геометрия преобразуется в массив индексированных буферов, она больше не использует разумно свойства исходной геометрии. Как упоминалось выше, геометрия плоского буфера может быть супероптимизирована, зная, что arrayBuffer получен из PlaneGeometry. Может быть, перезаписать метод MESH.raycast ( raycaster, intersects ), чтобы он основывался на типе геометрии?

Другой подход состоит в том, чтобы использовать Raycaster в качестве отдельного плагина, как и интерактивные элементы управления и загрузчики. Затем было бы здорово добавить производительный рейкастер, аналогичный тому, что предлагает @Usnul .

Мне нравится идея иметь подключаемые рейкастеры, но я думаю, что здесь есть некоторая путаница. Что я считаю полезным, так это пространственный индекс, а не Raycaster как таковой. Пространственный индекс позволяет такие вещи, как:

  • пространственная выбраковка (например, выбраковка усеченной пирамиды)
  • выполнение запросов видимости
  • создание средства визуализации трассировки пути
  • быстрая сортировка (используя локальность данных)

в настоящее время three.js делает 2 из них явно (сортировка и отбраковка) и 1 через примеры (рендерер с трассировкой лучей)

поддержание внутреннего пространственного индекса ускорит сортировку и отбраковку, давая все больше преимуществ для больших сцен за счет дополнительной оперативной памяти, необходимой для хранения индекса.

Почему бы вам просто не использовать выбор GPU? Есть несколько примеров, и это довольно легко реализовать. Спектакль день и ночь. В наших примерах использования с моделями из более чем миллиона полигонов процесс выбора увеличился с почти секунды до работы в реальном времени со скоростью 60 кадров в секунду при перетаскивании объектов по модели.

https://github.com/brianxu/GPUPicker

@hccampos
Выбор графического процессора не обязательно быстрее, чем на процессоре, для графического процессора вы должны рендерить с разрешением, пропорциональным желаемой точности, поэтому, если вам нужна точность пикселей, вы должны рендерить с разрешением экрана 1: 1. Имейте в виду, что это отдельный проход рендеринга, вы визуализируете объекты как отдельные разные цвета. Дополнительный проход рендеринга означает использование графической памяти (типично для отложенного конвейера).
Использование индекса разделения двоичного пространства дает вам log(n) временной профиль при выборе, поэтому для 1 000 000 полигонов вам потребуется около 14 операций для разрешения запроса луча. В зависимости от вашей структуры данных это может занять несколько микросекунд, что позволит вам выполнить тысячи запросов, прежде чем вы начнете делать брешь в своем бюджете кадров.

Давайте проведем сравнение, скажем, у вас есть полигональная модель размером 1 м, и вы хотите направить луч из пространства экрана прямо вдоль направления камеры в сцену (выбор варианта использования). Предположим, вы используете минимальное разрешение, «full hd» или 1920 × 1080. Предположим, вы визуализируете только RGB (24 бита на пиксель), вам потребуется 6220800 байт (около 6 МБ) или графическая память для рендеринга. это. Если вы используете процессорное решение, скажем, вы используете AABB BVH с 10 полигонами на лист, это означает, что вам нужно около 200 000 узлов, скажем, каждый узел занимает около 6 * 8 байтов для координат, промежуточные узлы имеют дополнительные 2 * 4 байта для дочерних указателей. а листовые узлы имеют 10 * 4 байта для указателя полигона, это 14 400 000 байт (около 14 МБ). Основное отличие проявляется, когда вы принимаете во внимание тот факт, что ваши запросы BVH очень мало требуют пропускной способности ОЗУ по сравнению со случаем с графическим процессором, и в каждом запросе задействовано всего несколько операций по сравнению с рендерингом полной 1-метровой полигональной геометрии.
Если вы возьмете разрешение, более типичное для настольных компьютеров, например 2560x1440, вы получите цель рендеринга 11059200 байт (11 МБ).

Если у вас большой бюджет пропускной способности графического ОЗУ и довольно приличное количество шейдерных ядер — конечно, это простой и прямой способ выбора.

@Usnul абсолютно, но это, вероятно, самое простое решение для реализации. Внедрение и поддержка структур данных пространственного индекса, вероятно, будет значительным бременем для тех, кто занимается сопровождением threejs.

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

Мне было любопытно реализовать такой пространственный индекс для моих используемых геометрий, поэтому я реализовал довольно простое октодерево (только создание и поиск), которое разбивает мою BufferGeomtry. С помощью этого простого решения я добился довольно многообещающих результатов: применительно к геометрии с примерно 500 тысячами вершин время raycast сократилось с ~ 120 мс до ~ 2,3 мс. Построение дерева в настоящее время занимает ~500 мс, но поскольку геометрия и создание дерева выполняются внутри веб-воркера только один раз при запуске приложения, это не такая уж проблема.

Я предполагаю, что алгоритм может быть довольно легко интегрирован в THREE.BufferGeometry и может быть включен или выключен с помощью флага, такого как THREE.BufferAttribute dynamic . Таким образом, его можно использовать только тогда, когда BufferGeometry не должен меняться. К сожалению, мне пришлось перезаписать метод THREE.Mesh raycast , хотя мне нужно было изменить в нем только две строки (вызов поиска Octree и итерация массива позиций).

В любом случае, в моем VR-приложении я должен обнаруживать столкновения объект-контроллер во время цикла рендеринга, а не только один раз при щелчке мыши. Таким образом, я должен полагаться на мое текущее решение. Я постараюсь, если я могу еще улучшить его.

ОБНОВЛЕНИЕ Я сделал ошибку при измерении времени raycast. Правильное значение составляет ~2,3 мс (вместо ~0,3 мс). Я изменил значение выше соответственно.

Я думаю, что в большинстве более сложных приложений, построенных на основе three.js, необходим способ быстрого пространственного поиска. Например, 3D-редактор. Я поигрался с некоторыми реализациями, но они либо плохо интегрируются, либо слишком тесно связаны с конкретной версией three.js. Поэтому, если у кого-то есть способ сделать это, не нарушая путь обновления до более новых версий three.js, это было бы здорово.

@matthias-w Я попробовал raycaster для модели obj, но контроллер ничего не обнаруживает. Лучи проходят сквозь модель. Можешь рассказать как ты решил эту проблему

По поводу наличия дополнительного пространственного индекса. Я считаю, что достаточно полезно даже для самого рендерера (например, для отбраковки) быть неотъемлемой частью движка. Вот соответствующее обсуждение:

13909

Привет! Я тоже был немного заинтересован в этом (хотя с тех пор я нашел другие решения для наших нужд raycast), но я решил, что тоже внесу свой вклад в некоторые из своих экспериментов. Это немного грубо, но я собрал это несколько месяцев назад:

https://github.com/gkjohnson/threejs-fast-raycast

Он добавляет функцию computeBoundsTree к трем объектам геометрии и переопределяет функцию raycast для ее использования (и возвращает только первое попадание в качестве дополнительной оптимизации). Это действительно полезно только для статических, очень сложных сеток и ничего не делает для пространственного сегментирования сцены. Вот демонстрация , где вы можете увидеть разницу в производительности raycast на 80 000 треугольных сетках. Вычисление дерева границ немного медленное, но с небольшой доработкой оно, вероятно, могло бы быть более плавным.

Что касается моего мнения по этому поводу, я чувствую себя немного противоречивым. Это похоже на то, что можно построить как расширение THREE. И, в конечном счете, не похоже, что выполнение проверок/столкновений/приведения для каждого треугольника для сложных или анимированных сеток в любом случае оптимально. В простых случаях это может быть хорошо, но кажется, что использование типичных представлений плоскости / куба / сферы / капсулы или упрощенных сеток лучше подходит для обеспечения сверхбыстрого рейкастинга (или отсечения окклюзии, коллизий и т. д.) в сложных случаях. Конечно, если вы ищете идеальные до пикселя отливки, это не так хорошо работает, но правильное решение действительно зависит от вашего варианта использования.

@Usnul @matthias-w Являются ли ваши реализации octree/BVH открытым исходным кодом или доступны в Интернете? Мне определенно было бы интересно взглянуть!

@gkjohnson

Являются ли ваши реализации octree/BVH открытым исходным кодом или доступны в Интернете? Мне определенно было бы интересно взглянуть!

В настоящее время код не является открытым исходным кодом. Я могу предоставить вам источники, если вы свяжетесь со мной в частном порядке.

Вот пример, который я сделал для инстансированных сеток:
http://server1.lazy-kitty.com/tests/instanced-foliage-1mil/
Приведенный выше пример включает следующее:

  • BVH обновляется динамически по мере добавления в дерево новых экземпляров.
  • BVH оптимизируется постепенно, используя 1-2 оборота глубины на лету.
  • BVH отбирается с запросом в виде усеченной вершины, в какие экземпляры следует отображать

У меня есть версия, работающая в игре, над которой я работаю:
http://server1.lazy-kitty.com/komrade/

Что касается вашей реализации. Мне это нравится, мой отличается двумя основными способами:

  • Я ориентируюсь на производительность
  • Я сосредотачиваюсь на памяти
  • Я избегаю сбора мусора во многих местах

Еще несколько конкретных моментов:

  • Я также прозрачно использую смесь стратегий разделения в зависимости от того, что вы хотите делать с BVH.
  • Мой BVH основан на AABB
  • Я поддерживаю обновления границ узла путем переоснащения

@Usnul Я не вижу вашего адреса электронной почты или чего-то еще, но мне очень интересно изучить ваше решение для пространственного индексирования.

В настоящее время я просто перебираю все соответствующие объекты сцены и вычисляю расстояние от камеры. Не самый оптимальный подход.

@титансофтиме
это
travnick at gmail com
Не знал, что его нет в открытом доступе. Виноват.

@Usnul Меня тоже интересует проект на 1 миллион. Возможно, даже 10 или 20 миллионов, если это возможно. Пожалуйста, напишите мне: kaori.nakamoto. [email protected]

Спасибо ОЧЕНЬ любезно!

Извините за поздний ответ.
@gkjohnson Код не является открытым исходным кодом. Кроме того, ваше решение звучит намного сложнее, чем мое. Таким образом, я думаю, что из моего решения можно не так уж многому научиться.

@ sid3007 Я не уверен, что понимаю вашу проблему. Я могу объяснить свой подход. Может быть, это полезно.

Мой вариант использования довольно прост. Когда мое приложение запускается, загружаются геометрии для разных моделей. Эти модели могут быть преобразованы пользователем. Геометрия не меняется. Деформаций геометрии нет. Поэтому я реализовал очень простое октодерево, которое строится один раз для каждой геометрии при запуске приложения. Октодерево не является динамическим. Он строится на основе ограничивающей рамки заданной геометрии и массива вершин. Во время построения он проверяет, содержит ли октант вершину или пересекается ли ограничительная рамка Box3 октанта с треугольником (три последовательные вершины в неиндексированной геометрии), и сохраняет ссылки на массив вершин с узлом октанта.
Затем октодерево для сетки сохраняется вместе с сеткой. Я также перезаписываю метод raycast THREE.Mesh экземпляров сетки (всего одну строку), чтобы фактически вызывать метод проверки пересечения октодерева. Это возвращает индексы вершин граней геометрии, которые могут использоваться логикой пересечения сетки по умолчанию.
Я сделал одну оптимизацию: создание октодерева выполняется один раз при запуске приложения внутри WebWorker (на самом деле это пул воркеров). Причина в том, что создание дерева для больших геометрий занимает довольно много времени (несколько секунд). Это заблокировало бы пользовательский интерфейс браузера, поэтому я переместил его в другой поток.
Надеюсь, мой подход станет ясным.

@matthias-w Звучит как отличная работа! Я независимо сделал почти то же самое, но не думаю, что добился почти такого же значительного улучшения производительности. https://discourse.threejs.org/t/octree-injection-for-faster-raytracing/8291/2 (реализация объектно-ориентированного октодерева и менее чистые модификации Mesh.raycast)

Не могли бы вы открыть исходный код/внести вклад в реализацию Octree, позволяя другим экспериментировать?

@EliasHasle Спасибо. На самом деле, прирост производительности не так уж и хорош, так как я ошибся в своих первых измерениях. Я исправил значение (см. мой пост выше). Теперь тайминги имеют больше смысла в связи с логарифмической сложностью поиска Octree. К сожалению, я не могу сделать код доступным в данный момент, но, возможно, позже в этом году. Во всяком случае, моя реализация довольно проста (и не такая чистая, кстати;)). Так что, думаю, никаких особых инсайтов не будет.

@matthias-w Я думаю, что 2,3 мс против 120 мс для raycast на сетке вершин 500 тыс. По-прежнему является значительным улучшением, которое, например, обеспечивает разрешение выпущенных пуль в играх в реальном времени (при довольно большой части вычислений бюджет на кадр).

Вы тоже пробовали трассировку лучей?

Ваша реализация основана на дереве объектов JS? Буквальные объекты или экземпляры прототипа? Мой полностью самоподобен, так что каждый узел представляет собой октодерево с методами и всем остальным.

@ЭлиасХасле

Если вы заинтересованы в рейкастинге по статической геометрии, я и другие приложили значительные усилия к three-mesh-bvh , который использует BVH для индексации треугольников и обеспечивает высокопроизводительный рейкастинг, а также обнаружение пересечений со статической сложной геометрией. Процесс построения дерева более сложен, поэтому он занимает немного больше времени, но сокращает время рейкастинга до миллисекунды и часто до 0,1 мс при рейкастировании по геометрии с сотнями тысяч треугольников.

Время сборки можно было улучшить несколькими способами, но оно было достаточно хорошим для того, что я хотел с ним сделать — улучшение этого есть в списке.

Я хотел бы построить динамическое октодерево на основе сцен, чтобы обеспечить лучшее raycasting и обнаружение столкновений для сцен с большим количеством сеток, но у меня самого не было хорошего варианта использования. Возможно когда-нибудь!

@EliasHasle Моя реализация представляет собой дерево объектов класса JS (я использую классы ES6, т.е. экземпляры-прототипы). По сути, в моей реализации узел — это дерево. Однако у меня есть дополнительный класс Octree, который содержит корневой узел и предоставляет методы для построения и поиска (а также некоторой отладки и визуализации) дерева.

Я не особо экспериментировал со значениями максимального уровня узла дерева и максимального количества вершин на листовой узел. Возможно, есть лучшая комбинация.
Я также использую иерархию ограничивающих объемов для ускорения тестов пересечения. Поэтому я проверяю ограничивающую сферу и ограничивающую рамку меша, прежде чем проверять октодерево геометрии меша.

Я могу порекомендовать книгу, которая представляет собой очень хороший сборник подходов к обнаружению столкновений: C. Ericson, Real-Time Collision Detection, CRC Press, 2004.

@gkjohnson Выглядит великолепно! Спектакль впечатляет. Какой БВХ вы используете?

@matthias-w Спасибо!

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

@gkjohnson Итак, реализация BVH представляет собой своего рода несбалансированное Kd-дерево с выбором оси, зависящим от формы коробки, верно? Если да, то я думал сделать что-то подобное для случаев, когда корень ББ был слишком далеко от куба, а затем использовать октодеревья после условного разбиения. Это, по-видимому, хорошо применимо к таким случаям, как мир карт @Usnul , где начальное разделение будет происходить в двух измерениях «карты», а последующее разделение будет происходить в 3D. Я думаю, что это гораздо лучшее решение, чем мое, которое состоит в том, чтобы расширить корневой BB до ограничивающего куба с тем же центром, а затем полностью использовать разбиение октодерева.

Я только что реализовал лучший метод рейкастинга в PlaneBufferGeometry.

@kpetrow Я думаю, что при оптимизации raycasts на PlaneBufferGeometry предположение о том, что позиции вершин не будут изменены, скорее всего, не будет действительным для геометрий с высоким разрешением, где линейного поиска недостаточно. Насколько я могу судить, основное использование PlaneBufferGeometry с высоким разрешением заключается в изменении его формы путем перемещения вершин при сохранении топологии, например, для построения ландшафта.

Закрытие в пользу #13909.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги