您的位置:首页 > 运维架构

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

2015-11-09 22:24 302 查看
前段时间做的东西需要读取场景的深度图,本打算使用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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: