Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 启用混合会使renderPipelineState无法在MetalKit MTKView中生成_Swift_Metal_Alphablending_Depth Buffer_Metalkit - Fatal编程技术网

Swift 启用混合会使renderPipelineState无法在MetalKit MTKView中生成

Swift 启用混合会使renderPipelineState无法在MetalKit MTKView中生成,swift,metal,alphablending,depth-buffer,metalkit,Swift,Metal,Alphablending,Depth Buffer,Metalkit,我正在渲染一个在metalkitMTKView中具有一些半透明区域(alpha

我正在渲染一个在metalkit
MTKView
中具有一些半透明区域(alpha<1)的几何体。如果在渲染管道状态的描述符中将
isBlendingEnabled
保留为false,则所有内容都会按应有的方式显示(尽管使用了所有纯色)

我知道渲染半透明对象取决于绘制顺序。目前,我只想测试alpha混合与渲染缓冲区中已经存在的半透明区域混合后的效果,即使它只是混合到背景中(此时仍然只是清晰的颜色)

但是,当我尝试启用混合时,
MakerRenderPipelineState
失败,出现以下错误:

编译器无法生成请求 错误域=编译器错误代码=1“片段着色器未写入渲染混合所需的目标颜色(0)和索引(1)”

下面是试图在MTKView的委托中构建管道状态的代码。在从MTKView继承属性的地方,我将这些属性的值放在注释中

do {


let descriptor = MTLRenderPipelineDescriptor()
descriptor.vertexFunction = vertex
descriptor.fragmentFunction = fragment
descriptor.sampleCount = view.sampleCount // 4
descriptor.depthAttachmentPixelFormat = view.depthStencilPixelFormat //.depth32Float

let renderAttachment = descriptor.colorAttachments[0]
renderAttachment?.pixelFormat = view.colorPixelFormat //.bgra8Unorm

// following 7 lines cause makeRenderPipelineState to fail
renderAttachment?.isBlendingEnabled = true
renderAttachment?.alphaBlendOperation = .add
renderAttachment?.rgbBlendOperation = .add
renderAttachment?.sourceRGBBlendFactor = .sourceAlpha
renderAttachment?.sourceAlphaBlendFactor = .sourceAlpha
renderAttachment?.destinationRGBBlendFactor = .oneMinusSourceAlpha
renderAttachment?.destinationAlphaBlendFactor = .oneMinusSource1Alpha

computePipelineState = try device.makeComputePipelineState(function: kernel)
renderPipelineState = try device.makeRenderPipelineState(descriptor: descriptor)

} catch {
    print(error)
}
考虑到错误是关于
color(0)
,我将
color[0]
绑定添加到片段着色器的输出:

constant float3 directionalLight = float3(-50, -30, 80);

struct FragOut {
    float4 solidColor [[ color(0) ]];
};

fragment FragOut passThroughFragment(Vertex fragIn [[ stage_in ]]) {
    FragOut fragOut;
    fragOut.solidColor = fragIn.color;
    fragOut.solidColor.rgb *= max(0.4, dot(fragIn.normal, normalize(directionalLight)));
    return fragOut;
};
最后,绘制代码:

if let renderPassDescriptor = view.currentRenderPassDescriptor,
    let drawable = view.currentDrawable {
    let commandBuffer = queue.makeCommandBuffer()
    renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(red: 0.8, green: 0.8, blue: 1, alpha: 1)
    let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)
    renderEncoder.setDepthStencilState(depthStencilState)
    renderEncoder.setRenderPipelineState(renderPipelineState)
    //renderEncoder.setTriangleFillMode(.lines)
    renderEncoder.setVertexBuffer(sceneBuffer, offset: 0, at: 0)
    renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 1)           
    renderEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: Int(vertexCount) ) 

    renderEncoder.endEncoding()
    commandBuffer.present(drawable)
    commandBuffer.commit()
}
我没有在片段着色器中显式设置任何纹理。这是否意味着currentDrawable隐式地是索引0处的颜色附件?为什么错误消息希望在索引1处查看颜色(0)?混合是否需要两种颜色的附件?(它不能只是添加到已经渲染的内容上?)


谢谢。

您似乎无意中调用了。不要将
destinationAlphaBlendFactor
设置为
oneminssource1alpha
,而是尝试
oneminssourcealpha
(注意缺少的
1


此外,您的直觉是,默认情况下金属写入第一个颜色附件是正确的(当前可绘制图形由
MTKView
配置为第一个颜色附件的纹理)。您可以从片段函数返回一个
float4
(或
half4
),而不是返回一个具有
[[color(0)]]
属性的成员的结构,该颜色将写入主颜色附件。然而,一旦混合因子配置正确,您编写它的方式应该会起作用。

哦,哇,我没有看到
1
!谢谢,现在效果很好。那么,深度模具也是着色器的隐式颜色附件吗?如果我将隐式附件添加到函数签名中,是否可以对着色器中的隐式附件进行采样?还感谢《示例金属》系列,这是一个很好的资源。您是否计划后续合并MetalKit、模型I/O等?深度贴图是一种单独的附件类型,但如果您在
MTKView
上设置了深度像素格式,深度纹理也将自动配置为视图提供的渲染过程描述符的深度附件。我不相信您可以像使用color framebuffer fetch(进行可编程混合)那样从当前深度贴图采样,尽管您可以提供一个显式的深度值,而不是使用片段的剪辑空间位置所暗示的深度值。