17 "title" :
"VuoImageBlend",
28 #define FilterSource "\
29 \n#include \"VuoGlslAlpha.glsl\"\
30 uniform sampler2D background;\
31 uniform sampler2D foreground;\
32 uniform float foregroundOpacity;\
33 uniform bool replaceOpacity;\
34 varying vec2 fragmentTextureCoordinate;\
36 float BlendLinearDodgef(float base, float blend) { return min(base + blend, 1.0); }\
37 float BlendLinearBurnf(float base, float blend) { return max(base + blend - 1.0, 0.0); }\
38 float BlendDividef(float base, float blend) { return (blend == 0.0) ? blend : base/blend; }\
40 float BlendLightenf(float base, float blend) { return max(blend, base); }\
41 float BlendDarkenf(float base, float blend) { return min(blend, base); }\
42 float BlendLinearLightf(float base, float blend) { return (blend < 0.5 ? BlendLinearBurnf(base, (2.0 * blend)) : BlendLinearDodgef(base, (2.0 * (blend - 0.5)))); }\
44 float BlendScreenf(float base, float blend) { return (1.0 - ((1.0 - base) * (1.0 - blend))); }\
45 float BlendOverlayf(float base, float blend) { return (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend))); }\
46 float BlendSoftLightf(float base, float blend) { return ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend))); }\
47 float BlendHardLightf(float base, float blend) { return BlendOverlayf(blend, base); }\
48 float BlendColorDodgef(float base, float blend) { return ((blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0)); }\
49 float BlendColorBurnf(float base, float blend) { return (blend == 0.0) ? blend : max((1.0 - ((1.0 - base) / blend)), 0.0); }\
51 float BlendVividLightf(float base, float blend) { return ((blend < 0.5) ? BlendColorBurnf(base, (2.0 * blend)) : BlendColorDodgef(base, (2.0 * (blend - 0.5)))); }\
52 float BlendPinLightf(float base, float blend) { return ((blend < 0.5) ? BlendDarkenf(base, (2.0 * blend)) : BlendLightenf(base, (2.0 *(blend - 0.5)))); }\
53 float BlendHardMixf(float base, float blend) { return ((BlendVividLightf(base, blend) < 0.5) ? 0.0 : 1.0); }\
55 \n#include \"VuoGlslHsl.glsl\"\
57 vec3 blendColors(vec4 bg, vec4 fg);\
61 vec4 backgroundColor = VuoGlsl_sample(background, fragmentTextureCoordinate); \
62 backgroundColor.rgb /= backgroundColor.a > 0. ? backgroundColor.a : 1.; \
63 vec4 foregroundColor = VuoGlsl_sample(foreground, fragmentTextureCoordinate); \
64 foregroundColor.rgb /= foregroundColor.a > 0. ? foregroundColor.a : 1.; \
65 foregroundColor.a *= foregroundOpacity; \
67 vec3 blendedColors = clamp(blendColors(backgroundColor, foregroundColor), 0., 1.); \
69 blendedColors = mix(foregroundColor.rgb, blendedColors, backgroundColor.a); \
71 vec4 mixed = replaceOpacity \
72 ? vec4(blendedColors*foregroundColor.a + backgroundColor.rgb*backgroundColor.a*(1.-foregroundColor.a), \
73 foregroundColor.a + backgroundColor.a*(1.-foregroundColor.a)) \
74 : vec4(blendedColors*foregroundColor.a*backgroundColor.a + backgroundColor.rgb*backgroundColor.a*(1.-foregroundColor.a), \
77 gl_FragColor = mixed; \
81 #define BLEND_FILTERS(source) "#version 120\n" FilterSource "\n" #source
84 vec3 blendColors(vec4 bg, vec4 fg)
91 vec3 blendColors(vec4 bg, vec4 fg)
93 return bg.rgb * fg.rgb;
98 vec3 blendColors(vec4 bg, vec4 fg)
100 return bg.rgb + fg.rgb;
105 vec3 blendColors(vec4 bg, vec4 fg)
107 return min(bg.rgb, fg.rgb);
112 vec3 blendColors(vec4 bg, vec4 fg)
114 float bgLum = VuoGlsl_rgbToHsl(bg.rgb).b;
115 float fgLum = VuoGlsl_rgbToHsl(fg.rgb).b;
116 return bgLum < fgLum ? bg.rgb : fg.rgb;
121 vec3 blendColors(vec4 bg, vec4 fg)
123 return max(bg.rgb, fg.rgb);
128 vec3 blendColors(vec4 bg, vec4 fg)
130 float bgLum = VuoGlsl_rgbToHsl(bg.rgb).b;
131 float fgLum = VuoGlsl_rgbToHsl(fg.rgb).b;
132 return bgLum > fgLum ? bg.rgb : fg.rgb;
137 vec3 blendColors(vec4 bg, vec4 fg)
139 return bg.rgb + fg.rgb - 1.;
144 vec3 blendColors(vec4 bg, vec4 fg)
146 return vec3(BlendColorBurnf(bg.r, fg.r),
147 BlendColorBurnf(bg.g, fg.g),
148 BlendColorBurnf(bg.b, fg.b));
153 vec3 blendColors(vec4 bg, vec4 fg)
155 return bg.rgb / (1. - fg.rgb*fg.a);
160 vec3 blendColors(vec4 bg, vec4 fg)
162 return vec3(BlendScreenf(bg.r, fg.r),
163 BlendScreenf(bg.g, fg.g),
164 BlendScreenf(bg.b, fg.b));
169 vec3 blendColors(vec4 bg, vec4 fg)
171 return vec3(BlendOverlayf(bg.r, fg.r),
172 BlendOverlayf(bg.g, fg.g),
173 BlendOverlayf(bg.b, fg.b));
178 vec3 blendColors(vec4 bg, vec4 fg)
180 return vec3(BlendSoftLightf(bg.r, fg.r),
181 BlendSoftLightf(bg.g, fg.g),
182 BlendSoftLightf(bg.b, fg.b));
187 vec3 blendColors(vec4 bg, vec4 fg)
189 return vec3(BlendHardLightf(bg.r, fg.r),
190 BlendHardLightf(bg.g, fg.g),
191 BlendHardLightf(bg.b, fg.b));
196 vec3 blendColors(vec4 bg, vec4 fg)
198 return vec3(BlendVividLightf(bg.r, fg.r),
199 BlendVividLightf(bg.g, fg.g),
200 BlendVividLightf(bg.b, fg.b));
205 vec3 blendColors(vec4 bg, vec4 fg)
207 return vec3(BlendLinearLightf(bg.r, fg.r),
208 BlendLinearLightf(bg.g, fg.g),
209 BlendLinearLightf(bg.b, fg.b));
214 vec3 blendColors(vec4 bg, vec4 fg)
216 return vec3(BlendPinLightf(bg.r, fg.r),
217 BlendPinLightf(bg.g, fg.g),
218 BlendPinLightf(bg.b, fg.b));
223 vec3 blendColors(vec4 bg, vec4 fg)
225 return vec3(BlendHardMixf(bg.r, fg.r),
226 BlendHardMixf(bg.g, fg.g),
227 BlendHardMixf(bg.b, fg.b));
232 vec3 blendColors(vec4 bg, vec4 fg)
234 return abs(bg.rgb - fg.rgb);
239 vec3 blendColors(vec4 bg, vec4 fg)
241 return bg.rgb + fg.rgb - 2.*bg.rgb*fg.rgb;
246 vec3 blendColors(vec4 bg, vec4 fg)
248 return bg.rgb - fg.rgb;
253 vec3 blendColors(vec4 bg, vec4 fg)
255 return vec3(BlendDividef(bg.r, fg.r),
256 BlendDividef(bg.g, fg.g),
257 BlendDividef(bg.b, fg.b));
262 vec3 blendColors(vec4 bg, vec4 fg)
264 vec3 baseHSL = VuoGlsl_rgbToHsl(bg.rgb);
265 return VuoGlsl_hslToRgb(vec3(VuoGlsl_rgbToHsl(fg.rgb).r, baseHSL.g, baseHSL.b));
270 vec3 blendColors(vec4 bg, vec4 fg)
272 vec3 baseHSL = VuoGlsl_rgbToHsl(bg.rgb);
273 return VuoGlsl_hslToRgb(vec3(baseHSL.r, VuoGlsl_rgbToHsl(fg.rgb).g, baseHSL.b));
278 vec3 blendColors(vec4 bg, vec4 fg)
280 vec3 blendHSL = VuoGlsl_rgbToHsl(fg.rgb);
281 return VuoGlsl_hslToRgb(vec3(blendHSL.r, blendHSL.g, VuoGlsl_rgbToHsl(bg.rgb).b));
286 vec3 blendColors(vec4 bg, vec4 fg)
288 vec3 baseHSL = VuoGlsl_rgbToHsl(bg.rgb);
289 return VuoGlsl_hslToRgb(vec3(baseHSL.r, baseHSL.g, VuoGlsl_rgbToHsl(fg.rgb).b));
294 vec3 blendColors(vec4 bg, vec4 fg)
296 return pow(bg.rgb, fg.rgb);
394 free(blendModeSummary);
406 if (!background && !foreground)
411 VuoInteger pixelsWide = background ? background->pixelsWide : foreground->pixelsWide;
412 VuoInteger pixelsHigh = background ? background->pixelsHigh : foreground->pixelsHigh;
415 if (colorDepthForeground > colorDepth)
416 colorDepth = colorDepthForeground;
421 background->scaleFactor = foreground->scaleFactor;
428 foreground->scaleFactor = background->scaleFactor;