Как сделать билинейную интерполяцию нормалей по квадру?

Я работаю над Minecraft-подобным движком в качестве хобби-проекта, чтобы увидеть, насколько далеко концепция воксельных ландшафтов может быть продвинута на современном оборудовании и OpenGL> = 3. Итак, вся моя геометрия состоит из квадратов или квадратов, если быть точным.

Я построил raycaster для оценки окружающей окклюзии и использую технику «изогнутых нормалей» для освещения. Так что мои нормали не перпендикулярны четырехугольнику, и при этом они не имеют единичной длины; скорее, они указывают приблизительно в пространство, где происходит наименьшее количество окклюзии, и короче, когда квад получает меньше света Преимущество этого метода заключается в том, что он требует единовременного вычисления окклюзии и является практически свободным во время визуализации.

Однако у меня возникают проблемы, когда я пытаюсь назначить разные нормали разным вершинам одного и того же четырехугольника, чтобы получить плавное освещение. Поскольку четырехугольник разбит на треугольники, и линейная интерполяция происходит по каждому треугольнику, результат интерполяции ясно показывает наличие треугольников в виде некрасивых диагональных артефактов:

Проблема в том, что OpenGL использует барицентрическую интерполяцию по каждому треугольнику, которая представляет собой взвешенную сумму по 3 из 4 углов. В идеале я хотел бы использовать билинейную интерполяцию, где все 4 угла используются для вычисления результата.

Я могу придумать некоторые обходные пути:

Сложите нормали в RGB-текстуру 2x2, и пусть текстурный процессор выполняет билинейную интерполяцию. Это происходит за счет поиска текстуры в фрагментном шейдере. Мне также нужно упаковать все эти мини-текстуры в более крупные для эффективности.

Используйте атрибуты вершины, чтобы прикрепить все 4 нормали к каждой вершине. Также прикрепите несколько коэффициентов [0..1] к каждой вершине, очень похоже на координаты текстуры, и выполните билинейную интерполяцию в шейдере фрагмента. Это происходит за счет передачи 4 нормали шейдеру вместо 1.

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

(Обратите внимание, что проблема не является специфической для нормалей; она в равной степени применима к цветам или любым другим значениям, которые необходимо плавно интерполировать по четырем.)

Есть идеи, как еще подойти к этой проблеме? Если нет, какой из двух методов выше будет лучше?

Ответы на вопрос(2)

Ваш ответ на вопрос