mirror of
https://github.com/status-im/Vulkan-Docs.git
synced 2025-01-18 10:22:20 +00:00
5abf83f95d
* Update release number to 107. Public Issues: * Fix revision date for the `<<VK_AMD_gpu_shader_half_float>>` appendix (public issue 617). * Make <<synchronization-pipeline-barriers-subpass-self-dependencies, subpass self-dependencies>> less restrictive (public issue 777). * Fix the `<<VK_EXT_full_screen_exclusive>>` dependency on `<<VK_KHR_win32_surface>>` in `vk.xml` (public pull request 849). * Remove single-page (`apispec.html`) refpage sub-targets from the Makefile `allman` target and the build instructions. The target is still present in the Makefile, but we have not been actively maintaining the single-page document and do not promise it will work. The full Specification and the individual API reference pages are what we support and publish at present (public issue 949). Internal Issues: * De-duplicate common valid usage statements shared by multiple commands or structures by using asciidoctor includes and dynamically assigning part of the valid usage ID based on which command or structure they're being applied to (internal issue 779). * Add reference pages for constructs not part of the formal API, such as platform calling convention macros, and script changes supporting them This required suppressing some check_spec_links warning classes in order to pass CI, until a more sophisticated fix can be done (internal issue 888). * Change math notation for the elink:VkPrimitiveTopology descriptions to use short forms `v` and `p` instead of `vertex` and `primitive`, increasing legibility (internal issue 1611). * Rewrite generated file includes relative to a globally specified path, fixing some issues with refpage generation (internal issue 1630). * Update contributor list for `<<VK_EXT_calibrated_timestamps>>`. * Fix use of pathlin in `scripts/generator.py` so the script will work on Windows under Python 3.5 (internal merge request 3107). * Add missing conditionals around the <<descriptorsets-accelerationstructure, Acceleration Structure>> section (internal merge request 3108). * More script synchronization with OpenXR spec repository (internal merge request 3109). * Mark the `<<VK_AMD_gpu_shader_half_float>>` and `<<VK_AMD_gpu_shader_int16>>` extensions as deprecated in `vk.xml` and the corresponding extension appendices (internal merge request 3112). New Extensions: * `<<VK_EXT_headless_surface>>`
804 lines
39 KiB
Plaintext
804 lines
39 KiB
Plaintext
|
|
[[framebuffer-blend-advanced]]
|
|
=== Advanced Blend Operations
|
|
|
|
The _advanced blend operations_ are those listed in tables
|
|
<<framebuffer-blend-advanced-fxyz-modes,f/X/Y/Z Advanced Blend Operations>>,
|
|
<<framebuffer-blend-advanced-hsl-modes,Hue-Saturation-Luminosity Advanced
|
|
Blend Operations>>, and
|
|
<<framebuffer-blend-advanced-additional-rgb,Additional RGB Blend
|
|
Operations>>.
|
|
|
|
[open,refpage='VkPipelineColorBlendAdvancedStateCreateInfoEXT',desc='Structure specifying parameters that affect advanced blend operations',type='structs']
|
|
--
|
|
|
|
If the pname:pNext chain of slink:VkPipelineColorBlendStateCreateInfo
|
|
includes a sname:VkPipelineColorBlendAdvancedStateCreateInfoEXT structure,
|
|
then that structure includes parameters that affect advanced blend
|
|
operations.
|
|
|
|
The sname:VkPipelineColorBlendAdvancedStateCreateInfoEXT structure is
|
|
defined as:
|
|
|
|
include::{generated}/api/structs/VkPipelineColorBlendAdvancedStateCreateInfoEXT.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:srcPremultiplied specifies whether the source color of the blend
|
|
operation is treated as premultiplied.
|
|
* pname:dstPremultiplied specifies whether the destination color of the
|
|
blend operation is treated as premultiplied.
|
|
* pname:blendOverlap is a elink:VkBlendOverlapEXT value specifying how the
|
|
source and destination sample's coverage is correlated.
|
|
|
|
If this structure is not present, pname:srcPremultiplied and
|
|
pname:dstPremultiplied are both considered to be ename:VK_TRUE, and
|
|
pname:blendOverlap is considered to be
|
|
ename:VK_BLEND_OVERLAP_UNCORRELATED_EXT.
|
|
|
|
.Valid Usage
|
|
****
|
|
* [[VUID-VkPipelineColorBlendAdvancedStateCreateInfoEXT-srcPremultiplied-01424]]
|
|
If the <<limits-advancedBlendNonPremultipliedSrcColor,non-premultiplied
|
|
source color>> property is not supported, pname:srcPremultiplied must:
|
|
be ename:VK_TRUE
|
|
* [[VUID-VkPipelineColorBlendAdvancedStateCreateInfoEXT-dstPremultiplied-01425]]
|
|
If the <<limits-advancedBlendNonPremultipliedDstColor,non-premultiplied
|
|
destination color>> property is not supported, pname:dstPremultiplied
|
|
must: be ename:VK_TRUE
|
|
* [[VUID-VkPipelineColorBlendAdvancedStateCreateInfoEXT-blendOverlap-01426]]
|
|
If the <<limits-advancedBlendCorrelatedOverlap,correlated overlap>>
|
|
property is not supported, pname:blendOverlap must: be
|
|
ename:VK_BLEND_OVERLAP_UNCORRELATED_EXT
|
|
****
|
|
|
|
include::{generated}/validity/structs/VkPipelineColorBlendAdvancedStateCreateInfoEXT.txt[]
|
|
--
|
|
|
|
When using one of the operations in table
|
|
<<framebuffer-blend-advanced-fxyz-modes,f/X/Y/Z Advanced Blend Operations>>
|
|
or <<framebuffer-blend-advanced-hsl-modes,Hue-Saturation-Luminosity Advanced
|
|
Blend Operations>>, blending is performed according to the following
|
|
equations:
|
|
|
|
[latexmath]
|
|
+++++++++++++++++++
|
|
\begin{aligned}
|
|
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) \\
|
|
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) \\
|
|
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) \\
|
|
A & = & X*p_0(A_s,A_d) & + & Y*p_1(A_s,A_d) & + & Z*p_2(A_s,A_d)
|
|
\end{aligned}
|
|
+++++++++++++++++++
|
|
|
|
where the function f and terms X, Y, and Z are specified in the table.
|
|
The R, G, and B components of the source color used for blending are derived
|
|
according to pname:srcPremultiplied.
|
|
If pname:srcPremultiplied is set to ename:VK_TRUE, the fragment color
|
|
components are considered to have been premultiplied by the A component
|
|
prior to blending.
|
|
The base source color [eq]#(R~s~',G~s~',B~s~')# is obtained by dividing
|
|
through by the A component:
|
|
|
|
[latexmath]
|
|
+++++++++++++++++++
|
|
\begin{aligned}
|
|
(R_s', G_s', B_s') & =
|
|
\begin{cases}
|
|
(0, 0, 0) & A_s = 0 \\
|
|
(\frac{R_s}{A_s}, \frac{G_s}{A_s}, \frac{B_s}{A_s}) & \text{otherwise}
|
|
\end{cases}
|
|
\end{aligned}
|
|
+++++++++++++++++++
|
|
|
|
If pname:srcPremultiplied is ename:VK_FALSE, the fragment color components
|
|
are used as the base color:
|
|
|
|
[latexmath]
|
|
+++++++++++++++++++
|
|
\begin{aligned}
|
|
(R_s', G_s', B_s') & = (R_s, G_s, B_s)
|
|
\end{aligned}
|
|
+++++++++++++++++++
|
|
|
|
The R, G, and B components of the destination color used for blending are
|
|
derived according to pname:dstPremultiplied.
|
|
If pname:dstPremultiplied is set to ename:VK_TRUE, the destination
|
|
components are considered to have been premultiplied by the A component
|
|
prior to blending.
|
|
The base destination color [eq]#(R~d~',G~d~',B~d~')# is obtained by dividing
|
|
through by the A component:
|
|
|
|
[latexmath]
|
|
+++++++++++++++++++
|
|
\begin{aligned}
|
|
(R_d', G_d', B_d') & =
|
|
\begin{cases}
|
|
(0, 0, 0) & A_d = 0 \\
|
|
(\frac{R_d}{A_d}, \frac{G_d}{A_d}, \frac{B_d}{A_d}) & \text{otherwise}
|
|
\end{cases}
|
|
\end{aligned}
|
|
+++++++++++++++++++
|
|
|
|
If pname:dstPremultiplied is ename:VK_FALSE, the destination color
|
|
components are used as the base color:
|
|
|
|
[latexmath]
|
|
+++++++++++++++++++
|
|
\begin{aligned}
|
|
(R_d', G_d', B_d') & = (R_d, G_d, B_d)
|
|
\end{aligned}
|
|
+++++++++++++++++++
|
|
|
|
[open,refpage='VkBlendOverlapEXT',desc='Enumerant specifying the blend overlap parameter',type='enums']
|
|
--
|
|
|
|
When blending using advanced blend operations, we expect that the R, G, and
|
|
B components of premultiplied source and destination color inputs be stored
|
|
as the product of non-premultiplied R, G, and B component values and the A
|
|
component of the color.
|
|
If any R, G, or B component of a premultiplied input color is non-zero and
|
|
the A component is zero, the color is considered ill-formed, and the
|
|
corresponding component of the blend result is undefined:.
|
|
|
|
The weighting functions [eq]#p~0~#, [eq]#p~1~#, and [eq]#p~2~# are defined
|
|
in table <<framebuffer-blend-advanced-overlap-modes,Advanced Blend Overlap
|
|
Modes>>.
|
|
In these functions, the A components of the source and destination colors
|
|
are taken to indicate the portion of the pixel covered by the fragment
|
|
(source) and the fragments previously accumulated in the pixel
|
|
(destination).
|
|
The functions [eq]#p~0~#, [eq]#p~1~#, and [eq]#p~2~# approximate the
|
|
relative portion of the pixel covered by the intersection of the source and
|
|
destination, covered only by the source, and covered only by the
|
|
destination, respectively.
|
|
|
|
Possible values of
|
|
slink:VkPipelineColorBlendAdvancedStateCreateInfoEXT::pname:blendOverlap,
|
|
specifying the blend overlap functions, are:
|
|
|
|
include::{generated}/api/enums/VkBlendOverlapEXT.txt[]
|
|
|
|
* ename:VK_BLEND_OVERLAP_UNCORRELATED_EXT specifies that there is no
|
|
correlation between the source and destination coverage.
|
|
* ename:VK_BLEND_OVERLAP_CONJOINT_EXT specifies that the source and
|
|
destination coverage are considered to have maximal overlap.
|
|
* ename:VK_BLEND_OVERLAP_DISJOINT_EXT specifies that the source and
|
|
destination coverage are considered to have minimal overlap.
|
|
|
|
[[framebuffer-blend-advanced-overlap-modes]]
|
|
.Advanced Blend Overlap Modes
|
|
[width="80%",options="header"]
|
|
|====
|
|
| Overlap Mode | Weighting Equations
|
|
| ename:VK_BLEND_OVERLAP_UNCORRELATED_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
p_0(A_s,A_d) & = A_sA_d \\
|
|
p_1(A_s,A_d) & = A_s(1-A_d) \\
|
|
p_2(A_s,A_d) & = A_d(1-A_s) \\
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OVERLAP_CONJOINT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
p_0(A_s,A_d) & = min(A_s,A_d) \\
|
|
p_1(A_s,A_d) & = max(A_s-A_d,0) \\
|
|
p_2(A_s,A_d) & = max(A_d-A_s,0) \\
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
| ename:VK_BLEND_OVERLAP_DISJOINT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
p_0(A_s,A_d) & = max(A_s+A_d-1,0) \\
|
|
p_1(A_s,A_d) & = min(A_s,1-A_d) \\
|
|
p_2(A_s,A_d) & = min(A_d,1-A_s) \\
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|====
|
|
--
|
|
|
|
[[framebuffer-blend-advanced-fxyz-modes]]
|
|
.f/X/Y/Z Advanced Blend Operations
|
|
[width="80%",options="header"]
|
|
|====
|
|
| Mode | Blend Coefficients
|
|
| ename:VK_BLEND_OP_ZERO_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (0,0,0) \\
|
|
f(C_s,C_d) & = 0
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
| ename:VK_BLEND_OP_SRC_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,0) \\
|
|
f(C_s,C_d) & = C_s
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_DST_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,0,1) \\
|
|
f(C_s,C_d) & = C_d
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_SRC_OVER_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = C_s
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_DST_OVER_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = C_d
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_SRC_IN_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,0,0) \\
|
|
f(C_s,C_d) & = C_s
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_DST_IN_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,0,0) \\
|
|
f(C_s,C_d) & = C_d
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_SRC_OUT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (0,1,0) \\
|
|
f(C_s,C_d) & = 0
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_DST_OUT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (0,0,1) \\
|
|
f(C_s,C_d) & = 0
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_SRC_ATOP_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,0,1) \\
|
|
f(C_s,C_d) & = C_s
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_DST_ATOP_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,0) \\
|
|
f(C_s,C_d) & = C_d
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_XOR_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (0,1,1) \\
|
|
f(C_s,C_d) & = 0
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_MULTIPLY_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = C_sC_d
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_SCREEN_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = C_s+C_d-C_sC_d
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
| ename:VK_BLEND_OP_OVERLAY_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
2 C_sC_d & C_d \leq 0.5 \\
|
|
1-2 (1-C_s)(1-C_d) & \text{otherwise}
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_DARKEN_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = min(C_s,C_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_LIGHTEN_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = max(C_s,C_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_COLORDODGE_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
0 & C_d \leq 0 \\
|
|
min(1,\frac{C_d}{1-C_s}) & C_d \gt 0 \text{ and } C_s \lt 1 \\
|
|
1 & C_d \gt 0 \text{ and } C_s \geq 1
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_COLORBURN_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
1 & C_d \geq 1 \\
|
|
1 - min(1,\frac{1-C_d}{C_s}) & C_d \lt 1 \text{ and } C_s \gt 0 \\
|
|
0 & C_d \lt 1 \text{ and } C_s \leq 0
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_HARDLIGHT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
2 C_sC_d & C_s \leq 0.5 \\
|
|
1-2 (1-C_s)(1-C_d) & \text{otherwise}
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_SOFTLIGHT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
C_d-(1-2 C_s)C_d(1-C_d) & C_s \leq 0.5 \\
|
|
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 \\
|
|
C_d+(2 C_s-1)(\sqrt{C_d}-C_d) & C_s \gt 0.5 \text{ and } C_d \gt 0.25
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_DIFFERENCE_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = \lvert C_d-C_s \rvert
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_EXCLUSION_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = C_s+C_d-2C_sC_d
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_INVERT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,0,1) \\
|
|
f(C_s,C_d) & = 1-C_d
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_INVERT_RGB_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,0,1) \\
|
|
f(C_s,C_d) & = C_s(1-C_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_LINEARDODGE_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
C_s+C_d & C_s+C_d \leq 1 \\
|
|
1 & \text{otherwise}
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_LINEARBURN_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
C_s+C_d-1 & C_s+C_d \gt 1 \\
|
|
0 & \text{otherwise}
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_VIVIDLIGHT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
1-min(1,\frac{1-C_d}{2C_s}) & 0 \lt C_s \lt 0.5 \\
|
|
0 & C_s \leq 0 \\
|
|
min(1,\frac{C_d}{2(1-C_s)}) & 0.5 \leq C_s \lt 1 \\
|
|
1 & C_s \geq 1
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_LINEARLIGHT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
1 & 2C_s+C_d \gt 2 \\
|
|
2C_s+C_d-1 & 1 \lt 2C_s+C_d \leq 2 \\
|
|
0 & 2C_s+C_d \leq 1
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_PINLIGHT_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
0 & 2C_s-1 \gt C_d \text{ and } C_s \lt 0.5 \\
|
|
2C_s-1 & 2C_s-1 \gt C_d \text{ and } C_s \geq 0.5 \\
|
|
2C_s & 2C_s-1 \leq C_d \text{ and } C_s \lt 0.5C_d \\
|
|
C_d & 2C_s-1 \leq C_d \text{ and } C_s \geq 0.5C_d
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_HARDMIX_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & =
|
|
\begin{cases}
|
|
0 & C_s+C_d \lt 1 \\
|
|
1 & \text{otherwise}
|
|
\end{cases}
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|====
|
|
|
|
|
|
When using one of the HSL blend operations in table
|
|
<<framebuffer-blend-advanced-hsl-modes,Hue-Saturation-Luminosity Advanced
|
|
Blend Operations>> as the blend operation, the RGB color components produced
|
|
by the function f are effectively obtained by converting both the
|
|
non-premultiplied source and destination colors to the HSL (hue, saturation,
|
|
luminosity) color space, generating a new HSL color by selecting H, S, and L
|
|
components from the source or destination according to the blend operation,
|
|
and then converting the result back to RGB.
|
|
In the equations below, a blended RGB color is produced according to the
|
|
following pseudocode:
|
|
|
|
[source,c++]
|
|
----------------------------------------
|
|
float minv3(vec3 c) {
|
|
return min(min(c.r, c.g), c.b);
|
|
}
|
|
float maxv3(vec3 c) {
|
|
return max(max(c.r, c.g), c.b);
|
|
}
|
|
float lumv3(vec3 c) {
|
|
return dot(c, vec3(0.30, 0.59, 0.11));
|
|
}
|
|
float satv3(vec3 c) {
|
|
return maxv3(c) - minv3(c);
|
|
}
|
|
|
|
// If any color components are outside [0,1], adjust the color to
|
|
// get the components in range.
|
|
vec3 ClipColor(vec3 color) {
|
|
float lum = lumv3(color);
|
|
float mincol = minv3(color);
|
|
float maxcol = maxv3(color);
|
|
if (mincol < 0.0) {
|
|
color = lum + ((color-lum)*lum) / (lum-mincol);
|
|
}
|
|
if (maxcol > 1.0) {
|
|
color = lum + ((color-lum)*lum) / (maxcol-lum);
|
|
}
|
|
return color;
|
|
}
|
|
|
|
// Take the base RGB color <cbase> and override its luminosity
|
|
// with that of the RGB color <clum>.
|
|
vec3 SetLum(vec3 cbase, vec3 clum) {
|
|
float lbase = lumv3(cbase);
|
|
float llum = lumv3(clum);
|
|
float ldiff = llum - lbase;
|
|
vec3 color = cbase + vec3(ldiff);
|
|
return ClipColor(color);
|
|
}
|
|
|
|
// Take the base RGB color <cbase> and override its saturation with
|
|
// that of the RGB color <csat>. The override the luminosity of the
|
|
// result with that of the RGB color <clum>.
|
|
vec3 SetLumSat(vec3 cbase, vec3 csat, vec3 clum)
|
|
{
|
|
float minbase = minv3(cbase);
|
|
float sbase = satv3(cbase);
|
|
float ssat = satv3(csat);
|
|
vec3 color;
|
|
if (sbase > 0) {
|
|
// Equivalent (modulo rounding errors) to setting the
|
|
// smallest (R,G,B) component to 0, the largest to <ssat>,
|
|
// and interpolating the "middle" component based on its
|
|
// original value relative to the smallest/largest.
|
|
color = (cbase - minbase) * ssat / sbase;
|
|
} else {
|
|
color = vec3(0.0);
|
|
}
|
|
return SetLum(color, clum);
|
|
}
|
|
----------------------------------------
|
|
|
|
[[framebuffer-blend-advanced-hsl-modes]]
|
|
.Hue-Saturation-Luminosity Advanced Blend Operations
|
|
[width="80%",options="header"]
|
|
|====
|
|
| Mode | Result
|
|
| ename:VK_BLEND_OP_HSL_HUE_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = SetLumSat(C_s,C_d,C_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_HSL_SATURATION_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = SetLumSat(C_d,C_s,C_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_HSL_COLOR_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = SetLum(C_s,C_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_HSL_LUMINOSITY_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(X,Y,Z) & = (1,1,1) \\
|
|
f(C_s,C_d) & = SetLum(C_d,C_s)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|====
|
|
|
|
|
|
When using one of the operations in table
|
|
<<framebuffer-blend-advanced-additional-rgb,Additional RGB Blend
|
|
Operations>> as the blend operation, the source and destination colors used
|
|
by these blending operations are interpreted according to
|
|
pname:srcPremultiplied and pname:dstPremultiplied.
|
|
The blending operations below are evaluated where the RGB source and
|
|
destination color components are both considered to have been premultiplied
|
|
by the corresponding A component.
|
|
|
|
[latexmath]
|
|
+++++++++++++++++++
|
|
\begin{aligned}
|
|
(R_s', G_s', B_s') & =
|
|
\begin{cases}
|
|
(R_s, G_s, B_s) & \text{if srcPremultiplied is VK\_TRUE} \\
|
|
(R_sA_s, G_sA_s, B_sA_s) & \text{if srcPremultiplied is VK\_FALSE}
|
|
\end{cases} \\
|
|
(R_d', G_d', B_d') & =
|
|
\begin{cases}
|
|
(R_d, G_d, B_d) & \text{if dstPremultiplied is VK\_TRUE} \\
|
|
(R_dA_d, G_dA_d, B_dA_d) & \text{if dstPremultiplied is VK\_FALSE}
|
|
\end{cases}
|
|
\end{aligned}
|
|
+++++++++++++++++++
|
|
|
|
[[framebuffer-blend-advanced-additional-rgb]]
|
|
.Additional RGB Blend Operations
|
|
[width="80%",options="header"]
|
|
|====
|
|
| Mode | Result
|
|
| ename:VK_BLEND_OP_PLUS_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) = ( & R_s'+R_d', \\
|
|
& G_s'+G_d', \\
|
|
& B_s'+B_d', \\
|
|
& A_s+A_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_PLUS_CLAMPED_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) = ( & min(1,R_s'+R_d'), \\
|
|
& min(1,G_s'+G_d'), \\
|
|
& min(1,B_s'+B_d'), \\
|
|
& min(1,A_s+A_d))
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) = ( & min(min(1,A_s+A_d),R_s'+R_d'), \\
|
|
& min(min(1,A_s+A_d),G_s'+G_d'), \\
|
|
& min(min(1,A_s+A_d),B_s'+B_d'), \\
|
|
& min(1,A_s+A_d))
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_PLUS_DARKER_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) = ( & max(0,min(1,A_s+A_d)-((A_s-R_s')+(A_d-R_d'))), \\
|
|
& max(0,min(1,A_s+A_d)-((A_s-G_s')+(A_d-G_d'))), \\
|
|
& max(0,min(1,A_s+A_d)-((A_s-B_s')+(A_d-B_d'))), \\
|
|
& min(1,A_s+A_d))
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_MINUS_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) = ( & R_d'-R_s', \\
|
|
& G_d'-G_s', \\
|
|
& B_d'-B_s', \\
|
|
& A_d-A_s)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_MINUS_CLAMPED_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) = ( & max(0,R_d'-R_s'), \\
|
|
& max(0,G_d'-G_s'), \\
|
|
& max(0,B_d'-B_s'), \\
|
|
& max(0,A_d-A_s))
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_CONTRAST_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) = ( & \frac{A_d}{2} + 2(R_d'-\frac{A_d}{2})(R_s'-\frac{A_s}{2}), \\
|
|
& \frac{A_d}{2} + 2(G_d'-\frac{A_d}{2})(G_s'-\frac{A_s}{2}), \\
|
|
& \frac{A_d}{2} + 2(B_d'-\frac{A_d}{2})(B_s'-\frac{A_s}{2}), \\
|
|
& A_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_INVERT_OVG_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) = ( & A_s(1-R_d') + (1-A_s)R_d', \\
|
|
& A_s(1-G_d') + (1-A_s)G_d', \\
|
|
& A_s(1-B_d') + (1-A_s)B_d', \\
|
|
& A_s+A_d-A_sA_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_RED_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) & = (R_s', G_d', B_d', A_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_GREEN_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) & = (R_d', G_s', B_d', A_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
| ename:VK_BLEND_OP_BLUE_EXT a|
|
|
[latexmath]
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
\begin{aligned}
|
|
(R,G,B,A) & = (R_d', G_d', B_s', A_d)
|
|
\end{aligned}
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|====
|