有没有人成功使用此扩展程序? Khronos规范可以在这里阅读:NV_depth_nonlinear extension
我已通过EGL配置选择成功检查扩展名:
public class CustomEGLConfigChooser implements EGLConfigChooser {
private static final int EGL_DEPTH_ENCODING_NV = 0x30E2;
private static final int EGL_DEPTH_ENCODING_NONLINEAR_NV = 0x30E3;
private int[] mValue = new int[1];
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
// request configs
EGLConfig[] configs = egl.eglChooseConfig(...);
// ...
EGLConfig bestConfig = null;
for(EGLConfig config : configs){
// check for EGL_DEPTH_ENCODING_NV
egl.eglGetConfigAttrib(display, config, EGL_DEPTH_ENCODING_NV, 0);
int hasDepthNonLinear = findConfigAttrib(egl, display, config, EGL_DEPTH_ENCODING_NV, 0);
if(hasDepthNonLinear == EGL_DEPTH_ENCODING_NONLINEAR_NV) {
// what to do now ???...
}
}
return bestConfig;
}
private int findConfigAttrib (EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue) {
if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
return mValue[0];
}
return defaultValue;
}
}
但是如何使用非线性深度扩展?我必须使用:
glBindRenderbuffer(...);
glRenderbufferStorage(...);
答案 0 :(得分:1)
为了开始使用任何GPU的非线性Z缓冲区,您需要启用扩展(就像您在代码中所做的那样)而不是其他内容。
非线性Z缓冲区由GPU本身处理,并且我们通常没有意识到,它被大多数现代GPU使用。
正如这篇有趣的文章(http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html)所述:
Z的决议。
人们经常没有意识到的是,在几乎所有的机器中, Z缓冲区是非线性的。存储在Z缓冲区中的实际数字 memory以这种方式与对象的Z坐标相关:
z_buffer_value =(1<
其中:
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. 缓冲区的位被浪费 - 将精细的细节存储在靠近的位置 在平面附近。如果你将近夹子拉近眼睛,那么 越来越多的比特专注于渲染事物的任务 靠近你的地方,精确度要高得多 进行。
因此,在大多数情况下,闪烁可以大大减少 - 或 甚至通过将近夹片平面从您的眼睛移开来消除。
在我的谦逊经历中,我已经在TEGRA中成功使用了非线性ZBuffer,正如我在此回复中所建议的那样,因此,我可以说它的工作原理如此。
答案 1 :(得分:0)
在Nexus 7上进行测试,我可以通过添加eglChooseConfig
电话来实现此目的:
EGL_DEPTH_ENCODING_NV, EGL_DEPTH_ENCODING_NONLINEAR_NV,
并使用
DEPTH_COMPONENT16_NONLINEAR_NV
代替我GL_DEPTH_COMPONENT16
来电glRenderbufferStorage
。
编辑:实际上我们不会为主要的egl表面使用深度缓冲区,因此只需要GL_DEPTH_COMPONENT16_NONLINEAR_NV
。还将DEPTH_COMPONENT16_NONLINEAR_NV
更改为GL_DEPTH_COMPONENT16_NONLINEAR_NV
,因为它在NDK中已定义。