glBlendFunc и альфа-смешивание - PullRequest
       4

glBlendFunc и альфа-смешивание

1 голос
/ 06 сентября 2011

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

В конце все проходы должны быть объединены в один выход.Чтобы объединить все проходы, я думал об использовании glblendfunc, но я не получил желаемый результат.

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//use first shader
draw();
if (secondShaderWished) {
    //use second shader
    draw()
}

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

Чтоя должен делать?Есть ли что-то еще, кроме alphablending?

Редактировать: Моя цель - объединить один или несколько проходов.Я хочу смешать цвета (скорее всего, сложив их вместе), поскольку цвет каждого пути рассчитывается с помощью следующей функции смешивания для разных слоев: glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)

* 1011РЕДАКТИРОВАТЬ: Привет еще раз!Я работаю над этой проблемой, но я застрял.Я не понимаю, как правильно установить sampler2d в любом шейдере ... Что я делаю не так?
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _FBO)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _Tex);
glViewport(0, 0, viewportSize.x(), viewportSize.y());
draw();
GLuint texLocation = glGetUniformLocation(_shader->getProgramID(),"pass0");
glUniform1i(texLocation, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

Ответы [ 2 ]

1 голос
/ 07 сентября 2011

Благодаря вашему комментарию вы можете просто визуализировать каждый проход по отдельности в текстуру (лучше всего это сделать с помощью FBOs ), используя необходимую функцию смешивания.Затем вы можете смешивать различные проходы вместе в одном проходе, просто рисуя квадрат размером с экран и усредняя все текстуры проходов вместе в фрагментном шейдере.

РЕДАКТИРОВАТЬ: Согласно вашему комментарию,Вы отрисовываете эти проходы индивидуально непосредственно в текстуру (которая связана как вложение FBO) каждый.Затем вы используете фрагментный шейдер, подобный этому, с квадратом размером с экран, предполагая, что у вас есть три прохода:

uniform sampler2D pass0;
uniform sampler2D pass1;
uniform sampler2D pass3;
uniform vec2 screenSize;

void main()
{
    vec2 texCoord = gl_FragCoord.xy / screenSize;
    gl_FragColor = (1.0/3.0) * (texture2d(pass0, texCoord) + 
                                texture2d(pass1, texCoord) + 
                                texture2d(pass2, texCoord));
}

EDIT: В качестве альтернативы вы можете использовать простой фрагментный шейдер с 1 текстурой(он просто ищет цвет из одной текстуры и выводит его) и рисует несколько текстурированных квадов, используя конфигурацию смешивания Тобиаса.Это также может лучше масштабироваться, если число проходов не известно априори.

0 голосов
/ 07 сентября 2011

Я думаю, что вы не хотите использовать альфа-значения текстур в качестве коэффициента смешения, а скорее постоянный коэффициент, который дает вам смешение 1: 1.

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

float factor = 1.0f / numTextures;
glBlendColor(factor, factor, factor, factor);
glBlendFunc(GL_CONSTANT_COLOR, GL_ONE);

Для 3 слоев, которые станут:

             source        dest
1st pass: (tex1 * 1/3) + (0 * 1)
2nd pass: (tex2 * 1/3) + (tex1 * 1/3 * 1)
3rd pass: (tex3 * 1/3) + ((tex2 * 1/3 + tex1 * 1/3) * 1)

Также помните, что альфа-смешение зависит от порядкаработа.

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