如何摆脱OpenGL中的z冲突问题? [英] How to get the rid of the z-fighting problem in OpenGL?

查看:177
本文介绍了如何摆脱OpenGL中的z冲突问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个飞行模拟器,并且陷入了这种类型的经典问题:视锥台的近平面必须足够近才能使飞机驾驶舱可见,远平面必须离得很远才能实现可见距离长达40公里.

I'm writing a flight simulator and got stuck with the classic problem of this genre: the near plane of the viewing frustum must be close enough to make aircraft cockpit visible, the far plane has to be far away to enable visible distances with up to 40km.

可见距离或近/远比确实超出了opengl的z缓冲区精度范围,远处的对象剧烈闪烁.这是一个花哨的3d引擎让您独自解决问题的地方,您需要对opengl有真正的了解:).可能我找到了解决问题的正确方法(如果我错了,OpenGL专家会纠正我),但是我的解决方案忽略了重要的一点.更改的渲染器执行两次通过渲染:

The visibility distance or near/far ratio is indeed beyond the z-buffer precision ability of opengl and distant objects flicker violently. This is the place a fancy 3d engine leaves you alone with your problem and you need a true knowledge of opengl :). Probably i found the right way to fix the problem (OpenGL experts correct me if i'm wrong), but my solution misses the important bit. Altered renderer performs double pass rendering:

  1. 在第一遍中,必须显示远处的对象和背景,将近平面移开,z缓冲区令人满意,地形看起来不错,但附近的物体被剪掉了.
  2. 在第二遍中,针对近距离对象调整了投影矩阵,并应显示驾驶舱.

未解决的问题:在第二遍中,所有遥远的物体和背景都是不可见的,因此我身后有座舱和黑色背景.第二遍的结果完全浪费了第一遍的结果. Ergo计划的覆盖不会发生.问题: 如何在第二遍中强制opengl忽略背景色,以便两个遍结果都可以创建所需的叠加层?

The unsolved problem: in the second pass all distant objects and background are invisible, hence i have the cockpit and black background behind it. The result of the second pass totally wastes the result of the first pass. Ergo planned overlay doesn't happen. Question: how to force the opengl to ignore the background color in the second pass so both pass results create desired overlay?

P.S.这是当前状态的图像(近端/远端平面使所有细节都清晰可见,没有通过投影调整就可以通过).

P.S. Here is the image of the status quo (near/far planes are at extremes to make all details visible, single pass without projection adjustments).

http://www.flickr.com /photos/43342833 @ N04/5995604542/sizes/l/in/photostream/

缓冲区清除仅在每个渲染周期发生一次,并且在两次遍历之间不涉及.这里是清除代码:

The buffer clearing happens only once per rendering cycle and and not involved between the 2 passes. Here the clearing code:

JoglContext jctx = (JoglContext) ctx;
GLContext context = context(ctx);
GL gl = context.getGL();
// Mask of which buffers to clear, this always includes color & depth
int clearMask = GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT;
gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT);
gl.glDepthMask(true);
gl.glClearColor(r, g, b, jctx.getAlphaClearValue());
gl.glClear(clearMask);
gl.glPopAttrib();

您描述的方法也用于2次通过:1.长距离"投影和地形2.近距离"与驾驶舱之间没有空隙,但是第二次通过之后,驾驶舱后面的背景为黑色.也许glDepthRange函数可以帮助您,必须检查一下手册.

The approach you describe is also used in the 2 passes: 1. "long distance" projection and terrain 2. "short distance" and the cockpit no clearing between, but after the second pass the background behind the cockpit is black. Maybe the glDepthRange function helps, got to check the manuals.

zbuffer的深度是24位.

The zbuffer depth is 24 bits.

推荐答案

不要清除两次通过之间的屏幕.如果您只想清除深度缓冲区,请清除 just 深度缓冲区.不要将GL_COLOR_BUFFER_BIT传递给glClear.

Don't clear the screen between the two passes. If you just want to clear the depth buffer, then clear just the depth buffer. Don't pass GL_COLOR_BUFFER_BIT to glClear.

无论如何,一种更好的方法(这样就不必重新渲染所有内容)是采用适当的深度范围.由于您的驾驶舱无法与场景相交,因此没有理由将其拖入场景的深度范围.

In any case, a better way to do this (so that you don't have to re-render everything) is to employ a proper depth range. Since your cockpit cannot intersect with the scene, there's no reason to draw it into the scene's depth range.

因此,首先,您使用合理的透视矩阵绘制场景(即:z面较大的透视矩阵,大约为几英尺).您的场景不包括您的座舱.此渲染的glDepthRange应该类似于[0.05,1.0].

So first, you draw your scene, using a reasonable perspective matrix (ie: one with a z-near that is reasonably large. On the order of several feet or so). Your scene does not consist of your cockpit. The glDepthRange for this rendering should be something like [0.05, 1.0].

在那之后,您就可以为驾驶舱使用合理的透视矩阵来绘制驾驶舱.为此的glDepthRange为[0,0.05].这应该为场景和驾驶舱提供足够的深度精度.

After that, you draw your cockpit, using a reasonable perspective matrix for just the cockpit. The glDepthRange for this would be [0, 0.05]. This should give you plenty of depth bits of precision for both the scene and the cockpit.

哦,请确保您有一个24位深度的缓冲区.

Oh, and make sure you're getting a 24-bit depth buffer.

这篇关于如何摆脱OpenGL中的z冲突问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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