1/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6// Helper functions. 7float hardlight(float dest, float src) { 8 if (src <= 0.5) { 9 return dest * (2.0 * src); 10 } else { 11 // Note: we substitute (2*src-1) into the screen formula below. 12 return 2.0 * dest + 2.0 * src - 1.0 - 2.0 * dest * src; 13 } 14} 15 16float dodge(float dest, float src) { 17 if (dest == 0.0) { 18 return 0.0; 19 } else if (src == 1.0) { 20 return 1.0; 21 } else { 22 return min(1.0, dest / (1.0 - src)); 23 } 24} 25 26float burn(float dest, float src) { 27 if (dest == 1.0) { 28 return 1.0; 29 } else if (src == 0.0) { 30 return 0.0; 31 } else { 32 return 1.0 - min(1.0, (1.0 - dest) / src); 33 } 34} 35 36float darken(float dest) { 37 if (dest <= 0.25) { 38 return ((16.0 * dest - 12.0) * dest + 4.0) * dest; 39 } else { 40 return sqrt(dest); 41 } 42} 43 44float softlight(float dest, float src) { 45 if (src <= 0.5) { 46 return dest - (1.0 - 2.0 * src) * dest * (1.0 - dest); 47 } else { 48 return dest + (2.0 * src - 1.0) * (darken(dest) - dest); 49 } 50} 51 52float Lum(float3 c) { 53 return dot(float3(0.3, 0.59, 0.11), c); 54} 55 56float3 ClipColor(float3 c) { 57 float L = Lum(c); 58 float n = min(min(c.r, c.g), c.b); 59 float x = max(max(c.r, c.g), c.b); 60 if (n < 0.0) { 61 c = L + (((c - L) * L) / (L - n)); 62 } 63 if (x > 1.0) { 64 c = L + (((c - L) * (1.0 - L)) / (x - L)); 65 } 66 return c; 67} 68 69float3 SetLum(float3 c, float L) { 70 float d = L - Lum(c); 71 return ClipColor(float3( 72 c.r + d, 73 c.g + d, 74 c.b + d)); 75} 76 77float Sat(float3 c) { 78 return max(max(c.r, c.g), c.b) - min(min(c.r, c.g), c.b); 79} 80 81// To use this helper, re-arrange rgb such that r=min, g=mid, and b=max. 82float3 SetSatInner(float3 c, float s) { 83 if (c.b > c.r) { 84 c.g = (((c.g - c.r) * s) / (c.b - c.r)); 85 c.b = s; 86 } else { 87 c.gb = float2(0.0, 0.0); 88 } 89 return float3(0.0, c.g, c.b); 90} 91 92float3 SetSat(float3 c, float s) { 93 if (c.r <= c.g) { 94 if (c.g <= c.b) { 95 c.rgb = SetSatInner(c.rgb, s); 96 } else if (c.r <= c.b) { 97 c.rbg = SetSatInner(c.rbg, s); 98 } else { 99 c.brg = SetSatInner(c.brg, s); 100 } 101 } else if (c.r <= c.b) { 102 c.grb = SetSatInner(c.grb, s); 103 } else if (c.g <= c.b) { 104 c.gbr = SetSatInner(c.gbr, s); 105 } else { 106 c.bgr = SetSatInner(c.bgr, s); 107 } 108 return c; 109} 110 111float3 BlendMultiply(float3 dest, float3 src) { 112 return dest * src; 113} 114 115float3 BlendScreen(float3 dest, float3 src) { 116 return dest + src - (dest * src); 117} 118 119float3 BlendOverlay(float3 dest, float3 src) { 120 return float3( 121 hardlight(src.r, dest.r), 122 hardlight(src.g, dest.g), 123 hardlight(src.b, dest.b)); 124} 125 126float3 BlendDarken(float3 dest, float3 src) { 127 return min(dest, src); 128} 129 130float3 BlendLighten(float3 dest, float3 src) { 131 return max(dest, src); 132} 133 134float3 BlendColorDodge(float3 dest, float3 src) { 135 return float3( 136 dodge(dest.r, src.r), 137 dodge(dest.g, src.g), 138 dodge(dest.b, src.b)); 139} 140 141float3 BlendColorBurn(float3 dest, float3 src) { 142 return float3( 143 burn(dest.r, src.r), 144 burn(dest.g, src.g), 145 burn(dest.b, src.b)); 146} 147 148float3 BlendHardLight(float3 dest, float3 src) { 149 return float3( 150 hardlight(dest.r, src.r), 151 hardlight(dest.g, src.g), 152 hardlight(dest.b, src.b)); 153} 154 155float3 BlendSoftLight(float3 dest, float3 src) { 156 return float3( 157 softlight(dest.r, src.r), 158 softlight(dest.g, src.g), 159 softlight(dest.b, src.b)); 160} 161 162float3 BlendDifference(float3 dest, float3 src) { 163 return abs(dest - src); 164} 165 166float3 BlendExclusion(float3 dest, float3 src) { 167 return dest + src - 2.0 * dest * src; 168} 169 170float3 BlendHue(float3 dest, float3 src) { 171 return SetLum(SetSat(src, Sat(dest)), Lum(dest)); 172} 173 174float3 BlendSaturation(float3 dest, float3 src) { 175 return SetLum(SetSat(dest, Sat(src)), Lum(dest)); 176} 177 178float3 BlendColor(float3 dest, float3 src) { 179 return SetLum(src, Lum(dest)); 180} 181 182float3 BlendLuminosity(float3 dest, float3 src) { 183 return SetLum(dest, Lum(src)); 184} 185