ps的颜色混合模式算法

先附上中英文对比


ps的颜色混合模式算法_第1张图片

ps的颜色混合模式算法_第2张图片


C++实现

#define ChannelBlend_Normal(A,B)     ((uint8)(A))
#define ChannelBlend_Lighten(A,B)    ((uint8)((B > A) ? B:A))
#define ChannelBlend_Darken(A,B)     ((uint8)((B > A) ? A:B))
#define ChannelBlend_Multiply(A,B)   ((uint8)((A * B) / 255))
#define ChannelBlend_Average(A,B)    ((uint8)((A + B) / 2))
#define ChannelBlend_Add(A,B)        ((uint8)(min(255, (A + B))))
#define ChannelBlend_Subtract(A,B)   ((uint8)((A + B < 255) ? 0:(A + B - 255)))
#define ChannelBlend_Difference(A,B) ((uint8)(abs(A - B)))
#define ChannelBlend_Negation(A,B)   ((uint8)(255 - abs(255 - A - B)))
#define ChannelBlend_Screen(A,B)     ((uint8)(255 - (((255 - A) * (255 - B)) >> 8)))
#define ChannelBlend_Exclusion(A,B)  ((uint8)(A + B - 2 * A * B / 255))
#define ChannelBlend_Overlay(A,B)    ((uint8)((B < 128) ? (2 * A * B / 255):(255 - 2 * (255 - A) * (255 - B) / 255)))
#define ChannelBlend_SoftLight(A,B)  ((uint8)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))))
#define ChannelBlend_HardLight(A,B)  (ChannelBlend_Overlay(B,A))
#define ChannelBlend_ColorDodge(A,B) ((uint8)((B == 255) ? B:min(255, ((A << 8 ) / (255 - B)))))
#define ChannelBlend_ColorBurn(A,B)  ((uint8)((B == 0) ? B:max(0, (255 - ((255 - A) << 8 ) / B))))
#define ChannelBlend_LinearDodge(A,B)(ChannelBlend_Add(A,B))
#define ChannelBlend_LinearBurn(A,B) (ChannelBlend_Subtract(A,B))
#define ChannelBlend_LinearLight(A,B)((uint8)(B < 128)?ChannelBlend_LinearBurn(A,(2 * B)):ChannelBlend_LinearDodge(A,(2 * (B - 128))))
#define ChannelBlend_VividLight(A,B) ((uint8)(B < 128)?ChannelBlend_ColorBurn(A,(2 * B)):ChannelBlend_ColorDodge(A,(2 * (B - 128))))
#define ChannelBlend_PinLight(A,B)   ((uint8)(B < 128)?ChannelBlend_Darken(A,(2 * B)):ChannelBlend_Lighten(A,(2 * (B - 128))))
#define ChannelBlend_HardMix(A,B)    ((uint8)((ChannelBlend_VividLight(A,B) < 128) ? 0:255))
#define ChannelBlend_Reflect(A,B)    ((uint8)((B == 255) ? B:min(255, (A * A / (255 - B)))))
#define ChannelBlend_Glow(A,B)       (ChannelBlend_Reflect(B,A))
#define ChannelBlend_Phoenix(A,B)    ((uint8)(min(A,B) - max(A,B) + 255))
#define ChannelBlend_Alpha(A,B,O)    ((uint8)(O * A + (1 - O) * B))
#define ChannelBlend_AlphaF(A,B,F,O) (ChannelBlend_Alpha(F(A,B),A,O))


shader

multiply:
result = base * blend;
screen:
result = vec4(1.0) - ((vec4(1.0) - blend) * (vec4(1.0) - base));
darken:
result = min( blend, base );
lighten:
result = max( blend, base );
difference:
result = abs( base - blend );
negation:
result = vec4(1.0) - abs( vec4(1.0) - base - blend );
exclusion:
result = base + blend - (2.0*base*blend);
overlay:
# per channel:
if (base < 0.5) {
    result = 2.0 * base * blend;
} else {
    result = vec4(1.0) - 2.0 * (vec4(1.0) - blend) * (vec4(1.0) - base);
}
hard light:
# per channel:
if (blend < 0.5) {
    result = 2.0 * base * blend;
} else {
    result = vec4(1.0) - 2.0 * (vec4(1.0) - blend) * (vec4(1.0) - base);
}
soft light:
# per channel:
if (blend < 0.5) {
    result = 2.0 * base * blend + base*base - 2.0 * base*base*blend;
} else {
    result = 2.0 * sqrt(base) * blend - sqrt(base) + 2.0 * base - 2.0 * base*blend;
}
dodge:
result = base / (vec4(1.0) - blend);
burn:
result = vec4(1.0) - (vec4(1.0) - base) / blend;


参考资料:

Adobe - Blending modes

Layer Blending Modes in Photoshop and Elements

stackoverflow - How does photoshop blend two images together?

Photoshop Blendmodi in GLSL

你可能感兴趣的:(图形学)