Я пытаюсь визуализировать SKScene
вне экрана с помощью SKRenderer
, который затем будет использоваться в SceneKit SCNMaterial
.myScene
здесь, это SKScene
.Я настроил рендерер так:
var device:MTLDevice!
var commandQueue: MTLCommandQueue!
var renderer: SKRenderer!
var offscreenTexture: MTLTexture!
let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
let bytesPerPixel = Int(4)
let bitsPerComponent = Int(8)
let bitsPerPixel:Int = 32
var textureSizeX:Int = Int(myScene.width)
var textureSizeY:Int = Int(myScene.height)
func setupMetal() {
if let defaultMtlDevice = MTLCreateSystemDefaultDevice() {
device = defaultMtlDevice
commandQueue = device.makeCommandQueue()
renderer = SKRenderer(device: device)
} else {
fatalError("iOS simulator does not support Metal, this example can only be run on a real device.")
}
}
func setupMetalUsingDevice(_ device: MTLDevice?) {
guard device != nil else {
setupMetal()
return
}
self.device = device
commandQueue = device!.makeCommandQueue()
renderer = SKRenderer(device: device!)
}
func setupTexture() {
var rawData0 = [UInt8](repeating: 0, count: Int(textureSizeX) * Int(textureSizeY) * 4)
let bytesPerRow = 4 * Int(textureSizeX)
let bitmapInfo = CGBitmapInfo.byteOrder32Big.rawValue | CGImageAlphaInfo.premultipliedLast.rawValue
let context = CGContext(data: &rawData0, width: Int(textureSizeX), height: Int(textureSizeY), bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: rgbColorSpace, bitmapInfo: bitmapInfo)!
context.setFillColor(UIColor.green.cgColor)
context.fill(CGRect(x: 0, y: 0, width: CGFloat(textureSizeX), height: CGFloat(textureSizeY)))
let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: MTLPixelFormat.rgba8Unorm, width: Int(textureSizeX), height: Int(textureSizeY), mipmapped: false)
textureDescriptor.usage = MTLTextureUsage(rawValue: MTLTextureUsage.renderTarget.rawValue | MTLTextureUsage.shaderRead.rawValue)
let textureA = device.makeTexture(descriptor: textureDescriptor)!
let region = MTLRegionMake2D(0, 0, Int(textureSizeX), Int(textureSizeY))
textureA.replace(region: region, mipmapLevel: 0, withBytes: &rawData0, bytesPerRow: Int(bytesPerRow))
offscreenTexture = textureA
}
func doRender() {
//rendering to a MTLTexture, so the viewport is the size of this texture
let viewport = CGRect(x: 0, y: 0, width: CGFloat(textureSizeX), height: CGFloat(textureSizeY))
//write to offscreenTexture, clear the texture before rendering using green, store the result
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.renderTargetWidth = textureSizeX
renderPassDescriptor.renderTargetHeight = textureSizeY
renderPassDescriptor.defaultRasterSampleCount = 1
renderPassDescriptor.colorAttachments[0].texture = offscreenTexture
renderPassDescriptor.colorAttachments[0].loadAction = .clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 1, 0, 1.0)
renderPassDescriptor.colorAttachments[0].storeAction = .store
guard let commandBuffer = commandQueue.makeCommandBuffer() else {
return
}
renderer.scene = myScene
renderer.scene?.isPaused = false
renderer.render(withViewport: viewport, commandBuffer: commandBuffer, renderPassDescriptor: renderPassDescriptor)
commandBuffer.commit()
}
func createMaterial() {
let material = SCNMaterial()
material.diffuse.contents = viewController.offscreenTexture
material.blendMode = blendMode
geometry?.materials = [material]
}
Как только вызывается doRender()
для начала рендеринга myScene, я получаю следующую ошибку:
- [MTLRenderPipelineDescriptorInternal validateWithDevice:], строка 2558: ошибка 'Смешивание включено для цели рендеринга 0;однако формат пикселя MTLPixelFormatInvalid для этой цели рендеринга не может быть смешан. '
Пожалуйста, кто-нибудь может сказать мне, что я делаю неправильно и как заставить вещи работать правильно?