До сих пор не верю, что мой
последний пост в тви про трассировку лучей собрал больше трех тысяч лайков, принес более 400 подписчиков и просто был добавлен в закладки более тысячи раз
Ну и раз эта тема столь интересна, я считаю, что должен продолжить. В прошлом посте я рассказывал о гибриде разных методов бросания лучей для отрисовки в один проход вокселей, SDF, гауссин и так далее. В этом посте я коротко поясню о том, как это работает (в приложенном видео анимация работы алгоритма) + дам необходимые ссылки ниже
1. Видимый мир
В данном на видео демо все, что мы рисуем, состоит из двух вещей: воксели и sdf (гладкие формы, шары, скругленные тела и не только). Мир гибридный — кубики и гладкие фигуры живут вместе в одной сетке. И на первом шаге мы строим эту сетку, определяя в какой клетке какие воксели или фигуры находятся. Важно заметить, что одна фигура может занимать несколько клеток, а несколько фигур могут занять одну клетку
2. Пирамида
Чтобы не проверять каждую клетку по отдельности (их миллионы), мы строим над сеткой пирамиду. Делим мир на более крупные ячейки и для каждой запоминаем всего одно: есть внутри хоть что-нибудь или там пусто. Потом объединяем ячейки по четыре в более крупные, и так уровень за уровнем. Получается "карта заполненности", где пустые области отваливаются целыми кусками, а в заполненных ячейках могут содержаться воксели и/или фигуры
3. Лучи
Теперь пускаем луч. Луч идет по пирамиде сверху вниз: попал в крупную пустую ячейку — перепрыгнул ее целиком одним шагом, не тратя время. Попал в заполненную — спускаемся на уровень мельче и смотрим внимательнее. Дошли до вокселей — включаем ray casting. Дошли до гладкой фигуры — включаем ray marching, пока не приблизимся на минимальную необходимую дистанцию или пролетим мимо. Так луч быстро проскакивает пустоту и быстро находит воксель или фигуру, в которую вероятнее всего упрется
Помимо вокселей и sdf сюда же могут идти отдельные модели с собственной воксельной сеткой, объемные гауссины, частицы и так далее. В каждом отдельном случае используется необходимый способ бросания луча или комбинация несколькольких
В демо на видео мне удалось в 60fps отрисовывать 1 073 741 824 цветных вокселя и около 100 простых sdf без использования GPU на обычном canvas 2d context (javascript)