Один прямоугольник (два соединенных квадрата) с двумя текстурами — ошибка с общей границей

У меня прямоугольник состоит из двух четырехугольников (8 вершин, я использую индексированные треугольники):

------+------
| \   | \   |
|  \  |  \  |
|   \ |   \ |
______+______

У меня также есть две текстуры для этого. Я связываю их обоих с шейдером.

Я хочу текстурировать одну часть прямоугольника (левый квад) с первой текстурой, а другую часть — со второй.

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

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

Говоря в основном: у меня есть модель и преимущество. Этот край говорит, где текстура меняется. Но как достичь этой цели? Когда я устанавливаю texture1 или texture2 на вершинах этого ребра, возникают некоторые ошибки.

0

Решение

Я думаю, что ваш подход неверен. Условное ветвление в шейдерах замедлит ваши шейдеры, и их следует избегать, когда это возможно. Это объясняется тем, что шейдеры оптимизированы для параллельного выполнения одного и того же кода для каждого пикселя. Если вы поместите условия в шейдер в зависимости от реализации карты grphics, произойдет одно из следующих действий: Либо шейдер выполнит обе ветви условия и выберет соответствующий путь для каждого пикселя после выполнения, либо все пиксели будут ждать до самого длинного пути. выполнения условия завершено, прежде чем продолжить.

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

Я могу думать о двух возможных подходах (может быть больше):

  1. Первый и самый простой — нарисовать два четырехугольника, каждый со своей текстурой. Это правда, что вы будете вызывать свой шейдер дважды, но я не вижу какого-либо реального замедления, так как точное число пикселей все равно рисуется.
  2. Второй подход несколько сложнее, но позволит вам рисовать только один раз. Что вам нужно сделать, это создать одну большую текстуру, содержащую две текстуры, расположенные рядом с другой, и сопоставить всю текстуру со всей полосой треугольника. Таким образом, средство визуализации позаботится о том, чтобы каждый квад имел свою «собственную» текстуру. С OpenGl это делается с помощью glTexSubimage2D, В Direct3D 9 это сложнее, и вы используете следующую последовательность:

    А. Создайте текстуру, используя CreateTexture

    B. Получить поверхность для уровня 0, используя IDirect3DTexture9::GetSurfaceLevel()

    C. Загрузите изображение на поверхность, используя D3DXLoadSurfaceFromMemory()

    D. Освободите поверхность

Таким образом, вы отображаете горизонтальные координаты текстуры от 0 до 0,5 с вершинами первого квада и координаты от 0,5 до 1 с вершинами второго квада. Если квадраты не имеют одинаковый размер или текстуры не одинакового размера, вы просто меняете отображение соответствующим образом

Если вы настаиваете на использовании ветки условия в своем шейдере, вы должны помнить, что речь идет о столбце пикселей, а не только о двух вершинах (в конце концов, это пиксельный шейдер), поэтому вам следует проверить все пиксели. Это может быть проблемой, поскольку у вас нет способа узнать результат преобразования для каждого пикселя, если нет преобразования. Лучше не запрашивать значения вершин в пиксельных шейдерах.

Надеюсь, что это приведет вас на правильный путь

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]