好吧,所以这一直困扰我一段时间,并且在MSDN上找不到任何涉及我需要的细节的内容。
这更像是一个3部分的问题,所以在这里:
1-)创建交换链应用程序时,请指定后备缓冲区像素格式,最常见的是B8G8R8A8或R8G8B8A8。这为每个颜色通道提供了8位,因此每个像素总共使用4个字节....所以为什么当float4实际上是16个字节时,像素着色器必须将颜色作为float4返回?
2-)当将纹理绑定到Pixel Shader时,我的纹理是DXGI_FORMAT_B8G8R8A8_UNORM格式,但为什么采样器需要每个像素一个float4才能工作?
3-)我在这里遗漏了什么?我是在思考这个还是什么?
请提供支持您声明的链接。最好来自MSDN !!!!
答案 0 :(得分:7)
GPU旨在对32位浮点数据执行计算,至少如果他们想要支持D3D11。从D3D10开始,您还可以执行32位有符号和无符号整数运算。对于HLSL中小于4字节的类型没有要求或语言支持,所以没有" byte / char"或"短"对于1和2字节整数或较低精度浮点。
任何使用" FLOAT"," UNORM"的DXGI格式或" SNORM"后缀是非整数格式,而" UINT"和" SINT"是无符号和有符号整数。前三种类型着色器执行的任何读取都将作为32位浮点提供给着色器,而不管原始格式是8位UNORM / SNORM还是10/11/16/32位浮点。顶点中的数据通常以比全脂32位浮点更低的精度存储以节省内存,但是当它到达着色器时它已经被转换为32位浮点数。
在输出(无人机或渲染目标)上,GPU压缩"浮动"或" uint"数据到目标创建的任何格式。如果您尝试将float4(4.4, 5.5, 6.6, 10.1)
输出到8位标准化的目标,那么它将被截断为(1.0,1.0,1.0,1.0)并且每个像素只消耗4个字节。
所以回答你的问题:
1)因为着色器仅在32位类型上运行,但GPU将根据需要压缩/截断您的输出,以存储在您当前根据其类型绑定的资源中。如果GPU支持的每种格式都有特殊的关键字和类型,那就太疯狂了。
2)&#34;采样器&#34;并不需要每个像素一个浮点数4来工作&#34;我认为你正在混合你的术语。纹理是Texture2D<float4>
的声明实际上只是声明这个纹理有四个组件并且格式不是整数格式。 &#34;浮动&#34;并不一定意味着源数据是32位浮点(或实际上甚至是浮点),而仅仅是数据具有一个小数分量(例如0.54,1.32)。同样地,将纹理声明为Texture2D<uint4>
并不意味着源数据必须是32位无符号,但更多的是它包含无符号整数数据的四个分量。但是,数据将返回给您并转换为32位浮点数或32位整数,以便在着色器中使用。
3)你错过了GPU在读取时解压缩纹理/顶点数据并在写入时再次压缩它的事实。用于顶点/纹理数据的存储量仅与创建资源的格式一样多,并且与着色器在32位浮点数/整数上运行的事实无关。