Нужна ли мне информация о треугольнике в моем поверхностном шейдере?
Обновить
Основной вопрос заключается в следующем: как я могу передать позиции вершин мирового космического треугольника в поверхностный шейдер в шейдере Unity. Как уже упоминалось в комментарии, может быть возможно передать их из геометрического шейдера. Но я где-то читал, что реализация пользовательского геометрического шейдера перезаписывает логику Unity s для вычисления теней и т. Д. Я бы добавил информацию о треугольнике в структуру Input. Но прежде чем изменить логику генерации сетки, я бы хотел узнать, возможно ли это. Для этого решения положения вершин треугольника должны быть постоянными для каждого пикселя в треугольнике и не должны быть интерполированы.
Это оригинальный вопрос:
Я пишу шейдер поверхности для треугольной сетки. Я установил пользовательский атрибут вершины с идентификатором текстуры для каждой вершины. Теперь я хочу, чтобы шейдер поверхности применил текстуру, как показано на следующем изображении. (Обратите внимание, что каждый цвет представляет текстуру)
В поверхностном шейдере мне нужны 3 вершины, которые определяют треугольник и их идентификаторы текстуры. Кроме того, мне нужно положение пикселя, который я рисую.
- Если все идентификаторы текстуры одинаковы, я выбираю эту текстуру для всех пикселей.
- Если один или два идентификатора текстуры различаются, я вычисляю расстояние в пикселях до вершин треугольника и выбираю текстуру, как показано на следующем изображении:
Поверхностный шейдер должен знать треугольник пикселей. С этой логикой я должен получить затенение, которое я ищу. Я создаю свою сетку программно, чтобы я мог добавить вершины треугольника и их идентификаторы текстуры в качестве атрибутов вершины и передать его в поверхностный шейдер.
Но я не уверен, возможно ли это с тем, как работают поверхностные / вершинные шейдеры. Есть ли связь между вершиной и пикселем для получения информации о моем произвольном треугольнике? Есть ли лучший способ сделать это?
Я использую 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 будет иметь доступ к значению через интерполяторы.