获取通过深度testing的碎片数量

在“现代”环境中, “NV遮挡查询”扩展提供了获取通过深度testing的片段数量的方法。 但是,在使用OpenGL ES的iPad / iPhone上,扩展名不可用。

什么是在片段着色器中实现类似行为的最高性能方法?

我的一些想法:

这些方法存在的问题是,管道停滞,导致主要的性能问题。 因此,我正在寻找更高效的方式来实现我的目标。

使用EXT_OCCLUSION_QUERY_BOOLEAN扩展

苹果公司在iPad 2的iOS 5.0中引入了EXT_OCCLUSION_QUERY_BOOLEAN 。

"4.1.6 Occlusion Queries Occlusion queries use query objects to track the number of fragments or samples that pass the depth test. An occlusion query can be started and finished by calling BeginQueryEXT and EndQueryEXT, respectively, with a target of ANY_SAMPLES_PASSED_EXT or ANY_SAMPLES_PASSED_CONSERVATIVE_EXT. When an occlusion query is started with the target ANY_SAMPLES_PASSED_EXT, the samples-boolean state maintained by the GL is set to FALSE. While that occlusion query is active, the samples-boolean state is set to TRUE if any fragment or sample passes the depth test. When the occlusion query finishes, the samples-boolean state of FALSE or TRUE is written to the corresponding query object as the query result value, and the query result for that object is marked as available. If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, an implementation may choose to use a less precise version of the test which can additionally set the samples-boolean state to TRUE in some other implementation dependent cases." 

第一句暗示了一个正在寻找的行为:以asynchronous的方式获得通过深度testing的像素数量,而没有太多的性能损失。 但是,文档的其余部分只描述了如何获得布尔结果。

是否有可能利用这个扩展来获得像素数? 硬件是否支持它,以便可能有隐藏的API来访问像素数量?

其他可被利用的扩展将是debuggingfunction,如调用片段着色器的次数(DirectX中的PSInvocations – 不确定OpenGL ES中是否有可用的东西)。 但是,这也会导致管道堵塞。

是否有可能利用这个扩展来获得像素数? 硬件是否支持它,以便可能有隐藏的API来访问像素数量?

不,不,不。 那么,我想如果你在窗口空间绘制一系列一个像素大小的三角形,你可以计算你得到的布尔值数量。 但是,这将需要为每个像素单独查询。 可能不是世界上最快的东西。

如果有一个“隐藏的API”,你将无法访问它(因为它是隐藏的),所以没关系。 此外,延伸的性质已经表明没有。 毕竟,如果硬件具有实际的片段数量,为什么不直接暴露在桌面OpenGL的方式呢? 如果硬件支持它,他们可能已经采取了ARB_occlusion_query并使用它。

但他们没有。 这强烈表明他们不能。

结果是返回一个GLuint,(也可以GLint为另一个不同的调用)不幸的是,结果总是一个0或1,也许他们会改变它注册碎片在未来。

在整个互联网上看起来也不是一个人发布了关于这些新的扩展…所以在这里他们设置正确…这是没有logging在任何地方,据我可以告诉…你可以想象他们是如何会从这个小的sudo代码在这里你的代码:

 import UIKit/UIKit.h import GLKit/GLKit.h import "GLProgram.h" GLuint testBox,hasBeenTested,theParams; //... glGenQueriesEXT(1, &testBox); glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, testBox); //... draw an object ....... glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); glGetQueryObjectuivEXT(testBox, GL_QUERY_RESULT_AVAILABLE_EXT, &hasBeenTested); if (hasBeenTested) glGetQueryObjectuivEXT(testBox, GL_QUERY_RESULT_EXT, &theParams); glDeleteQueriesEXT(1, &testBox); if (!theParams) object is hidden; don't draw next time;