如何在不使用 CAMetalDrawable 的情况下获得渲染后的纹理?

问题描述 投票:0回答:1

我想渲染我的纹理,并得到它的结果,这样我就可以在下一个渲染步骤中重复使用该纹理。但我不知道如何获得渲染结果。

这是我用来渲染的代码。

var destinationTexture: MTLTexture?

func update(texture: MTLTexture) {
        // Create render targets for offscreen camera image and scene render
        let width = texture.width
        let height = texture.height

        let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: texture.pixelFormat,
                                                                         width: width,
                                                                         height: height,
                                                                         mipmapped: false)
        textureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite]

        guard let newTexture = destinationTexture ??  texture.makeTextureView(pixelFormat: texture.pixelFormat) else {
            fatalError("Could not create texture of size: (\(width), \(height))")
        }

        _ = inFlightSemaphore.wait(timeout: DispatchTime.distantFuture)

        if let commandBuffer = commandQueue.makeCommandBuffer() {
            updateBufferStates()
            updateState()

            let vertexBuffer = sharedMetalRenderingDevice.device.makeBuffer(bytes: kImagePlaneVertexData,
            length: kImagePlaneVertexData.count * MemoryLayout<Float>.size, options: [])!

            let renderPass = MTLRenderPassDescriptor()
            renderPass.colorAttachments[0].texture = newTexture
            renderPass.colorAttachments[0].clearColor = MTLClearColorMake(1, 0, 0, 1)
            renderPass.colorAttachments[0].storeAction = .store
            renderPass.colorAttachments[0].loadAction = .clear

            guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPass) else {
                fatalError("Could not create render encoder")
            }
            renderEncoder.setRenderPipelineState(strip.renderPipelineState)

            // Setup plane vertex buffers
            renderEncoder.setVertexBuffer(imagePlaneVertexBuffer, offset: 0, index: 0)
            renderEncoder.setVertexBuffer(scenePlaneVertexBuffer, offset: 0, index: 1)

            renderEncoder.setFragmentBuffer(sharedUniformBuffer, offset: sharedUniformBufferOffset, index: Int(kBufferIndexSharedUniforms.rawValue))

            // ... set pipelane state and so on

            renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4)
            renderEncoder.endEncoding()

        commandBuffer.addCompletedHandler { _ in

                let updatedTexture = renderPass.colorAttachments[0].texture
                self.destinationTexture = updatedTexture
            }

            commandBuffer.commit()
        }
        inFlightSemaphore.signal()
    }

我做了所有我需要的事情 texture 但我不明白如何在我的片段着色器中获得最终的 MTLTexture 对象的内容?如果我试图获取 texture 之后 commandBuffer.commit() 它和渲染前的效果是一样的。

ios swift gpu rendering metal
1个回答
0
投票

你的实现是错误的,你应该在应用程序开始时初始化你的framebuffer纹理,然后在你的更新函数中重用。

© www.soinside.com 2019 - 2024. All rights reserved.