在draw()循环中重复使用currentDrawable.texture时,MTKView混合问题 [英] MTKView blend issues when re-using currentDrawable.texture in draw() loop

查看:284
本文介绍了在draw()循环中重复使用currentDrawable.texture时,MTKView混合问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个金属支持的绘画应用程序中,将笔画分为两步:第一步将笔画的前边缘绘制到屏幕上,并通过以下方式将其捕获到MTLTexture中:

I am working on a metal-backed painting application in which I divide the drawing of a stroke in two steps: the first step draws the leading edge of a stroke to screen and captures the entire to an MTLTexture via:

metalTextureComposite = self.currentDrawable!.texture

第二步绘制前进笔触的更新前缘,并在使用最后保存的metalTextureComposite纹理化的多边形上进行合成.

the second step draws an updated leading edge of the advancing stroke, and composites atop a polygon textured with the last saved metalTextureComposite.

这种方法使我可以画出无限长的笔画而又不影响性能,因为在绘制周期的每一帧中都会重复执行这两个步骤.

This method allows me to draw infinitely long strokes without sacrificing performance, as these two steps get repeated for each frame of the drawing cycle.

我遇到的问题是,使用所需的基于源的合成模式(请参见下面的代码),我只能看到笔画的前缘被绘制到屏幕上.这告诉我要么我没有从currentDrawable捕获足够的metalTextureComposite,要么我对要使用的混合模式做出了错误的假设,顺便说一下,是这样的:

The problem I'm having is that, using the desired source-over composite mode (see below code), I am only seeing the leading edge of the stroke being drawn to screen. This tells me that either I am not adequately capturing metalTextureComposite from the currentDrawable, or that I am making the wrong assumptions regarding the blending mode to use, which incidentally is as follows:

renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha       
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha                 
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha

如果使用不同的混合模式,我确实会看到整个笔画,但不一定是我想要的外观.以下是我包含在MTKView的draw()方法中的部分代码.

If I use different blending modes, I do see the entirety of the stroke being drawn, but not necessarily the appearance I'm after. Below is the part of the code I'm including inside the MTKView's draw() method.

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的速度被写入),如果是这样,我应该如何处理呢?目标是为背景多边形和前导笔触多边形使用单一混合模式.任何帮助将不胜感激.

Should I be handling metalTextureComposite differently (since it is being written to at 1/fps) and if so, how should I handle it? The goal is to use a single blending mode for the background poly and the leading stroke polygons. Any help would be appreciated.

推荐答案

您似乎正在存储对drawable纹理的引用,然后在下一帧使用它.

You seem to be storing a reference to drawable's texture and then using it the next frame.

我可以看到2种可能的问题: -在下一个帧绘制周期,图形处理器可能尚未绘制前一帧的纹理 -drawable的纹理可能同时被系统和应用程序的代码使用

I can see 2 possible problems with this: - at the next frame draw cycle, the previous frame's texture might not yet be drawn to by the graphics processor - drawable's texture might be used by the system and app's code at the same time

我建议尝试在commandBuffer?.addCompletedHandler { }

这篇关于在draw()循环中重复使用currentDrawable.texture时,MTKView混合问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆