1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2009 Adobe Systems Incorporated 5// All Rights Reserved. 6// 7// NOTICE: Adobe permits you to use, modify, and distribute this file 8// in accordance with the terms of the license agreement accompanying it. 9// 10//////////////////////////////////////////////////////////////////////////////// 11<languageVersion : 1.0;> 12kernel Saturation 13< namespace : "Flame"; 14 vendor : "Adobe"; 15 version : 1; 16 description : "Saturation blend mode"; 17> 18{ 19 input image4 dst; 20 input image4 src; 21 output pixel4 result; 22 23 // PB bytecode can't do functions, use macros to define common functions 24 // gets the max number out of the three 25 #define max3( x, y, z ) ( max((x), max((y), (z))) ) 26 // gets the min number out of the three 27 #define min3( x, y, z ) ( min((x), min((y), (z))) ) 28 29 // gets the max number out of the three elements in a vector 30 #define max3v(C) ( max3((C.x), (C.y), (C.z)) ) 31 // gets the min number out of the three elements in a vector 32 #define min3v(C) ( min3((C.x), (C.y), (C.z)) ) 33 34 // Sat - returns float, takes in a pixel3, or pixel4 35 #define saturation(C) ( (max3((C.r), (C.g), (C.b)) - min3((C.r), (C.g), (C.b))) ) 36 37 // Luminance - returns float, takes in a pixel3, or pixel4 38 #define luminance(C) ( (((C.r) * 0.3) + ((C.g) * 0.59) + ((C.b) * 0.11)) ) 39 40 void 41 evaluatePixel() 42 { 43 pixel4 a = sampleNearest(dst,outCoord()); // cb 44 pixel4 b = sampleNearest(src,outCoord()); // cs 45 46 // remove premultiplied (srcCP/srcA, dstCP/dstA) 47 pixel3 cb = a.rgb; 48 pixel3 cs = b.rgb; 49 if (a.a > 0.0) { 50 cb.rgb = a.rgb / a.a; 51 } 52 if (b.a > 0.0) { 53 cs.rgb = b.rgb / b.a; 54 } 55 56 // dstA' = (1-srcA)*dstA + srcA 57 result.a = (1.0-b.a)*a.a + b.a; 58 59 // record old version of cb 60 //float3 old_cb.rgb = cb.rgb; 61 62 // SetSat(cb, Sat(cs)) 63 64 // setSat (setSatColor, sat) -> setSatResult 65 /* -------------------------------------------------------- 66 * void setsaturation(inout float3 color, in float satVal) 67 * makes color have the target saturation. 68 * input and output of float3 color 69 * input of the target saturation 70 * 71 * -------------------------------------------------------- 72 void setsatcomponents(inout float minComp, inout float midComp, inout float maxComp, in float satVal) 73 { 74 midComp -= minComp; 75 maxComp -= minComp; 76 minComp = 0.0; 77 if (maxComp > 0.0) { 78 // max(..., 0.0000001) prevents divide by 0 79 midComp *= satVal/max(maxComp, 0.0000001); 80 maxComp = satVal; 81 } 82 } 83 */ 84 85 float3 color = cb.rgb; 86 float satVal = saturation(cs); 87 88 if (color.x <= color.y) { 89 if (color.y <= color.z) { 90 // x <= y <= z 91 // setsatcomponents(color.x, color.y, color.z, satVal); 92 // min, mid, max, val 93 94 color.y -= color.x; 95 color.z -= color.x; 96 color.x = 0.0; 97 if (color.z > 0.0) { 98 // max(..., 0.0000001) prevents divide by 0 99 color.y *= satVal/max(color.z, 0.0000001); 100 color.z = satVal; 101 } 102 103 } else { 104 if (color.x <= color.z) { 105 // x <= z <= y 106 // setsatcomponents(color.x, color.z, color.y, satVal); 107 // min, mid, max, value 108 109 color.z -= color.x; 110 color.y -= color.x; 111 color.x = 0.0; 112 if (color.y > 0.0) { 113 // max(..., 0.0000001) prevents divide by 0 114 color.z *= satVal/max(color.y, 0.0000001); 115 color.y = satVal; 116 } 117 } else { 118 // z <= x <= y 119 // setsatcomponents(color.z, color.x, color.y, satVal); 120 // min, mid, max, val 121 122 color.x -= color.z; 123 color.y -= color.z; 124 color.z = 0.0; 125 if (color.y > 0.0) { 126 // max(..., 0.0000001) prevents divide by 0 127 color.x *= satVal/max(color.y, 0.0000001); 128 color.y = satVal; 129 } 130 } 131 } 132 } else { 133 if (color.x <= color.z) { 134 // y <= x <= z 135 // setsatcomponents(color.y, color.x, color.z, satVal); 136 137 color.x -= color.y; 138 color.z -= color.y; 139 color.y = 0.0; 140 if (color.z > 0.0) { 141 // max(..., 0.0000001) prevents divide by 0 142 color.x *= satVal/max(color.z, 0.0000001); 143 color.z = satVal; 144 } 145 } else { 146 if (color.y <= color.z) { 147 // y <= z <= x 148 // setsatcomponents(color.y, color.z, color.x, satVal); 149 // min, mid, max, val 150 151 color.z -= color.y; 152 color.x -= color.y; 153 color.y = 0.0; 154 if (color.x > 0.0) { 155 // max(..., 0.0000001) prevents divide by 0 156 color.z *= satVal/max(color.x, 0.0000001); 157 color.x = satVal; 158 } 159 } else { 160 // z <= y <= x 161 // setsatcomponents(color.z, color.y, color.x, satVal); 162 // min, mid, max, val 163 164 color.y -= color.z; 165 color.x -= color.z; 166 color.z = 0.0; 167 if (color.x > 0.0) { 168 // max(..., 0.0000001) prevents divide by 0 169 color.y *= satVal/max(color.x, 0.0000001); 170 color.x = satVal; 171 } 172 } 173 } 174 } 175 // end setSaturation - result: color ---------------------- // 176 177 // adjustment 178 //color = color + lum_cb - luminance(color); 179 //dstColorOld - dstColor 180 float3 adjVec = cb.rgb - color.rgb; 181 float adjustment = luminance(adjVec); 182 float3 adjustedColor = color + adjustment; 183 184 // ClipRGB(adjustedColor) -> color_cl 185 186 /* -------------------------------------------------------- 187 * void clipcolor(inout float3 color) 188 * clips color. 189 * input and output float3 color_cl 190 * 191 * -------------------------------------------------------- */ 192 float3 color_cl = adjustedColor; 193 float lum_cl = luminance(color_cl); 194 float3 lumVec = float3(lum_cl, lum_cl, lum_cl); 195 float mini = min3v(color_cl); 196 float maxi = max3v(color_cl); 197 if (mini < 0.0) { 198 mini = lum_cl - mini; 199 // max(..., 0.0000001) prevents divide by 0 200 color_cl = lumVec + (color_cl - lumVec)*lum_cl/max(mini, 0.0000001); 201 } 202 if (maxi > 1.0) { 203 maxi = maxi - lum_cl; 204 // max(..., 0.0000001) prevents divide by 0 205 color_cl = lumVec + (color_cl - lumVec)*(1.0 - lum_cl)/max(maxi, 0.0000001); 206 } 207 // end clipcolor - result: color_cl ---------------------- // 208 209 210 // dstCP' = (1-srcA)*dstCP + (1-dstA)*srcCP + srcA*dstA*Blend(srcCP/srcA, dstCP/dstA) 211 result .rgb = ((1.0-b.a)*a.rgb) + ((1.0-a.a)*b.rgb) + b.a*a.a*color_cl.rgb; 212 } 213} 214