[英]Appropriate Usage of MPSImageGaussianPyramid with Metal
我想使用MPSImageGaussianPyramid
但是對於Metal的用法和mipmaps來說是一個新手。 我想使用濾鏡為圖像處理技術生成圖像金字塔。
根據我的能力, MPSImageGaussianPyramid
創建了一個MPSImageGaussianPyramid
圖像,但是在我的代碼中,即使要確保我正確看到了輸出,也很難。 是否有使用此過濾器的示例? 我的問題是:
應用濾鏡后,如何訪問mipmapped圖像?
是否可以將映射的圖像復制到另一個圖像進行處理?
與通過自定義濾鏡手動創建金字塔相比,此mipmapped圖像會更快嗎?
謝謝,稍后我將提供一些無法使用的示例代碼。
有關使用MPS內核的一些建議,特別是有關圖像金字塔過濾器的一些建議:
edgeMode
內核的屬性來.clamp
質量采樣時,由於采樣外的界限(如高斯金字塔做的第一步),默認情況下將返回黑色和引進人工暗像素。 kernel.encode(commandBuffer: commandBuffer, inPlaceTexture: &myTexture)
如您所注意到的,運行圖像金字塔內核會將結果放入要降低采樣的紋理的可用mip級別。 這意味着您提供的紋理應該已經分配了想要填充的mip級別。 因此,您應該確保用於創建紋理的描述符具有適當的mipmapLevelCount
(這由texture2DDescriptorWithPixelFormat
便捷方法確保,並且可以通過將.allocateMipmaps
選項與MTKTextureLoader
一起間接控制)。
假設您現在知道如何對內核進行編碼並將所需的結果轉換為紋理,以下是對您的問題的一些答案:
1.應用濾鏡后,如何訪問被映射的圖像?
您可以在渲染時通過使用具有mip過濾器的采樣器在着色器中隱式使用lod_option
,或者可以通過將類型level
的lod_option
參數傳遞給sample
函數來從特定的mip級別顯式采樣:
constexpr sampler mySampler(coord::normalized, filter::linear, mip_filter::linear);
float4 color = myTexture.sample(mySampler, texCoords, level(selectedLod))
這適用於計算內核以及渲染功能。 如果要從單個Mip級別進行采樣,請使用nearest
或舍入所選LOD的Mip過濾器,而不要使用三線性mip過濾。
2.是否可以將映射的圖像復制到另一個圖像進行處理?
由於由圖像金字塔內核縮減采樣的紋理必須已經具有.pixelFormatView
使用標志,因此您可以在選擇一個或多個mip級別的壓縮紋理上創建紋理視圖 。 例如,如果要選擇第一個和更高的Mip級別(刪除基本級別),可以這樣進行:
let textureView = myTexture.makeTextureView(pixelFormat: myTexture.pixelFormat,
textureType: myTexture.textureType,
levels: Range<Int>(uncheckedBounds: (1, myTexture.mipmapLevelCount)),
slices: Range<Int>(uncheckedBounds: (0, 1)))
您還可以使用blit命令編碼器從一個紋理復制到另一個紋理,並指定要包括的mip級別。 如果要回收較低MIP級別使用的內存,則可以釋放原始紋理。
如果要使用可用於圖像而非紋理的API,則可以將MTLTexture
與MPSImage
包裝MTLTexture
:
let image = MPSImage(texture: myTexture, featureChannels: 4)
3.與通過自定義濾鏡手動創建金字塔相比,此mipmapped圖像會更快嗎?
幾乎可以確定。 Metal Performance Shaders針對每一代設備進行了調整,並具有多種試探法,可優化執行速度和能耗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.