Нахождение длины луча в кубе - PullRequest
1 голос
/ 22 ноября 2010

У меня есть луч, идущий наружу от камеры, мне нужно найти длину луча внутри куба.Обратите внимание, что камера может находиться внутри куба, и в этом случае она должна возвращать расстояние до края куба.

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

Есть идеи?

Ответы [ 2 ]

4 голосов
/ 22 ноября 2010

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

Предположим, что луч начинается в q и имеет направление r . Тогда любая точка на луче может быть представлена ​​как q + t r для скалярного параметра t . Теперь предположим, что мы хотим пересечь этот луч с плоскостью, заданной уравнением p · n = k (где n - это внешний -установка нормальная к лицу). Луч пересекает плоскость, когда

( q + t r ) · n = k

То есть, когда

q · n + t r · n = k

и так

t = ( k - q · n ) / r · n

Луч входит в лицо, когда r · n отрицательно, и выходит, когда r · n положительно. Когда r · n равно нулю, луч параллелен лицу. Вы должны проверить этот случай, чтобы избежать деления на ноль; и в этом случае, если q · n > k , луч полностью пропускает многогранник.

Итак, найдите t для всех граней вашего многогранника и пусть t в будет максимальным t для точек, где луч входит в лицо, и t out будет минимальным t для точек, где луч выходит из лица. Тогда длина луча внутри многогранника равна

max (max ( t out , 0) - max ( t in , 0), 0) / | г |

Если r - единичный вектор, вы можете избежать деления здесь. Два внутренних максимума ( t , 0) необходимы для обработки случая, когда камера находится внутри куба или куб находится позади камеры. Внешний максимум (..., 0) предназначен для обработки случая, когда луч полностью не попадает в куб (в этом случае t в будет больше t из ).

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

2 голосов
/ 22 ноября 2010

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

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

  1. Нет пересечения
  2. Одно пересечение - вы находитесь внутри куба, вычислите расстояние между пересечением и положением камеры
  3. Два пересечения - вы находитесь за пределами куба, рассчитайте расстояние между двумя пересечениями
  4. Бесконечно много пересечений - вектор представления является касательной к кубу, просто отбросьте пересечения касательной плоскости и возьмите только два пересечения с двумя соседними плоскостями

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...