- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在通过 MTKView 合成一组 UIImage,我发现刷新问题仅在合成阶段出现,但一旦我与应用程序交互,这些问题就会消失。换句话说,复合 Material 按预期工作,但它们在屏幕上的外观看起来有点问题,直到我通过放大/翻译等强制刷新。
我发布了两个显示实际问题的视频:Glitch1 , Glitch2
我选择的复合方法是,我将每个 UIImage 转换为一个 MTLTexture,我将其提交给设置为“.load”的渲染缓冲区,渲染一个带有该纹理的多边形,然后我对每个图像重复该过程在 UIImage 数组中。
复合 Material 有效,但屏幕反馈,正如您从视频中看到的那样,非常有问题。
关于可能发生的事情有什么想法吗?任何建议将不胜感激
一些相关的代码:
for strokeDataCurrent in strokeDataArray {
let strokeImage = UIImage(data: strokeDataCurrent.image)
let strokeBbox = strokeDataCurrent.bbox
let strokeType = strokeDataCurrent.strokeType
self.brushStrokeMetal.drawStrokeImage(paintingViewMetal: self.canvasMetalViewPainting, strokeImage: strokeImage!, strokeBbox: strokeBbox, strokeType: strokeType)
} // end of for strokeDataCurrent in strokeDataArray
...
func drawStrokeUIImage (strokeUIImage: UIImage, strokeBbox: CGRect, strokeType: brushTypeMode) {
// set up proper compositing mode fragmentFunction
self.updateRenderPipeline(stampCompStyle: drawStampCompMode)
let stampTexture = UIImageToMTLTexture(strokeUIImage: strokeUIImage)
let stampColor = UIColor.white
let stampCorners = self.stampSetVerticesFromBbox(bbox: strokeBbox)
self.stampAppendToVertexBuffer(stampUse: stampUseMode.strokeBezier, stampCorners: stampCorners, stampColor: stampColor)
self.renderStampSingle(stampTexture: stampTexture)
} // end of func drawStrokeUIImage (strokeUIImage: UIImage, strokeBbox: CGRect)
func renderStampSingle(stampTexture: MTLTexture) {
// this routine is designed to update metalDrawableTextureComposite one stroke at a time, taking into account
// whatever compMode the stroke requires. Note that we copy the contents of metalDrawableTextureComposite to
// self.currentDrawable!.texture because the goal will be to eventually display a resulting composite
let renderPassDescriptorSingleStamp: MTLRenderPassDescriptor? = self.currentRenderPassDescriptor
renderPassDescriptorSingleStamp?.colorAttachments[0].loadAction = .load
renderPassDescriptorSingleStamp?.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0)
renderPassDescriptorSingleStamp?.colorAttachments[0].texture = metalDrawableTextureComposite
// Create a new command buffer for each tessellation pass
let commandBuffer: MTLCommandBuffer? = commandQueue.makeCommandBuffer()
let renderCommandEncoder: MTLRenderCommandEncoder? = commandBuffer?.makeRenderCommandEncoder(descriptor: renderPassDescriptorSingleStamp!)
renderCommandEncoder?.label = "Render Command Encoder"
renderCommandEncoder?.setTriangleFillMode(.fill)
defineCommandEncoder(
renderCommandEncoder: renderCommandEncoder,
vertexArrayStamps: vertexArrayStrokeStamps,
metalTexture: stampTexture) // foreground sub-curve chunk
renderCommandEncoder?.endEncoding() // finalize renderEncoder set up
//begin presentsWithTransaction approach (needed to better synchronize with Core Image scheduling
copyTexture(buffer: commandBuffer!, from: metalDrawableTextureComposite, to: self.currentDrawable!.texture)
commandBuffer?.commit() // commit and send task to gpu
commandBuffer?.waitUntilScheduled()
self.currentDrawable!.present()
// end presentsWithTransaction approach
self.initializeStampArray(stampUse: stampUseMode.strokeBezier) // clears out the stamp array in preparation of next draw call
} // end of func renderStampSingle(stampTexture: MTLTexture)
最佳答案
首先,Metal 领域非常深,它在 MTKView 构造中的使用记录很少,特别是对于不属于更传统游戏范例的任何应用程序。在@warrenm、@ken-thomases 和@modj 等人的帮助下,我在 Metal 方面积累了有限的经验,这就是我发现自己的地方,他们的贡献对我和 Swift/Metal 社区都非常有值(value)在逃。非常感谢你们所有人。
其次,任何对 Metal 进行故障排除的人,请注意以下事项:如果您收到消息:
[CAMetalLayerDrawable present] should not be called after already presenting this drawable. Get a nextDrawable instead
请不要忽视它。它可能看起来无害,特别是如果它只被报告一次。但请注意,这表明您的部分实现存在缺陷,必须先解决,然后才能对应用程序的任何其他与 Metal 相关的方面进行故障排除。至少对我来说是这样。正如您从视频帖子中看到的那样,出现此问题的症状非常严重,并导致了不可预测的行为,我很难确定问题的根源。对我来说特别难以看到的是,我只在应用程序周期的早期收到过一次这条消息,但那个单一的实例足以让其他一切以我认为可归因于 CoreImage 和/或我做出的其他完全不相关的设计选择。
那么,我是如何摆脱这个警告的呢?好吧,就我而言,我假设具有以下设置:
self.enableSetNeedsDisplay = true // needed so we can call setNeedsDisplay() to force a display update as soon as metal deems possible
self.isPaused = true // needed so the draw() loop does not get called once/fps
self.presentsWithTransaction = true // for better synchronization with CoreImage (such as simultaneously turning on a layer while also clearing MTKView)
意味着只要我想刷新屏幕,我几乎可以直接调用 currentDrawable!.present()
或 commandBuffer.presentDrawable(view.currentDrawable)
。好吧,事实并非如此。事实证明,这些调用只能在 draw() 循环内进行,并且只能通过 setNeedsDisplay()
调用进行访问。进行此更改后,我就顺利解决了我的刷新难题。
此外,我发现 MTKView
设置 self.isPaused = true
(这样我就可以直接调用 setNeedsDisplay()
)导致了一些意想不到的行为。所以,相反,我选择了:
self.enableSetNeedsDisplay = false // needed so we can call setNeedsDisplay() to force a display update as soon as metal deems possible
self.isPaused = false // draw() loop gets called once/fps
self.presentsWithTransaction = true // for better synchronization with CoreImage
以及修改我的 draw() 循环以驱动在我设置 metalDrawableDriver
标志并调用 setNeedsDisplay()
后执行哪种更新:
override func draw(_ rect: CGRect) {
autoreleasepool(invoking: { () -> () in
switch metalDrawableDriver {
case stampRenderMode.canvasRenderNoVisualUpdates:
return
case stampRenderMode.canvasRenderClearAll:
renderClearCanvas()
case stampRenderMode.canvasRenderPreComputedComposite:
renderPreComputedComposite()
case stampRenderMode.canvasRenderStampArraySubCurve:
renderSubCurveArray()
} // end of switch metalDrawableDriver
}) // end of autoreleasepool
} // end of draw()
这可能看起来很迂回,但这是我发现获得一致的用户驱动显示更新的唯一机制。
我希望这篇文章描述了一种无错误且可行的解决方案,Metal 开发人员可能会在未来发现它有用。
关于swift - MTKView刷新问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56980853/
我在由窗口 Controller 管理的窗口中有一个 MTKView。当我第一次实例化窗口 Controller 和窗口时,MTKView 调用我的委托(delegate)的两个调用,并以首选速率调用
我想在 Mac 应用程序上使用 MTKView。初始化 MTKView 后,它显示红色而不是预期的清晰颜色我的笔记本电脑是 macOS Catalina 10.15.2 的 MacBook Pro,它
我有一个 Metal 片段着色器,它返回一些带有 alpha channel 的透明颜色,我想在 MTKView 下显示一个 UIView,但我得到的背景结果只有黑色和“错误噪声”。 MTLRende
我有一个简单的 macOS 应用程序,它有一个 MTKView——它只是窗口内的一个 MTKView。片段着色器总是这样做: return float4(1, 0, 0, 0.01) 这是带有 1%
我知道在 SceneKit 中,您可以在 SKView 的一侧启用横幅查看实时帧速率和其他有用的调试信息。但是 MTKView 呢? ?我似乎没有找到这样的属性来启用,或者我如何查询当前的帧速率。 (
我正在使用 MTKView 来绘制 Metal 内容。它的配置如下: mtkView = MTKView(frame: self.view.frame, device: device)
我已经成功地创建了一个应用程序来接收实时的 h264 编码视频流,然后使用 Video Toolbox 和 AVSampleBufferDisplayLayer 解码并显示视频。这按预期工作,但我希望
我得到了什么 我正在关注 Apple 示例代码 AVCamPhotoFilter 在 MTKView 上显示相机画面。 我想做什么 除了上面的MTKView,我还需要显示第二个MTKView。但是,第
我是 Metal 的新手,但正在努力遵循 Apple 的 AVCamFilter示例项目。该项目演示了如何使用 MTKView 作为 AVCaptureSession 的预览。 我一直未能弄清楚如何让
我正在尝试实现一个 Metal 支持的绘图应用程序,其中通过沿路径重复冲压纹理正方形在 MTKView 上绘制笔触。我遇到的问题是,虽然每个画笔图章都正确显示了纹理的不透明度,但重叠的方 block
我正在尝试使用 MTKView 进行多重采样。我有一个带有委托(delegate)的 MTKView。我将 View 的 sampleCount 属性设置为 4。我创建了一个将 rasterSampl
众所周知,更新 AppKit 中的用户界面或 UIKit需要在主线程上进行。在展示 drawable 时,Metal 是否有相同的要求? ? 在一个层托管 NSView我一直在玩,我注意到我可以调用[
我有一个项目,用户可以在其中拍摄视频,然后为他们添加滤镜或更改亮度和对比度等基本设置。为此,我使用 BBMetalImage ,它基本上返回 MTKView 中的视频(在项目中命名为 BBMetalV
我正在尝试实现一个 Metal 支持的绘图应用程序,其中通过沿着路径重复冲压纹理方 block 来在 MTKView 上绘制笔触。我在绘制笔触时在顶点级别改变图章的颜色/透明度,这样我就可以模拟墨水效
我正在将 CIImage 渲染到 MTKView 并且图像小于可绘制对象。 let centered = image.transformed(by: CGAffineTransform(transla
我在我的 UIKit 应用程序中使用 MTKViews 来选择 UI 元素。我有一个中央 Metal Controller ,它做的事情有点像这样: public class MetalView: M
这里我有一个 MTKView 并在摄像头源上实时运行一个简单的 CIFilter。这很好用。 问题 在旧设备的自拍相机上,例如 iPhone 5、iPad Air,提要绘制在较小的区域。 更新:发现发
这可能更像是一个通用的图形编程问题,但目前这是在 macOS 上使用 Apple 的 Metal 框架的上下文中。 在 NSView mouseDown 中,只需调用以下命令即可轻松获取鼠标按下事件发
从 MTKView 捕获帧的最有效方法是什么?如果可能的话,我想实时保存帧中的 .mov 文件。是否可以渲染成 AVPlayer 帧或其他东西? 目前正在使用此代码绘制(基于@warrenm Perf
如果我将窗口大小调整为小于 Metal View ,我可以看到滚动条一秒钟,但我无法单击它们,它们也保持可见。你知道我该如何改变这种行为吗?我希望只要窗口小于 Metal View ,滚动条就可见且可
我是一名优秀的程序员,十分优秀!