glDepthMask 使用时遇到的问题

原文 http://stackmirror.cn/page/3xwgq8v46k4

https://stackoverflow.com/questions/3388294/opengl-question-about-the-usage-of-gldepthmask

问 :我如下绘制物体A。 场景中还有其它物体。

void Draw()
{
if( glIsList( displayListID ) )
{
glPushAttrib( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT );

    glEnable( GL_BLEND );
    glEnable( GL_DEPTH_TEST );
    //glDepthMask( GL_FALSE );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    glEnable( GL_LINE_SMOOTH );
    glEnable( GL_POINT_SMOOTH );
    glEnable( GL_POLYGON_SMOOTH );

    glMatrixMode( GL_MODELVIEW ); 

    color.setAlpha(alpha); // set alpha transparent of this objectA
    glCallList( displayListID );

    //glDepthMask( GL_TRUE );
    glDisable( GL_BLEND );  

    glPopAttrib();
}

}

现在的问题是, 如果我注释掉//glDepthMask( GL_FALSE ); //glDepthMask( GL_TRUE );这两句, 物体A和场景中其它物体的深度都会正确。
但是, 修改物体A的alpha 值就不会起作用(如 color.setAlpha(alpha) )。

如果我取消那两句的注释, alpha 的修改能正常工作,但是深度会出现问题, 换句话说, A应该在其它物体后面,但看上去它在前面。
我该如何解决这个问题?
谢谢

答:
1)开启深度写入, glDepthMask( GL_TRUE )
2)渲染所有的不透明物体,以任何顺序
3) 关闭深度写入, glDepthMask( GL_FALSE )
4) 开启混合 glEnable( GL_BLEND )
5) 从远到近渲染透明物体

为什么要这么做?
你需要关注两个缓存: 深度缓存和颜色缓存。 这两个缓存其实就是两个很大的2维数组, 大小为窗口的高度 X 宽度。 颜色缓存不停地更新(如果测试通过),最终会得到屏幕上看到的颜色。每一个屏幕像素的值都会有颜色缓存跟它对应(如像像素pixel[100][100] 的最终颜色就是颜色缓存color[100][100])。 和颜色缓存类似,每一个像素也都一个深度缓存的值跟它对应, 只不过它用在别的地方。 深度缓存则描述片元离相机的远近,然后取最近的深度。

如果你渲染一个三角形,它远离相机,它会为将要覆盖的屏幕像素产生一组颜色和深度缓存。当渲染另一个离相机近一点的多边形,它也会为它覆盖的像素产生一组颜色和深度缓存。现在颜色缓存就会产生“竞争”,离得远的片元(深度值大)将被丢弃。最后, 只有离相机最近的片元才能跟新颜色和深度buffer, 渲染到屏幕上(如果两个多边形重叠,则会产生Z冲突)。

一开始渲染不透明物体,允许写入深度 。 这意味着所有渲染的物体,只有赢得深度测试时,才会有机会更新深度缓冲区和颜色缓冲区。

接下来3) 关闭深度写入, glDepthMask( GL_FALSE ) , 4)开启混合 glEnable( GL_BLEND ) 5)从远到近渲染透明物体

感觉这很奇怪?

关闭深度写入(glDepthMask( GL_FALSE ) )后,渲染透明物体, OpenGL将读取深度缓存,然后决定时候丢弃该片元(例如, 如果你的透明物体在已经绘制的不透明物体后面, 则透明物体的片元将丢弃)。

由于没有开启深度写入, 当透明物体离相机更近时,此透明的片元不会阻挡后面的片元,而是会跟他们混合(跟新颜色buffer, 但不更新深度buffer)。

这很重要,因为假如你渲染离你很近的挡风玻璃,让它区更新深度缓冲区,那么接下的要绘制的物体你将不会看到,如果它在挡风玻璃后面(深度测试失败)。

关闭深度测试是“欺骗”OpenGL, 让它不知道哪一个透明片元离相机最近(透明片元不会因为之前绘制的透明片元而深度测试失败),关闭深度写入常常会用来渲染透明片元。同时,也能解释为什么要由远到近地绘制透明物体。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值