SpriteKit:带有自定义着色器的 SKShader 无法正确进行“混合”

SpriteKit: SKShader with custom shader not doing `mix` properly

我正在使用自定义着色器在 SpriteKit 中创建精灵。

着色器的主要部分就是这样做的...

vec4 col = mix(baseColor, overlayColor, overlayColor.a);

我的颜色有点像...

baseColor = UIColor(red:0.51, green:0.71, blue:0.88, alpha:1.0)

和...

overlay = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.5)

根据互联网上的任何地方(链接跟随),我在上面使用的混合功能与 Photoshop、Pixelmator、Sketch 等中的 Normal 混合模式相同...这应该会导致在颜色...

col = UIColor(red:0.75, green:0.85, blue:0.95, alpha:1.00)

这是一种明亮的蓝色。然而,我得到的是...

col = UIColor(red:0.51, green:0.61, blue:0.69, alpha:1.00)

这是一种暗灰色。

你可以在这里看到它应该是什么样子... https://thebookofshaders.com/glossary/?search=mix

如果您输入代码...

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform float u_time;

vec4 colorA = vec4(0.5, 0.7, 0.9, 1.0);
vec4 colorB = vec4(1.0, 1.0, 1.0, 0.5);

void main() {
    vec4 color = vec4(0.0);

    // Mix uses pct (a value from 0-1) to
    // mix the two colors
    color = mix(colorA, colorB, colorB.a);
    color.a = 1.0;

    gl_FragColor = color;
}

理想的输出颜色是这样的……

但是看起来是这样的……

我明天再调查一下。我希望我知道为什么输出与其他地方所说的完全不同。

好的,感谢@Reaper 的评论,我开始全面调查这到底出了什么问题。

在我们的着色器中混合硬编码颜色时,颜色实际上是正确的。

所以它引导我查看我们使用的纹理图像。

那个有 50% alpha 的白色肯定是白色的。 (不是灰色)。

但是...(系统中的怪癖?)Open GL 将其拾取为 50% 灰色和 50% alpha。

所以混合实际上并没有首先混合正确的颜色。

我们通过对颜色使用 100% alpha 图像和对 alpha 贴图(黑色 -> 白色)使用 100% 图像来解决此问题。

这样做解决了我们遇到的问题。