OPENGL深度缓存精度问题及解决

来源:互联网 发布:java视频教程百度网盘 编辑:程序博客网 时间:2024/05/16 19:00
 前段时间做的东西需要读取场景的深度图,本打算使用OPENGL自带函数glReadPiexles()去实现此功能,但OPENGL中只提供读取单个像素处的深度信息,不支持读取整个深度缓存的功能。且当时感觉读取到深度是个单字节的,也看到网上有人说深度缓冲和模板缓冲共用4个字节,就自己使用GLSL改写了渲染管道,将深度信息直接渲染出来,这种方法可生成32位精度的深度图。     这段时间又翻阅了OPENGL,发现深度缓冲并不是像网上某些人说的(他们可能指的很久以前或者其它渲染引擎)只占一个或两个字节。OPENGL深度缓冲的可为8,16,24,32都可以,但GLUT没有提出直接 设置方式,书上说自动选择最优的深度位数。而我们若想改变深度缓冲的每个像素所占字节,有以下两种方案:    一,使用WINDOWS下的提出的设置渲染场景的方式,设置像素格式,可实现深度位设置。..........................................        代码省略..........................................


     pfd.cDetpBit=24;二,使用帧缓存P Frame Buffer为帧缓存设置深度缓存时设置深度位数   //创建FBO
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);


// 创建深度红缓存
glGenRenderbuffersEXT(1, &depthBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, width, height);//设置为32
       暂时只找到两种设置深度缓存位数的方式,如果想查询当前环境的深度缓存可使用               glGetIntegerv(GL_DEPTH_BITS,&x);
       深度缓存的作用就不多说了,下面说说为什么设置深度缓冲的位数总结网上解决方法。深度缓存位数越高,代表深度缓冲的精度也就越高,在通过ZBUFFE进行比较渲染时就不容易出现Z-fight问题,如果当前深度缓冲下,仍出现了Z-fight问题,说明此时深度缓冲精度不够,此外在使用阴影贴图(shadow Map)方式生成阴影时也需要高精度的深度缓冲,此时有三个解决方法一,OPENGL中可使用改变深度缓存位数的方式稍加改善,有的显卡已经支持浮点数深度缓存,这个时候使用浮点缓存可更加提高(没见过,也没用过),这个思路 就是尽可能提高深度缓存精度,可解决部分Z-Fighting问题。对于生成阴影的方面,除了采用这个方式外(同样适于Z-fighting,有种高射炮打蚊子的感觉),还可过自己SHADER语言重写ZBUFFER缓存的方式来提高精度,这个时候深度信息你可以设置DOUBLE型,也就没有这么多限制,但这种方式增加了计算量,如何选择看自己。二,就是通过深度偏移方式来解决Z-fignth问题,OPENGL使用下面方式,D3D类似 rdener1()//绘制物体glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(0.0f,-1.0f)
rdener2()//绘制物体
这种方式,不同移动,移动后渲染,物体不在原来位置,而使用深度偏移后,物体 仍在原来位置。三,是网上一位前辈说的,增大近裁剪面距离,公式推导有兴趣的阅读http://www.cnitblog.com/lethep/articles/25570.html


0 0