Blending functions
From polycount
Revision as of 14:49, 6 August 2014 by Haiddasalami (Talk | contribs)
Here are all the Photoshop Blending Modes, in easy to use functions for various languages.
Contents
HLSL
Category 1 (Darker)
float4 Darken (float4 cBase, float4 cBlend) { float4 cNew; cNew.rgb = min(cBase.rgb, cBlend.rgb); cNew.a = 1.0; return cNew; }
float4 Multiply (float4 cBase, float4 cBlend) { return (cBase * cBlend); }
float4 ColorBurn (float4 cBase, float4 cBlend) { return (1 - (1 - cBase) / cBlend); }
float4 LinearBurn (float4 cBase, float4 CBlend) { return (cBase + cBlend - 1); }
Category 2 (Lighter)
float4 Lighten (float4 cBase, float4 cBlend) { float4 cNew; cNew.rgb = max(cBase.rgb, cBlend.rgb); cNew.a = 1.0; return cNew; }
float4 Screen (float4 cBase, float4 cBlend) { return (1 - (1 - cBase) * (1 - cBlend)); }
float4 ColorDodge (float4 cBase, float4 cBlend) { return (cBase / (1 - cBlend)); }
float4 LinearDodge (float4 cBase, float4 cBlend) { return (cBase + cBlend); }
Category 3 (Complex)
float4 Overlay (float4 cBase, float4 cBlend) { /* float4 cNew; if (cBase.r > .5) { cNew.r = 1 - (1 - 2 * (cBase.r - .5)) * (1 - cBlend.r); } else { cNew.r = (2 * cBase.r) * cBlend.r; } if (cBase.g > .5) { cNew.g = 1 - (1 - 2 * (cBase.g - .5)) * (1 - cBlend.g); } else { cNew.g = (2 * cBase.g) * cBlend.g; } if (cBase.b > .5) { cNew.b = 1 - (1 - 2 * (cBase.b - .5)) * (1 - cBlend.b); } else { cNew.b = (2 * cBase.b) * cBlend.b; } cNew.a = 1.0; return cNew; */ // Vectorized (easier for compiler) float4 cNew; // overlay has two output possbilities // which is taken is decided if pixel value // is below half or not cNew = step(0.5,cBase); // we pick either solution // depending on pixel // first is case of < 0.5 // second is case for >= 0.5 // interpolate between the two, // using color as influence value cNew= lerp((cBase*cBlend*2),(1.0-(2.0*(1.0-cBase)*(1.0-cBlend))),cNew); cNew.a = 1.0; return cNew; }
float4 SoftLight (float4 cBase, float4 cBlend) { float4 cNew; if (cBlend.r > .5) { cNew.r = cBase.r * (1 - (1 - cBase.r) * (1 - 2 * (cBlend.r)));} else { cNew.r = 1 - (1 - cBase.r) * (1 - (cBase.r * (2 * cBlend.r))); } if (cBlend.g > .5) { cNew.g = cBase.g * (1 - (1 - cBase.g) * (1 - 2 * (cBlend.g)));} else { cNew.g = 1 - (1 - cBase.g) * (1 - (cBase.g * (2 * cBlend.g))); } if (cBlend.g > .5) { cNew.b = cBase.b * (1 - (1 - cBase.b) * (1 - 2 * (cBlend.b)));} else { cNew.b = 1 - (1 - cBase.b) * (1 - (cBase.b * (2 * cBlend.b))); } cNew.a = 1.0; return cNew; }
float4 HardLight (float4 cBase, float4 cBlend) { float4 cNew; if (cBlend.r > .5) { cNew.r = 1 - (1 - cBase.r) * (1 - 2 * (cBlend.r)); } else { cNew.r = cBase.r * (2 * cBlend.r); } if (cBlend.g > .5) { cNew.g = 1 - (1 - cBase.g) * (1 - 2 * (cBlend.g)); } else { cNew.g = cBase.g * (2 * cBlend.g); } if (cBlend.b > .5) { cNew.b = 1 - (1 - cBase.b) * (1 - 2 * (cBlend.b)); } else { cNew.b = cBase.b * (2 * cBlend.b); } cNew.a = 1.0; return cNew; }
float4 VividLight (float4 cBase, float4 cBlend) { float4 cNew; if (cBlend.r > .5) {cNew.r = 1 - (1 - cBase.r) / (2 * (cBlend.r - .5)); } else {cNew.r = cBase.r / (1 - 2 * cBlend.r); } if (cBlend.g > .5) {cNew.g = 1 - (1 - cBase.g) / (2 * (cBlend.g - .5)); } else {cNew.g = cBase.g / (1 - 2 * cBlend.g); } if (cBlend.b > .5) {cNew.b = 1 - (1 - cBase.b) / (2 * (cBlend.b - .5)); } else {cNew.b = cBase.b / (1 - 2 * cBlend.b); } cNew.a = 1.0; return cNew; }
float4 LinearLight (float4 cBase, float4 cBlend) { float4 cNew; if (cBlend.r > .5) {cNew.r = cBase.r + 2 * (cBlend.r - .5); } else {cNew.r = cBase.r + 2 * cBlend.r - 1; } if (cBlend.g > .5) {cNew.g = cBase.g + 2 * (cBlend.g - .5); } else {cNew.g = cBase.g + 2 * cBlend.g - 1; } if (cBlend.b > .5) {cNew.b = cBase.b + 2 * (cBlend.b - .5); } else {cNew.b = cBase.b + 2 * cBlend.b - 1; } cNew.a = 1.0; return cNew; }
float4 PinLight (float4 cBase, float4 cBlend) { float4 cNew; if (cBlend.r > .5) { cNew.r = max(cBase.r, 2 * (cBlend.r - .5)); } else {cNew.r = min(cBase.r, 2 * cBlend.r); } if (cBlend.g > .5) { cNew.g = max(cBase.g, 2 * (cBlend.g - .5)); } else {cNew.g = min(cBase.g, 2 * cBlend.g); } if (cBlend.b > .5) { cNew.b = max(cBase.b, 2 * (cBlend.b - .5)); } else {cNew.b = min(cBase.b, 2 * cBlend.b); } cNew.a = 1.0; return cNew; }
Category 4 (Comparison)
float4 Difference (float4 cBase, float4 cBlend) { return (abs(cBase - cBlend)); }
float4 Exclusion (float4 cBase, float4 cBlend) { return (.5 - 2 * (cBase - .5) * (cBlend - .5)); }