[英]Alpha blending with two transparent textures not working correctly
I have a destination texture:我有一个目标纹理:
Here the whole texture will be transparent (alpha = 0) except red color part.这里整个纹理将是透明的(alpha = 0),除了红色部分。 Red color will have alpha value of 0.5.
红色的 alpha 值为 0.5。 I used a rectangle plane to present this texture.
我用一个矩形平面来呈现这个纹理。
Then i have this source texture.然后我有这个源纹理。 It is also a transparent texture with black color part.
它也是带有黑色部分的透明纹理。 Black color will have alpha value of 0.5.
黑色的 alpha 值为 0.5。 I used another rectangle plane to present this texture and i change
MTLRenderPipelineDescriptor
blending to我使用另一个矩形平面来呈现此纹理,并将
MTLRenderPipelineDescriptor
混合更改为
pipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .one
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .one
pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
Here blending works fine between two textures.在这里,两种纹理之间的混合效果很好。
Then i try to merge these two textures into one destination texture.然后我尝试将这两个纹理合并为一个目标纹理。 using
MTLComputeCommandEncoder
.使用
MTLComputeCommandEncoder
。 My kernel function:我的内核函数:
kernel void compute(
texture2d<float, access::read_write> des [[texture(0)]],
texture2d<float, access::read> src [[texture(1)]],
uint2 gid [[thread_position_in_grid]])
{
float4 srcColor = src.read(gid);
float4 desColor = des.read(gid);
float srcAlpha = srcColor.a;
float4 outColor = srcColor + desColor * (1 - srcAlpha);
des.write(outColor, gid);
}
But after that blended color will be different than previous.但在那之后混合的颜色将与以前不同。 Blending color is lighter than previous one.
混合颜色比前一种颜色浅。
How do I properly blend two transparent textures in kernel function?如何在内核函数中正确混合两个透明纹理? What is wrong with my solution?
我的解决方案有什么问题?
I think that you are using premultiplied alpha...我认为您正在使用预乘 alpha ......
Try this instead (which is not premultiplied alpha):试试这个(这不是预乘 alpha):
float4 srcColor = src.read(gid);
float4 desColor = des.read(gid);
float4 outColor;
outColor.a = srcColor.a + desColor.a * (1f - srcColor.a);
if (outColor.a == 0f) {
outColor.r = 0f;
outColor.g = 0f;
outColor.b = 0f;
} else {
outColor.r = (srcColor.r * srcColor.a + desColor.r * desColor.a * (1f - srcColor.a)) / outColor.a;
outColor.g = (srcColor.g * srcColor.a + desColor.g * desColor.a * (1f - srcColor.a)) / outColor.a;
outColor.b = (srcColor.b * srcColor.a + desColor.b * desColor.a * (1f - srcColor.a)) / outColor.a;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.