我一直在尝试学习Metal,当我试图将两个图像混合在一起时,我变得卡住了。
我有两个纹理四边形,其中一个的不透明度设置为0.5,它被缩放到另一个大小的75%。
四元组包括:

和

MTKView用红色清除。当我尝试混合它们时,结果是:

我所期待的是:

对于我的管道设置,我使用:
descriptor.colorAttachments[0].pixelFormat = .bgra8Unorm
descriptor.colorAttachments[0].isBlendingEnabled = true
descriptor.colorAttachments[0].rgbBlendOperation = .add
descriptor.colorAttachments[0].alphaBlendOperation = .add
descriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
descriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
descriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
descriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha金属着色器函数包括:
vertex VertexOut vertex_shader(const VertexIn vertex_in [[ stage_in ]], constant ModelMatrix &matrix [[ buffer(1) ]], constant const UniformsStruct &uniforms [[ buffer(2) ]]) {
VertexOut vertex_out;
vertex_out.position = matrix.mvpMatrix * vertex_in.position;
vertex_out.colour = vertex_in.colour;
vertex_out.textureCoordinates = vertex_in.textureCoordinates;
vertex_out.opacity = uniforms.opacity;
return vertex_out;
}
fragment half4 masked_textured_fragment_shader(VertexOut vertex_from_vertex_shader [[ stage_in ]], sampler sampler2d [[ sampler(0) ]], texture2d<float> mask [[ texture(1) ]], texture2d<float> texture [[ texture(0) ]]) {
float4 keyPixel = mask.sample(sampler2d, vertex_from_vertex_shader.textureCoordinates);
float4 colour = texture.sample(sampler2d, vertex_from_vertex_shader.textureCoordinates);
return half4(colour.r * keyPixel.r, colour.g * keyPixel.g, colour.b * keyPixel.b, vertex_from_vertex_shader.opacity);
}我目前最好的猜测是管道没有设置正确的选项,但更改它们并不会使两个四元组混合,但确实会产生一些有趣的效果!
发布于 2018-03-11 11:16:18
为第二个四边形设置正确的管道状态是实现混合的唯一需要做的事情--你不需要在片段函数中做任何计算。
试着设置一个简单的管道,后面的四边形没有任何混合。然后设置管道,就像上面为前面的四边形设置的那样。
渲染两个四边形时,请切换管道状态,以便后面的四边形渲染时不进行混合,而前面的四边形渲染时进行混合。

为了得到上面的结果,这是我的两个四元组的片段函数:
fragment float4 fragment_main (VertexOut in [[ stage_in ]],
texture2d<float> texture [[ texture(0) ]]) {
constexpr sampler sampler2d;
float4 color = texture.sample(sampler2d, in.textureCoordinates);
color.a = 0.5; // set opacity. Ignored if blending is not enabled
return color;
}这是“固定功能”混合-您通过使用两种不同的流水线状态将GPU的状态设置为混合。
你可以在Metal By Example上阅读更多关于它的内容
https://stackoverflow.com/questions/48569436
复制相似问题