前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >怎样使用深度纹理

怎样使用深度纹理

作者头像
逍遥剑客
发布2022-01-11 15:08:20
6160
发布2022-01-11 15:08:20
举报
文章被收录于专栏:逍遥剑客的游戏开发

这个问题经常出现, 所以我试着来总结一下ATi和nVidia芯片对于深度纹理的支持情况. 如果发现我说错了nVidia的深度实现, 请告知我 :)

ATi和nVidia在硬件上都支持深度纹理, 虽然方法不一样. 深度纹理的创建非常相似:

代码语言:javascript
复制
* 曝光的格式
- ATi曝光了两个FOURCC 来创建16或24位深度的纹理:
#define FOURCC_DF16 ((D3DFORMAT) MAKEFOURCC('D','F','1','6'))  #define FOURCC_DF24 ((D3DFORMAT) MAKEFOURCC('D','F','2','4'))  
DF16在R300或以上的芯片(9500+)上支持而DF24 只有RV530 和以上的芯片(X1600和X1900)才支持.
- nVidia 使用预定义的D3DFMT_D16 和D3DFMT_D24S8 格式.GeForce3 和之后的芯片都支持这个.

大多数情况下16位的格式应该满足多数需要了. 只要你适当地选择投影矩阵(近裁剪面尽量大)并且Z的范围适当, 它的精度是足够的. 强烈建议尽可能选择16位的Shadow map, 因为它具有更好的性能, 而且被广泛支持.

代码语言:javascript
复制
* 要检测这些格式的有效性, 可使用CheckDeviceFormat() API. 
- 因此, 对于ATi的16位深度纹理需要调用:
hres = d3d->CheckDeviceFormat(Adapter, DeviceType, AdapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_DF16); 
- 对于nVidia:
hres = d3d->CheckDeviceFormat(Adapter, DeviceType, AdapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_D16); 

注意, 检查nVidia的设备ID比上面的做法更安全, 因为nVidia的深度纹理是”重载”的现有格式(一个关键的不同就是对nVidia的深度纹理进行采样返回的不是真正意义上的深度值).

代码语言:javascript
复制
* 纹理表面(surface)创建
同样的, ATi和nVidia的调用只有一点不同:
- 对于ATI:
hres = d3ddevice->CreateTexture(ShadowMapWidth, ShadowMapHeight, 1, D3DUSAGE_DEPTHSTENCIL, FOURCC_DF16, D3DPOOL_DEFAULT, &pShadowMap); 
- 对于nVidia:
hres = d3ddevice->CreateTexture(ShadowMapWidth, ShadowMapHeight, 1, D3DUSAGE_DEPTHSTENCIL, D3DFMT_D16,  D3DPOOL_DEFAULT, &pShadowMap); 

* 中间的设置(surface绑定, viewport, 等等) 两者都是一样的.

* 当渲染完成后深度纹理可以当作是一张普通纹理通过SetTexture() 来使用.

* ATi和nVidia的深度纹理实现的主要不同是在shader的使用上. - 从ATi深度纹理进行采样会返回深度值. 这需要shader取出深度并与输入的Z值进行比较. 这样允许更为灵活的为每个采样选择滤波掩模(kernel)和权重. X1600和X1900支持一项叫做Fetch4的特性, 它会在每次纹理指令执行时返回四个邻近的深度采样到目标RGBA通道. 这就使高性能的shadow map和更大的掩模成为可能. - 从nVidia的深度纹理进行采样会返回PCF(Percentage-Closer-Filtered)的结果, 并且在采样的同时会自动与输入的Z值做比较.

自动迎合ATi或nVidia版本的深度纹理创建应该是很简单的, 因为它们在代码上非常相似. 大部分的工作在于HLSL shader代码中的#ifdef来区分ATi和nVidia风格的逐像素阴影贡献计算. 双方的开发网站上都有相应的代码和shader示例和文档. 为了确保高性能, 有两条值得注意的事情(基于实际的例子:)):

- 记着在渲染投影物体到深度纹理时关闭颜色写入(color write). 大多数情况下你会对深度纹理的内容感兴趣(运行时需要绑定一个有效的跟深度纹理/纹理大小一致的颜色缓冲(color buffer)). "忘记"关闭颜色写入会引起不必要的颜色缓冲带宽消耗.

- 关于渲染透明(alpha测试)投影物体到深度纹理: 确保只对需要透明的三角形开启了alpha测试 (或者texkill 如果目标surface不能与 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING一起使用). 为所有投影物体 保持alpha测试开着(或使用一个texkill shader)会让早期的Z优势失效, 因为pixel shader可能会在深度比较之前执行. 所有阴影渲染也可以使用同一个灵活的shader, 但这需要付出额外的步骤:) Nick European Developer Relations, ATI Technologies MrT@ati.com

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2009/05/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档