如何在不使用 CAMetalDrawable 的情况下获取渲染纹理?
How to get rendered texture without using CAMetalDrawable?
我想渲染我的纹理并获得它的结果,这样我就可以在下一个渲染步骤中重用该纹理。但是不知道怎么得到渲染的结果
这是我用来渲染的代码:
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
做了我需要的一切,但我不明白如何在 swift 核心中获得最终的 MTLTexture
对象?如果我在 commandBuffer.commit()
之后尝试获取 texture
的内容,它与渲染之前相同。
你的实现是错误的,你应该在应用程序启动时初始化你的帧缓冲区纹理,并在你的更新函数上重用。
我想渲染我的纹理并获得它的结果,这样我就可以在下一个渲染步骤中重用该纹理。但是不知道怎么得到渲染的结果
这是我用来渲染的代码:
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
做了我需要的一切,但我不明白如何在 swift 核心中获得最终的 MTLTexture
对象?如果我在 commandBuffer.commit()
之后尝试获取 texture
的内容,它与渲染之前相同。
你的实现是错误的,你应该在应用程序启动时初始化你的帧缓冲区纹理,并在你的更新函数上重用。