Артефакт границы в пиксельном шейдере GLSL

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

Код:

precision mediump float;

uniform sampler2D Texture0;
uniform int pixelCount;
varying vec2 fTexCoord;

void main(void)
{
   float pixelWidth = 1.0/float(pixelCount);

   float x = floor(fTexCoord.x/pixelWidth)*pixelWidth + pixelWidth/2.0;
   float y = floor(fTexCoord.y/pixelWidth)*pixelWidth + pixelWidth/2.0;

   gl_FragColor = texture2D(Texture0, vec2(x, y));
}

Пожалуйста, смотрите прикрепленное изображение.

Я понятия не имею, почему это происходит.
Пожалуйста, помогите мне с этим...

Граница артефакта между пикселизациями.


person CuriousChettai    schedule 12.07.2012    source источник


Ответы (1)


Я думаю, что ваша проблема связана с интерполяцией текстур.

Используете ли вы GL_NEAREST для своих сэмплеров текстур (это заставляет сэмплер текстур использовать точечный сэмплер вместо некоторой интерполяции)?

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

Также вам, вероятно, не следует использовать MIP-карты.

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

person Mortennobel    schedule 12.07.2012
comment
Вы были правы насчет Mipmaps.‹br› Проблема не в фильтрации. но мипмапы есть. ‹br›Но я до сих пор не понимаю, почему мипмапы делают этот артефакт. Может ли кто-нибудь объяснить теорию, стоящую за этим? - person CuriousChettai; 13.07.2012
comment
Проблема в том, что при создании MIP-карт (таких как gluBuild2DMipmaps) функция использует некоторую интерполяцию для получения хорошо выглядящих уменьшенных изображений. Но в некоторых случаях это не работает: иногда вы хотите сохранить острые края (как вы), а иногда значения в текстурах не являются цветами и не могут использовать линейную интерполяцию (в этом случае текстура сохраняет карту нормалей). . В этих случаях вы должны генерировать уровни MIP-карт вручную (или вообще не использовать MIP-карты). - person Mortennobel; 13.07.2012
comment
Спасибо, Мортеннобель. ‹br/› У моего любопытного ума все еще есть вопросы. ‹br/›Если это из-за отфильтрованных текселей из MIP-карты, то почему артефакт ограничивается только границами. Уровень MIP-карты должен обслуживать пиксели в некоторой непрерывной области до тех пор, пока текселы не станут достаточно малы для следующего уровня MIP-карты; правильно? - person CuriousChettai; 13.07.2012
comment
Я все еще хотел бы знать, содержит ли ваш скриншот только один квадрат или 9 квадратов? Также я предполагаю, что ваша текстура только RGB, а не RGBA (с альфа-значением). - person Mortennobel; 13.07.2012
comment
Чтобы ответить на ваш последний вопрос: да, мипмэппинг обслуживает значение пикселя из ближайшего уровня мипмапа (или интерполирует между двумя ближайшими уровнями мипмапа). В любом случае проверьте следующие ссылки - это может вам помочь: opengl.org/wiki/Common_Mistakes#Creating_a_Texture и opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation - person Mortennobel; 13.07.2012
comment
Спасибо, Мортеннобель. Это одиночный квадроцикл; а текстура в формате RGB. - person CuriousChettai; 13.07.2012