【问题标题】:Blend mode with alpha带 alpha 的混合模式
【发布时间】:2021-03-28 14:17:30
【问题描述】:

我正在尝试复制混合模式。目前我已经重新创建了一个屏幕混合模式,但它似乎不适用于透明图像。

我有两个纹理

图像 1(前景)

图片 2(背景)

我得到的结果是这样的

计算着色器代码

#pragma kernel Blend

RWTexture2D<float4> Result;

Texture2D<float4> TopLayer;
Texture2D<float4> BottomLayer;

[numthreads(8, 8, 1)]
void Blend(uint3 id : SV_DispatchThreadID)
{
    if (TopLayer[id.xy].w == 0 && BottomLayer[id.xy].w > 0)
    {
        Result[id.xy] = BottomLayer[id.xy];
    }
    else if (BottomLayer[id.xy].w == 0 && TopLayer[id.xy].w > 0)
    {
        Result[id.xy] = TopLayer[id.xy];
    }
    else if (BottomLayer[id.xy].w == 0 && TopLayer[id.xy].w == 0)
    {
        Result[id.xy] = float4(0, 0, 0, 0);
    }
    else
    {
        float alpha_final = BottomLayer[id.xy].w + TopLayer[id.xy].w - BottomLayer[id.xy].w * TopLayer[id.xy].w;

        float4 tex = 1 - (1 - TopLayer[id.xy]) * (1 - BottomLayer[id.xy]);

        Result[id.xy] = float4(tex.x, tex.y, tex.z, alpha_final);
    }
}

如何正确混合具有不同 alpha 的图像?

【问题讨论】:

  • 它确定你在寻找什么输出,但我猜你想在混合中使用 alpha 作为权重。
  • 我已经将每个图层的颜色乘以其 alpha 像这样 float4 tex = 1 - (1 - TopLayer[id.xy] * TopLayer[id.xy].w) * (1 - BottomLayer[id .xy] * BottomLayer[id.xy].w);现在看起来好多了,不过,我不确定它是否 100% 正确。看起来我正在使用普通模式。就像我在另一层之上添加一层一样。这是这样做的方法吗?增加重量
  • 好吧,你的第二张图片大部分都是透明的。您可能需要更复杂的输入来查看混合模式之间的差异。
  • 我尝试使用颜色减淡和乘法模式实现相同的方法。颜色闪避似乎会产生与例如类似的结果。 Photoshop,我将不得不做更多的测试,但是乘法结果肯定是不正确的。我使用这个等式 (TopLayer[id.xy] * TopLayer[id.xy].w) * (BottomLayer[id.xy] * BottomLayer[id.xy].w);我认为混合似乎是正确的,但是淡化图像越透明,背景图像就越暗。我猜这是因为将颜色乘以低 alpha 会使像素颜色变暗,但是我该如何正确混合呢?

标签: c# unity3d image-processing alphablending compute-shader


【解决方案1】:

与 Alpha 通道混合需要使用 Alpha 值进行加权。

我之前没有想过如何在屏幕混合情况下正确加权,这是一种乘法合成。我认为像weighted geometric mean:https://en.m.wikipedia.org/wiki/Weighted_geometric_mean) 那样做是有意义的:将被乘数提高到相应权重(alpha 值)的幂,然后将结果提高到权重总和的倒数的幂.因为我们想复制两个 alpha 都为 1 的标准情况:

1 - (1-a) (1-b)

其中没有平方根,我们将 alpha 值的总和除以 2:

1 - [ (1-a)wa (1-b)wb ] 2/(wa+wb)

输出 Alpha 通道本身可以以相同的方式计算,或者可以是两个 Alpha 值的简单最大值。我不知道什么会更好看。

【讨论】:

  • 感谢您的回复!我让它与屏幕和颜色减淡一起工作。我混合了不同的图像并得到了准确的结果!但是,我无法让乘法模式工作。透明区域产生黑色。 ://
  • @UnknownUser:如果 wa 和 wb 都为 0,则 2/(wa+wb) 是无穷大,您可能希望避免这种情况。您应该对这种情况进行特殊处理。我不知道在你的环境中是否正确处理了提升到无穷大的力量。
  • 我找到了这个 alpha 复合方程:(1 - fgA / a) * bgC + (fgA / a) * round((1 - bgA) * fgC + bgA * bC);并将其用于每个颜色通道,例如 alphaCompose(BottomLayer[id.xy].w, TopLayer[id.xy].w, a, BottomLayer[id.xy].x, TopLayer[id.xy].x, TopLayer[id.xy].x * BottomLayer[id.xy].x);它解决了这个问题,尽管混合结果与 Photoshop 结果相比太暗
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 2011-12-14
  • 2010-11-20
相关资源
最近更新 更多