Dav*_*ine 2 ios swift metal metal-performance-shaders
我想使用MPSImageGaussianPyramid但对 Metal 的用法和 mipmap 非常陌生。我想使用过滤器为图像处理技术生成图像金字塔。
根据我能够收集的内容,MPSImageGaussianPyramid创建了一个 mipmapped 图像,但是在我的代码中,我什至很难确保我正确地看到了输出。是否有正确使用此过滤器的示例?我的问题是:
应用过滤器后如何访问 mipmap 图像?
是否可以将 mipmapped 图像复制到另一个图像进行处理?
这个 mipmapped 图像会比通过自定义过滤器手动创建金字塔更快吗?
谢谢,稍后我将提供一些我无法开始工作的示例代码。
一般使用 MPS 内核的一些建议,特别是图像金字塔过滤器:
edgeMode内核的属性设置为.clamp下采样时,因为越界采样(如高斯金字塔在第一步中所做的那样)将默认返回黑色并引入人为的暗像素。kernel.encode(commandBuffer: commandBuffer, inPlaceTexture: &myTexture)
正如您所注意到的,运行图像金字塔内核会将结果放入被下采样的纹理的可用 mip 级别。这意味着您提供的纹理应该已经分配了您想要填充的 Mip 级别。因此,您应该确保用于创建纹理的描述符具有适当的mipmapLevelCount(这是通过texture2DDescriptorWithPixelFormat便捷方法确保的,并且可以通过使用.allocateMipmapswith 选项间接控制MTKTextureLoader)。
假设您现在知道如何编码内核并将所需的结果放入您的纹理中,以下是您问题的一些答案:
1. 应用过滤器后如何访问mipmapped图像?
通过使用具有有MIP过滤器,也可以从一个特定的MIP级别传递一个明确的样品采样渲染时,可以隐式使用的贴图的着色器lod_option类型的参数level的sample函数:
constexpr sampler mySampler(coord::normalized, filter::linear, mip_filter::linear);
float4 color = myTexture.sample(mySampler, texCoords, level(selectedLod))
Run Code Online (Sandbox Code Playgroud)
这适用于计算内核以及渲染函数。nearest如果要从单个 mip 级别采样而不是使用三线性 mip 过滤,请使用选定 LOD的 mip 过滤器或舍入该 LOD。
2.是否可以将mipmapped图像复制到另一个图像进行处理?
由于图像金字塔内核下采样的纹理必须已经具有.pixelFormatView使用标志,因此您可以在选择一个或多个 mip 级别的 mipped 纹理上创建纹理视图。例如,如果您想选择第一个和更高的 mip 级别(删除基础级别),您可以这样做:
let textureView = myTexture.makeTextureView(pixelFormat: myTexture.pixelFormat,
textureType: myTexture.textureType,
levels: Range<Int>(uncheckedBounds: (1, myTexture.mipmapLevelCount)),
slices: Range<Int>(uncheckedBounds: (0, 1)))
Run Code Online (Sandbox Code Playgroud)
您还可以使用 blit 命令编码器从一个纹理复制到另一个纹理,指定要包含的 mip 级别。如果您想回收较低 mip 级别使用的内存,这允许您释放原始纹理。
你可以用一MTLTexture用MPSImage,如果你想使用的API与图像,而不是纹理的工作:
let image = MPSImage(texture: myTexture, featureChannels: 4)
Run Code Online (Sandbox Code Playgroud)
3. 这个 mipmapped 图像会比通过自定义过滤器手动创建金字塔更快吗?
几乎肯定。Metal 性能着色器针对每一代设备进行了调整,并具有许多优化执行速度和能源使用的启发式方法。
| 归档时间: |
|
| 查看次数: |
379 次 |
| 最近记录: |