Нужна ли мне информация о треугольнике в моем поверхностном шейдере?

Обновить

Основной вопрос заключается в следующем: как я могу передать позиции вершин мирового космического треугольника в поверхностный шейдер в шейдере Unity. Как уже упоминалось в комментарии, может быть возможно передать их из геометрического шейдера. Но я где-то читал, что реализация пользовательского геометрического шейдера перезаписывает логику Unity s для вычисления теней и т. Д. Я бы добавил информацию о треугольнике в структуру Input. Но прежде чем изменить логику генерации сетки, я бы хотел узнать, возможно ли это. Для этого решения положения вершин треугольника должны быть постоянными для каждого пикселя в треугольнике и не должны быть интерполированы.

Это оригинальный вопрос:

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

В поверхностном шейдере мне нужны 3 вершины, которые определяют треугольник и их идентификаторы текстуры. Кроме того, мне нужно положение пикселя, который я рисую.

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

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

Но я не уверен, возможно ли это с тем, как работают поверхностные / вершинные шейдеры. Есть ли связь между вершиной и пикселем для получения информации о моем произвольном треугольнике? Есть ли лучший способ сделать это?

Я использую Unitys ShaderLab для своих шейдеров.

2 ответа

Решение

Хорошо, я думаю, что нашел решение. Спасибо за комментарии, они где полезны.

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

vertexColor.r = vertexTextureId0; // Texture to use for vertex 0
vertexColor.g = vertexTextureId1; // Texture to use for vertex 1
vertexColor.b = vertexTextureId2; // Texture to use for vertex 2

Мне не нужно беспокоиться об интерполяции, потому что все вершины треугольника имеют одинаковую информацию о цвете. Теперь я создаю текстуру, чтобы определить, к какой вершине принадлежит мой пиксель. Эта текстура похожа на изображения, которые я разместил в вопросе. Я должен транспонировать координаты УФ в соответствии с ДВУМ или ТРИ случая. Это решение дает мне свободу легко изменить край и сделать его более рваным.

Нет, вы не должны (и не должны) использовать данные вершин в фрагментном шейдере. В фрагментном шейдере у вас есть доступ только к данным о данном пикселе, вы не можете вернуться назад и посмотреть на сетку, которая его сформировала (так устроен конвейер).

То, что вы можете сделать (и это обычная практика), - это запекать данные в один из доступных каналов (то есть в другие каналы UV Mapping) вершин в вершинном шейдере. Таким образом, шейдер Fragment будет иметь доступ к значению через интерполяторы.

Другие вопросы по тегам