directx - 在 HLSL 中随机访问 R8G8B8A8_UNorm 格式的 D3D11 缓冲区

标签 directx directx-11 hlsl

我有一个包含几百万个元素的 D3D11 缓冲区,该缓冲区应该保存 R8G8B8A8_UNorm 中的数据。格式。

所需的行为如下:一个着色器计算 vec4并以随机访问模式将其写入缓冲区。在下一个 channel 中,另一个着色器以随机访问模式读取数据并进一步处理它们。

我最好的猜测是创建一个 UnorderedAccessViewR8G8B8A8_UNorm格式。但我如何声明 RWBuffer<?>在 HLSL 中,如何写入和读取?是否有必要声明为RWBuffer<uint>并从 vec4 进行包装至uint手动?

在 OpenGL 中,我将创建一个缓冲区和一个缓冲区纹理。然后我可以声明 imageBufferrgba8在着色器中格式化,通过 imageLoad 访问它和imageStore ,硬件为我完成所有转换。这在 D3D11 中可能吗?

最佳答案

由于有很多不同的问题,这有点棘手,但你应该能够做这样的事情。

在写入缓冲区的着色器中声明:

RWBuffer<float4> WriteBuf : register( u1 );

请注意,它必须注册 u1 而不是 u0。无序访问 View (UAV) 必须从插槽 1 开始,因为 u# 寄存器也用于渲染目标。

要写入缓冲区,只需执行以下操作:

WriteBuf[0] = float4(0.5, 0.5, 0, 1);

请注意,您必须一次写入所有 4 个值。

在您的 C++ 代码中,您必须创建一个无序访问缓冲区,并将其绑定(bind)到无人机。您可以使用DXGI_FORMAT_R8G8B8A8_UNORM格式。当您向其中写入 4 个 float 时,这些值将自动转换并打包。可以使用 OMSetRenderTargetsAndUnorderedAccessViews 将无人机绑定(bind)到管道。

在从缓冲区读取的着色器中声明一个只读缓冲区:

Buffer<float4> ReadBuf : register( t0 );

请注意,此缓冲区使用 t0,因为它将绑定(bind)为着色器资源 View (SRV) 而不是 UAV。

要访问缓冲区,请使用以下内容:

float4 val = ReadBuf[0];

在您的 C++ 代码中,您可以将之前创建的相同缓冲区绑定(bind)到 SRV 而不是 UAV。 SRV 可以使用 PSSetShaderResources 绑定(bind)到管道,也可以使用 DXGI_FORMAT_R8G8B8A8_UNORM 创建。

您不能同时将使用相同缓冲区的 SRV 和 UAV 绑定(bind)到管道。因此,您必须首先绑定(bind)无人机并运行第一个着色器 channel 。然后解除无人机的绑定(bind),绑定(bind)SRV,并运行第二个着色器 channel 。

可能还有其他方法可以做到这一点。请注意,所有这些都需要着色器模型 5。

关于directx - 在 HLSL 中随机访问 R8G8B8A8_UNorm 格式的 D3D11 缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26611274/

相关文章:

c++ - 访问冲突读取位置 0x00184000

C++ 多定义符号

c++ - 在 Windows 8 上使用 Media Engine 播放音乐

c# - HLSL 和 XNA : How do I get the position and color of surrounding pixels of the current pixel shader iteration?

directx - HLSL:在结构内使用数组

c++ - win32原始键盘输入删除自动重复

c++ - 为什么我的选择功能会出现意外行为?

c++ - Windows 8.1 上的 DirectX 11 缺少 SDK 组件

c++ - 明智地填充 texture3d 切片

c# - Bézier 曲线、Loop 和 Blinn 样式