我是Metal的新手,尝试在present()
和commit()
之前在MTLTexture上绘制两次。第一次使用SCNRenderer.render
从SCNScene绘制背景,然后第二次使用CIContext.render
对具有透明度的用户进行深度过滤。
我的renderPassDescriptor设置为:
// SCNRenderer
let viewport = CGRect(x: 0, y: 0, width: CGFloat(currentDrawable.texture.width), height: CGFloat(currentDrawable.texture.width))
//write to offscreenTexture, clear the texture before rendering using red, store the result
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = currentDrawable.texture
renderPassDescriptor.colorAttachments[0].loadAction = .clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1, 0, 0, 1.0); // red
renderPassDescriptor.colorAttachments[0].storeAction = .store
scnRenderer.render(atTime: 0, viewport: viewport, commandBuffer: commandBuffer, passDescriptor: renderPassDescriptor)
// CIContext render
ciContext.render(ciImage, to: currentDrawable.texture, commandBuffer: commandBuffer, bounds: ciImage.extent, colorSpace: colorSpace)
如果我切换了scnRenderer.render
和ciContext
的顺序,则按预期出现在屏幕上。
由于CIContext
的第二次绘制使用具有透明度的图像,因此我在此article之后启用了alpha混合。
// Enable alpha Blending
pipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
这是通过片段着色器的功能:
fragment float4 passThroughFragment(ColorInOut in [[ stage_in ]],
texture2d<float> texture [[ texture(0) ]]) {
constexpr sampler colorSampler;
float4 color = texture.sample(colorSampler, in.texCoord);
return color;
}
如何防止CIImage
的透明度覆盖为SCNScene绘制的片段颜色?谢谢。