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

时间:2018-07-03 12:06:09

标签: opengl-es blending

由于评论,问题已更新。

纹理如何重叠的屏幕截图
Screenshot of how textures overlap

要使用模具缓冲区使用画笔纹理绘制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)

您能否建议在哪里寻找以便通过完全不透明的画笔图像区域在模板缓冲区中填充1s?

1 个答案:

答案 0 :(得分:3)

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

如果纹理颜色的Alpha通道低于阈值,请使用较小的阈值并discard片段:

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

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

请参见Khronos OpenGL-Refpages glAlphaFunc

  

alpha测试会根据传入片段的alpha值与恒定参考值之间的比较结果来丢弃片段。

在进行以下alpha测试时,丢弃其alpha通道低于threshold的片段:

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