Trying to create a new blending mode option for color-dodge
(or divide
both are very similar.)
current list of blending modes for webgl:
fragmentSource: {
multiply: 'gl_FragColor.rgb *= uColor.rgb;\n',
screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n',
add: 'gl_FragColor.rgb += uColor.rgb;\n',
diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n',
subtract: 'gl_FragColor.rgb -= uColor.rgb;\n',
lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n',
darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n',
exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n',
overlay: 'if (uColor.r < 0.5) {\n' +
'gl_FragColor.r *= 2.0 * uColor.r;\n' +
'} else {\n' +
'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n' +
'}\n' +
'if (uColor.g < 0.5) {\n' +
'gl_FragColor.g *= 2.0 * uColor.g;\n' +
'} else {\n' +
'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n' +
'}\n' +
'if (uColor.b < 0.5) {\n' +
'gl_FragColor.b *= 2.0 * uColor.b;\n' +
'} else {\n' +
'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n' +
'}\n',
tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\n' +
'gl_FragColor.rgb += uColor.rgb;\n',
},
according to resources i've read ( 1 , 2 , 3 ), for color-dodge
the math should be per channel and should be min(1.0, baseColor / (1 - blendColor))
i've tried to add an option for
divide: 'gl_FragColor.r = min(1.0, gl_FragColor.r / (1 - uColor.r));\n' +
'gl_FragColor.g = min(1.0, gl_FragColor.g / (1 - uColor.g));\n' +
'gl_FragColor.b = min(1.0, gl_FragColor.b / (1 - uColor.b));\n',
but the result image is always a different shade of the same blue no matter what color is passed in to be blended
here is how i'm applying the filter
var fabricImg = new fabric.Image(pageBackgroundImg), // make a fabric.Image object out of the HTMLImageElement
blendedCanvas = new fabric.StaticCanvas(null, {
width: fabricImg.getScaledWidth(),
height: fabricImg.getScaledHeight(),
renderOnAddRemove: false
}),
pageBackgroundPattern;
// add the color filter to the image
fabricImg.filters.push(
new fabric.Image.filters.BlendColor({
color: '#' + color,
mode: 'divide'
})
);
fabricImg.applyFilters();
// add the image to the canvas
blendedCanvas.add(fabricImg);
blendedCanvas.renderAll();
So i added a snippet so that we can understand better. The filter you added IS doing something, if this is what should happen with a photoshop divide/colordodge, we can understand only comparing. Your code is correct and is indeed working
Scroll down to compare original image with the filtered one
function start() { var canvas = new fabric.Canvas('c'); var image = document.getElementById('img'); var fabricImg = new fabric.Image(image); fabric.Image.filters.BlendColor.prototype.fragmentSource.divide = 'gl_FragColor.r = min(1.0, gl_FragColor.r / (1.0 - uColor.r));\\n' + 'gl_FragColor.g = min(1.0, gl_FragColor.g / (1.0 - uColor.g));\\n' + 'gl_FragColor.b = min(1.0, gl_FragColor.b / (1.0 - uColor.b));\\n'; fabricImg.filters.push( new fabric.Image.filters.BlendColor({ color: '#0000ff', mode: 'divide' }) ); fabricImg.applyFilters(); canvas.add(fabricImg); canvas.requestRenderAll(); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.min.js"></script> <canvas id="c" width=500 height=400 ></canvas> <img crossOrigin="anonymous" onload="start()" src="https://raw.githubusercontent.com/fabricjs/fabricjs.com/gh-pages/assets/dragon2.jpg" id="img" />
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.