Как сделать трассировку лучей в современном OpenGL?
Так что я нахожусь в точке, где я должен начать освещать свои плоско окрашенные модели. Тестовое приложение является тестовым примером для реализации только новейших методов, поэтому я понял, что в идеале оно должно реализовывать трассировку лучей (поскольку теоретически оно может быть идеальным для графики в реальном времени через несколько лет).
Но с чего мне начать?
Предположим, что я никогда не работал с освещением в старом OpenGL, поэтому я бы обратился непосредственно к не осуждаемым методам.
В настоящее время приложение правильно настроило объекты буфера вершин, ввод вершин, нормалей и цветов, и оно правильно рисует и преобразует модели в пространстве, в плоский цвет.
Есть ли источник информации, который бы брал один из плоских вершин во все, что необходимо для правильного конечного результата через GLSL? В идеале с любыми другими дополнительными методами освещения, которые могут потребоваться для его дополнения.
6 ответов
Я бы не советовал пробовать реальную трассировку лучей в OpenGL, потому что для этого нужно много хаков и хитростей, и, если вы спросите меня, нет никакого смысла делать это вообще. Если вы хотите выполнить трассировку лучей на GPU, вам следует использовать любой язык GPGPU, такой как CUDA или OpenCL, потому что он делает вещи намного проще (но все-таки далеко не тривиальными).
Чтобы проиллюстрировать проблему немного подробнее: для трассировки лучей вам необходимо отследить вторичные лучи и проверить их на пересечение с геометрией. Следовательно, вам необходим доступ к геометрии каким-то хитрым способом внутри вашего шейдера, однако внутри фрагментного шейдера вы не сможете получить доступ к геометрии, если не сохраните ее "закодированной" в какой-либо текстуре. Вершинный шейдер также не предоставляет вам эту информацию о геометрии изначально, а геометрические шейдеры знают только соседей, поэтому проблема уже начинается. Далее, вам нужны ускоряющие структуры данных, чтобы получить любую разумную частоту кадров. Однако обходить, например, Kd-Tree внутри шейдера довольно сложно, и, если я правильно помню, есть несколько статей, посвященных исключительно этой проблеме. Если вы действительно хотите пойти по этому пути, тем не менее, есть много статей на эту тему, их не должно быть слишком сложно найти.
Трассировщик лучей требует чрезвычайно хорошо спроектированных схем доступа и кэширования для достижения хорошей производительности. Тем не менее, у вас мало контроля над этим внутри GLSL, и оптимизация производительности может быть очень сложной.
Еще один момент, на который следует обратить внимание: по крайней мере, насколько мне известно, трассировка лучей в реальном времени на графических процессорах в основном ограничена статическими сценами, потому что, например, kd-деревья работают (хорошо) только для статических сцен. Если вы хотите иметь динамические сцены, вам нужны другие структуры данных (например, BVH, iirc?), Но вы должны постоянно поддерживать их. Если я ничего не пропустил, то сейчас еще много исследований по этому вопросу.
Вы можете путать некоторые вещи.
OpenGL - растеризатор. Заставить его сделать трассировку лучей возможно, но сложно. Вот почему raytracing не "идеален для графики в реальном времени через несколько лет". Через несколько лет только гибридные системы будут жизнеспособными.
Итак, у вас есть три возможности.
- Чистая трассировка лучей. Визуализируйте только полноэкранный четырехугольник, и в своем фрагментном шейдере прочитайте описание сцены, упакованное в буфер (например, текстуру), пройдите по иерархии и вычислите пересечения лучей и треугольников.
- Гибридная трассировка лучей. Растеризуйте вашу сцену обычным способом и используйте трассировку лучей в вашем шейдере в некоторых частях сцены, которые действительно в этом нуждаются (рефракция,... но это может быть симулировано при растеризации)
- Чистая растеризация. Фрагмент шейдера выполняет свою обычную работу.
Что именно вы хотите достичь? Я могу улучшить ответ в зависимости от ваших потребностей.
Во всяком случае, этот вопрос так тесно связан. Даже если эта конкретная реализация имеет ошибку, это определенно путь. Другая возможность - openCL, но концепция та же.
Opengl и glsl можно использовать как для трассировки лучей, так и для трассировки путей, если вы действительно хороши в этом. однако есть несколько других лучших вариантов, таких как Nvidia Optix с набором инструментов Cuda, DirectX 12, трассировка лучей vulkan, металл, falcor. Обратите внимание, что все это низкоуровневые API, которые могут обеспечить хорошую производительность с новейшей технологией Nvidia rtx и поддержкой нескольких графических процессоров.
Что касается 2019, трассировка лучей является опцией для рендеринга в реальном времени, но требует высокопроизводительных графических процессоров, которых у большинства пользователей нет. Некоторые из этих графических процессоров разработаны специально для трассировки лучей. OpenGL в настоящее время не поддерживает аппаратное усиление трассировки лучей. DirectX 12 на Windows имеет поддержку для этого. Рекомендуется подождать еще несколько лет, прежде чем создавать средство визуализации только с трассировкой лучей, хотя это возможно при использовании DirectX 12 с текущим оборудованием для настольных компьютеров и ноутбуков. Поддержка с мобильного может занять десятилетия. Я не вижу OpenGL, поддерживающего трассировку лучей, но Vulkan может в будущем поддержать его.
Я нашел некоторые другие ответы подробными и многословными. Для наглядных примеров, которые ДА, функциональные трассировщики лучей МОГУТ быть построены с использованием OpenGL API, я настоятельно рекомендую проверить некоторые проекты, которые люди делают на https://www.shadertoy.com/ (Предупреждение: задержка)
Чтобы ответить на тему: у OpenGL нет расширения RTX, а у Vulkan есть, и взаимодействие возможно. Пример здесь: https://github.com/nvpro-samples/gl_vk_raytrace_interop
Что касается самого вопроса: для освещения треугольников существует множество методов, ищите средства визуализации «вперед», «вперед +» или «отложенный». Используемая техника зависит от вашей цели. Самым простым и красивым в наши дни является освещение на основе изображения (IBL) с физически основанным затенением (PBS). По сути, вы используете кубическую карту и размываете ее более или менее в зависимости от степени глянца объекта. Для простого средства просмотра объектов большего и не нужно.