在draw()循环中重用currentDrawable.texture时,MTKView混合问题

问题描述 投票:0回答:1

我正在研究一种金属支持的绘画应用程序,其中我分两步绘制笔划的绘图:第一步绘制笔划的前沿到屏幕并通过以下方式将整个绘图捕获到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写入),如果是这样,我应该如何处理它?目标是对背景多边形和前导笔划多边形使用单一混合模式。任何帮助,将不胜感激。

swift4 metal render-to-texture metalkit mtlbuffer
1个回答
0
投票

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

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

我建议尝试复制drawable的纹理,供你在commandBuffer?.addCompletedHandler { }中使用

© www.soinside.com 2019 - 2024. All rights reserved.