使用深度分辨率的完整分辨率进行2D渲染


9

我正在使用正交投影为2D引擎进行从前到后的渲染器。我想使用深度缓冲区以避免过度绘制。我有一个16位的深度缓冲区,一个Z = 100的相机查看Z = 0,zNear为1,zFar为1000。每个渲染的精灵将其Z坐标设置为越来越远的值,从而允许深度测试跳过渲染下面的任何东西。

但是我知道Z位置以Z缓冲区值结束的方式是非线性的。我想利用16位深度缓冲区的完整分辨率,即允许65536个唯一值。因此,对于每个渲染的精灵,我想将Z位置增加到下一个位置,以与下一个唯一的深度缓冲区值相关联。

换句话说,我想将绘制的精灵的递增索引(0、1、2、3 ...)转到每个精灵的适当Z位置,以具有唯一的深度缓冲区值。我不确定这背后的数学原理。这样做的计算是什么?

注意我正在使用WebGL(基本上是OpenGL ES 2),并且我需要支持广泛的硬件,因此尽管gl_FragDepth之类的扩展名可能使此操作更容易,但出于兼容性原因,我无法使用它。


我无法想象使用z缓冲区会在您添加所有z缓冲区的编写,计算和比较以及将纹理复制回到最前面之后为您带来很多性能提升(如果有的话),更不用说任何alpha透明度/混合麻烦。
马特·埃施

@MattEsch:想法是所有这些计算都是在GPU中以极高的速度完成的,因此这样做确实有意义。
2015年

@MattEsch:FWIW这是针对Intel集成GPU,它使用系统内存而不是专用GPU内存。这会使它们变得相当缓慢,并且在绘制大量精灵时会达到填充率限制。英特尔向我推荐了这种方法,作为解决它的一种方法。据推测,他们对深度测试的实施得到了很好的优化,可以节省大量的填充率。不过还有待观察,我还没有介绍它!
AshleysBrain,2015年

@PandaPajama块复制内存实际上确实非常快,因此,如果只是将纹理涂抹到表面上,那确实会非常快。首先的主要开销是首先将数据获取到GPU,正如Ashley指出的那样,在集成GPU上这可能会更加昂贵。您会发现,即使很多3D游戏在CPU上所做的工作也非常繁琐(例如骨骼动画),因为首先上传进行这些矩阵计算所需的数据太昂贵了。
马特·埃施

@MattEsch:光是只能做很多事情。想到旋转,缩放和变形,但是由于您拥有像素/顶点着色器,因此与硬件相比,对硬件的限制远高于对信号处理的限制。
熊猫睡衣

Answers:


5

实际上,存储在z缓冲区中的值与对象的实际z坐标不是线性的,而是与它们的倒数成线性关系,以便为靠近眼睛的物体提供比靠近背面的物体更高的分辨率。

您要做的是将映射zNear0和映射zFar1。对于zNear=1zFar=2,它应该看起来像这样

缓冲

计算方式如下:

z_buffer_value = k * (a + (b / z))

哪里

 k = (1 << N), maximum value the Z buffer can store
 N = number of bits of Z precision
 a = zFar / ( zFar - zNear )
 b = zFar * zNear / ( zNear - zFar )
 z = distance from the eye to the object

...并且z_buffer_value是整数。

上面的公式由这个很棒的页面提供给您,该页面很好地解释了z缓冲区。

因此,为了找到z给定的必需项z_buffer_value,我们只需清除z

z = (k * b) / (z_buffer_value - (k * a))

感谢您的回答!不过,我有点困惑,您是如何得出最终公式的。如果我z_buffer_value = k * (a + (b / z))只是简单地重新安排求解z,那么我得到:z = b / ((z_buffer_value / k) - a)-您是如何得出不同的最后一个公式的?
AshleysBrain,2015年

@AshleysBrain:使用分母(v / k) - a => (v - k * a) / k,然后折叠为(k * b) / (v - (k * a))。结果是一样的。
2015年

知道了 感谢您的回答,它运行良好!
AshleysBrain,2015年

0

也许您应该更改您的方法以更简单一些。我会怎么做;保留Z深度的东西,但保留一份渲染的列表。根据z Depth值对列表进行排序,并按照列表的顺序渲染对象。

希望这会有所帮助。人们总是告诉我保持简单。


1
抱歉,没有太大帮助。我已经在做。问题是要选择哪个Z位置。
AshleysBrain,2015年

0

由于您已经有了要渲染的东西的排序列表(从前到后),您真的需要增加Z索引吗?不能将“小于或等于”用于“检查功能”吗?这样,它将实际上检查是否已经绘制了特定像素。


“小于或等于”仍将绝对导致所有内容被透支,因为所有内容始终具有相等的Z索引,因此通过了深度测试。
AshleysBrain,2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.