我正在尝试使用Metal创建一个程序游戏,我正在使用基于八叉树的块方法来实现Level of Detail.
我正在使用的方法涉及CPU为地形创建八叉树节点,然后使用计算着色器在GPU上创建其网格.此网格存储在块对象中的顶点缓冲区和索引缓冲区中以进行渲染.
所有这些看起来都运行得相当不错,但是在渲染块时我很早就遇到了性能问题.目前我收集了一系列要绘制的块,然后将其提交给我的渲染器,这将创建一个MTLParallelRenderCommandEncoder然后MTLRenderCommandEncoder为每个块创建一个块,然后将其提交给GPU.
从它的外观来看,大约50%的CPU时间花费在MTLRenderCommandEncoder为每个块创建.目前我只是为每个块创建一个简单的8顶点立方体网格,我有一个4x4x4阵列的块,我在这些早期阶段下降到50fps左右.(实际上似乎MTLRenderCommandEncoder每个最多只能有63 个MTLParallelRenderCommandEncoder因此它不完全是4x4x4)
我已经读过,重点MTLParallelRenderCommandEncoder是MTLRenderCommandEncoder在一个单独的线程中创建每个,但是我没有太多运气让它工作.同样多线程它不会绕过63个块的上限被渲染为最大值.
我觉得以某种方式将每个块的顶点和索引缓冲区合并到一个或两个更大的缓冲区中以提交将有所帮助,但我不知道如何在没有大量memcpy()调用的情况下执行此操作以及这是否甚至可以提高效率.
这是我的代码,它接收节点数组并绘制它们:
func drawNodes(nodes: [OctreeNode], inView view: AHMetalView){
// For control of several rotating buffers
dispatch_semaphore_wait(displaySemaphore, DISPATCH_TIME_FOREVER)
makeDepthTexture()
updateUniformsForView(view, duration: view.frameDuration)
let commandBuffer = commandQueue.commandBuffer()
let optDrawable = layer.nextDrawable()
guard let drawable = optDrawable else{
return
}
let passDescriptor = MTLRenderPassDescriptor()
passDescriptor.colorAttachments[0].texture = drawable.texture
passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.2, 0.2, 0.2, 1)
passDescriptor.colorAttachments[0].storeAction = .Store
passDescriptor.colorAttachments[0].loadAction = .Clear …Run Code Online (Sandbox Code Playgroud) 我想要一个简单的矩形跟踪控制器,我可以得到矩形检测正常,但跟踪请求总是因为我找不到的原因而失败.
有时跟踪请求会在失败之前触发它几次回调,有时它会在单次回调发生之前立即失败.我觉得这与我提交请求的方式有关,但我无法深究它.
这是视图控制器的代码
class TestController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
// Video capture
private var videoSession = AVCaptureSession()
private var videoLayer: AVCaptureVideoPreviewLayer!
// Detection
private var detectionRequest: VNDetectRectanglesRequest?
private let sequenceHandler = VNSequenceRequestHandler()
// Tracking
private var trackingRequest: VNTrackRectangleRequest?
private var shape: Detection?
private var pixelBuffer: CVImageBuffer?
// MARK: Setup
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
startVideoFeed()
}
override func viewDidLayoutSubviews() {
videoLayer.frame = view.layer.bounds
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
startDetectingRectangles()
}
private func startDetectingRectangles() { …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用swift验证本地播放器,但每次我获得.authenticated属性的错误值.这是我正在使用的代码,当应用程序启动时,它由主视图控制器调用.
func authenticateLocalPlayer(){
var localPlayer = GKLocalPlayer()
localPlayer.authenticateHandler = {(viewController, error) -> Void in
if viewController {
self.presentViewController(viewController, animated: true, completion: nil)
}else{
println((GKLocalPlayer().authenticated))
}
}
}
Run Code Online (Sandbox Code Playgroud)
它可以很好地显示日志视图,但是当我输入测试帐户登录时,它只返回GKLocalPlayer().authenticatedfalse.iTunes Connect和info.plist中的软件包标识符与版本和应用程序名称完全相同.在iTunes Connect和Xcode上为Game Center启用了所有内容,但我感觉这不是编码错误,这是应用程序记录中的设置错误,但我不能在我的生活中找到哪里.
经过进一步的修补,我收到了这个错误:
Error Domain = GKErrorDomain Code = 15"无法完成请求的操作,因为Game Center无法识别此应用程序." UserInfo = 0x17006b300 {NSLocalizedDescription =无法完成请求的操作,因为Game Center无法识别此应用程序.}
我不知道为什么会这样,捆绑ID,名称和版本都匹配......
任何帮助将不胜感激.
我正在尝试使用UIView带有效果的UIVisualEffectView子视图UIBlurEffect.视图在屏幕一侧创建,然后使用动画滑入.
在模拟器上一切正常(我在iPhone 4S和iPhone 6上测试过)但是在我的手机(iPhone 6)上,模糊不会模糊,看起来更像alpha是0.5的深灰色.此外,当我拍摄设备的屏幕截图或从主屏幕打开它时,在再次开始一致渲染之前,将为该单帧渲染模糊.
这是目前视图的截图:

然而,在设备上模糊不存在,它基本上只是一个黑暗,透明的视图.
这是我用来初始化视图的代码,blurView和vibrancyView属性被声明为全局变量:
init(left: Bool){
self.left = left
let screenSize = UIScreen.mainScreen().bounds.size
var rect: CGRect
if left{
rect = CGRectMake(-screenSize.width*0.3, 0, screenSize.width*0.3, screenSize.height)
}else{
rect = CGRectMake(screenSize.width, 0, screenSize.width*0.3, screenSize.height)
}
super.init(frame: rect)
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame = CGRectMake(0, 0, self.frame.width, self.frame.height)
self.addSubview(blurView)
let vibrancy = UIVibrancyEffect(forBlurEffect: blurEffect)
vibrancyView = UIVisualEffectView(effect: vibrancy)
vibrancyView.frame = blurView.frame
blurView.addSubview(vibrancyView)
self.userInteractionEnabled …Run Code Online (Sandbox Code Playgroud) 我想使用Metal着色器将卡通/单元着色应用于场景中使用的材质。我尝试实现的着色器是 AppleAAPLCelShader在MetalShaderShowcase中找到的自己的着色器。我对实现着色器有点陌生,SceneKit所以我可能会做完全错误的事情。
根据我在文档中的理解,从 iOS 9 和 Xcode 7 开始,aMetal或 GL 着色器可用于修改SceneKit渲染。文档表明,这与 GL 着色器的完成方式相同。
我的方法是尝试获取文件的路径,然后将其加载到一个字符串中,以 [String: String] 字典的形式在属性中.metal使用,就像使用 GL 着色器一样(尽管我还没有SCNMaterial shaderModifiers使其正常工作)。
我的代码是:
var shaders = [String: String]()
let path = NSBundle.mainBundle().pathForResource("AAPLCelShader", ofType: "metal")!
do{
let celShader = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
shaders[SCNShaderModifierEntryPointLightingModel] = celShader
}catch let error as NSError{
error.description
}
scene.rootNode.enumerateChildNodesUsingBlock({ (node, stop) -> Void in
node.geometry?.firstMaterial?.shaderModifiers = shaders
})
Run Code Online (Sandbox Code Playgroud)
这是在一个测试场景上运行的,其中有一个从.scn文件加载的盒子几何体。文件加载工作正常,所以这不是问题。 …
我希望将游戏迁移到swift,我唯一遇到的问题是阻塞/关闭.这是我不理解的语法,而在Objective CI中则使用:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){
if (viewController != nil) {
[self presentViewController:viewController animated:YES completion:nil];
}
}
Run Code Online (Sandbox Code Playgroud)
etc.etc.但我不确定如何在Swift中做同样的事情.我知道这很简单,但我无法让它工作,即使在阅读了Swift书并自己搜索答案之后.我只是一个业余爱好者程序员,所以我对这一切都远非完美.
任何帮助,将不胜感激.