Чтобы пересечь луч с выпуклым многогранником, пересечь луч с плоскостями, содержащими каждую грань.
Предположим, что луч начинается в точке 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 · п
Луч входит в грань, когда r · n имеет отрицательное значение, и выходит, когда r · n является положительным. Когда r · n равно нулю, луч параллелен грани. Вам нужно проверить этот случай, чтобы избежать деления на ноль; и в этом случае, если q · n > k, луч полностью проходит мимо многогранника.
Итак, найдите t для всех граней вашего многогранника и пусть tin будет максимальным t для точек где луч входит в грань, а tout – минимальное значение t для точек, в которых луч выходит из грани. Тогда длина луча внутри многогранника равна
max(max(tвыход, 0) − max(tвход, 0), 0) / | р|
Если r является единичным вектором, вы можете избежать деления здесь. Два внутренних значения max(t, 0) необходимы для обработки случая, когда камера находится внутри куба или куб находится за камерой. Внешний max(..., 0) предназначен для обработки случая, когда луч полностью проходит мимо куба (в этом случае tin будет больше, чем твыход).
Боюсь, я понятия не имею, как представить это вычисление на вашем языке шейдеров, не говоря уже о том, как сделать это без ответвлений.
person
Gareth Rees
schedule
22.11.2010