在OpenGL 4.6中没有alpha混合对我有用

时间:2019-01-12 10:36:37

标签: opengl shader blending spir-v

我正在使用OpenGL和460版着色器(已编译为SPIR-V)在粒子系统上工作。

我的粒子基于带有Alpha的PNG纹理,并且实际上非常简单,我之前在较早的OpenGL版本中就已经做到了。

但是,输出窗口中的粒子仍然是正方形,角落是黑色的-意思是alpha通道绘制为黑色。我使用了不同的PNG文件,其中一个的粒子为alpha上的灰色或黑色的灰色。我在片段着色器中将第四个组件设置为0.0或0.5,以查看任何更改,但没有任何更改。我尝试更改loadTexture函数中的格式,但仍然相同。

我尝试了所有不同的混合模式并更改了行的顺序。我在RenderDoc中注意到,目标混合已禁用。但是,将glEnable(GL_BLEND)更改为另一个位置没有帮助。

非常感谢您的帮助!

particle texture1 particle texture2

// init stuff
glEnable(GL_POINT_SPRITE);
initbasicShaders(); // vertex, fragment
initTexture();
...

void application::initTexture()
{
    m_ParticleTex = Texture(); // empty constructor
    m_ParticleTex.loadTexture(TEXTURE_PATH);

    GLint baseImageLoc = glGetUniformLocation(m_RenderProgramHandle, "u_Texture");
    glUseProgram(m_RenderProgramHandle);
    glUniform1i(baseImageLoc, 0); 
    glActiveTexture(GL_TEXTURE0 + 0);
    glBindTexture(GL_TEXTURE_2D, m_ParticleTex.getTextureID());
}

// using the library stb_image
void Texture::loadTexture(const char* fileName)
{
    int channels, width, height;
    unsigned char * localBuffer;
    m_FilePath = fileName;

    localBuffer = stbi_load(fileName, &width, &height, &channels, 4);

    glGenTextures(1, &m_TextureID);
    glBindTexture(GL_TEXTURE_2D, m_TextureID);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, localBuffer);
    glBindTexture(GL_TEXTURE_2D, 0);

    if (localBuffer) {
        stbi_image_free(localBuffer);
    }
}

...
...
...
// Now - the render loop:
void application::runOpenGLBuffer()
{
    Log::logInfoRun(m_Name, "OpenGL buffer");
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    glEnable(GL_POINT_SMOOTH);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_ALPHA_TEST);

    glPointSize(PARTICLE_SIZE);
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);

        glUseProgram(m_RenderProgramHandle);
    this->updateTextures();
        glDrawArrays(GL_POINTS, 0, NUM_PARTICLES);
}


...
// and the fragment shader
#version 460
#extension GL_ARB_separate_shader_objects : enable

layout(std430, binding = 3) buffer density_block
{
    float density[];
};

void main()
{
// densitColor is just a variable color from density
    vec4 particleColor = vec4(texture(u_Texture, gl_PointCoord) * densityColor);
    color = particleColor;
}

这里是渲染帧中的输出和RenderDoc的信息:

enter image description here enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

glEnable的参数(如GL_BLENDGL_POINT_SMOOTH)是一个枚举数常量,而不是位字段的位。 |运算符无法连接不同的枚举器常量。每个状态必须分别启用:

glEnable(GL_BLEND | GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);

请注意,按位或运算通过对两个值的每一位执行“或”运算来计算新值。结果对glEnable可能没有任何意义。这会导致代码中未启用GL_BLENDGL_POINT_SMOOTH