当前位置: 首页 > news >正文

怎样使用深度纹理

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

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

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

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

* 要检测这些格式的有效性, 可使用CheckDeviceFormat() API.
-
因此, 对于ATi16位深度纹理需要调用
:
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的深度纹理进行采样返回的不是真正意义上的深度值).

* 纹理表面(surface)创建
同样的, ATinVidia的调用只有一点不同:
-
对于
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() 来使用.

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

自动迎合ATinVidia版本的深度纹理创建应该是很简单的, 因为它们在代码上非常相似. 大部分的工作在于HLSL shader代码中的#ifdef来区分ATinVidia风格的逐像素阴影贡献计算. 双方的开发网站上都有相应的代码和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

相关文章:

  • LeetCode -- Expression Add Operators
  • [Web 开发] 获取页面元素的坐标及大小
  • LeetCode -- First Bad Version
  • 本地SPAN和远程SPAN监控原理
  • LeetCode -- House Robber II
  • 打破传统,实战至上的网管师认证
  • LeetCode -- Invert Binary Tree
  • 使用简单ORM开发框架进行快速开发
  • LeetCode -- Largest Number
  • LeetCode -- Length of last word
  • 编程是一种“组合的艺术”
  • LeetCode -- Majority Element II
  • 3G上网卡招标,华为成最大赢家
  • LeetCode -- Nim Game
  • 近期阅读关注(200905)
  • 【Leetcode】101. 对称二叉树
  • 分享的文章《人生如棋》
  • [case10]使用RSQL实现端到端的动态查询
  • 【个人向】《HTTP图解》阅后小结
  • android 一些 utils
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • Java 多线程编程之:notify 和 wait 用法
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • Laravel Mix运行时关于es2015报错解决方案
  • MaxCompute访问TableStore(OTS) 数据
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • nodejs:开发并发布一个nodejs包
  • SpiderData 2019年2月25日 DApp数据排行榜
  • storm drpc实例
  • Unix命令
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 当SetTimeout遇到了字符串
  • 仿天猫超市收藏抛物线动画工具库
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 用element的upload组件实现多图片上传和压缩
  • C# - 为值类型重定义相等性
  • 进程与线程(三)——进程/线程间通信
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • $.ajax()
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (五)关系数据库标准语言SQL
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • ***详解账号泄露:全球约1亿用户已泄露
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .NET简谈设计模式之(单件模式)
  • ??在JSP中,java和JavaScript如何交互?
  • @AutoConfigurationPackage的使用