OpenGL - текстурный атлас "смазывание" - PullRequest
2 голосов
/ 04 августа 2011

Я использую текстурный атлас, который я сделал, соединив 2 изображения одинакового размера вместе друг с другом. Когда я изменяю координаты текстуры, я делаю следующее в следующем порядке:

  1. if(texCoordx>1) texCoordx = texCoordx % 1 - Таким образом, одна текстура не проникает в другую.
  2. if(texCoordx<0) texCoordx = 1 + texCoordx - Опять же, поэтому одна текстура не проникает в другую.
  3. Масштабировать координаты текстуры на 0,5.
  4. Добавьте 0,5, если хотите нарисовать текстуру справа.

Это работает в основном нормально, однако, я, кажется, получаю «пятно» по краям, где текстура s приближается к 1 и 0. Похоже, что она смазывается вдоль t ось. Я приложил скриншот.

Image smudged at border

Я знаю, что был найден один ответ здесь , но это лишь немного сужает пятно. Я использую свой собственный шейдер, но он не изменяет координаты текстуры. Я также включаю GL_REPEAT. Кто-нибудь знает какие-либо возможные причины / решения?

1 Ответ

4 голосов
/ 04 августа 2011

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

0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2

после того, как вы завернули в шаге 1, теперь у вас есть что-то вроде

0.2, 0.4, 0.6, 0.8, 1, 0.2, 0.4, 0.6, 0.8, 1

, который впоследствии стал

0.1, 0.2, 0.3, 0.4, 0.5, 0.1, 0.2, 0.3, 0.4, 0.5

Здесь мы видим проблему в 0,5, 0,1, где монотонность изменяется. OpenGL не знает, что вы хотите перейти от 0,5 до 0,1 влево-вправо. Он просто берет разницу, которая составляет -0,4, и таким образом интерполирует справа налево назад к началу текстуры (и, следовательно, сжимает всю текстуру внутри этого небольшого интервала назад, поэтому вдоль оси t это действительно правильно). Это связано с тем, что OpenGL не знает, что ваша текстура переносится в середине текстуры, так как концептуально она видит только одну большую текстуру, а не атлас маленьких текстур, а режим обтекания GL_REPEAT работает только на край большой текстуры.

Вы должны выполнить перенос (первые два шага) в фрагментном шейдере, прежде чем получить доступ к текстуре. Таким образом, ваши координаты текстуры являются монотонными и корректно интерполируются. Затем на фрагмент вы можете смело оборачивать координаты текстуры На самом деле вы можете сделать все шаги во фрагментном шейдере. Просто дайте ему униформу для смещения внутри атласа (выбирая фактическую суб-текстуру). Затем вы делаете обтекание, масштабирование и добавление смещения непосредственно перед доступом к текстуре.

...