程序员被D3D的一堆格式搅的心神不宁、如坠云雾,这是可以理解的,因为MS对底层封装一般,而且不对情形做任何解释,我只能在主观猜测的基础上对
显示系统做个最粗浅的说明,权当参考,希望对初学者有帮助。D3D将顶点绘制到最终的显示器上经历了太多了磨难,但我不在此不说明顶点变换和光栅化部分,
因为这属于3D图形范畴,这里要阐明的是D3D没有开放给程序员的部分,viewport以及从PS里出来到显示器上对应像素的流程。
简单说明下显示系统的层级结构:
人眼 —肌肉— GDI桌面 —windows manager— 窗口Client —present— D3D Backbuffer —— PS —rasterization viewport— VS
我对D3D不太熟悉,但根据硬件的原理,推出几个简单的格式适用规则:
1、全屏模式的D3D程序的backbuffer不能使用带ALPHA通道的格式,大家可以到DirectX Caps Viewer / D3D9 Devices / Display Modes中求证。
因为显示器本身的最终缓冲无法透明(否则不看到机器里的零件了)。
2、现代的显卡不支持16位色以下的落后格式。
得不偿失。
3、窗口模式的程序Backbuffer可以使用格式必须能简单转换到当前桌面显示的格式(最好是相同的),一般只支持X8R8G8B8和A8R8G8B8。
实时Present,考虑到转换效率。
4、RenderTarget和Backbuffer还是有点差别,个人觉得可以直接Present到显示Buffer的RenderTarget叫做Backbuffer,所以相比Backbuffer
只用来做RenderTexture的RenderTarget格式应该非常丰富,至少支持带ALPHA通道的格式。
因为毕竟不用直接显示,而在shader计算中通过采样计算输出显示透明转换格式是比较廉价的。
6、限制最少的应该就是Texuture Format和Plain Surface Format。
因为这两个一般都只在计算内部用,不会直接显示。
结论可能有错误,欢迎拍砖:)
现在流行shader mode版本为2.0/2.x,开放了顶点变换和像素着色计算,但没有开放光栅化部分,当然是效率考虑,唯独在之前提供了一个viewport机制,
三角形顶点坐标经VS变换到投影空间,又经viewport缩放平移后进入光栅化,由光栅单元按需启动PS(MSAA)计算好像素颜色后,绘制到对应的rendertarget
像素,而present控制backbuffer绘制到窗口的区域,在此再经过硬件的缩放和平移,而窗口的client显示区域则早由windows manager平移过(没有缩放),
而整个桌面缓冲显示到显示器,则还会经过显示器缩放和平移(调节显示器上的按钮控制);最后经过眼睛的透视成像,经过神经反馈在大脑中形成图像!
D3D9文档中有一段rasterization rules,指明了像素中心对应了准确的坐标,比如(0,0)指renderTarget最左上角的像素(注意不是窗口),
viewport还必须在正式光栅化之前,而纹理采样就不同了,纹理坐标(0,0)在D3D9中居然不对应着最左上角纹素的中心,想要正好采中纹素,还需
自己在坐标上偏移半个纹素,有点恶心。
有人问我关于D3D10和D3D11的API问题,说实在我真不熟悉,其实就理解图形软硬件原理来说,D3D9是最合适的,因为它封装得最少(所以丑陋),
我觉得在3D算法上,D3D和9/10/11三个版本差别很小。大方面上,10相比9多了一个GS和stream-out,纹理矩阵和VS取纹理也勉强算吧,而相比
10,11就多了曲面曲线方面的算法功能Tesselation,而且加了个太监的CS。当然API接口上一代比一代整洁人性化,效率可能也更高,不过单从揣摩学习上
来讲,个人觉得D3D9比较合适,更何况目前D3D9还是主流。