ios - iOS Swift Metal SKRenderer 离屏渲染
问题描述
我正在尝试使用 渲染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 不可混合。
请有人告诉我我做错了什么以及如何让事情正常工作?
解决方案
推荐阅读
- javascript - 如何理解用户何时滚动到 div 的底部?
- string - str 之类的迭代器
- python-3.x - 寻找圆的标准差 - OpenCV 相关
- javascript - 类型错误:findByID 不是函数(Node.js)
- asp.net-core - .NET 5 API 与实体框架一对多关系不起作用
- wordpress - 在 WordPress 帖子中从文本切换到可视框时,输入框的代码消失
- c# - 从服务器下载文件。MVC
- javascript - 仅在切换选项卡后承诺返回未定义
- python - 如何将变量从 dcc.DatePickerRange 导入到另一个类?
- simulation - 在 Anylogic 中定义不同区域之间的距离