Найдите, какие объекты 3D камера может видеть в Three.js - Raycast от каждой камеры к объекту

У меня есть сетка точек (object3D с использованием THREE.Points) в моей сцене Three.js с моделью, расположенной поверх сетки, как показано ниже. В коде модель называется default mesh и использует объединенную геометрию для повышения производительности:

модель

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

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

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

gridPointsVisible = gridPoints.geometry.vertices.slice(0);
startPoint = camera.position.clone();

//create the rays from each point in the grid to the camera position
for ( var point in gridPoints.geometry.vertices) {
    direction = gridPoints.geometry.vertices[point].clone();
    vector.subVectors(direction, startPoint);
    ray = new THREE.Raycaster(startPoint, vector.clone().normalize());

    if(ray.intersectObject( defaultMesh ).length > 0){
        gridPointsVisible.pop(gridPoints.geometry.vertices[point]);
    }
}

В показанном примере модели создается около 2300 лучей, а сетка имеет 1500 граней, поэтому рендеринг занимает вечность.

Итак, у меня 2 вопроса:

  1. Есть ли лучший способ найти, какие объекты видит камера?
  2. Если нет, могу ли я ускорить проверку лучей / пересечений?

Заранее спасибо!


person Joe Morgan    schedule 13.03.2018    source источник
comment
Взгляните на этот пример выбора графического процессора: threejs.org/examples/webgl_interactive_cubes_gpu.html You можно было бы сделать что-то подобное, особенно простое, поскольку у вас есть конечный и упорядоченный набор сфер. Идея состоит в том, что вы должны использовать шейдер для вычисления (возможно, на основе позиции) плоского цвета для каждой сферы и рендеринга в цель рендеринга за пределами экрана. Затем вы проанализируете данные целевого объекта рендеринга на предмет цветов и сможете снова отобразить их на свои сферы. Любые видимые цвета также являются видимыми сферами. Все оставшиеся сферы скрыты. Этот метод должен давать результаты быстрее, чем raycasting.   -  person TheJim01    schedule 14.03.2018
comment
Спасибо за комментарий @ TheJim01, однако я не уверен, что полностью понимаю. Что вы имеете в виду под целью рендеринга вне экрана и что вы имеете в виду, отображая данные обратно на сферы? Спасибо   -  person Joe Morgan    schedule 14.03.2018
comment
WebGLRenderTarget позволяет рисовать в буфер без рисования на холсте. Что касается сопоставления, вы проанализируете целевой буфер рендеринга и создадите список всех уникальных цветов, которые вы видите (все несферические объекты должны быть другого плоского цвета). Затем вы можете прокручивать свои сферы в цикле - и вы должны знать, какого цвета должна быть каждая сфера, с тем же расчетом цвета, что и используемый шейдер. Если цвет сферы находится в вашем списке найденных цветов, то эта сфера видна. Имеет ли это смысл?   -  person TheJim01    schedule 14.03.2018
comment
Спасибо @ TheJim01. Я потратил все утро на реализацию модифицированной версии этого примера. Проблема, с которой я столкнулся, заключается в том, что он невероятно медленно проходит через целевой буфер рендеринга, поскольку он содержит каждый пиксель на экране (в отличие от всего одного пикселя под мышью в этом примере). Любые идеи?   -  person Joe Morgan    schedule 15.03.2018
comment
1) Вы можете уменьшить разрешение цели рендеринга. Вы можете потерять очки, видимые только по щепкам, но вы можете настроить разрешение в соответствии со своими потребностями. 2) Если у вас меньше 256 точек, вы можете использовать только красные значения, что уменьшает количество проверенных значений до 1 из каждых 4 (проверяйте только R пикселя RGBA). Если вы выйдете за пределы 256, включите проверку значений зеленого и так далее.   -  person TheJim01    schedule 15.03.2018
comment
@ TheJim01, сейчас все реализовано и работает отлично. Если вы поставите свой комментарий в качестве ответа, я могу отметить его как правильный. Большое спасибо за Вашу помощь   -  person Joe Morgan    schedule 16.03.2018


Ответы (1)


Взгляните на этот пример выбора графического процессора.

Вы можете сделать что-то подобное, особенно просто, поскольку у вас есть конечный и упорядоченный набор сфер. Идея состоит в том, что вы должны использовать шейдер для вычисления (возможно, на основе позиции) плоского цвета для каждой сферы и рендеринга в цель рендеринга за пределами экрана. Затем вы проанализируете данные целевого объекта рендеринга на предмет цветов и сможете снова отобразить их на свои сферы. Любые видимые цвета также являются видимыми сферами. Все оставшиеся сферы скрыты. Этот метод должен давать результаты быстрее, чем raycasting.

WebGLRenderTarget позволяет рисовать в буфер без рисования на холсте. Затем вы можете получить доступ к буферу изображения целевой рендеринга попиксельно (на самом деле по цвету в RGBA).

Для сопоставления вы проанализируете этот буфер и создадите список всех уникальных цветов, которые вы видите (все несферические объекты должны быть другого плоского цвета). Затем вы можете прокручивать свои точки в цикле - и вы должны знать, какого цвета должна быть каждая сфера, с тем же расчетом цвета, что и используемый шейдер. Если цвет точки находится в вашем списке найденных цветов, то эта точка видна.

Чтобы оптимизировать эту идею, вы можете уменьшить разрешение цели рендеринга. Вы можете потерять очки, видимые только по щепкам, но вы можете настроить разрешение в соответствии со своими потребностями. Кроме того, если у вас меньше 256 точек, вы можете использовать только красные значения, что уменьшает количество проверенных значений до 1 из каждых 4 (проверяйте только R пикселя RGBA). Если вы выйдете за пределы 256, включите проверку значений зеленого и так далее.

person TheJim01    schedule 16.03.2018