- 圖層混合模式介紹
Fireworks 8 混合模式詳解
Blending modes in Adobe Photoshop
- glBlendFunc介紹
Android OpenGLES2.0(十八)——輕松搞定Blend顏色混合
終端圖像處理系列 - OpenGL混合模式的使用
LearnOpenGL-混合
glBlendFunc(GLenum src_factor, GLenum dest_factor)
color_result = color_ src ?src_factor + color_dest?dest_factor
dest指的是當(dāng)前儲存在顏色緩沖中的顏色向量历等,即目標(biāo)色撒顿,底色消请,本色莉擒。底部的背景赊堪。
src指的是新的萨惑,要用于合成的紋理的顏色,即源色白群,用于合成的資源竟痰。上層的前景签钩。
比較常規(guī)的配置應(yīng)該是
// norm模式
glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
注意:
OpenGL里執(zhí)行完glBlendFunc后掏呼,記得恢復(fù)之前的glIsEnabled和glBlendFunc. 這點容易被忘記導(dǎo)致各種渲染異常。
- Android里對應(yīng)的顏色混合工具是Xfermodes
各個擊破搞明白PorterDuff.Mode
porter-duff.png
Xfermodes 和 OpenGL Blend函數(shù)的映射關(guān)系 https://github.com/OpenSource-Infinix/android_frameworks_base_one/blob/0287c3e3f6f763cd630290343cda11e15db1844f/libs/hwui/renderstate/Blend.cpp
- 用OpenGL Shader實現(xiàn)圖層混合模式
OpenGL(十七)Photoshop blend算法 與 圖層混合模式
終端圖像處理系列 - 圖像混合模式的Shader實現(xiàn)(有介紹3D場景下的混合方案)(對應(yīng)源碼)
Shader 中的顏色混合模式(Blend Mode)
postprocessing
glsl-blend
GIMP對Blend的處理
w3c的混合模式標(biāo)準(zhǔn)
- 不用shader就能實現(xiàn)的PS的混合模式:
Multiply 正片疊底
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
(AE在正片疊底時對透明度的處理邏輯不詳边臼,所以只適用于不透明的兩個圖層混合的情況哄尔。圖層有透明度時假消,實際效果可能會和AE的有差異)
Darken 變暗
glBlendFunc(GL_ONE, GL_ONE) glBlendEquation(GL_FUNC_MIN)
(Android 不支持GL_FUNC_MIN柠并,iOS可以用GL_MIN_EXT)
Lighten 變亮
glBlendFunc(GL_ONE,GL_ONE) glBlendEquation(GL_FUNC_MAX)
(Android 不支持GL_FUNC_MAX,iOS可以用GL_MAX_EXT)
Difference 差值
glBlendFunc(GL_ONE, GL_ONE) glBlendEquation(GL_FUNC_SUBTRACT)
(只適用src的RGBA值比dest的RGBA值都大的情況富拗,否則還是需要用shader計算兩張圖的RGBA差值的絕對值)
Screen 屏幕
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR)
或glBlendFunc(GL_MINUS_DST_COLOR, GL_ONE)
兩者結(jié)果一樣
Linear Dodge(Add) 線性減淡(增加)
glBlendFunc(GL_ONE, GL_ONE)
(BodyMoving插件只支持Add, 不支持Linear Dodge)
Normal 常規(guī)混合
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
- 在線調(diào)試
調(diào)試glBlendFunc
混合模式對應(yīng)的數(shù)學(xué)公式
- 考慮透明度的shader代碼示例
// 柔光
const char *gl_fra_SoftLight = SHADER_SRC(
precision highp float;
varying vec2 vTexCoord;
uniform sampler2D uTexture;
uniform sampler2D uTexture2;
float blend(const float x, const float y) {
return (y < 0.5) ?
(2.0 * x * y + x * x * (1.0 - 2.0 * y)) :
(sqrt(x) * (2.0 * y - 1.0) + 2.0 * x * (1.0 - y));
}
void main() {
vec4 front = texture2D(uTexture2, vTexCoord);
vec4 back = texture2D(uTexture, vTexCoord);
vec3 dest = vec3(blend(back.r, front.r), blend(back.g, front.g),
blend(back.b, front.b));
float alpha = max(front.a, back.a);
float mixAlpha = front.a*back.a;
vec3 remainColor = back.rgb * (1.0 - front.a)*back.a + front.rgb * (1.0 - back.a)*front.a;
gl_FragColor = vec4((dest*mixAlpha + remainColor), alpha);
}
);