Как получить информацию о пикселях внутри фрагментного шейдера? - PullRequest
26 голосов
/ 20 марта 2012

В моем фрагментном шейдере я могу загрузить текстуру, а затем сделать это:

uniform sampler2D tex;

void main(void) {
   vec4 color = texture2D(tex, gl_TexCoord[0].st);
   gl_FragColor = color;
}

Устанавливает для текущего пикселя значение цвета текстуры. Я могу изменить их и т. Д., И это хорошо работает.

Но несколько вопросов. Как мне сказать, «какой» пиксель я? Например, скажем, я хочу установить пиксель 100,100 (x, y) на красный. Все остальное к черному. Как мне сделать:

"если currentSelf.Position () == (100,100); тогда цвет = красный; иначе цвет = черный?"

Я знаю, как устанавливать цвета, но как мне получить «мое» местоположение?

Во-вторых, как мне получить значения из соседнего пикселя?

Я пробовал это:

vec4 nextColor = texture2D(tex, gl_TexCoord[1].st);

Но не ясно, что он возвращает? если я пиксель 100,100; как я могу получить значения от 101 100 или 100 101?

Ответы [ 2 ]

30 голосов
/ 20 марта 2012

Как мне сказать, "какой" я пиксель?

Вы не пиксель.Вы фрагмент .Есть причина, по которой OpenGL называет их «Фрагментные шейдеры»;это потому что они не пиксели пока .Действительно, они не только не могут стать пикселями (с помощью discard или тестов глубины или чего-либо еще), благодаря мультисэмплингу, несколько фрагментов могут объединяться в один пиксель.

Если вы хотитечтобы узнать, где находится ваш фрагментный шейдер в пространстве окна, используйте gl_FragCoord.Позиции фрагментов являются значениями с плавающей запятой, а не целыми числами, поэтому вам нужно тестировать с диапазоном вместо одного значения «100, 100».

Во-вторых, как получить значения из соседнего пикселя?

Если вы говорите о соседнем пикселе кадрового буфера, вы не .Фрагментные шейдеры не могут произвольно считывать данные из кадрового буфера, либо в своей собственной позиции, либо в соседнем.

Если вы говорите о доступе к соседнему texel из того, к которому вы обращались, то этопросто смещение координаты текстуры, которую вы передаете texture2D.Вы должны получить размер текстуры (так как вы не используете GLSL 1.30 или выше, вы должны передать это вручную), инвертировать размер и либо добавить, либо вычесть эти размеры из компонента S и T координаты текстуры.

3 голосов
/ 31 октября 2017

Легкий горох.

Просто рассчитайте размер пикселя в зависимости от разрешения. Затем посмотрите вверх +1 и -1.

vec2 onePixel = vec2(1.0, 1.0) / u_textureSize;
gl_FragColor = (
   texture2D(u_image, v_texCoord) +
   texture2D(u_image, v_texCoord + vec2(onePixel.x, 0.0)) +
   texture2D(u_image, v_texCoord + vec2(-onePixel.x, 0.0))) / 3.0;

Вот хороший пример здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...