我一直在努力学习金属,并在尝试将两个图像混合在一起时陷入困境 .
我有两个纹理四边形,其不透明度设置为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);
}
我目前最好的猜测是管道没有设置正确的选项,但更改它们不会使两个四边形混合,但确实给出了一些有趣的效果!
1 回答
为第二个四元组设置正确的管道状态是实现混合所必须做的唯一事情 - 您不必在片段函数中进行任何计算 .
尝试设置一个简单的管道,没有后四边形的混合 . 然后按照上面的前四边形设置管道 .
渲染两个四边形时,切换管道状态,使后四边形渲染而不混合,前四边形渲染与混合 .
得到上面的结果,这是两个四边形的片段函数:
这是“固定功能”混合 - 您可以通过使用两种不同的管道状态来设置GPU的状态 .
你可以在Metal By Example阅读更多相关信息 .