Раскрашивание плоскости на основе пикселей текстуры

Используя шейдер, я пытаюсь раскрасить плоскость так, чтобы она воспроизводила пиксели текстуры. Текстура имеет размер 32x32 пикселя, а плоскость также имеет размер 32x32 в пространственных координатах.

Кто-нибудь знает, как мне проверить первый пиксель на текстуре, а затем использовать его, чтобы раскрасить первый квадрат (1x1) на плоскости?

Пример сгенерированной текстуры: (Первый пиксель специально красный)
введите описание изображения здесь

Этот код, использующий vec2 с координатами (0,0), работает не так, как я ожидал. Я предположил, что цвет в точке (0,0) будет красным, но это не так, он зеленый:

vec4 color = texture2D(texture, vec2(0, 0));

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

Если бы кто-нибудь мог мне помочь, я был бы очень признателен. Спасибо.


РЕДАКТИРОВАТЬ:
Спасибо за комментарии и ответы! Используя этот код, теперь он работает:

// Flip the texture vertically
vec3 verpos2 = verpos.xyz * vec3(1.0, 1.0, -1.0);

// Calculate the pixel coordinates the fragment belongs to
float pixX = floor(verpos2.x - floor(verpos2.x / 32.0) * 32.0);
float pixZ = floor(verpos2.z - floor(verpos2.z / 32.0) * 32.0);

float texX = (pixX + 0.5) / 32.0;
float texZ = (pixZ + 0.5) / 32.0;

gl_FragColor = texture2D(texture, vec2(texX, texZ));

Тем не менее, у меня проблема с неровными линиями по краям каждого «блока». Мне кажется, что у меня нет математики, и я не понимаю, какого цвета должны быть стороны, потому что у меня не было этой проблемы при использовании только цветов вершин. Может ли кто-нибудь увидеть, где я ошибся или как это можно было бы улучшить?
Еще раз спасибо!

введите описание изображения здесь


person Joey Morani    schedule 24.10.2013    source источник
comment
Если у вас GL-ES 3.0, вы можете использовать 'texelFetch' < / а>. В противном случае может помочь этот ответ.   -  person Brett Hale    schedule 24.10.2013
comment
Спасибо за ссылку. Очевидно, WebGL не поддерживает texelFetch, поэтому, к сожалению, я не могу его использовать :(   -  person Joey Morani    schedule 24.10.2013
comment
Я считаю, что система координат OpenGL ES начинается снизу слева - на iOS иногда необходимо переворачивать изображения по вертикали.   -  person Ben Pious    schedule 25.10.2013


Ответы (1)


Да ... как сказал Бен Пиус в комментарии, помните, что WebGL отображает 0,0 в нижнем левом углу.

Кроме того, для индексации текстур попробуйте взять образец из «середины» каждого пикселя. Для исходной текстуры 32x32, чтобы получить пиксель (0,0), вам нужно:

texture2D(theSampler, vec2(0.5/32.0, 0.5/32.0));

Или, в более общем смысле,

texture2D(theSampler, vec2((xPixelIndex + 0.5) / width, (yPixelIndex + 0.5) / height);

Это только в том случае, если вы явно обращаетесь к пикселям текстуры; если вы получаете значения, интерполированные и переданные из вершинного шейдера (скажем, квадрат от (-1, -1) до (1,1), и передайте различные vec2 ((x + 1) / 2, (y + 1) / 2) к фрагментному шейдеру), эта «середина каждого пикселя» отражается в вашем изменяющемся значении.

Но, вероятно, это просто Y-up, как говорит Бен. :)

person david van brink    schedule 24.10.2013
comment
Еще раз спасибо за ответ. : P Сделал то, что сказали вы и Бен Пиус, и теперь это работает, но возникла проблема с неровными линиями. Если вы снова хотите мне помочь, я отредактировал свой вопрос. :) - person Joey Morani; 25.10.2013
comment
Вернувшись в офис, я бы сказал, пожалуйста, закройте исходную ошибку как исправленную и отправьте новую для новой проблемы :-) Я не совсем уверен, что делает ваш новый код, но, возможно, все этажи и тому подобное не нужны ; они могут препятствовать интерполяции WebGL. Вы можете попробовать просто texture2D (texture, vec2 (verpos2.x, verpos2.z)); Похоже, они прибывают с диапазоном 0..31? - person david van brink; 26.10.2013
comment
Теперь это выяснилось. Спасибо, Дэвид. :) - person Joey Morani; 26.10.2013