OpenGL-关于glDepthMask使用的问题 [英] OpenGL - Question about the usage of glDepthMask

查看:398
本文介绍了OpenGL-关于glDepthMask使用的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在场景中绘制了一个objectA,如下所示.场景中还有许多其他对象.

I have rendered an objectA in a scene as follows. The scene has many other objects too.

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);

As shown, I comment out two lines //glDepthMask( GL_FALSE ); //glDepthMask( GL_TRUE );

该场景在深度上正确渲染了objectA和其他对象.然而, 对objectA alpha的修改不再起作用(即color.setAlpha(alpha)).

the scene renders the objectA and other objects correctly in depth. However, the modification of the objectA alpha doesn't work anymore (i.e. color.setAlpha(alpha) ).

如果我取消对以上两行的注释,则alpha修改将恢复工作.但是,深度渲染不正确.换句话说,有时objectA应该在其他对象之后,但看起来objectA在所有对象之前.

If I uncomment the above two lines, then alpha modification is back to work. However, the depth rendering is NOT correct. In other words, sometimes, the objectA should be behind other objects but it looks like the objectA is in front of all objects.

如何解决此问题?

谢谢

推荐答案

  1. 打开 深度蒙版glDepthMask( GL_TRUE )
  2. 以任何顺序绘制所有不透明的对象
  3. 关闭深度遮罩glDepthMask( GL_FALSE )
  4. 打开BLEND_MODE
  5. 绘制从最远到最近
  6. 排序的半透明对象
  1. Turn on the depth mask glDepthMask( GL_TRUE )
  2. Draw all opaque objects, in any order
  3. Turn off the depth mask glDepthMask( GL_FALSE )
  4. Turn on a BLEND_MODE
  5. Draw translucent objects sorted from furthest away to nearest

您为什么这样做?

您需要担心两个缓冲区:深度缓冲区颜色缓冲区.这些缓冲区实际上只是大的2d数组,每个数组的宽度x屏幕的高度.

There are 2 buffers you need to worry about: the depth buffer and the color buffer. These buffers are really just big 2d arrays, each the width x height of your screen.

颜色缓冲区自然会保留每个像素的最终颜色.每个屏幕像素的颜色缓冲区中只有一个条目. 深度缓冲区,就像颜色缓冲区一样,每个屏幕像素只有一个条目,但是它用于不同的东西. 深度缓冲区中的条目是每个彩色像素实际接近"程度的度量.

The color buffer naturally is going to hold the final coloration of each pixel. There is one entry in the color buffer per screen pixel. The depth buffer, is like the color buffer in that there is one entry per screen pixel, but it is used for something different. Entries in the depth buffer are a measure of "how close" each colored pixel really is.

如果渲染1个三角形,该三角形与摄影机相距很远,它将为希望"覆盖在屏幕上的每个像素生成一组颜色和深度值.假设您随后渲染了另一个更接近的多边形,它还将为深度和颜色缓冲区生成一组值.现在,在像素着色时出现了一种竞争",其中丢弃了更远的"片段(较大的深度缓冲区值),仅保留了最接近的片段.较近的片段最终会为您的像素着色. (当两个多边形几乎重叠时,会发生Z-fighting )

If you render 1 triangle, that is far away from the camera, it generates a set of colors and depth values for each pixel it "wants" to cover on the screen. Say you then render another poly that is closer, it also will generate a set of values for the depth and color buffers. Now, there is a sort of "contest" at pixel coloration time where the "further away" fragments (large depth buffer values) are discarded, and only the closest fragments are kept. The closer fragments end up coloring the pixel you had. (When two polygons are nearly overlapping, Z-fighting can occur)

首先在启用深度蒙版的情况下渲染场景中的对象.这意味着您渲染的每个形状,当其像素变色时,深度缓冲区都会随着比赛的获胜者"进行更新.

Start by rendering the objects in your scene with the depth mask on. This means every shape you render, when its pixels get colored, the depth buffer gets updated with the "winner" of the contest.

然后,您3)glDepthMask( GL_FALSE )禁用 off 用于写入的深度缓冲区,4)启用混合,5)从最远到最近渲染半透明形状.看起来很奇怪,是吧?

Then, you 3) glDepthMask( GL_FALSE ) turns off the depth buffer for writing, 4) turn on blending, 5) render translucent shapes from furthest to nearest. Seems weird, huh?

当您关闭深度蒙版并渲染半透明形状时,OpenGL仍会读取深度缓冲区以确定要丢弃的片段(即,如果半透明形状位于已经渲染的实体后面)形状,然后将那个半透明形状的碎片扔掉).但是它不会写入深度缓冲区,因此,如果半透明的形状确实非常接近眼睛(例如半透明的挡风玻璃),则这些挡风玻璃碎片请勿阻止其他实际上更远的片段被绘制.这很重要,因为如果您的挡风玻璃就在您的面前,并且将其变为半透明,请并且让挡风玻璃碎片更新深度缓冲区,那么除了挡风玻璃之外,您在场景中将看不到其他任何东西,即使它背后有形状,因为OpenGL会认为由于这些深度缓冲区的读数,该挡风玻璃是用户唯一应看到的东西,因此,我不会再花任何距离来渲染此挡风玻璃了."关闭深度遮罩是一种将OpenGL欺骗"为不知道"存在非常紧密但半透明的碎片的方法.

When you turn off the depth mask, and render the translucent shapes, OpenGL will still read the depth buffer to determine which fragments to throw away (i.e. if your translucent shape is behind an already rendered solid shape, then you throw that translucent shape's fragments away). But it will not write to the depth buffer, so if a translucent shape is really really close to the eye (say like a translucent windshield), those windshield fragments do not prevent other fragments that are actually further away from being drawn. This is important, because if your windshield is right in front of you and you render it translucent, and you let the windshield fragments update the depth buffer then you will see nothing else in your scene except the windshield, even though there are shapes behind it, because OpenGL will think "Hey, that windshield is the only thing the user should see, due to these depth buffer readings, so I won't bother rendering anything further away than this windshield, then." Turning off the depth mask is a way of "tricking" OpenGL into "not knowing" there are very close, but translucent, fragments.

这篇关于OpenGL-关于glDepthMask使用的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆