2013-10-24 3 views
2

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

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

Сгенерированные текстуры Пример: (Первый пиксель красный на цели)
enter image description here

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

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

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

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


EDIT:
Спасибо за комментарии и ответы! Используя этот код, он сейчас работает:

// 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)); 

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

enter image description here

+0

Если у вас есть GL-ES 3.0, вы можете использовать ['texelFetch'] (http://www.khronos.org/opengles/sdk/docs/manglsl/xhtml/texelFetch.xml). В противном случае ответ [this] (http://stackoverflow.com/questions/5879403/opengl-texture-coordinates-in-pixel-space) может помочь. –

+0

Спасибо за ссылку. По-видимому, WebGL не поддерживает texelFetch, поэтому, к сожалению, я не могу это использовать :( –

+2

Я считаю, что система координат OpenGL ES начинается с нижнего левого края - на iOS, иногда необходимо вертикально переворачивать изображения. –

ответ

2

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

Кроме того, для индексирования в свои текстуры попробуйте выполнить выборку из «середины» каждого пикселя. На источнике 32х32 текстуры, чтобы получить пиксель (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, как говорит Бен. :)

+0

Еще раз спасибо за Отвечая.: P Сделал то, что вы и Бен Пойдж сказал, и он работает сейчас, но имеет проблемы с зубчатыми линиями.Если вы готовы помочь мне снова, я отредактировал свой вопрос. :) –

+0

Вернувшись в офис, я бы поставил: «PLS закрывает исходную ошибку как исправленную, и файл новый для новой проблемы» :-) Я не совсем уверен, что делает ваш новый код, но, возможно, все полы и т. д. не нужны; они могут препятствовать интерполяции WebGL. Вы можете попробовать только texture2D (текстура, vec2 (verpos2.x, verpos2.z)); Похоже, что они входят с диапазоном 0..31? –

+1

Получил это сейчас. Спасибо Дэвиду. :) –