[OpenGL]混合和面剔除

文章目录[x]
  1. 1:Alpha测试
  2. 2:Alpha混合
  3. 3:面剔除

Alpha测试


只需在片元着色器中使用discard即可

void main()
{
    vec4 texColor = texture(uTexture1, iTexCoords);
    if (texColor.a < 0.1)
        discard;

    fragColor = texColor;
}

discard 表示舍弃当前片元。

不过要注意的是,此时的纹理环绕模式应该设置为 GL_CLAMP_TO_EDGE ,否则可能出现下图情况。

AlphaTest

 

 

Alpha混合


// 开启混合
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// 为RGB和alpha通道分别设置不同的选项
// glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);

// 注释绘制的时候需要排序
virtual void Render() override
{
    // 不要打乱顺序
    // 1.先绘制所有不透明的物体。
    DepthTestAndStencilTest::Basic::Render();

    // 2.对所有透明的物体排序。
    // 使用map自动排序
    std::map<float, glm::vec3> sorted;
    for (unsigned int i = 0; i < windows.size(); i++)
    {
        float distance = glm::length(m_Camera->GetEye() - windows[i]);
        sorted[distance] = windows[i];
    }

    // 3.按顺序绘制所有透明的物体。
    m_Texture[1]->Bind(1);
    m_Shader[1]->Bind();
    m_Shader[1]->SetInt("uTexture1", 1);
    m_Shader[1]->SetMat4f("view", m_Camera->GetViewMatrix());
    m_Shader[1]->SetMat4f("projection", m_Camera->GetProjectionMatrix());
    for (std::map<float, glm::vec3>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); ++it)
    {
        glm::mat4 model = glm::identity<glm::mat4>();
        model = glm::translate(model, it->second + glm::vec3(0.0f, 0.5f, 0.0f));
        m_Shader[1]->SetMat4f("model", model);
        m_Renderer.Draw(m_VA[1], 6, m_Shader[1]);
    }
}
已排序

未排序

已排序

 

面剔除


// 开启面剔除, 默认所有的背面都将被剔除
glEnable(GL_CULL_FACE);
// 这句代码可以设置剔除的面 GL_BACK/GL_FRONT/GL_FRONT_AND_BACK
// glCullFace(GL_BACK);
// 这句代码告诉OpenGL哪个方向是正面,GL_CCW逆时针/GL_CW顺时针
// glFrontFace(GL_CCW);

开启正面剔除后的效果

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像