代码之家  ›  专栏  ›  技术社区  ›  NeomerArcana

OpenGL frag shader纹理在每次写入后都会淡出

  •  0
  • NeomerArcana  · 技术社区  · 8 年前

    我有一个程序采用以下纹理:

    enter image description here

    通过freetype2生成。基本上,它为我要求绘制的每个角色创建了一个纹理图集。正如你所看到的,人物是明亮和清晰的。实际上,您可以看到小写字母“i”的最左上角像素的值为 71 (出 255 0.7098 当我检查renderDoc中的纹理时。

    接下来,引擎将字母快速发送到一个帧缓冲区对象上。这是通过纹理四边形完成的。顶点明暗器:

    #version 330
    
    layout(location=0) in vec2 inVertexPosition;
    layout(location=1) in vec2 inTexelCoords;
    layout(location=2) in float inDepth;
    
    out vec2 texelCoords;
    out float depth;
    
    void main()
    {
        gl_Position = vec4(inVertexPosition.x,-inVertexPosition.y, 0.0, 1.0);
        texelCoords = vec2(inTexelCoords.x,1-inTexelCoords.y);
        depth = inDepth;
    }
    

    以及frag shader:

    #version 330
    
    layout(location=0) out vec4 frag_colour;
    
    in vec2 texelCoords;
    in float depth;
    
    uniform sampler2D uTexture;
    uniform vec4 uTextColor;
    
    void main()
    {
        vec4 c = texture(uTexture,texelCoords);
        frag_colour = uTextColor * c.r;
        gl_FragDepth = depth;
    }
    

    如您所见,它将像素颜色设置为红色通道的一个因子。

    但是,当我通过renderDoc查看FBO的内容并保存到这里的文件时,您会看到:

    enter image description here

    如果你看这个没有透明度(在gimp下面只添加了第二层以更好地说明):

    enter image description here

    你可以看到,文本比以前有点褪色。如果你看小写字母“i”的最左上角的像素,它现在是 50.2 或者在0-1的范围内 0.50196 (通过renderDoc)。

    接下来,当fbo最终通过另一个纹理四元体放到屏幕上时,它会变得更加淡出。首先是顶点着色:

    #version 330
    
    layout(location=0) in vec2 inVertexPosition;
    layout(location=1) in vec2 inTexelCoords;
    
    varying vec2 texelCoords;
    
    void main()
    {
        gl_Position = vec4(inVertexPosition.x,-inVertexPosition.y, 0.0, 1.0);
        texelCoords = vec2(inTexelCoords.x,1-inTexelCoords.y);
    }
    

    片段着色:

    #version 330
    
    precision highp float;
    
    layout(location=0) out vec4 frag_colour;
    
    varying vec2 texelCoords;
    
    uniform sampler2D uTexture;
    
    void main()
    {
        vec4 c = texture(uTexture,texelCoords);
        frag_colour = c;
    }
    

    正如我所说,结果比以前更容易褪色:

    原件: enter image description here

    为清晰起见,GIMP背景:

    enter image description here

    现在该像素的值为 25.1 0.05139

    为什么每次渲染后都会褪色?

    我认为重要的是要注意明亮的区域不会褪色。

    我的帧缓冲区创建代码

    glGenFramebuffers(1, &m_framebuffer);
    glGenTextures(1, &m_fboColorAttachment);
    glGenTextures(1, &m_fboAdditionalInfo);
    glGenTextures(1, &m_fboDepthStencil);
    
    glCall(glBindFramebuffer,GL_FRAMEBUFFER, m_framebuffer);
    
        /* setup color output 0 */
        glBindTexture(GL_TEXTURE_2D, m_fboColorAttachment);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
            glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_RGBA8, screenDimensionsX, screenDimensionsY, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_fboColorAttachment, 0);
        glBindTexture(GL_TEXTURE_2D, 0);
    
        /* setup color output 1 */
        glBindTexture(GL_TEXTURE_2D, m_fboAdditionalInfo);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
            glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_R32UI, screenDimensionsX, screenDimensionsY, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_fboAdditionalInfo, 0);
        glBindTexture(GL_TEXTURE_2D, 0);
    
        /* setup depth and stencil */
        glBindTexture(GL_TEXTURE_2D, m_fboDepthStencil);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
            glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, screenDimensionsX, screenDimensionsY, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_fboDepthStencil, 0);
        glBindTexture(GL_TEXTURE_2D, 0);
    

    初始(红色)纹理创建:

    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1,&textureData.texture);
    glBindTexture(GL_TEXTURE_2D,textureData.texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 500, 500, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    

    我的混合是做为

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    1 回复  |  直到 8 年前
        1
  •  0
  •   derhass    8 年前

    值为 71 (出 255 0.7098

    不知道,你在这里是什么意思。 71/255 会是 0.278 零点七零九八 标准化将是 181 由于 二百五十五 . 看起来你的“255个”只是百分比值,占100%。

    glblendfunc(gl_src_alpha,gl_one_减去_src_alpha);

    使用红色通道中的颜色值也可以作为alpha,因此,当启用混合时,最终会 0.7098*0.7098=.5038 . 由于结果将四舍五入到最接近的可表示值,我们宁愿以 181/255 * 181/255 = .50382 四舍五入 128/255

    现在它的价值是 50.2 或者在0-1的范围内 0.50196

    128/255个 0.50196078...

    因此,解决方案是:当您不需要时,禁用所有步骤的混合。或者如果需要,设置有用的alpha值。

    旁注:

    现在该像素的值为 25.1 0.05139

    不知道这意味着什么, 二十五点一 不涉及 0.05139个 以任何明显的方式,您再次明确地改变了这些值的含义。