我使用图像块数据将半透明片段存储在 3 层堆栈中,如下所示:
#define TRANSPARENCY_LAYERS 3
struct TransparentFragmentValues {
rgba8unorm<float4> color [[raster_order_group(0)]] [TRANSPARENCY_LAYERS];
float depth [[raster_order_group(0)]] [TRANSPARENCY_LAYERS];
};
在最后阶段,这些透明片段与我的渲染的其余部分混合。 它工作正常,除了如果我启用多重采样抗锯齿(4 个样本),它会在整个屏幕上显示伪影:
我的图块为 16x16,每个片段正好占用 64 个字节(4 个不透明颜色 + 4 个深度 + 3 x (4+4) 个透明数据),总计 16kB(不使用 MSAA),使用 MSAA 时为 64kB -4,这是我的 GPU 的内存限制。
我怀疑这与我初始化图像块数据的方式有关:
kernel void transparent_fragment_store_init (
imageblock<TransparentFragmentValues, imageblock_layout_explicit> blockData,
ushort2 localThreadID[[thread_position_in_threadgroup]])
{
threadgroup_imageblock TransparentFragmentValues* fragmentValues = blockData.data(localThreadID);
for (short i = 0; i < TRANSPARENCY_LAYERS; i++) {
fragmentValues->color[i] = 0.0;
fragmentValues->depth[i] = INFINITY;
}
}
此函数没有考虑到每个线程必须初始化 4 个透明FragmentValue,而不是仅初始化一个。但我怎样才能索引它们呢?我不能只添加更多线程:如果不是 16x16,它就会失败。
阅读完
metal_imageblocks
标题后,我认为您不需要使用 T *data(ushort2 coord)
,而是使用该函数的 T *data(ushort2 coord, ushort index, imageblock_data_rate rate)
变体,同时将 imageblock_data_rate::sample
和 index
传递给它,这将是您的示例索引。