D3D9中如何访问深度缓冲?

Leon8086 2005-12-17 08:07:56
我指的是访问其中对应的像素的值,对于这个在某些处理上还是很有用处的,但D3D9的Surface对应的Buffer Format中貌似只有D3DFMT_D16_LOCKABLE和D3DFMT_D32F_LOCKABLE可以锁定,其他的都不能锁定,而这两种格式在我的显卡(GF5600)上不支持,我想大部分显卡都不支持吧?另外无论是D3D8的CopyRect或者9的UpdateSurface都不能对DepthStencil缓冲表面进行操作。

所以我想知道D3D中有没有什么方法可以访问某个像素对应的深度值?
...全文
396 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jedimaster 2006-02-01
  • 打赏
  • 举报
回复
OpenGL有FBO
why54 2005-12-21
  • 打赏
  • 举报
回复
to:Leon8086
能否把你的方法贡献出来,大家都看看是怎么解决的,谢谢
寻开心 2005-12-21
  • 打赏
  • 举报
回复
dx9 当中有一个新技术可以用
http://data.gameres.com/message.asp?TopicID=11409

遮挡判断在这里用的就是z的数值,但是这个功能是封装在内部接口里面的
也就是说,dx自己可以用zbuffer的数值,而我们还不行
寻开心 2005-12-21
  • 打赏
  • 举报
回复
opengl当中也没有提供直接访问缓冲区的功能
而是通过ReadPixel这样的功能实现的,速度也比较慢

它所谓的支持,也是变相的

Question:
How do I access the frame/depth/texture memory directly?

Answer:
You don't. OpenGL does not provide any interface for accessing this memory directly. You can get access to the contents of those buffers by using glReadPixels() but it is slow. There has been much debate over whether this is a good thing or a bad thing, but the reasons are basically irrelevant. You can't get direct access through OpenGL. Access to these buffers belongs in the windowing system and not in the OpenGL API. Currently MS Windows does not provide any means to access this information.
寻开心 2005-12-20
  • 打赏
  • 举报
回复
1 现代的显卡自己会对1/z进行插值的,不仅仅是顶点,中间点也会做到的

2 借助vs访问zbuffer也是一种办法

3 LPDIRECT3DSURFACE8 pZBuffer;
m_d3dDevice->GetDepthStencilSurface( &pZBuffer );
Leon8086 2005-12-20
  • 打赏
  • 举报
回复
1.2的gl支持从depth buffer中读取数据,不过没试过,不知道是否能用硬件加速来实现。也不知道开销多大,精度多高。

DX中的zbuffer数据是属于“可用,但不可访问”类型的,实在烦。

回头看看用gl能不能实现。
Leon8086 2005-12-20
  • 打赏
  • 举报
回复
哎,花了不少力气终于能满足要求了。还是只能编码到rgb上来作,可以达到小数点后面5~6位的精度。
寻开心 2005-12-20
  • 打赏
  • 举报
回复
redner to texture 的一个例子
http://www.two-kings.de/tutorials/dxgraphics/dxgraphics16.html
寻开心 2005-12-20
  • 打赏
  • 举报
回复
opengl是支持硬件设备无关的深度缓冲连接功能的, dx没有这个功能(dx当中是和显卡相关的)
http://www.xmission.com/~legalize/d3d-vs-opengl.html
Frame Buffer 第一项对比当中做了这个说明

寻开心 2005-12-20
  • 打赏
  • 举报
回复
是的, D3DFMT_D16_LOCKABLE 之类是需要硬件支持的

这个是dx的架构设置的问题,XBox没有这个问题,opengl应该也没有这个限制
opengl 1.2以上是提供了这个能力的

dx是提供了另外一种备选方案的
The only way to do it would be to create a Depth texture, do a render there and then use this depth texture to do the same thing.
Leon8086 2005-12-20
  • 打赏
  • 举报
回复
在我的机器上,根据经验,vs内部浮点计算的精度是小数点后面6位的样子,我希望至少能保持这个精度。
Leon8086 2005-12-20
  • 打赏
  • 举报
回复
关键是用3这个方法得到的zbuffer是不可以lock,这样就不能取得对应点的深度值。

用vs编码z值的方法最大的问题在于精度,即便target的像素格式是float型的,经过插值得到的z如果放置在rgba位的话,他在小数点后面第3位就会出现误差,误差在0.001~0.002左右(估计是因为GPU内部对颜色依然是使用8位进行插值运算),如果考虑到使用的z必须归一化到0~1.0上的话,假设整个场景的深度有100m左右,那么这个误差就有10cm这么大,就是小数点后面1位。

归一化是必须作的,颜色值如果不在0~1之间的话会被自动截断0~1之间。
mimile 2005-12-19
  • 打赏
  • 举报
回复
做完world view proj变换之后的z/w,存到rendertarget里,如果不支持multi-rendertarget,只好多画一个pass,target的格式任意,自己保证一致就可以了
mimile 2005-12-19
  • 打赏
  • 举报
回复
在ps中作除法,如果在vs中除好了的话范围就到0~1了,误差自然就大了
Leon8086 2005-12-19
  • 打赏
  • 举报
回复
我的做法是写一个vs,将z编码在顶点对应的rgba里面,但是这样精度上的损失是比较大的,经过插值之后得到的z值往往精度达不到小数点后面第二位的精度。
why54 2005-12-19
  • 打赏
  • 举报
回复
还是不明白???
why54 2005-12-18
  • 打赏
  • 举报
回复
楼上能否详细介绍一下模拟depthbuffer的技术,谢谢,
听说有一种1/Z的技术,据说在解决Z缓冲精度不足问题上很有用,知道该技术的实现吗?
mimile 2005-12-17
  • 打赏
  • 举报
回复
不支持的话只有自己模拟一下depthbuffer了,其实自己模拟的好处还是很多的,比如可以在ps中访问

8,303

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧