Эффект трейлов, очистка буфера кадра с прозрачным квад - PullRequest
1 голос
/ 05 июля 2019

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

Все работает хорошо, движущиеся частицы производят длинные следы, КРОМЕ черного квада не очищает FBO до идеального нуля.Слабые следы остаются навсегда (например, RGBA буфера = 4,4,4,255).

Я предполагаю, что проблема начинается, когда функция смешивания умножает небольшие значения 8-битного RGBA (цвета назначения) FBO, например, на (1,0-0,1)) = 0,9 и округление предотвращает дальнейшее уменьшение.Например, 4 * 0,9 = 3,6 -> округлено до 4, навсегда.

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

Трассы нарисованы с использованием кода:

    GLuint drawableFBO;
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &drawableFBO);


    glBindFramebuffer(GL_FRAMEBUFFER, FBO);   /// has an attached texture glFramebufferTexture2D -> FBOTextureId

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    glUseProgram(fboClearShader);
    glUniform4f(fboClearShader.uniforms.color, 0.0, 0.0, 0.0, 0.1);
    glUniformMatrix4fv(fboClearShader.uniforms.modelViewProjectionMatrix, 1, 0, mtx.m);
    glBindVertexArray(fboClearShaderBuffer);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);


    glUseProgram(particlesShader);
    glUniformMatrix4fv(shader.uniforms.modelViewProjectionMatrix, 1, 0, mtx.m);
    glUniform1f(shader.uniforms.globalAlpha, 0.9);
    glBlendFunc(GL_ONE, GL_ONE);
    glBindTexture(particleTextureId);
    glBindVertexArray(particlesBuffer);
    glDrawArrays(GL_TRIANGLES, 0, 1000*6);


    /// back to drawable buffer
    glBindFramebuffer(GL_FRAMEBUFFER, drawableFBO);

    glUseProgram(fullScreenShader);
    glBindVertexArray(screenQuad);
    glBlendFuncGL_ONE dFactor:GL_ONE];
    glBindTexture(FBOTextureId);
    glDrawArrays(GL_TRIANGLES, 0, 6);

1 Ответ

2 голосов
/ 05 июля 2019

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

Используйте функцию наложения, которая вычитает крошечное значение из буфера назначения, поэтому цвет назначения будет немного уменьшенв каждом кадре и, наконец, становится 0,0.
Результаты уравнений смешивания ограничены диапазоном [0, 1].

например,

dest_color = dest_color - RGB(0.01)

Уравнение смешивания, которое вычитаетисходный цвет формы целевой цвет: GL_FUNC_REVERSE_SUBTRACT:

float dec = 0.01f; // should be at least 1.0/256.0

glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_ONE, GL_ONE);

glUseProgram(fboClearShader);
glUniform4f(fboClearShader.uniforms.color, dec, dec, dec, 0.0);
...