使用模板缓冲区渲染时纹理中的 OpenGL 透明度

OpenGL transparency in texture when render with stencil buffer

由于评论,问题已更新。

纹理如何重叠的屏幕截图

要使用模板缓冲区使用画笔纹理绘制 2 个点以避免纹理透明度重叠,使用以下代码:

    glEnable(GL_STENCIL_TEST.gluint)

    glClear(GL_STENCIL_BUFFER_BIT.gluint | GL_DEPTH_BUFFER_BIT.gluint)

    glStencilOp(GL_KEEP.gluint, GL_KEEP.gluint, GL_REPLACE.gluint)

    glStencilFunc(GL_ALWAYS.gluint, 1, 1)
    glStencilMask(1)

    glDrawArrays(GL_POINTS.gluint, 0, 1)

    glStencilFunc(GL_NOTEQUAL.gluint, 1, 1)
    glStencilMask(1)

    glDrawArrays(GL_POINTS.gluint, 1, 1)

    glDisable(GL_STENCIL_TEST.gluint)

并且模板缓冲区有效,但是,每个点填充模板缓冲区中的一个完整矩形,但纹理图像具有透明度。那么也许纹理以错误的方式使用?

纹理是这样加载的

    glGenTextures(1, &gl_id)
    glBindTexture(GL_TEXTURE_2D.gluint, gl_id)
    glTexParameteri(GL_TEXTURE_2D.gluint, GL_TEXTURE_MIN_FILTER.gluint, GL_LINEAR)
    glTexImage2D(GL_TEXTURE_2D.gluint, 0, GL_RGBA, gl_width.int32, gl_height.int32, 0, GL_RGBA.gluint, GL_UNSIGNED_BYTE.gluint, gl_data)

混合设置为

    glEnable(GL_BLEND.gluint)
    glBlendFunc(GL_ONE.gluint, GL_ONE_MINUS_SRC_ALPHA.gluint)

能否请您指点一下要在模板缓冲区中通过画笔图像的完全不透明区域填充 1?

我建议discard 片段着色器中纹理的透明部分。可以通过 discard 关键字在片段着色器中完全跳过一个片段。
参见 Fragment Shader - Special operations

使用小阈值和discard一个片段,如果纹理颜色的alpha通道低于阈值:

vec4  texture_color = .....;
float threshold = 0.01;
if ( texture_color.a < threshold )
    discard; 

另一种可能性是使用 Alpha test。这将仅在 OpenGL 兼容性配置文件中可用,但在核心配置文件或 OpenGL ES 中不可用。

参见Khronos OpenGL-Refpages glAlphaFunc

The alpha test discards fragments depending on the outcome of a comparison between an incoming fragment's alpha value and a constant reference value.

通过以下 alpha 测试,alpha 通道低于 threshold 的片段将被丢弃:

float threshold = 0.01;
glAlphaFunc(GL_GEQUAL, threshold);
glEnable(GL_ALPHA_TEST)