文章目录[x]
- 1:Alpha测试
- 2:Alpha混合
- 3:面剔除
Alpha测试
只需在片元着色器中使用discard即可
void main()
{
vec4 texColor = texture(uTexture1, iTexCoords);
if (texColor.a < 0.1)
discard;
fragColor = texColor;
}
discard
表示舍弃当前片元。
不过要注意的是,此时的纹理环绕模式应该设置为 GL_CLAMP_TO_EDGE
,否则可能出现下图情况。
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);
开启正面剔除后的效果