advanced_blend.txt
1 2 [[framebuffer-blend-advanced]] 3 === Advanced Blend Operations 4 5 The _advanced blend operations_ are those listed in tables 6 <<framebuffer-blend-advanced-fxyz-modes,f/X/Y/Z Advanced Blend Operations>>, 7 <<framebuffer-blend-advanced-hsl-modes,Hue-Saturation-Luminosity Advanced 8 Blend Operations>>, and 9 <<framebuffer-blend-advanced-additional-rgb,Additional RGB Blend 10 Operations>>. 11 12 [open,refpage='VkPipelineColorBlendAdvancedStateCreateInfoEXT',desc='Structure specifying parameters that affect advanced blend operations',type='structs'] 13 -- 14 15 If the pname:pNext chain of slink:VkPipelineColorBlendStateCreateInfo 16 includes a sname:VkPipelineColorBlendAdvancedStateCreateInfoEXT structure, 17 then that structure includes parameters that affect advanced blend 18 operations. 19 20 The sname:VkPipelineColorBlendAdvancedStateCreateInfoEXT structure is 21 defined as: 22 23 include::{generated}/api/structs/VkPipelineColorBlendAdvancedStateCreateInfoEXT.txt[] 24 25 * pname:sType is the type of this structure. 26 * pname:pNext is `NULL` or a pointer to an extension-specific structure. 27 * pname:srcPremultiplied specifies whether the source color of the blend 28 operation is treated as premultiplied. 29 * pname:dstPremultiplied specifies whether the destination color of the 30 blend operation is treated as premultiplied. 31 * pname:blendOverlap is a elink:VkBlendOverlapEXT value specifying how the 32 source and destination sample's coverage is correlated. 33 34 If this structure is not present, pname:srcPremultiplied and 35 pname:dstPremultiplied are both considered to be ename:VK_TRUE, and 36 pname:blendOverlap is considered to be 37 ename:VK_BLEND_OVERLAP_UNCORRELATED_EXT. 38 39 .Valid Usage 40 **** 41 * [[VUID-VkPipelineColorBlendAdvancedStateCreateInfoEXT-srcPremultiplied-01424]] 42 If the <<limits-advancedBlendNonPremultipliedSrcColor,non-premultiplied 43 source color>> property is not supported, pname:srcPremultiplied must: 44 be ename:VK_TRUE 45 * [[VUID-VkPipelineColorBlendAdvancedStateCreateInfoEXT-dstPremultiplied-01425]] 46 If the <<limits-advancedBlendNonPremultipliedDstColor,non-premultiplied 47 destination color>> property is not supported, pname:dstPremultiplied 48 must: be ename:VK_TRUE 49 * [[VUID-VkPipelineColorBlendAdvancedStateCreateInfoEXT-blendOverlap-01426]] 50 If the <<limits-advancedBlendCorrelatedOverlap,correlated overlap>> 51 property is not supported, pname:blendOverlap must: be 52 ename:VK_BLEND_OVERLAP_UNCORRELATED_EXT 53 **** 54 55 include::{generated}/validity/structs/VkPipelineColorBlendAdvancedStateCreateInfoEXT.txt[] 56 -- 57 58 When using one of the operations in table 59 <<framebuffer-blend-advanced-fxyz-modes,f/X/Y/Z Advanced Blend Operations>> 60 or <<framebuffer-blend-advanced-hsl-modes,Hue-Saturation-Luminosity Advanced 61 Blend Operations>>, blending is performed according to the following 62 equations: 63 64 [latexmath] 65 +++++++++++++++++++ 66 \begin{aligned} 67 R & = & f(R_s',R_d')*p_0(A_s,A_d) & + & Y*R_s'*p_1(A_s,A_d) & + & Z*R_d'*p_2(A_s,A_d) \\ 68 G & = & f(G_s',G_d')*p_0(A_s,A_d) & + & Y*G_s'*p_1(A_s,A_d) & + & Z*G_d'*p_2(A_s,A_d) \\ 69 B & = & f(B_s',B_d')*p_0(A_s,A_d) & + & Y*B_s'*p_1(A_s,A_d) & + & Z*B_d'*p_2(A_s,A_d) \\ 70 A & = & X*p_0(A_s,A_d) & + & Y*p_1(A_s,A_d) & + & Z*p_2(A_s,A_d) 71 \end{aligned} 72 +++++++++++++++++++ 73 74 where the function f and terms X, Y, and Z are specified in the table. 75 The R, G, and B components of the source color used for blending are derived 76 according to pname:srcPremultiplied. 77 If pname:srcPremultiplied is set to ename:VK_TRUE, the fragment color 78 components are considered to have been premultiplied by the A component 79 prior to blending. 80 The base source color [eq]#(R~s~',G~s~',B~s~')# is obtained by dividing 81 through by the A component: 82 83 [latexmath] 84 +++++++++++++++++++ 85 \begin{aligned} 86 (R_s', G_s', B_s') & = 87 \begin{cases} 88 (0, 0, 0) & A_s = 0 \\ 89 (\frac{R_s}{A_s}, \frac{G_s}{A_s}, \frac{B_s}{A_s}) & \text{otherwise} 90 \end{cases} 91 \end{aligned} 92 +++++++++++++++++++ 93 94 If pname:srcPremultiplied is ename:VK_FALSE, the fragment color components 95 are used as the base color: 96 97 [latexmath] 98 +++++++++++++++++++ 99 \begin{aligned} 100 (R_s', G_s', B_s') & = (R_s, G_s, B_s) 101 \end{aligned} 102 +++++++++++++++++++ 103 104 The R, G, and B components of the destination color used for blending are 105 derived according to pname:dstPremultiplied. 106 If pname:dstPremultiplied is set to ename:VK_TRUE, the destination 107 components are considered to have been premultiplied by the A component 108 prior to blending. 109 The base destination color [eq]#(R~d~',G~d~',B~d~')# is obtained by dividing 110 through by the A component: 111 112 [latexmath] 113 +++++++++++++++++++ 114 \begin{aligned} 115 (R_d', G_d', B_d') & = 116 \begin{cases} 117 (0, 0, 0) & A_d = 0 \\ 118 (\frac{R_d}{A_d}, \frac{G_d}{A_d}, \frac{B_d}{A_d}) & \text{otherwise} 119 \end{cases} 120 \end{aligned} 121 +++++++++++++++++++ 122 123 If pname:dstPremultiplied is ename:VK_FALSE, the destination color 124 components are used as the base color: 125 126 [latexmath] 127 +++++++++++++++++++ 128 \begin{aligned} 129 (R_d', G_d', B_d') & = (R_d, G_d, B_d) 130 \end{aligned} 131 +++++++++++++++++++ 132 133 [open,refpage='VkBlendOverlapEXT',desc='Enumerant specifying the blend overlap parameter',type='enums'] 134 -- 135 136 When blending using advanced blend operations, we expect that the R, G, and 137 B components of premultiplied source and destination color inputs be stored 138 as the product of non-premultiplied R, G, and B component values and the A 139 component of the color. 140 If any R, G, or B component of a premultiplied input color is non-zero and 141 the A component is zero, the color is considered ill-formed, and the 142 corresponding component of the blend result is undefined:. 143 144 The weighting functions [eq]#p~0~#, [eq]#p~1~#, and [eq]#p~2~# are defined 145 in table <<framebuffer-blend-advanced-overlap-modes,Advanced Blend Overlap 146 Modes>>. 147 In these functions, the A components of the source and destination colors 148 are taken to indicate the portion of the pixel covered by the fragment 149 (source) and the fragments previously accumulated in the pixel 150 (destination). 151 The functions [eq]#p~0~#, [eq]#p~1~#, and [eq]#p~2~# approximate the 152 relative portion of the pixel covered by the intersection of the source and 153 destination, covered only by the source, and covered only by the 154 destination, respectively. 155 156 Possible values of 157 slink:VkPipelineColorBlendAdvancedStateCreateInfoEXT::pname:blendOverlap, 158 specifying the blend overlap functions, are: 159 160 include::{generated}/api/enums/VkBlendOverlapEXT.txt[] 161 162 * ename:VK_BLEND_OVERLAP_UNCORRELATED_EXT specifies that there is no 163 correlation between the source and destination coverage. 164 * ename:VK_BLEND_OVERLAP_CONJOINT_EXT specifies that the source and 165 destination coverage are considered to have maximal overlap. 166 * ename:VK_BLEND_OVERLAP_DISJOINT_EXT specifies that the source and 167 destination coverage are considered to have minimal overlap. 168 169 [[framebuffer-blend-advanced-overlap-modes]] 170 .Advanced Blend Overlap Modes 171 [width="80%",options="header"] 172 |==== 173 | Overlap Mode | Weighting Equations 174 | ename:VK_BLEND_OVERLAP_UNCORRELATED_EXT a| 175 [latexmath] 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 177 \begin{aligned} 178 p_0(A_s,A_d) & = A_sA_d \\ 179 p_1(A_s,A_d) & = A_s(1-A_d) \\ 180 p_2(A_s,A_d) & = A_d(1-A_s) \\ 181 \end{aligned} 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 183 184 | ename:VK_BLEND_OVERLAP_CONJOINT_EXT a| 185 [latexmath] 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 187 \begin{aligned} 188 p_0(A_s,A_d) & = min(A_s,A_d) \\ 189 p_1(A_s,A_d) & = max(A_s-A_d,0) \\ 190 p_2(A_s,A_d) & = max(A_d-A_s,0) \\ 191 \end{aligned} 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 193 | ename:VK_BLEND_OVERLAP_DISJOINT_EXT a| 194 [latexmath] 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 196 \begin{aligned} 197 p_0(A_s,A_d) & = max(A_s+A_d-1,0) \\ 198 p_1(A_s,A_d) & = min(A_s,1-A_d) \\ 199 p_2(A_s,A_d) & = min(A_d,1-A_s) \\ 200 \end{aligned} 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 202 |==== 203 -- 204 205 [[framebuffer-blend-advanced-fxyz-modes]] 206 .f/X/Y/Z Advanced Blend Operations 207 [width="80%",options="header"] 208 |==== 209 | Mode | Blend Coefficients 210 | ename:VK_BLEND_OP_ZERO_EXT a| 211 [latexmath] 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 213 \begin{aligned} 214 (X,Y,Z) & = (0,0,0) \\ 215 f(C_s,C_d) & = 0 216 \end{aligned} 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 218 219 220 | ename:VK_BLEND_OP_SRC_EXT a| 221 [latexmath] 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 223 \begin{aligned} 224 (X,Y,Z) & = (1,1,0) \\ 225 f(C_s,C_d) & = C_s 226 \end{aligned} 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 228 229 | ename:VK_BLEND_OP_DST_EXT a| 230 [latexmath] 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 232 \begin{aligned} 233 (X,Y,Z) & = (1,0,1) \\ 234 f(C_s,C_d) & = C_d 235 \end{aligned} 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 237 238 | ename:VK_BLEND_OP_SRC_OVER_EXT a| 239 [latexmath] 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 241 \begin{aligned} 242 (X,Y,Z) & = (1,1,1) \\ 243 f(C_s,C_d) & = C_s 244 \end{aligned} 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 246 247 | ename:VK_BLEND_OP_DST_OVER_EXT a| 248 [latexmath] 249 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 250 \begin{aligned} 251 (X,Y,Z) & = (1,1,1) \\ 252 f(C_s,C_d) & = C_d 253 \end{aligned} 254 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 255 256 | ename:VK_BLEND_OP_SRC_IN_EXT a| 257 [latexmath] 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 259 \begin{aligned} 260 (X,Y,Z) & = (1,0,0) \\ 261 f(C_s,C_d) & = C_s 262 \end{aligned} 263 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 264 265 | ename:VK_BLEND_OP_DST_IN_EXT a| 266 [latexmath] 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 268 \begin{aligned} 269 (X,Y,Z) & = (1,0,0) \\ 270 f(C_s,C_d) & = C_d 271 \end{aligned} 272 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 273 274 | ename:VK_BLEND_OP_SRC_OUT_EXT a| 275 [latexmath] 276 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 277 \begin{aligned} 278 (X,Y,Z) & = (0,1,0) \\ 279 f(C_s,C_d) & = 0 280 \end{aligned} 281 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 282 283 | ename:VK_BLEND_OP_DST_OUT_EXT a| 284 [latexmath] 285 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 286 \begin{aligned} 287 (X,Y,Z) & = (0,0,1) \\ 288 f(C_s,C_d) & = 0 289 \end{aligned} 290 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 291 292 | ename:VK_BLEND_OP_SRC_ATOP_EXT a| 293 [latexmath] 294 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 295 \begin{aligned} 296 (X,Y,Z) & = (1,0,1) \\ 297 f(C_s,C_d) & = C_s 298 \end{aligned} 299 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 300 301 | ename:VK_BLEND_OP_DST_ATOP_EXT a| 302 [latexmath] 303 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 304 \begin{aligned} 305 (X,Y,Z) & = (1,1,0) \\ 306 f(C_s,C_d) & = C_d 307 \end{aligned} 308 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 309 310 | ename:VK_BLEND_OP_XOR_EXT a| 311 [latexmath] 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 313 \begin{aligned} 314 (X,Y,Z) & = (0,1,1) \\ 315 f(C_s,C_d) & = 0 316 \end{aligned} 317 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 318 319 | ename:VK_BLEND_OP_MULTIPLY_EXT a| 320 [latexmath] 321 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 322 \begin{aligned} 323 (X,Y,Z) & = (1,1,1) \\ 324 f(C_s,C_d) & = C_sC_d 325 \end{aligned} 326 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 327 328 | ename:VK_BLEND_OP_SCREEN_EXT a| 329 [latexmath] 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 331 \begin{aligned} 332 (X,Y,Z) & = (1,1,1) \\ 333 f(C_s,C_d) & = C_s+C_d-C_sC_d 334 \end{aligned} 335 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 336 337 338 | ename:VK_BLEND_OP_OVERLAY_EXT a| 339 [latexmath] 340 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 341 \begin{aligned} 342 (X,Y,Z) & = (1,1,1) \\ 343 f(C_s,C_d) & = 344 \begin{cases} 345 2 C_sC_d & C_d \leq 0.5 \\ 346 1-2 (1-C_s)(1-C_d) & \text{otherwise} 347 \end{cases} 348 \end{aligned} 349 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 350 351 | ename:VK_BLEND_OP_DARKEN_EXT a| 352 [latexmath] 353 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 354 \begin{aligned} 355 (X,Y,Z) & = (1,1,1) \\ 356 f(C_s,C_d) & = min(C_s,C_d) 357 \end{aligned} 358 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 359 360 | ename:VK_BLEND_OP_LIGHTEN_EXT a| 361 [latexmath] 362 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 363 \begin{aligned} 364 (X,Y,Z) & = (1,1,1) \\ 365 f(C_s,C_d) & = max(C_s,C_d) 366 \end{aligned} 367 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 368 369 | ename:VK_BLEND_OP_COLORDODGE_EXT a| 370 [latexmath] 371 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 372 \begin{aligned} 373 (X,Y,Z) & = (1,1,1) \\ 374 f(C_s,C_d) & = 375 \begin{cases} 376 0 & C_d \leq 0 \\ 377 min(1,\frac{C_d}{1-C_s}) & C_d \gt 0 \text{ and } C_s \lt 1 \\ 378 1 & C_d \gt 0 \text{ and } C_s \geq 1 379 \end{cases} 380 \end{aligned} 381 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 382 383 | ename:VK_BLEND_OP_COLORBURN_EXT a| 384 [latexmath] 385 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 386 \begin{aligned} 387 (X,Y,Z) & = (1,1,1) \\ 388 f(C_s,C_d) & = 389 \begin{cases} 390 1 & C_d \geq 1 \\ 391 1 - min(1,\frac{1-C_d}{C_s}) & C_d \lt 1 \text{ and } C_s \gt 0 \\ 392 0 & C_d \lt 1 \text{ and } C_s \leq 0 393 \end{cases} 394 \end{aligned} 395 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 396 397 | ename:VK_BLEND_OP_HARDLIGHT_EXT a| 398 [latexmath] 399 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 400 \begin{aligned} 401 (X,Y,Z) & = (1,1,1) \\ 402 f(C_s,C_d) & = 403 \begin{cases} 404 2 C_sC_d & C_s \leq 0.5 \\ 405 1-2 (1-C_s)(1-C_d) & \text{otherwise} 406 \end{cases} 407 \end{aligned} 408 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 409 410 | ename:VK_BLEND_OP_SOFTLIGHT_EXT a| 411 [latexmath] 412 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 413 \begin{aligned} 414 (X,Y,Z) & = (1,1,1) \\ 415 f(C_s,C_d) & = 416 \begin{cases} 417 C_d-(1-2 C_s)C_d(1-C_d) & C_s \leq 0.5 \\ 418 C_d+(2 C_s-1)C_d((16 C_d-12)C_d+3) & C_s \gt 0.5 \text{ and } C_d \leq 0.25 \\ 419 C_d+(2 C_s-1)(\sqrt{C_d}-C_d) & C_s \gt 0.5 \text{ and } C_d \gt 0.25 420 \end{cases} 421 \end{aligned} 422 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 423 424 | ename:VK_BLEND_OP_DIFFERENCE_EXT a| 425 [latexmath] 426 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 427 \begin{aligned} 428 (X,Y,Z) & = (1,1,1) \\ 429 f(C_s,C_d) & = \lvert C_d-C_s \rvert 430 \end{aligned} 431 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 432 433 | ename:VK_BLEND_OP_EXCLUSION_EXT a| 434 [latexmath] 435 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 436 \begin{aligned} 437 (X,Y,Z) & = (1,1,1) \\ 438 f(C_s,C_d) & = C_s+C_d-2C_sC_d 439 \end{aligned} 440 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 441 442 | ename:VK_BLEND_OP_INVERT_EXT a| 443 [latexmath] 444 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 445 \begin{aligned} 446 (X,Y,Z) & = (1,0,1) \\ 447 f(C_s,C_d) & = 1-C_d 448 \end{aligned} 449 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 450 451 | ename:VK_BLEND_OP_INVERT_RGB_EXT a| 452 [latexmath] 453 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 454 \begin{aligned} 455 (X,Y,Z) & = (1,0,1) \\ 456 f(C_s,C_d) & = C_s(1-C_d) 457 \end{aligned} 458 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 459 460 | ename:VK_BLEND_OP_LINEARDODGE_EXT a| 461 [latexmath] 462 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 463 \begin{aligned} 464 (X,Y,Z) & = (1,1,1) \\ 465 f(C_s,C_d) & = 466 \begin{cases} 467 C_s+C_d & C_s+C_d \leq 1 \\ 468 1 & \text{otherwise} 469 \end{cases} 470 \end{aligned} 471 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 472 473 | ename:VK_BLEND_OP_LINEARBURN_EXT a| 474 [latexmath] 475 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 476 \begin{aligned} 477 (X,Y,Z) & = (1,1,1) \\ 478 f(C_s,C_d) & = 479 \begin{cases} 480 C_s+C_d-1 & C_s+C_d \gt 1 \\ 481 0 & \text{otherwise} 482 \end{cases} 483 \end{aligned} 484 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 485 486 | ename:VK_BLEND_OP_VIVIDLIGHT_EXT a| 487 [latexmath] 488 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 489 \begin{aligned} 490 (X,Y,Z) & = (1,1,1) \\ 491 f(C_s,C_d) & = 492 \begin{cases} 493 1-min(1,\frac{1-C_d}{2C_s}) & 0 \lt C_s \lt 0.5 \\ 494 0 & C_s \leq 0 \\ 495 min(1,\frac{C_d}{2(1-C_s)}) & 0.5 \leq C_s \lt 1 \\ 496 1 & C_s \geq 1 497 \end{cases} 498 \end{aligned} 499 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 500 501 | ename:VK_BLEND_OP_LINEARLIGHT_EXT a| 502 [latexmath] 503 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 504 \begin{aligned} 505 (X,Y,Z) & = (1,1,1) \\ 506 f(C_s,C_d) & = 507 \begin{cases} 508 1 & 2C_s+C_d \gt 2 \\ 509 2C_s+C_d-1 & 1 \lt 2C_s+C_d \leq 2 \\ 510 0 & 2C_s+C_d \leq 1 511 \end{cases} 512 \end{aligned} 513 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 514 515 | ename:VK_BLEND_OP_PINLIGHT_EXT a| 516 [latexmath] 517 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 518 \begin{aligned} 519 (X,Y,Z) & = (1,1,1) \\ 520 f(C_s,C_d) & = 521 \begin{cases} 522 0 & 2C_s-1 \gt C_d \text{ and } C_s \lt 0.5 \\ 523 2C_s-1 & 2C_s-1 \gt C_d \text{ and } C_s \geq 0.5 \\ 524 2C_s & 2C_s-1 \leq C_d \text{ and } C_s \lt 0.5C_d \\ 525 C_d & 2C_s-1 \leq C_d \text{ and } C_s \geq 0.5C_d 526 \end{cases} 527 \end{aligned} 528 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 529 530 | ename:VK_BLEND_OP_HARDMIX_EXT a| 531 [latexmath] 532 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 533 \begin{aligned} 534 (X,Y,Z) & = (1,1,1) \\ 535 f(C_s,C_d) & = 536 \begin{cases} 537 0 & C_s+C_d \lt 1 \\ 538 1 & \text{otherwise} 539 \end{cases} 540 \end{aligned} 541 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 542 543 |==== 544 545 546 When using one of the HSL blend operations in table 547 <<framebuffer-blend-advanced-hsl-modes,Hue-Saturation-Luminosity Advanced 548 Blend Operations>> as the blend operation, the RGB color components produced 549 by the function f are effectively obtained by converting both the 550 non-premultiplied source and destination colors to the HSL (hue, saturation, 551 luminosity) color space, generating a new HSL color by selecting H, S, and L 552 components from the source or destination according to the blend operation, 553 and then converting the result back to RGB. 554 In the equations below, a blended RGB color is produced according to the 555 following pseudocode: 556 557 [source,c++] 558 ---------------------------------------- 559 float minv3(vec3 c) { 560 return min(min(c.r, c.g), c.b); 561 } 562 float maxv3(vec3 c) { 563 return max(max(c.r, c.g), c.b); 564 } 565 float lumv3(vec3 c) { 566 return dot(c, vec3(0.30, 0.59, 0.11)); 567 } 568 float satv3(vec3 c) { 569 return maxv3(c) - minv3(c); 570 } 571 572 // If any color components are outside [0,1], adjust the color to 573 // get the components in range. 574 vec3 ClipColor(vec3 color) { 575 float lum = lumv3(color); 576 float mincol = minv3(color); 577 float maxcol = maxv3(color); 578 if (mincol < 0.0) { 579 color = lum + ((color-lum)*lum) / (lum-mincol); 580 } 581 if (maxcol > 1.0) { 582 color = lum + ((color-lum)*lum) / (maxcol-lum); 583 } 584 return color; 585 } 586 587 // Take the base RGB color <cbase> and override its luminosity 588 // with that of the RGB color <clum>. 589 vec3 SetLum(vec3 cbase, vec3 clum) { 590 float lbase = lumv3(cbase); 591 float llum = lumv3(clum); 592 float ldiff = llum - lbase; 593 vec3 color = cbase + vec3(ldiff); 594 return ClipColor(color); 595 } 596 597 // Take the base RGB color <cbase> and override its saturation with 598 // that of the RGB color <csat>. The override the luminosity of the 599 // result with that of the RGB color <clum>. 600 vec3 SetLumSat(vec3 cbase, vec3 csat, vec3 clum) 601 { 602 float minbase = minv3(cbase); 603 float sbase = satv3(cbase); 604 float ssat = satv3(csat); 605 vec3 color; 606 if (sbase > 0) { 607 // Equivalent (modulo rounding errors) to setting the 608 // smallest (R,G,B) component to 0, the largest to <ssat>, 609 // and interpolating the "middle" component based on its 610 // original value relative to the smallest/largest. 611 color = (cbase - minbase) * ssat / sbase; 612 } else { 613 color = vec3(0.0); 614 } 615 return SetLum(color, clum); 616 } 617 ---------------------------------------- 618 619 [[framebuffer-blend-advanced-hsl-modes]] 620 .Hue-Saturation-Luminosity Advanced Blend Operations 621 [width="80%",options="header"] 622 |==== 623 | Mode | Result 624 | ename:VK_BLEND_OP_HSL_HUE_EXT a| 625 [latexmath] 626 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 627 \begin{aligned} 628 (X,Y,Z) & = (1,1,1) \\ 629 f(C_s,C_d) & = SetLumSat(C_s,C_d,C_d) 630 \end{aligned} 631 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 632 633 | ename:VK_BLEND_OP_HSL_SATURATION_EXT a| 634 [latexmath] 635 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 636 \begin{aligned} 637 (X,Y,Z) & = (1,1,1) \\ 638 f(C_s,C_d) & = SetLumSat(C_d,C_s,C_d) 639 \end{aligned} 640 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 641 642 | ename:VK_BLEND_OP_HSL_COLOR_EXT a| 643 [latexmath] 644 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 645 \begin{aligned} 646 (X,Y,Z) & = (1,1,1) \\ 647 f(C_s,C_d) & = SetLum(C_s,C_d) 648 \end{aligned} 649 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 650 651 | ename:VK_BLEND_OP_HSL_LUMINOSITY_EXT a| 652 [latexmath] 653 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 654 \begin{aligned} 655 (X,Y,Z) & = (1,1,1) \\ 656 f(C_s,C_d) & = SetLum(C_d,C_s) 657 \end{aligned} 658 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 659 |==== 660 661 662 When using one of the operations in table 663 <<framebuffer-blend-advanced-additional-rgb,Additional RGB Blend 664 Operations>> as the blend operation, the source and destination colors used 665 by these blending operations are interpreted according to 666 pname:srcPremultiplied and pname:dstPremultiplied. 667 The blending operations below are evaluated where the RGB source and 668 destination color components are both considered to have been premultiplied 669 by the corresponding A component. 670 671 [latexmath] 672 +++++++++++++++++++ 673 \begin{aligned} 674 (R_s', G_s', B_s') & = 675 \begin{cases} 676 (R_s, G_s, B_s) & \text{if srcPremultiplied is VK\_TRUE} \\ 677 (R_sA_s, G_sA_s, B_sA_s) & \text{if srcPremultiplied is VK\_FALSE} 678 \end{cases} \\ 679 (R_d', G_d', B_d') & = 680 \begin{cases} 681 (R_d, G_d, B_d) & \text{if dstPremultiplied is VK\_TRUE} \\ 682 (R_dA_d, G_dA_d, B_dA_d) & \text{if dstPremultiplied is VK\_FALSE} 683 \end{cases} 684 \end{aligned} 685 +++++++++++++++++++ 686 687 [[framebuffer-blend-advanced-additional-rgb]] 688 .Additional RGB Blend Operations 689 [width="80%",options="header"] 690 |==== 691 | Mode | Result 692 | ename:VK_BLEND_OP_PLUS_EXT a| 693 [latexmath] 694 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 695 \begin{aligned} 696 (R,G,B,A) = ( & R_s'+R_d', \\ 697 & G_s'+G_d', \\ 698 & B_s'+B_d', \\ 699 & A_s+A_d) 700 \end{aligned} 701 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 702 703 | ename:VK_BLEND_OP_PLUS_CLAMPED_EXT a| 704 [latexmath] 705 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 706 \begin{aligned} 707 (R,G,B,A) = ( & min(1,R_s'+R_d'), \\ 708 & min(1,G_s'+G_d'), \\ 709 & min(1,B_s'+B_d'), \\ 710 & min(1,A_s+A_d)) 711 \end{aligned} 712 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 713 714 | ename:VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT a| 715 [latexmath] 716 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 717 \begin{aligned} 718 (R,G,B,A) = ( & min(min(1,A_s+A_d),R_s'+R_d'), \\ 719 & min(min(1,A_s+A_d),G_s'+G_d'), \\ 720 & min(min(1,A_s+A_d),B_s'+B_d'), \\ 721 & min(1,A_s+A_d)) 722 \end{aligned} 723 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 724 725 | ename:VK_BLEND_OP_PLUS_DARKER_EXT a| 726 [latexmath] 727 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 728 \begin{aligned} 729 (R,G,B,A) = ( & max(0,min(1,A_s+A_d)-((A_s-R_s')+(A_d-R_d'))), \\ 730 & max(0,min(1,A_s+A_d)-((A_s-G_s')+(A_d-G_d'))), \\ 731 & max(0,min(1,A_s+A_d)-((A_s-B_s')+(A_d-B_d'))), \\ 732 & min(1,A_s+A_d)) 733 \end{aligned} 734 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 735 736 | ename:VK_BLEND_OP_MINUS_EXT a| 737 [latexmath] 738 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 739 \begin{aligned} 740 (R,G,B,A) = ( & R_d'-R_s', \\ 741 & G_d'-G_s', \\ 742 & B_d'-B_s', \\ 743 & A_d-A_s) 744 \end{aligned} 745 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 746 747 | ename:VK_BLEND_OP_MINUS_CLAMPED_EXT a| 748 [latexmath] 749 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 750 \begin{aligned} 751 (R,G,B,A) = ( & max(0,R_d'-R_s'), \\ 752 & max(0,G_d'-G_s'), \\ 753 & max(0,B_d'-B_s'), \\ 754 & max(0,A_d-A_s)) 755 \end{aligned} 756 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 757 758 | ename:VK_BLEND_OP_CONTRAST_EXT a| 759 [latexmath] 760 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 761 \begin{aligned} 762 (R,G,B,A) = ( & \frac{A_d}{2} + 2(R_d'-\frac{A_d}{2})(R_s'-\frac{A_s}{2}), \\ 763 & \frac{A_d}{2} + 2(G_d'-\frac{A_d}{2})(G_s'-\frac{A_s}{2}), \\ 764 & \frac{A_d}{2} + 2(B_d'-\frac{A_d}{2})(B_s'-\frac{A_s}{2}), \\ 765 & A_d) 766 \end{aligned} 767 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 768 769 | ename:VK_BLEND_OP_INVERT_OVG_EXT a| 770 [latexmath] 771 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 772 \begin{aligned} 773 (R,G,B,A) = ( & A_s(1-R_d') + (1-A_s)R_d', \\ 774 & A_s(1-G_d') + (1-A_s)G_d', \\ 775 & A_s(1-B_d') + (1-A_s)B_d', \\ 776 & A_s+A_d-A_sA_d) 777 \end{aligned} 778 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 779 780 | ename:VK_BLEND_OP_RED_EXT a| 781 [latexmath] 782 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 783 \begin{aligned} 784 (R,G,B,A) & = (R_s', G_d', B_d', A_d) 785 \end{aligned} 786 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 787 788 | ename:VK_BLEND_OP_GREEN_EXT a| 789 [latexmath] 790 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 791 \begin{aligned} 792 (R,G,B,A) & = (R_d', G_s', B_d', A_d) 793 \end{aligned} 794 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 795 796 | ename:VK_BLEND_OP_BLUE_EXT a| 797 [latexmath] 798 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 799 \begin{aligned} 800 (R,G,B,A) & = (R_d', G_d', B_s', A_d) 801 \end{aligned} 802 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 803 |====