我正在一个金属支持的绘画应用程序中,将笔画分为两步:第一步将笔画的前边缘绘制到屏幕上,并通过以下方式将整个捕捉到MTLTexture:
metalTextureComposite = self.currentDrawable!.texture
第二步绘制前进笔触的更新前缘,并在使用最后保存的metalTextureComposite纹理化的多边形上进行合成。
这种方法使我可以画出无限长的笔画而又不牺牲性能,因为在绘制周期的每一帧中都会重复执行这两个步骤。
我遇到的问题是,使用所需的基于源的合成模式(请参见下面的代码),我只能看到笔画的前缘被绘制到屏幕上。这告诉我要么我没有从currentDrawable中充分捕获metalTextureComposite,要么我对要使用的混合模式做出了错误的假设,顺便说一下,如下:
renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
如果使用不同的混合模式,则确实会看到整个笔画,但不一定是我想要的外观。以下是我包含在MTKView的draw()方法中的部分代码。
func metalRenderStampArray() {
// first encode uber-stamp with previous loop's metalTextureComposite in a background polygon
// note metalTexture= metalTextureComposite contains previous loop's drawable contents
metalCommandEncode(renderCommandEncoder: renderCommandEncoder, stampLayer: stampLayerMode.stampLayerBG, vertexArrayStamps: vertexArrayStampsBG, metalTexture: metalTextureComposite) // background uber-stamp
// empty out uber-stamp in preparation for the next cycle
initializeStampArrays(stampLayer: stampLayerMode.stampLayerBG)
// next, encode current subCurve chunk polygons in foreground
// note metalTexture=brushTexture.texture is a round brush texture with alpha
metalCommandEncode(renderCommandEncoder: renderCommandEncoder, stampLayer: stampLayerMode.stampLayerFG, vertexArrayStamps: vertexArrayStampsFG, metalTexture: brushTexture.texture) // foreground sub-curve chunk
renderCommandEncoder?.endEncoding() // finalize renderEncoder set up
// now present bg + fg composite which is where I see the problem
commandBuffer?.present(self.currentDrawable!)
// 7b. Render to pipeline
commandBuffer?.commit() // commit and send task to gpu
metalTextureComposite = nil // empty out before re-populating
metalTextureComposite = self.currentDrawable!.texture // set up bg texture for next iteration
metalStampComputeComposite() // compute coordinates for the background composite stamp for the next iteration
} // end of func metalRenderStampArray()
我应该以不同的方式处理metalTextureComposite(因为它以1 / fps的速度被写入),如果是这样,我应该如何处理?目标是对背景多边形和前笔画多边形使用单一混合模式。任何帮助将不胜感激。
答案 0 :(得分:0)
您似乎正在存储对drawable纹理的引用,然后在下一帧使用它。
我可以看到2种可能的问题: -在下一帧绘制循环中,图形处理器可能尚未绘制前一帧的纹理 -drawable的纹理可由系统和应用程序的代码同时使用
我建议尝试在commandBuffer?.addCompletedHandler { }