hlsl 中使用的常量缓冲区(cbuffer)究竟是什么?

IOS*_*IOS 3 directx buffer constants hlsl

目前,我的顶点着色器类中有此代码:

cbuffer MatrixBuffer {
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix; };
Run Code Online (Sandbox Code Playgroud)

我不知道为什么我需要将这些变量包装在 cbuffer 中。如果我删除缓冲区,我的代码也能正常工作。如果有人能给我一个简短的解释,为什么使用 cbuffers 是必要的,我将不胜感激。

Chu*_*urn 6

无论哪种方式都可以工作的原因是由于在 Direct3D 8/Direct3D 9 中处理常量的传统方式。当时,整个着色器只有一个共享常量数组(一个用于 VS,一个用于 PS)。这要求您每次调用Draw.

在 Direct3D 10 中,常量被重新组织到一个或多个常量缓冲区中,以便更轻松地更新某些常量,同时保留其他常量,从而减少向 GPU 发送的数据。

请参阅经典演示Windows to Reality:在游戏中充分利用 Direct3D 10 图形,了解有关不断更新影响的大量详细信息。

这里的结果是,如果你不指定cbuffer,所有的常量都会被放入一个单一的隐式常量缓冲区,绑定到寄存器b0来模拟旧的“一个常量数组”行为。

有编译器标志来控制对旧构造的接受:/Gec用于向后兼容模式以支持旧的 Direct3D 8/9 内在函数,并/Ges启用更严格的编译以淘汰旧的构造。也就是说,HLSL 编译器几乎总是会接受全局常量,cbuffer并将它们粘贴到单个隐式常量缓冲区中,因为这种模式在着色器代码中极为常见。