我有一个大的MTLTexture(高达16k),我需要创建一个低分辨率的纹理-比如一半或四分之一的比例。
我可以将高分辨率纹理绘制成低分辨率纹理:
let descriptorSmallerCanvas = MTLRenderPassDescriptor()
descriptorSmallerCanvas.colorAttachments[0].texture = canvasTextureSmaller
descriptorSmallerCanvas.colorAttachments[0].storeAction = .store
descriptorSmallerCanvas.colorAttachments[0].loadAction = .clear
let renderSmallCanvas = commandBuffer.makeRenderCommandEncoder(descriptor: descriptorSmallerCanvas)
renderSmallCanvas?.pushDebugGroup("Render Small Texture")
renderSmallCanvas?.setRenderPipelineState(renderCanvasPipelineState)
renderSmallCanvas?.setFragmentTexture(canvasTexture, index: 0)
renderSmallCanvas?.setVertexBuffer(uniformOrthoBuffer, offset: 0, index: 0)
renderSmallCanvas?.setCullMode(.none)
renderSmallCanvas?.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1)
renderSmallCanvas?.popDebugGroup()
renderSmallCanvas?.endEncoding()
这是有效的,但我想知道是否有更有效的方法来做到这一点?是MTLBlitCommandEncoder
的generateMipmaps(for: canvasTexture)
更有效,还是有更有效的方法?
答案取决于你想要缩减的算法。
在不知道renderCanvasPipelineState
是什么情况下,我猜它会渲染一个全屏四边形,将较大的纹理渲染成较小的纹理将使用您在着色器中拥有的采样器状态的minFilter
(我猜它是constexpr
采样器,因为您在这里没有绑定任何),所以它最多只会使用MTLSamplerMinMagFilterLinear
,这不是"高质量"。降尺度。
我认为你最好的选择不写自己的调整大小是使用MPSImageLanczosScale或mpsimagelbilineearscale这取决于你想要做出的质量权衡。
注:你不需要.clear
你的附件,如果你填充整个屏幕而不混合,让它在.dontCare
,它会覆盖每一个像素。