繁体   English   中英

在金属中手动设置1D纹理

[英]Manually set a 1D Texture in Metal

我试图手动用值填充一维纹理并将该纹理传递到计算着色器(这些是我要通过代码设置的2个像素,它们不代表任何图像)。

由于目前仅有少量的Metal示例,我可以找到所有示例,这些示例都涉及2D纹理 ,该2D纹理通过将已加载的UIImage转换为原始字节数据来加载纹理,但是创建虚拟UIImage对我来说就像是hack。

这是我开始的“天真”方式-

...
var manualTextureData: [Float] = [ 1.0, 0.0, 0.0, 1.0,
                                   0.0, 0.0, 1.0, 1.0 ];
let region: MTLRegion = MTLRegionMake1D(0, textureDescriptor.width);
myTexture.replaceRegion(region, mipmapLevel: 0, withBytes: &manualTextureData, bytesPerRow: 0);

但是Metal无法在着色器中识别这些值(除第一个值外,它将获得空纹理)。

我很快意识到Float数组可能必须转换为字节数组(例如UInt8 ),但是也找不到从[Float]转换为[UInt8]方法。

我考虑的另一个可能的选择是使用CVPixelBuffer对象,但这也感觉像是解决该问题的方法。

那么解决这个问题的正确方法是什么?

提前致谢。

  • 请注意,我对Objective-C并不熟悉,因此我不确定使用CVPixelBuffer / UIImage是否会因为某些简单的事情而被夸大。

如果要浮动纹理,则bytesPerRow应为宽度的4倍,因为浮动的大小为4个字节。 Metal复制内存,而不关心值。 那是你的任务;-)

就像是:

myTexture.replaceRegion(region, mipmapLevel: 0, withBytes: &manualTextureData, bytesPerRow: manualTextureData.count * sizeof(Float));

我看不出有任何理由使用1D纹理传递数据。 相反,我会只传递一个缓冲区。 像这样:

var dataBuffer:MTLBuffer? = device.newBufferWithBytes(&manualTextureData, length: sizeOf(manualTextureData), options: MTLResourceOptions.OptionCPUCacheModeDefault)

然后像这样将其挂接到您的renderCommandEncoder

renderCommandEncoder.setFragmentBuffer(dataBuffer, offset: 0, atIndex: 1)//Note that if you want this buffer to be passed to you vertex shader you should use setVertexBuffer

然后在您的着色器中,应添加类似此const device float* bufferPassed [[ buffer(1) ]]参数const device float* bufferPassed [[ buffer(1) ]]

然后在着色器实现中像这样使用它:

float firstFloat = bufferPassed[0];

这样就可以完成工作。

不能真正回答您的问题,但是您可以在金属着色器中定义一个数组,而不是将值作为纹理传递。

就像是:

constant float manualData[8] = { 1.0, 0.0, 0.0, 1.0,
                               0.0, 0.0, 1.0, 1.0 };

vertex float4 world_vertex(unsigned int vid[[vertex_id]], ...) {
    int manualIndex = vid % 8;
    float manualValue = manualData[manualIndex];
    // something deep and meaningful here...
    return float4(manualValue);
}

请原谅简短的答复,但您可能会发现查看我对Swift和Metal的实验很有用。 我已经在Swift中创建了一个粒子系统,该系统作为粒子结构的一维数组传递到Metal计算着色器。 通过使用posix_memalign,我可以消除在Metal和Swift之间传递数组引起的瓶颈。

我已经在此广泛地写过博客: http : //flexmonkey.blogspot.co.uk/search/label/Metal

我希望这有帮助。

西蒙

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM