首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >HLSL中的3D缓冲区?

HLSL中的3D缓冲区?
EN

Stack Overflow用户
提问于 2016-11-18 06:10:39
回答 2查看 1.5K关注 0票数 0

我想把一系列的整数以3D数组的形式用统一的形式发送到HLSL。我已经试着做了几天了,但没有任何收获。我试图将缓冲区打包到另一个(StructuredBuffer<StructuredBuffer<StructuredBuffer<int>>>)中,但它根本无法工作。我需要使这个东西可调整大小,所以我不能在structs中使用数组。我该怎么办?

编辑:为了进一步澄清我在这里要做的事情,这是一个医疗项目。当你对身体进行扫描时,会生成一些文件。这些文件称为DICOM文件(.dcm)。这些文件被分发给了医生。医生应该打开程序,选择所有的DICOM文件并加载它们。每个DICOM文件都包含一个图像。然而,这些图像并不是我们日常生活中使用的正常图像。这些图像是灰度的,每个像素的值在-1000到几千之间,因此每个像素被保存为2个字节(或一个Int16)。我需要生成被扫描的身体的三维模型,所以我使用Marching多维数据集算法来生成它(请看一下标量场的多边形化)。问题是我经常在360 512*512大小的图像中循环每个像素,这花费了太多的时间。当我使用CPU时,我常常在需要时从每个文件中读取像素数据。现在,我正在尝试使这个过程在运行时发生。在处理之前,我需要将所有像素数据发送到GPU。这是我的问题。我需要GPU从磁盘读取数据。因为这是不可能的,我需要以Ints的3D数组的形式向GPU发送360*512*512*4字节的数据。我还计划将数据保存在那里,以避免大量内存的重新传输。我该怎么办?请参阅此链接,以了解更多关于我正在做什么的信息

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-21 13:04:08

根据我所理解的,我建议尝试以下几种方法:

  1. 夷平数据(嵌套缓冲区不是gpu上想要的)
  2. 如果有必要,可以将数据拆分到多个ComputeBuffers (当我在Nvidia上使用它们时,每个缓冲区可以存储大约1GB的数据。我用1.5GB的数据渲染了一个3D点云,你提到的360 360MBytes的数据不应该是问题)
  3. 如果您需要多个缓冲区:根据您的行进立方体算法的需要,让它们重叠。
  4. ComputeShader中进行所有计算(我认为需要DX11,如果有多个缓冲区,则运行多次并累积结果),然后在标准着色器中使用OnPostRender函数调用的结果(使用Graphics.DrawProcedural内部绘制点或在gpu上构建网格)

编辑(您可能感兴趣)

如果您想将数据附加到gpu缓冲区(因为您不知道确切的大小,或者不能立即将其写入gpu ),则可以使用AppendBuffersComputeShader

C#脚本片段:

代码语言:javascript
代码运行次数:0
运行
复制
struct DataStruct
{
    ...
}

DataStruct[] yourData;
yourData = loadStuff();    

ComputeBuffer tmpBuffer = new ComputeBuffer(512, Marshal.SizeOf(typeof(DataStruct)));
ComputeBuffer gpuData = new ComputeBuffer(MAX_SIZE, Marshal.SizeOf(typeof(DataStruct)), ComputeBufferType.Append);

for (int i = 0; i < yourData.Length / 512; i++) {

    // write data subset to temporary buffer on gpu
    tmpBuffer.SetData(DataStruct.Skip(i*512).Take((i+1)*512).ToArray()); // Use fancy Linq stuff to select data subset

    // set up and run compute shader for appending data to "gpuData" buffer
    AppendComputeShader.SetBuffer(0, "inBuffer", tmpBuffer);
    AppendComputeShader.SetBuffer(0, "appendBuffer", gpuData);
    AppendComputeShader.Dispatch(0, 512/8, 1, 1); // 8 = gpu work group size -> use 512/8 work groups
}

ComputeShader:

代码语言:javascript
代码运行次数:0
运行
复制
struct DataStruct // replicate struct in shader
{
    ...
}

#pragma kernel append
StructuredBuffer<DataStruct> inBuffer;
AppendStructuredBuffer<DataStruct> appendBuffer;

[numthreads(8,1,1)]
void append(int id: SV_DispatchThreadID) {
    appendBuffer.Append(inBuffer[id]);
}

注意:

  • AppendComputeShader必须通过检验员分配
  • 512是一个任意的批处理大小,有一个上限,您可以同时添加多少数据到gpu缓冲区,但我认为这取决于硬件(对我来说,它似乎是65536 *4字节)。
  • 您必须为gpu缓冲区提供最大大小(在泰坦X上,它似乎是~1GB)
票数 1
EN

Stack Overflow用户

发布于 2016-11-18 18:56:03

在团结中,我们目前有一个MaterialPropertyBlock,它允许SetMatrixArraySetVectorArray,为了使它更加甜美,我们可以使用static SetGlobalVectorArraySetGlobalMatrixArray进行全局设置。我相信这些会帮到你的。

如果您喜欢旧的方式,请查看这篇很好的文章演示如何传递向量数组。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40670427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档