Я работаю над Minecraft-подобным движком в качестве хобби-проекта, чтобы увидеть, насколько далеко концепция воксельных ландшафтов может быть продвинута на современном оборудовании и OpenGL> = 3. Итак, вся моя геометрия состоит из четырехугольников или квадратов длябыть точным.
Я построил raycaster для оценки окружающей окклюзии и использую технику "изогнутых нормалей" для освещения.Так что мои нормали не перпендикулярны четырехугольнику, и при этом они не имеют единичной длины;скорее, они примерно указывают на пространство, где происходит наименьшее количество окклюзии, и короче, когда квад получает меньше света.Преимущество этого метода заключается в том, что он просто требует однократного вычисления окклюзии и практически свободен во время рендеринга.
Однако у меня возникают проблемы, когда я пытаюсь назначить разные нормали разным вершинамтот же квадроцикл, чтобы получить плавное освещение.Поскольку четырехугольник разбит на треугольники, и линейная интерполяция происходит по каждому треугольнику, результат интерполяции ясно показывает наличие треугольников в виде некрасивых диагональных артефактов:
Проблема в том, что OpenGL использует барицентрическую интерполяцию по каждому треугольнику, которая является взвешенной суммой по 3 из 4 углов.В идеале, я хотел бы использовать билинейную интерполяцию, где все 4 угла используются для вычисления результата.
Я могу придумать несколько обходных путей:
- * 1015нормали в RGB-текстуру 2x2, и пусть текстурный процессор выполняет билинейную интерполяцию.Это происходит за счет поиска текстуры в фрагментном шейдере.Мне также нужно упаковать все эти мини-текстуры в более крупные для эффективности.
Используйте атрибуты вершины, чтобы прикрепить все 4 нормали к каждой вершине.Также прикрепите несколько коэффициентов [0..1] к каждой вершине, очень похоже на координаты текстуры, и выполните билинейную интерполяцию в шейдере фрагмента.Это происходит за счет передачи 4 нормалей шейдеру вместо 1 *. 1020 *
Я думаю, что оба эти метода можно заставить работать, но они кажутся мне клочьями для чего-то, что должнобыть намного прощеМожет быть, я мог бы как-то преобразовать нормали, чтобы интерполяция OpenGL давала результат, который не зависит от конкретной используемой триангуляции.
(Обратите внимание, что проблема не является специфичной для нормалей; она в равной степени применима к цветам илилюбое другое значение, которое должно быть плавно интерполировано через квад.)
Есть идеи, как еще подойти к этой проблеме?Если нет, какой из двух методов выше будет лучше?