图像操作
图像操作概述
Vulkan 图像操作是由那些使用 OpTypeImage
(表示 VkImageView
)或 OpTypeSampledImage
(表示(VkImageView
、VkSampler
)对)的 SPIR-V 图像指令执行的操作。读取、写入和原子操作也使用纹理坐标作为操作数,并根据图像内纹理元素(纹素)的邻域返回一个值。查询操作返回绑定的图像或查找本身的属性。OpTypeImage
的“深度”操作数被忽略。
纹素是纹理和元素这两个词的组合。早期的交互式计算机图形支持纹理上的纹理操作,这是此处描述的图像上的一小部分图像操作。离散样本仍然基本等效,因此我们保留历史术语纹素来指代它们。 |
图像操作包括以下 SPIR-V 图像指令的功能
-
OpImageSample*
和OpImageSparseSample*
读取图像的一个或多个相邻纹素,并根据采样器的状态过滤纹素值。 -
OpImageFetch
和OpImageSparseFetch
返回图像的单个纹素。不使用采样器。 -
OpImage*Gather
和OpImageSparse*Gather
读取相邻的纹素,并返回每个纹素的单个分量。 -
OpImageRead
(和OpImageSparseRead
)和OpImageWrite
分别读取和写入图像中的纹素。不使用采样器。 -
OpImageSampleFootprintNV
识别并返回有关与等效的OpImageSample*
指令将访问的图像中的纹素集的信息。 -
OpImage*Dref*
指令在纹素值上应用深度比较。 -
OpImageSparse*
指令还会返回一个稀疏驻留代码。 -
OpImageQuerySize
、OpImageQuerySizeLod
、OpImageQueryLevels
和OpImageQuerySamples
返回将被访问的图像描述符的属性。不会访问图像本身。 -
OpImageQueryLod
返回将在采样操作中使用的 LOD 参数。不执行实际操作。 -
OpImageWeightedSampleQCOM
读取纹素的 2D 邻域,并使用来自单独的权重纹理的权重值计算加权平均值。 -
opImageBlockMatchSADQCOM
和opTextureBlockMatchSSD
比较来自两个纹理的纹素的 2D 邻域。 -
OpImageBoxFilterQCOM
读取纹素的 2D 邻域,并计算纹素的加权平均值。 -
opImageBlockMatchWindowSADQCOM
和opImageBlockMatchWindowSSDQCOM
比较来自两个纹理的纹素的 2D 邻域,并在目标纹理的窗口区域中重复比较。 -
opImageBlockMatchGatherSADQCOM
和opImageBlockMatchWindowSSDQCOM
将目标纹理中的四个 2D 纹素邻域与参考纹理中的单个 2D 邻域进行比较。每个比较的 R 分量被收集并返回到输出中。
纹素坐标系
图像通过纹素坐标寻址。有三种纹素坐标系
-
归一化纹素坐标 [0.0, 1.0]
-
未归一化纹素坐标 [0.0, 宽度 / 高度 / 深度)
-
整数纹素坐标 [0, 宽度 / 高度 / 深度)
SPIR-V OpImageFetch
、OpImageSparseFetch
、OpImageRead
、OpImageSparseRead
、opImageBlockMatchSADQCOM
、opImageBlockMatchSSDQCOM
、opImageBlockMatchWindowSADQCOM
、opImageBlockMatchWindowSSDQCOM
和 OpImageWrite
指令使用整数纹素坐标。
其他图像指令可以使用归一化或非归一化纹素坐标(由指令中使用的采样器的 unnormalizedCoordinates
状态选择),但在支持的操作、图像状态和采样器状态方面存在限制。归一化坐标在逻辑上转换为非归一化坐标作为图像操作的一部分,并且某些步骤仅在归一化坐标上执行。即使其他坐标被归一化,数组层坐标也始终被视为非归一化坐标。
归一化纹素坐标被称为 (s,t,r,q,a),其中坐标具有以下含义
-
s: 图像的第一维坐标。
-
t: 图像的第二维坐标。
-
r: 图像的第三维坐标。
-
(s,t,r) 被解释为立方体图像的方向向量。
-
-
q: 第四个坐标,用于齐次(投影)坐标。
-
a: 数组层的坐标。
坐标根据图像变量的维度和指令类型从 SPIR-V 操作数中提取。对于 Proj
指令,组件按顺序为 (s, [t,] [r,] q),其中 t 和 r 根据图像的 Dim
有条件地存在。对于非 Proj
指令,坐标为 (s [,t] [,r] [,a]),其中 t 和 r 根据图像的 Dim
有条件地存在,而 a 根据图像的 Arrayed
属性有条件地存在。投影图像指令在 Arrayed
图像上不受支持。
非归一化纹素坐标被称为 (u,v,w,a),其中坐标具有以下含义
-
u: 图像的第一维坐标。
-
v: 图像的第二维坐标。
-
w: 图像的第三维坐标。
-
a: 数组层的坐标。
只有 u 和 v 坐标直接从 SPIR-V 操作数中提取,因为只有 1D 和 2D(非 Arrayed
)维度支持非归一化坐标。组件按顺序为 (u [,v]),当维度为 2D 时,v 有条件地存在。当归一化坐标转换为非归一化坐标时,会使用所有四个坐标。
整数纹素坐标被称为 (i,j,k,l,n),其中坐标具有以下含义
-
i: 图像的第一维坐标。
-
j: 图像的第二维坐标。
-
k: 图像的第三维坐标。
-
l: 数组层的坐标。
-
n: 纹素内样本的索引。
它们按顺序从 SPIR-V 操作数中提取,顺序为 (i [,j] [,k] [,l] [,n]),其中 j 和 k 根据图像的 Dim
有条件地存在,而 l 根据图像的 Arrayed
属性有条件地存在。n 有条件地存在,并从 Sample
图像操作数中获取。
如果访问的图像是通过使用 VkImageViewSlicedCreateInfoEXT 从视图创建,并通过 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
描述符访问,则 k 的值会增加 VkImageViewSlicedCreateInfoEXT::sliceOffset
,得到 k ← sliceOffset + k。图像在第三维中的可访问范围为 k < sliceOffset + sliceCount。如果 VkImageViewSlicedCreateInfoEXT::sliceCount
为 VK_REMAINING_3D_SLICES_EXT
,则范围从图像的深度范围继承,如 图像 Mip 级别大小调整 中指定的那样。
对于所有坐标类型,未使用的坐标都分配为零值。
纹素坐标系 - 对于显示的 8×4 纹素二维图像的示例。
-
归一化纹素坐标
-
s 坐标从 0.0 到 1.0。
-
t 坐标从 0.0 到 1.0。
-
-
非归一化纹素坐标
-
u 坐标在 0.0 到 8.0 范围内时位于图像内,否则在图像外。
-
v 坐标在 0.0 到 4.0 范围内时位于图像内,否则在图像外。
-
-
整数纹素坐标
-
i 坐标在 0 到 7 范围内寻址图像内的纹素,否则在图像外。
-
j 坐标在 0 到 3 范围内寻址图像内的纹素,否则在图像外。
-
-
还显示了线性滤波
-
给定非归一化坐标 (u,v),选择的四个纹素是 i0j0、i1j0、i0j1 和 i1j1。
-
分数 α 和 β。
-
给定偏移量 Δi 和 Δj,偏移量选择的四个纹素是 i0j'0、i1j'0、i0j'1 和 i1j'1。
-
对于具有降分辨率组件的格式,Δi 和 Δj 相对于最高分辨率组件的分辨率,因此相对于较低分辨率组件的非归一化坐标空间,可以除以 2。 |
纹素坐标系 - 对于显示的 8×4 纹素二维图像的示例。
-
纹素坐标如上所述。还显示了最近邻滤波
-
给定非归一化坐标 (u,v),选择的纹素是 ij。
-
给定偏移量 Δi 和 Δj,偏移量选择的纹素是 ij'。
-
对于角采样图像,纹素样本位于网格交点处,而不是纹素中心。
转换公式
RGB 到共享指数转换
RGB 颜色 (red, green, blue) 转换为共享指数颜色 (redshared, greenshared, blueshared, expshared),如下所示
首先,将分量 (red, green, blue) 钳制为 (redclamped, greenclamped, blueclamped),如下所示
-
redclamped = max(0, min(sharedexpmax, red))
-
greenclamped = max(0, min(sharedexpmax, green))
-
blueclamped = max(0, min(sharedexpmax, blue))
其中
如果支持 NaN,则按以下方式处理 |
确定最大的钳制分量 maxclamped
-
maxclamped = max(redclamped, greenclamped, blueclamped)
计算初步的共享指数 exp'
计算共享指数 expshared
最后,计算范围为 0 到 2N 的三个整数值
纹素输入操作
纹素输入指令是指从图像读取数据的 SPIR-V 图像指令。纹素输入操作是指在处理纹素输入指令时对状态、坐标和纹素值执行的一系列步骤,这些步骤对于某些或所有纹素输入指令是通用的。它们包括以下步骤,并按列出的顺序执行:
对于涉及多个纹素(用于采样或收集)的纹素输入指令,这些步骤将应用于指令中使用的每个纹素。根据图像指令的类型,其他步骤可能会在这些步骤之间有条件地执行,或涉及多个坐标或纹素值。
如果色度重建是隐式的,则纹素过滤会在色度重建期间进行,然后在发生采样器 Y′CBCR 转换之前进行。
纹素输入验证操作
纹素输入验证操作检查指令/图像/采样器状态或坐标,并在某些情况下导致纹素值被替换或变为未定义。纹素会经历一系列验证。
指令/采样器/图像视图验证
在许多情况下,SPIR-V 指令可能与采样器、图像视图或两者都存在不匹配,并且在许多其他情况下,采样器可能与图像视图不匹配。在这些情况下,返回的纹素值是未定义的。
这些情况包括:
-
采样器的
borderColor
是整数类型,并且图像视图的format
不是VkFormat 整数类型之一,也不是深度/模板格式的模板组件。 -
采样器的
borderColor
是浮点类型,并且图像视图的format
不是VkFormat 浮点类型之一,也不是深度/模板格式的深度组件。 -
采样器的
borderColor
是不透明黑色颜色之一(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK
或VK_BORDER_COLOR_INT_OPAQUE_BLACK
),并且图像视图的VkComponentSwizzle 对于任何VkComponentMapping 组件都不是恒等混洗,并且未启用 VkPhysicalDeviceBorderColorSwizzleFeaturesEXT::borderColorSwizzleFromImage
功能,并且未指定 VkSamplerBorderColorComponentMappingCreateInfoEXT。 -
VkSamplerBorderColorComponentMappingCreateInfoEXT::
components
(如果指定)具有与图像视图的组件混洗不匹配的组件混洗,并且任何一个组件混洗都不是恒等混洗的形式。 -
VkSamplerBorderColorComponentMappingCreateInfoEXT::
srgb
(如果指定)与图像视图的 sRGB 编码不匹配。 -
采样器的
borderColor
是自定义颜色(VK_BORDER_COLOR_FLOAT_CUSTOM_EXT
或VK_BORDER_COLOR_INT_CUSTOM_EXT
),并且提供的 VkSamplerCustomBorderColorCreateInfoEXT::customBorderColor
超出了图像视图的format
中可表示的值的范围。 -
采样器的
borderColor
是自定义颜色(VK_BORDER_COLOR_FLOAT_CUSTOM_EXT
或VK_BORDER_COLOR_INT_CUSTOM_EXT
),并且图像视图的VkComponentSwizzle 对于任何VkComponentMapping 组件都不是恒等混洗,并且未启用 VkPhysicalDeviceBorderColorSwizzleFeaturesEXT::borderColorSwizzleFromImage
功能,并且未指定 VkSamplerBorderColorComponentMappingCreateInfoEXT。 -
图像视图中任何子资源的 VkImageLayout 与用于写入图像描述符的 VkDescriptorImageInfo::
imageLayout
不匹配。 -
SPIR-V 图像格式与图像视图的
format
不兼容。 -
采样器的
unnormalizedCoordinates
为VK_TRUE
,并且违反了未归一化坐标的限制中的任何一项。 -
采样器创建时,
flags
包含VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT
,而图像创建时,flags
未包含VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT
。 -
采样器创建时,
flags
未包含VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT
,而图像创建时,flags
包含VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT
。 -
采样器创建时,
flags
包含VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT
,并与不是OpImageSampleImplicitLod
或OpImageSampleExplicitLod
的函数一起使用,或者与操作数Offset
或ConstOffsets
一起使用。 -
SPIR-V 指令是
OpImage*Dref*
指令之一,并且采样器的compareEnable
为VK_FALSE
。 -
SPIR-V 指令不是
OpImage*Dref*
指令之一,并且采样器的compareEnable
为VK_TRUE
。 -
SPIR-V 指令是
OpImage*Dref*
指令之一,图像视图的format
是深度/模板格式之一,并且图像视图的方面不是VK_IMAGE_ASPECT_DEPTH_BIT
。 -
SPIR-V 指令的图像变量的属性与图像视图不兼容。
-
如果图像视图的
viewType
是VK_IMAGE_VIEW_TYPE_1D_ARRAY
、VK_IMAGE_VIEW_TYPE_2D_ARRAY
或VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
之一,则指令必须具有Arrayed
= 1。否则,指令必须具有Arrayed
= 0。 -
如果图像创建时,VkImageCreateInfo::
samples
等于VK_SAMPLE_COUNT_1_BIT
,则指令必须具有MS
= 0。 -
如果图像创建时,VkImageCreateInfo::
samples
不等于VK_SAMPLE_COUNT_1_BIT
,则指令必须具有MS
= 1。 -
如果
OpTypeImage
的Sampled
Type
与 SPIR-V 类型不匹配。 -
如果任何读取或采样操作的符号性与图像格式的符号性不匹配。
-
-
如果图像创建时使用 VkImageCreateInfo::
flags
包含VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV
,则采样器寻址模式必须仅使用VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
的 VkSamplerAddressMode。 -
SPIR-V 指令是
OpImageSampleFootprintNV
,其中Dim
= 2D,并且采样器中的addressModeU
或addressModeV
不是VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
。 -
SPIR-V 指令是
OpImageSampleFootprintNV
,其中Dim
= 3D,并且采样器中的addressModeU
、addressModeV
或addressModeW
不是VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
。 -
采样器创建时指定了 VkSamplerCustomBorderColorCreateInfoEXT::
format
,它与它正在采样的图像视图的 VkFormat 不匹配。 -
采样器正在采样
VK_FORMAT_B4G4R4A4_UNORM_PACK16
、VK_FORMAT_B5G6R5_UNORM_PACK16
或VK_FORMAT_B5G5R5A1_UNORM_PACK16
格式的图像视图,但没有指定 VkSamplerCustomBorderColorCreateInfoEXT::format
。
只有 OpImageSample*
和 OpImageSparseSample*
可以与启用 采样器 Y′CBCR 转换的采样器或图像视图一起使用。
OpImageFetch
、OpImageSparseFetch
、OpImage*Gather
和 OpImageSparse*Gather
必须不与启用 采样器 Y′CBCR 转换的采样器或图像视图一起使用。
ConstOffset
和 Offset
操作数必须不与启用 采样器 Y′CBCR 转换的采样器或图像视图一起使用。
如果底层 VkImage
格式在其格式描述中具有 X 分量,则从这些位读取的值是未定义的。
如果 |
在以下情况下,某些实现将返回未定义的值:采样器使用 此行为在 Vulkan 一致性测试套件版本 1.3.8.0 之前未经过测试。受影响的实现将对此问题进行一致性测试豁免。 |
整数纹素坐标验证
整数纹素坐标会根据图像级别的大小以及图像中的层数和样本数进行验证。对于使用整数纹素坐标的 SPIR-V 指令,此操作直接在整数坐标上执行。对于使用归一化或非归一化纹素坐标的指令,此操作在转换为整数纹素坐标后产生的坐标上执行。
如果整数纹素坐标不满足所有条件
-
0 ≤ i < ws
-
0 ≤ j < hs
-
0 ≤ k < ds
-
0 ≤ l < layers
-
0 ≤ n < samples
其中
-
ws = 图像级别的宽度
-
hs = 图像级别的高度
-
ds = 图像级别的深度
-
layers = 图像中的层数
-
samples = 图像中每个纹素的样本数
则纹素未通过整数纹素坐标验证。
有四种情况需要考虑
-
有效纹素坐标
-
如果纹素坐标通过验证(即,坐标位于图像内),
则纹素值来自图像内存中的值。
-
-
边界纹素
-
如果纹素坐标未通过验证,并且
-
如果读取是图像采样指令或图像收集指令的结果,并且
-
如果图像不是立方体图像,或者如果使用使用
VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT
创建的采样器,
则纹素是边界纹素,并且执行 纹素替换。
-
-
无效纹素
-
如果纹素坐标未通过验证,并且
-
如果读取是图像获取指令、图像读取指令或原子指令的结果,
则纹素是无效纹素,并且执行 纹素替换。
-
-
立方体贴图边缘或角
否则,纹素坐标位于所选立方体贴图面的边缘或角之外,并且执行 立方体贴图边缘处理。
立方体贴图边缘处理
如果纹素坐标位于所选立方体贴图面的边缘或角之外(如上一节所述),则执行以下步骤。请注意,当在 mip 级别中使用 VK_FILTER_NEAREST
滤波时,不会发生这种情况,因为 VK_FILTER_NEAREST
被视为使用 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
。
-
立方体贴图边缘纹素
-
如果纹素仅在 i 或仅在 j 中超出所选立方体贴图面,则坐标 (i,j) 和数组层 l 会被转换,以从适当的相邻面中选择相邻纹素。
-
-
立方体贴图角纹素
-
如果纹素在 i 和 j 中都超出所选立方体贴图面,则没有唯一的相邻面可以从中读取该纹素。纹素应该被每个入射面中相邻纹素的三个值的平均值替换。但是,实现可以使用其他方法替换立方体贴图角纹素。这些方法受限于以下约束:对于线性滤波,如果三个可用的纹素具有相同的值,则生成的滤波纹素必须具有该值;对于三次滤波,如果十二个可用的样本具有相同的值,则生成的滤波纹素必须具有该值。
-
稀疏验证
如果纹素从稀疏图像的未绑定区域读取,则该纹素是稀疏未绑定纹素,并且继续进行 纹素替换。
布局验证
如果不相交的多平面图像的所有平面不在同一图像布局中,则必须不使用启用 采样器 Y′CBCR 转换来采样该图像。
格式转换
纹素会从图像视图的 VkFormat 转换为浮点或有符号或无符号整数分量的向量,其中分量的数量基于格式中存在的分量数量。
-
根据格式,颜色格式具有一个、两个、三个或四个分量。
-
深度/模板格式是一个组件。深度或模板组件由图像视图的
aspectMask
选择。
每个组件都根据其类型和大小进行转换(如 格式定义 部分针对每个 VkFormat 所定义的那样),使用 16 位浮点数、无符号 11 位浮点数、无符号 10 位浮点数、定点数据转换 和 共享指数到 RGB 中的相应公式。小于 32 位的有符号整数组件将进行符号扩展。
如果图像视图格式为 sRGB,则颜色分量首先会被视为 UNORM 进行转换,然后按照 Khronos 数据格式规范 的“sRGB EOTF”部分所述,对 R、G 和 B 分量应用 sRGB 到线性的转换。A 分量(如果存在)保持不变。
如果 VkSamplerYcbcrConversionYcbcrDegammaCreateInfoQCOM::enableYDegamma
等于 VK_TRUE
,则按照 Khronos 数据格式规范 的“sRGB EOTF”部分所述,对 G 分量应用 sRGB 到线性的转换。如果 VkSamplerYcbcrConversionYcbcrDegammaCreateInfoQCOM::enableCbCrDegamma
等于 VK_TRUE
,则按照 Khronos 数据格式规范 的“sRGB EOTF”部分所述,对 R 和 B 分量应用 sRGB 到线性的转换。A 分量(如果存在)保持不变。
如果图像视图格式为块压缩格式,则首先解码纹素值,然后根据压缩格式定义的类型和分量数量进行转换。
纹素替换
如果纹素是以下情况之一(并且仅是其中之一),则该纹素将被替换:
-
边界纹素,
-
无效纹素,或
-
稀疏未绑定纹素。
边界纹素会被替换为基于图像格式和采样器的 borderColor
的值。边界颜色为:
采样器 borderColor |
对应的边界颜色 |
---|---|
|
[Br, Bg, Bb, Ba] = [0.0, 0.0, 0.0, 0.0] |
|
[Br, Bg, Bb, Ba] = [0.0, 0.0, 0.0, 1.0] |
|
[Br, Bg, Bb, Ba] = [1.0, 1.0, 1.0, 1.0] |
|
[Br, Bg, Bb, Ba] = [0, 0, 0, 0] |
|
[Br, Bg, Bb, Ba] = [0, 0, 0, 1] |
|
[Br, Bg, Bb, Ba] = [1, 1, 1, 1] |
|
[Br, Bg, Bb, Ba] = [Ur, Ug, Ub, Ua] |
|
[Br, Bg, Bb, Ba] = [Ur, Ug, Ub, Ua] |
自定义边界颜色 (U) 可能在纹素替换之前被实现四舍五入,但这种四舍五入引入的误差 必须 不超过图像 format
的一个 ULP。
名称 |
这通过替换图像格式中的分量数量来代替纹素值
纹素方面或格式 | 分量赋值 |
---|---|
深度方面 |
D = Br |
模板方面 |
S = Br† |
一个分量颜色格式 |
Colorr = Br |
两个分量颜色格式 |
[Colorr,Colorg] = [Br,Bg] |
三个分量颜色格式 |
[Colorr,Colorg,Colorb] = [Br,Bg,Bb] |
四个分量颜色格式 |
[Colorr,Colorg,Colorb,Colora] = [Br,Bg,Bb,Ba] |
单分量 Alpha 格式 |
[Colorr,Colorg,Colorb, Colora] = [0,0,0,Ba] |
† 当 VkSamplerCreateInfo::borderColor
为 VK_BORDER_COLOR_INT_CUSTOM_EXT
并且 VkSamplerCustomBorderColorCreateInfoEXT::format
为 VK_FORMAT_UNDEFINED
时,S = Bg 可能会被实现作为替换方法。实现 应该 使用 S = Br 作为替换方法。
除非读取操作来自缓冲区资源并且启用了 robustBufferAccess
功能,否则读取无效纹素返回的值是 未定义的。在这种情况下,无效纹素将按照 robustBufferAccess
功能的描述进行替换。如果访问的是图像资源,并且 x、y、z 或图层坐标验证失败,并且启用了 robustImageAccess
功能,则如果存在,R、G 和 B 分量 必须 返回零。如果存在 A 分量,则 必须 返回零或一。如果启用了 robustImageAccess2
功能,则 必须 返回零值。如果仅样本索引无效,则返回的值是 未定义的。
此外,如果启用了 robustImageAccess
功能,但未启用 robustImageAccess2
功能,则任何无效纹素 可能 在纹素替换之前扩展到四个分量。这意味着图像格式中不存在的分量可以用 0 替换,或者可以像往常一样进行 转换为 RGBA。
从空描述符加载返回一个所有分量均为零的四分量颜色值。但是,对于使用显式 SPIR-V 图像格式的存储图像和存储纹素缓冲区,如果格式不包含 alpha,则从空描述符加载 可能 返回 alpha 值为 1(浮点或整数,取决于格式)。
如果 VkPhysicalDeviceSparseProperties::residencyNonResidentStrict
属性为 VK_TRUE
,则稀疏未绑定纹素将分别用图像格式的整数和浮点分量的 0 或 0.0 值替换。
如果 residencyNonResidentStrict
为 VK_FALSE
,则稀疏未绑定纹素的值是未定义的。
深度比较操作
如果图像视图具有深度/模板格式,则深度分量由 aspectMask
选择,并且操作是 OpImage*Dref*
指令,则会执行深度比较。如果比较结果为 true,则结果为 1.0,否则为 0.0。此值将替换深度分量 D。
比较操作由 VkCompareOp 值选择,该值由 VkSamplerCreateInfo::compareOp
设置。SPIR-V 操作数 Dref 中的参考值和纹素深度值 Dtex 在该操作中分别用作参考值和测试值。
如果采样的图像具有无符号归一化定点格式,则在比较操作之前,Dref 会被钳制到 [0,1]。
转换为 RGBA
根据图像基本颜色,纹素从一个、两个或三个分量扩展到四个分量。
纹素方面或格式 | RGBA 颜色 |
---|---|
深度方面 |
[Colorr,Colorg,Colorb, Colora] = [D,0,0,one] |
模板方面 |
[Colorr,Colorg,Colorb, Colora] = [S,0,0,one] |
一个分量颜色格式 |
[Colorr,Colorg,Colorb, Colora] = [Colorr,0,0,one] |
两个分量颜色格式 |
[Colorr,Colorg,Colorb, Colora] = [Colorr,Colorg,0,one] |
三个分量颜色格式 |
[Colorr,Colorg,Colorb, Colora] = [Colorr,Colorg,Colorb,one] |
四个分量颜色格式 |
[Colorr,Colorg,Colorb, Colora] = [Colorr,Colorg,Colorb,Colora] |
一个 alpha 分量颜色格式 |
[Colorr,Colorg,Colorb, Colora] = [0,0,0,Colora] |
其中 one = 1.0f 用于浮点格式和深度方面,one = 1 用于整数格式和模板方面。
分量混洗
所有纹素输入指令都基于以下内容应用混洗:
-
如果未启用 采样器 Y′CBCR 转换,则读取的图像的 VkImageViewCreateInfo 结构的
components
成员中的 VkComponentSwizzle 枚举,以及 -
如果启用了采样器 Y′CBCR 转换,则用于 采样器 Y′CBCR 转换的 VkSamplerYcbcrConversionCreateInfo 结构的
components
成员中的 VkComponentSwizzle 枚举。
混洗可以重新排列纹素的分量,或者为任何分量替换零或一。它对于每个颜色 component 定义如下:
其中
如果边框颜色是 VK_BORDER_COLOR_*_OPAQUE_BLACK
枚举之一,并且对于所有分量,VkComponentSwizzle 不是 恒等混洗,则混洗后的纹素的值是未定义的。
如果图像视图具有深度/模板格式,并且 VkComponentSwizzle 是 VK_COMPONENT_SWIZZLE_ONE
,并且 VkPhysicalDeviceMaintenance5Properties
::depthStencilSwizzleOneSupport
不是 VK_TRUE
,则混洗后的纹素的值是未定义的。
稀疏驻留
OpImageSparse*
指令返回一个结构,其中包括一个驻留代码,指示该指令访问的任何纹素是否是稀疏未绑定纹素。此代码可以由 OpImageSparseTexelsResident
指令解释,该指令将驻留代码转换为布尔值。
色度重建
在某些颜色模型中,颜色表示是根据单色光强度(通常称为“亮度”)和相对于此强度的颜色差异(通常称为“色度”)来定义的。对于除 RGB 之外的颜色模型,通常以比亮度分量更低的空间分辨率表示色度分量。此方法用于利用人眼对颜色的空间敏感度低于其对亮度的敏感度的特点。较不常见的是,相同的方法也用于加色,因为绿色分量在人眼对光强度的敏感度中占主导地位,并且红色和蓝色引入的颜色空间敏感度较低。
较低分辨率的分量通过将它们调整为比表示亮度的分量更低的空间分辨率进行“下采样”。此过程通常也称为“色度二次采样”。每个纹理纹素中都有一个亮度样本,但每个色度样本可能会在纹理的一个或两个维度中被多个纹素共享。
-
“
_444
”格式与亮度相比,不会对色度值进行空间下采样:每个纹素都有唯一的色度样本。 -
“
_422
”格式在 x 维度(对应于 u 或 s 坐标)中具有下采样:在该维度中,它们的采样分辨率是亮度的一半。 -
“
_420
”格式在 x 维度(对应于 u 或 s 坐标)和 y 维度(对应于 v 或 t 坐标)中具有下采样:它们在两个维度中的采样分辨率都是亮度的一半。
为纹理访问重建完整颜色值的过程涉及在同一位置访问色度和亮度值。为了准确生成颜色,必须从较低分辨率的样本位置重建亮度样本位置的较低分辨率分量的值,无论实际颜色模型如何,该操作在此处称为“色度重建”。
色度样本相对于亮度坐标的位置由用于创建采样器 Y′CBCR 转换的 VkSamplerYcbcrConversionCreateInfo 结构的 xChromaOffset
和 yChromaOffset
成员确定。
下图显示了非归一化 (u,v) 坐标和亮度分量中 (i,j) 整数纹素位置之间的关系(以黑色显示,圆圈显示整数样本位置)以及以红色交叉显示的降低分辨率色度分量的纹素坐标。
如果通过插值在亮度样本的位置重建色度值,则需要来自图像边界之外的色度样本;这些样本根据环绕操作确定。这些图通过显示“色度纹素”的边界延伸到图像边界之外,并包括插值所需的额外色度样本位置来表示这一点。 |
重建以两种方式之一实现
如果要采样的图像的格式设置了 VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT
,或者 VkSamplerYcbcrConversionCreateInfo 的 forceExplicitReconstruction
为 VK_TRUE
,则重建将作为独立于过滤的显式步骤执行,如显式重建部分所述。
如果要采样的图像的格式未设置 VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT
,并且如果 VkSamplerYcbcrConversionCreateInfo 的 forceExplicitReconstruction
为 VK_FALSE
,则重建将作为颜色模型转换之前过滤的隐式部分执行,没有单独的转换后纹素过滤步骤,如隐式重建部分所述。
显式重建
-
如果 VkSamplerYcbcrConversionCreateInfo 结构的
chromaFilter
成员为VK_FILTER_NEAREST
-
如果 VkSamplerYcbcrConversionCreateInfo 结构的
chromaFilter
成员是VK_FILTER_LINEAR
-
如果格式的 R 和 B 分量在宽度上的分辨率相对于 G 分量降低了二分之一(即,这是一个 “
_422
” 格式)-
如果
xChromaOffset
是VK_CHROMA_LOCATION_COSITED_EVEN
-
如果
xChromaOffset
是VK_CHROMA_LOCATION_MIDPOINT
-
-
如果格式的 R 和 B 分量在宽度和高度上的分辨率相对于 G 分量降低了二分之一(即,这是一个 “
_420
” 格式),则适用类似的关系。由于选项数量众多,这些公式以更简洁的方式表达如下
-
如果纹理本身按照 纹素过滤 中所述进行双线性插值,因此过滤操作需要四个全彩色样本,并且由于 |
采样器 Y′CBCR 转换
采样器 Y′CBCR 转换执行以下操作,实现 可以 将其组合为单个数学运算
采样器 Y′CBCR 范围扩展
采样器 Y′CBCR 范围扩展应用于所有非特定于采样器 Y′CBCR 转换的纹素输入操作之后的颜色分量值。例如,此阶段的输入值已使用普通的格式转换规则进行转换。
如果启用了ycbcrDegamma
特性,则此阶段的输入值可能已使用 sRGB 到线性的转换进行转换。
如果 ycbcrModel
为 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY
,则不应用采样器 Y′CBCR 范围扩展。也就是说,着色器接收组件置换阶段输出的向量 C'rgba,而无需进一步修改。
对于 ycbcrModel
的其他值,范围扩展应用于 组件置换输出的纹素分量值,该置换由 VkSamplerYcbcrConversionCreateInfo 的 components
成员定义。范围扩展独立应用于图像的每个分量。为了进行范围扩展和 Y′CBCR 模型转换,R 和 B 分量包含色差(色度)值,而 G 分量包含亮度。A 分量不会被采样器 Y′CBCR 范围扩展修改。
要应用的范围扩展由 VkSamplerYcbcrConversionCreateInfo 结构的 ycbcrRange
成员定义。
-
如果
ycbcrRange
为VK_SAMPLER_YCBCR_RANGE_ITU_FULL
,则应用以下转换这些公式对应于Khronos 数据格式规范的“量化方案”章节中的“全范围”编码。
如果未来对这些公式所依据的 ITU 规范进行任何修改,Vulkan 使用的公式 可以 也进行更新以保持一致。
-
如果
ycbcrRange
为VK_SAMPLER_YCBCR_RANGE_ITU_NARROW
,则应用以下转换这些公式对应于Khronos 数据格式规范的“量化方案”章节中的“窄范围”编码。
-
n 是格式中分量的位深度。
范围扩展期间执行的操作的精度 必须 至少与源格式的精度相同。
实现 可以 钳制这些范围扩展操作的结果,使得 Y′ 落在 [0,1] 范围内,和/或使得 CB 和 CR 落在 [-0.5,0.5] 范围内。
采样器 Y′CBCR 模型转换
范围扩展后的值根据 ycbcrModel
成员中指定的颜色模型转换在颜色模型之间进行转换。
VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY
-
颜色分量不会被颜色模型转换修改,因为它们被假设已经表示着色器正在运行的所需颜色模型;Y′CBCR 范围扩展也被忽略。
VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY
-
颜色分量不会被颜色模型转换修改,并被假定在内存和着色器中都被视为 Y′CBCR 形式;Y′CBCR 范围扩展应用于分量,如同其他 Y′CBCR 模型一样,向量 (CR,Y′,CB,A) 提供给着色器。
VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709
-
颜色分量从 Y′CBCR 表示形式转换为 R′G′B′ 表示形式,如Khronos 数据格式规范的“BT.709 Y′CBCR 转换”部分所述。
VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601
-
颜色分量从 Y′CBCR 表示形式转换为 R′G′B′ 表示形式,如Khronos 数据格式规范的“BT.601 Y′CBCR 转换”部分所述。
VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020
-
颜色分量从 Y′CBCR 表示形式转换为 R′G′B′ 表示形式,如Khronos 数据格式规范的“BT.2020 Y′CBCR 转换”部分所述。
在此操作中,每个输出分量都依赖于每个输入分量。
实现 可以 将这些转换的 R′G′B′ 结果钳制到 [0,1] 范围内。
模型转换期间执行的操作的精度 必须 至少与源格式的精度相同。
alpha 分量不会被这些模型转换修改。
在非线性颜色空间中的采样操作可能会在急剧的过渡边界处引入颜色和强度的偏移。为了避免这个问题,可以按照Khronos 数据格式规范的“颜色转换简介”章节中描述的技术上精确的颜色校正顺序进行操作:
与直接使用输出相比,在 如果 |
纹素输出操作
纹素输出指令是写入图像的 SPIR-V 图像指令。纹素输出操作是在处理纹素输出指令时,对状态、坐标和纹素值执行的一系列步骤,这些步骤对于某些或所有纹素输出指令都是通用的。它们包括以下步骤,并按所列顺序执行
纹素输出验证操作
纹素输出验证操作检查指令/图像状态或坐标,并且在某些情况下会导致写入无效。纹素会经历一系列验证。
纹素格式验证
如果 OpTypeImage
的图像格式与 VkImageView
的 format
不兼容,则写入会导致图像内存的内容变为未定义。
稀疏纹素操作
如果纹素尝试写入稀疏图像的未绑定区域,则该纹素是稀疏的未绑定纹素。在这种情况下,如果VkPhysicalDeviceSparseProperties::residencyNonResidentStrict
属性为 VK_TRUE
,则稀疏的未绑定纹素写入无效。如果 residencyNonResidentStrict
为 VK_FALSE
,则写入可能会产生副作用,该副作用对于任何资源中对未绑定纹素的其他访问是可见的,但对于应用程序分配的任何设备内存将不可见。
纹素输出格式转换
如果图像格式为 sRGB,则按照Khronos 数据格式规范的“sRGB EOTF”章节中的描述,对 R、G 和 B 分量应用线性到 sRGB 的转换。A 分量(如果存在)保持不变。
然后,纹素将从纹素数据的浮点、有符号或无符号整数类型转换为图像视图的VkFormat。如果纹素数据中的分量数量大于格式中的分量数量,则会丢弃其他分量。
每个分量都根据其类型和大小进行转换(如每个VkFormat的格式定义部分中所定义)。浮点输出的转换如浮点格式转换和定点数据转换中所述。整数输出的转换会保留其值。任何无法以目标格式表示的整数的转换后的值都是未定义的。
如果 VkImageView
格式在其格式描述中具有 X 分量,则会向这些位写入未定义的值。
如果底层 VkImage
格式在其格式描述中具有 X 分量,则也会向这些位写入未定义的值,即使结果格式转换会为这些位产生有效值,因为 VkImageView
格式是不同的。
标准化纹素坐标操作
如果图像采样器指令提供标准化纹素坐标,则会执行以下一些操作。
导数图像操作
导数用于 LOD 选择。这些导数可以是隐式的(在网格、任务、计算或片段着色器中的 ImplicitLod
图像指令中),也可以是显式的(由着色器在任何着色器中显式提供给图像指令)。
对于隐式导数图像指令,纹素坐标的导数以与导数操作相同的方式计算。即
某些图像维度未定义的上述偏导数设置为零。
对于显式 LOD 图像指令,如果提供了可选的 SPIR-V 操作数 Grad
,则操作数值将用于导数。给定图像维度的每个导数中存在的组件数量与上面计算的偏导数数量相匹配。
如果提供了可选的 SPIR-V 操作数 Lod
,则导数设置为零,跳过立方体贴图导数变换,并跳过缩放因子运算。相反,浮点标量坐标将直接赋值给 λbase,如 LOD 操作中所述。
如果隐式导数图像指令使用的图像或采样器对象在四边形中不均匀,并且不支持 quadDivergentImplicitLod
,则导数和 LOD 值是未定义的。当图像和采样器以及控制流在四边形中均匀时,即使它们在不同的四边形之间发散,隐式导数也是定义良好的。
如果支持 quadDivergentImplicitLod
,即使图像或采样器对象在四边形内不均匀,导数和隐式 LOD 值也是定义良好的。导数按照上述指定计算,并且每个着色器调用的隐式 LOD 计算都使用其各自的图像和采样器对象进行。
立方体贴图面选择和变换
对于立方体贴图图像指令,(s,t,r) 坐标被视为方向向量 (rx,ry,rz)。该方向向量用于选择立方体贴图面。方向向量被转换为每个面的纹素坐标系 (sface,tface)。方向向量还用于将导数转换为每个面的导数。
立方体贴图面选择
方向向量根据最大幅度坐标方向(主轴方向)选择立方体贴图的一个面。由于两个或多个坐标可能具有相同的幅度,因此实现必须具有规则来消除这种情况的歧义。
这些规则的第一个规则应该是 rz 胜过 ry 和 rx,第二个规则是 ry 胜过 rx。实现可以选择其他规则,但这些规则必须是确定性的,并且仅取决于 (rx,ry,rz)。
层号(对应于立方体贴图面)、sc、tc、rc 的坐标选择以及导数的选择由主轴方向确定,如下两个表所示。
主轴方向 | 层号 | 立方体贴图面 | sc | tc | rc |
---|---|---|---|---|---|
+rx |
0 |
正 X |
-rz |
-ry |
rx |
-rx |
1 |
负 X |
+rz |
-ry |
rx |
+ry |
2 |
正 Y |
+rx |
+rz |
ry |
-ry |
3 |
负 Y |
+rx |
-rz |
ry |
+rz |
4 |
正 Z |
+rx |
-ry |
rz |
-rz |
5 |
负 Z |
-rx |
-ry |
rz |
主轴方向 | ∂sc / ∂x | ∂sc / ∂y | ∂tc / ∂x | ∂tc / ∂y | ∂rc / ∂x | ∂rc / ∂y |
---|---|---|---|---|---|---|
+rx |
-∂rz / ∂x |
-∂rz / ∂y |
-∂ry / ∂x |
-∂ry / ∂y |
+∂rx / ∂x |
+∂rx / ∂y |
-rx |
+∂rz / ∂x |
+∂rz / ∂y |
-∂ry / ∂x |
-∂ry / ∂y |
-∂rx / ∂x |
-∂rx / ∂y |
+ry |
+∂rx / ∂x |
+∂rx / ∂y |
+∂rz / ∂x |
+∂rz / ∂y |
+∂ry / ∂x |
+∂ry / ∂y |
-ry |
+∂rx / ∂x |
+∂rx / ∂y |
-∂rz / ∂x |
-∂rz / ∂y |
-∂ry / ∂x |
-∂ry / ∂y |
+rz |
+∂rx / ∂x |
+∂rx / ∂y |
-∂ry / ∂x |
-∂ry / ∂y |
+∂rz / ∂x |
+∂rz / ∂y |
-rz |
-∂rx / ∂x |
-∂rx / ∂y |
-∂ry / ∂x |
-∂ry / ∂y |
-∂rz / ∂x |
-∂rz / ∂y |
缩放因子运算、LOD 运算和图像层级选择
LOD 选择可以是显式的(由图像指令显式提供)或隐式的(从根据导数计算的缩放因子确定)。LOD 必须以 mipmapPrecisionBits
的精度计算。
缩放因子运算
导数的大小按以下方式计算:
-
mux = |∂s/∂x| × wbase
-
mvx = |∂t/∂x| × hbase
-
mwx = |∂r/∂x| × dbase
-
muy = |∂s/∂y| × wbase
-
mvy = |∂t/∂y| × hbase
-
mwy = |∂r/∂y| × dbase
其中
-
∂t/∂x = ∂t/∂y = 0(对于 1D 图像)
-
∂r/∂x = ∂r/∂y = 0(对于 1D、2D 或立方体图像)
并且
-
wbase = image.w
-
hbase = image.h
-
dbase = image.d
(对于来自图像描述符的 baseMipLevel
)。
对于角采样图像,wbase、hbase 和 dbase 则为
-
wbase = image.w - 1
-
hbase = image.h - 1
-
dbase = image.d - 1
屏幕空间中的点采样在纹理空间中具有椭圆形的足迹。最小和最大缩放因子 (ρmin, ρmax) 应该是此椭圆的短轴和长轴。
根据 x 和 y 方向的导数大小计算的缩放因子 ρx 和 ρy 用于计算最小和最大缩放因子。
ρx 和 ρy 可以使用函数 fx 和 fy 近似,但须满足以下约束:
最小和最大缩放因子 (ρmin,ρmax) 由下式确定:
-
ρmax = max(ρx, ρy)
-
ρmin = min(ρx, ρy)
各向异性比率由下式确定:
-
η = min(ρmax/ρmin, maxAniso)
其中
-
sampler.maxAniso =
maxAnisotropy
(来自采样器描述符) -
limits.maxAniso =
maxSamplerAnisotropy
(来自物理设备限制) -
maxAniso = min(sampler.maxAniso, limits.maxAniso)
如果 ρmax = ρmin = 0,则所有偏导数均为零,片段在纹素空间中的足迹是一个点,并且 η 应该被视为 1。如果 ρmax ≠ 0 且 ρmin = 0,则沿一个轴的所有偏导数均为零,片段在纹素空间中的足迹是一条线段,并且 η 应该被视为 maxAniso。但是,只要足迹在纹素空间中很小,即使 ρmin 为零或接近零,实现可以使用较小的 η 值。如果 VkPhysicalDeviceFeatures::samplerAnisotropy
或 VkSamplerCreateInfo::anisotropyEnable
为 VK_FALSE
,则 maxAniso 设置为 1。
如果 η = 1,则采样是各向同性的。如果 η > 1,则采样是各向异性的。
采样率 (N) 的推导公式如下
-
N = ⌈η⌉
实现可以将 N 向上取整到最近的受支持采样率。实现可以使用 N 的值作为 η 的近似值。
图像层级选择
从中读取纹素的图像层级 d、dhi 和 dlo 由图像层级参数 dl 确定,该参数基于 LOD 参数计算,如下所示
其中
并且
baseMipLevel
和 levelCount
取自图像视图的 subresourceRange
。
minLodimageView 必须小于或等于 levelbase + q。
如果采样器的 mipmapMode
是 VK_SAMPLER_MIPMAP_MODE_NEAREST
,则选择的层级是 d = dl。
如果采样器的 mipmapMode
是 VK_SAMPLER_MIPMAP_MODE_LINEAR
,则选择两个相邻的层级
δ 是用于层级之间线性滤波的小数值,量化为mipmap 精度位数。
(s,t,r,q,a) 到 (u,v,w,a) 的变换
归一化的纹素坐标按图像层级的维度进行缩放,并选择数组层。
此变换对滤波中使用的每个层级执行一次(d,或 dhi 和 dlo)。
其中
-
widthscale = widthlevel
-
heightscale = heightlevel
-
depthscale = depthlevel
对于传统图像,以及
-
widthscale = widthlevel - 1
-
heightscale = heightlevel - 1
-
depthscale = depthlevel - 1
对于角采样图像。
其中 (Δi, Δj, Δk) 取自图像指令(如果包含 ConstOffset
或 Offset
操作数),否则它们被视为零。
然后操作继续到非归一化纹素坐标操作。
非归一化纹素坐标操作
(u,v,w,a) 到 (i,j,k,l,n) 的变换和数组层选择
非归一化纹素坐标被转换为相对于选定 mipmap 层级的整数纹素坐标。
层索引 l 的计算公式为
-
l = clamp(RNE(a), 0,
layerCount
- 1) +baseArrayLayer
其中 layerCount
是图像视图的图像子资源范围中的层数,baseArrayLayer
是子资源范围中的第一层,其中
采样索引 n 被赋值为 0。
最近邻滤波 (VK_FILTER_NEAREST
) 计算非归一化坐标所在的整数纹素坐标
其中
-
shift = 0.0
对于传统图像,以及
-
shift = 0.5
对于角采样图像。
线性滤波 (VK_FILTER_LINEAR
) 计算一组包围非归一化坐标的相邻坐标。整数纹素坐标是 i0 或 i1、j0 或 j1、k0 或 k1 的组合,以及权重 α、β 和 γ。
其中
-
shift = 0.5
对于传统图像,以及
-
shift = 0.0
对于角采样图像,其中
其中保留的小数位数由 VkPhysicalDeviceLimits
::subTexelPrecisionBits
指定。
三次滤波 (VK_FILTER_CUBIC_EXT
) 计算一组包围非归一化坐标的相邻坐标。整数纹素坐标是 i0、i1、i2 或 i3、j0、j1、j2 或 j3、k0、k1、k2 或 k3 的组合,以及权重 α、β 和 γ。
其中
其中保留的小数位数由 VkPhysicalDeviceLimits
::subTexelPrecisionBits
指定。
整数纹素坐标操作
整数纹素坐标操作可以使用可选的 SPIR-V 操作数 Lod
提供要从中读取或写入纹素的 LOD。如果提供了 Lod
,则它必须是整数。
选择的图像层级为
如果 d 不在范围 [baseMipLevel
, baseMipLevel
+ levelCount
) 内,或者 d 小于 minLodIntegerimageView,则如果启用 robustImageAccess2
功能,则获取的任何值都为零,否则为未定义,并且任何写入(如果支持)都会被丢弃。
图像采样操作
环绕操作
如果使用的采样器在创建时没有使用 VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT
,则 Cube
图像会忽略采样器中指定的环绕模式。相反,如果在 mip 层级内使用 VK_FILTER_NEAREST
,则使用 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
;如果在 mip 层级内使用 VK_FILTER_LINEAR
,则在边缘的采样按照立方体贴图边缘处理部分前面的描述执行。
第一个整数纹素坐标 i 根据采样器的 addressModeU
参数进行转换。
其中
j(对于 2D 和 Cube 图像)和 k(对于 3D 图像)分别根据采样器的 addressModeV
和 addressModeW
参数进行类似转换。
纹素收集
名称中带有 Gather
的 SPIR-V 指令会返回一个从图像视图的基层中的 4 个纹素派生的向量。VK_FILTER_LINEAR
缩小过滤器的规则用于识别选择的四个纹素。然后根据转换为 RGBA将每个纹素转换为 RGBA 值,然后进行通道重组。然后,通过从四个纹素的通道重组颜色值中获取指令中 Component
值指示的组件,来组装一个四组件向量。如果操作不使用 ConstOffsets
图像操作数,则四个纹素形成用于纹理滤波的 2 × 2 矩形
如果操作确实使用 ConstOffsets
图像操作数,则偏移允许定义自定义滤波器
其中
OpImage*Gather
不得用于启用了采样器 Y′CBCR 转换的采样图像。
如果 levelbase < minLodIntegerimageView,则如果启用 robustImageAccess2
功能,则获取的任何值都为零。否则,这些值是未定义的。
纹素滤波
首先对每个层级(d 或 dhi 和 dlo)执行纹素过滤。
如果 λ 小于或等于零,则称纹理被放大,并且通过采样器中的 magFilter
选择 mip 层级内的过滤模式。如果 λ 大于零,则称纹理被缩小,并且通过采样器中的 minFilter
选择 mip 层级内的过滤模式。
纹素线性过滤
在 mip 层级内,VK_FILTER_LINEAR
过滤将 8 个(对于 3D)、4 个(对于 2D 或立方体)或 2 个(对于 1D)纹素值与其线性权重组合在一起。线性权重从先前计算的分数得出。
多个纹素的值与其权重组合在一起,以产生过滤后的值。
VkSamplerReductionModeCreateInfo::reductionMode
可以控制多个纹素及其权重组合以生成过滤后的纹理值的过程。
当 reductionMode
被设置为(显式或隐式)VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE
时,将计算加权平均值。
但是,如果减少模式是 VK_SAMPLER_REDUCTION_MODE_MIN
或 VK_SAMPLER_REDUCTION_MODE_MAX
,则该过程将对上述多个纹素及其权重进行操作,分别计算具有非零权重的纹素集合的分量最小值或最大值。
纹素三次过滤
在 mip 层级内,VK_FILTER_CUBIC_EXT
过滤计算 64 个(对于 3D)、16 个(对于 2D)或 4 个(对于 1D)纹素值的加权平均值,以及由 VkSamplerCubicWeightsCreateInfoQCOM 指定的 Catmull-Rom、零切线基数、B 样条或 Mitchell-Netravali 权重。
由 VK_CUBIC_FILTER_WEIGHTS_CATMULL_ROM_QCOM
指定的 Catmull-Rom 权重从先前计算的分数得出。
由 VK_CUBIC_FILTER_WEIGHTS_ZERO_TANGENT_CARDINAL_QCOM
指定的零切线基数权重从先前计算的分数得出。
由 VK_CUBIC_FILTER_WEIGHTS_B_SPLINE_QCOM
指定的 B 样条权重从先前计算的分数得出。
由 VK_CUBIC_FILTER_WEIGHTS_MITCHELL_NETRAVALI_QCOM
指定的 Mitchell-Netravali 权重从先前计算的分数得出。
多个纹素的值与其权重组合在一起,以产生过滤后的值。
VkSamplerReductionModeCreateInfo::reductionMode
可以控制多个纹素及其权重组合以生成过滤后的纹理值的过程。
当 reductionMode
被设置为(显式或隐式)VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE
或 VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_RANGECLAMP_QCOM
时,将计算加权平均值。
但是,如果减少模式是 VK_SAMPLER_REDUCTION_MODE_MIN
或 VK_SAMPLER_REDUCTION_MODE_MAX
,则该过程将对上述多个纹素及其权重进行操作,分别计算具有非零权重的纹素集合的分量最小值或最大值。
纹素范围钳制
当 reductionMode
是 VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_RANGECLAMP_QCOM
时,加权平均值被钳制在具有非零权重的纹素集合的分量最小值和最大值之间。
纹素 Mipmap 过滤
VK_SAMPLER_MIPMAP_MODE_NEAREST
过滤返回单个 mipmap 层级的值,
τ = τ[d].
VK_SAMPLER_MIPMAP_MODE_LINEAR
过滤将多个 mipmap 层级(τ[hi] 和 τ[lo])的值与其线性权重组合在一起。
线性权重从先前计算的分数得出。
多个 mipmap 层级的值与其权重组合在一起,以生成最终过滤后的值。
VkSamplerReductionModeCreateInfo::reductionMode
可以控制多个纹素及其权重组合以生成过滤后的纹理值的过程。
当 reductionMode
被设置为(显式或隐式)VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE
时,将计算加权平均值。
但是,如果减少模式是 VK_SAMPLER_REDUCTION_MODE_MIN
或 VK_SAMPLER_REDUCTION_MODE_MAX
,则该过程将对上述值及其权重进行操作,分别计算具有非零权重的分量最小值或最大值。
纹素各向异性过滤
采样器中的 anisotropyEnable
启用各向异性过滤。启用后,图像过滤方案会考虑一定程度的各向异性。
各向异性纹理过滤的特定方案取决于具体实现。实现应考虑采样器的 magFilter
、minFilter
和 mipmapMode
来控制所使用的各向异性过滤方案的细节。此外,实现应考虑采样器的 minLod
和 maxLod
。
由于历史原因,各向异性过滤的供应商实现以不同的方式解释这些采样器参数,尤其是在 以下描述了一种为 2D 图像实现各向异性过滤的特定方法;实现可以选择其他方法。 给定 不是单个各向同性样本,而是在图像级别 d 的图像覆盖区内采样 N 个各向同性样本,以近似各向异性过滤器。总和 τ2Daniso 是使用级别 d 的单个各向同性 τ2D(u,v) 定义的。 当 VkSamplerReductionModeCreateInfo:: |
纹素覆盖区评估
SPIR-V 指令 OpImageSampleFootprintNV
评估在 纹素过滤 操作期间将从单个 mip 层级访问的纹素集合。除了等效的 OpImageSample*
指令会接受的输入外,OpImageSampleFootprintNV
还接受两个附加输入。Granularity
输入是一个整数,用于标识用于评估覆盖区的纹素组的大小。返回的覆盖区掩码中的每个位都对应于一个对齐的纹素块,其大小由下表给出。
粒度 |
Dim = 2D |
Dim = 3D |
---|---|---|
0 |
不支持 |
不支持 |
1 |
2x2 |
2x2x2 |
2 |
4x2 |
不支持 |
3 |
4x4 |
4x4x2 |
4 |
8x4 |
不支持 |
5 |
8x8 |
不支持 |
6 |
16x8 |
不支持 |
7 |
16x16 |
不支持 |
8 |
不支持 |
不支持 |
9 |
不支持 |
不支持 |
10 |
不支持 |
16x16x16 |
11 |
64x64 |
32x16x16 |
12 |
128x64 |
32x32x16 |
13 |
128x128 |
32x32x32 |
14 |
256x128 |
64x32x32 |
15 |
256x256 |
不支持 |
Coarse
输入用于在使用 mipmapMode
为 VK_SAMPLER_MIPMAP_MODE_LINEAR
时,在纹素过滤期间可能访问的两个 mip 级别之间进行选择。当在两个 mip 级别之间进行过滤时,Coarse
值为 true
表示请求较低分辨率 mip 级别(较高级别编号)中的足迹,而 false
表示请求较高分辨率 mip 级别中的足迹。如果纹素过滤仅访问单个 mip 级别,则当 Coarse
为 false
时,将返回该级别中的足迹;当 Coarse
为 true
时,将返回空足迹。
OpImageSampleFootprintNV
的足迹在一个包含六个成员的结构中返回。
-
第一个成员是一个布尔值,如果纹素过滤操作仅访问单个 mip 级别,则该值为 true。
-
第二个成员是一个两分量或三分量整数向量,其中包含足迹锚点位置。对于二维图像,返回的分量以 8 个纹素组为单位。对于三维图像,返回的分量以 4 个纹素组为单位。
-
第三个成员是一个两分量或三分量整数向量,其中包含相对于锚点的足迹偏移量。所有返回的分量均以纹素组为单位。
-
第四个成员是一个两分量整数向量掩码,其中包含一个位域,用于标识相对于锚点和偏移量的 8x8 或 4x4x4 邻域中的纹素组集。
-
第五个成员是一个整数,用于标识包含由锚点、偏移量和掩码标识的足迹的 mip 级别。
-
第六个成员是一个整数,用于标识返回的足迹的粒度。
对于二维图像 (Dim2D
) 中的足迹,OpImageSampleFootprintNV
返回的掩码指示在纹素过滤期间,8x8 局部纹素组邻域中的每个纹素组是否会访问一个或多个纹素。在掩码中,如果且仅当以下条件成立时,具有局部组坐标
其中
-
和 ;以及 -
是返回的双组分掩码。
如果纹理过滤操作会访问一个或多个
并且
-
和 ; -
是一个双分量向量,保存了由粒度标识的纹素组的宽度和高度; -
是返回的双分量锚点向量;以及 -
是返回的双分量偏移向量。
对于三维图像(Dim3D
)中的足迹,OpImageSampleFootprintNV
返回的掩码指示在纹理过滤期间,是否会访问 4x4x4 局部纹理组邻域中的每个纹理组的一个或多个纹素。在掩码中,局部组坐标为
其中
-
, , 以及 \(0 \leq lgz < 4\); 并且 -
是返回的双组分掩码。
The local group with coordinates
并且
-
, , ; -
是一个三组件向量,它保存了由粒度标识的纹素组的宽度、高度和深度; -
是返回的三组件锚点向量;并且 -
是返回的三分量偏移向量。
如果 OpImageSampleFootprintNV
使用的采样器通过 anisotropyEnable
启用了各向异性纹素过滤,则在 mip 级别中访问的纹素组集合可能太大,无法使用指令中请求的粒度以 8x8 或 4x4x4 掩码表示。在这种情况下,实现会使用大于请求粒度的纹素组。当使用较大的纹素组大小时,OpImageSampleFootprintNV
会返回一个整数粒度值,该值可以以与提供给指令的粒度值相同的方式解释,以确定所使用的纹素组大小。如果在采样器中禁用各向异性纹素过滤,或者如果各向异性足迹可以表示为具有请求粒度的 8x8 或 4x4x4 掩码,则 OpImageSampleFootprintNV
将按原样使用请求的粒度,并返回零的粒度值。
OpImageSampleFootprintNV
仅支持二维和三维图像访问(Dim2D
和 Dim3D
),并且如果采样器使用除 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
之外的寻址模式,则返回的足迹是未定义的。
权重图像采样
SPIR-V 指令 OpImageWeightedSampleQCOM
指定一个涉及两个图像的纹理采样操作:采样图像和权重图像。它类似于双线性过滤,但可能参与过滤的纹素多于 2x2 个,并且过滤权重是应用程序指定的,而不是由固定功能硬件计算的。权重图像视图定义了采样期间使用的 2D 内核权重。
OpImageWeightedSampleQCOM
支持归一化或非归一化的纹素坐标。除了等效 OpImageSample*
指令将接受的输入之外,OpImageWeightedSampleQCOM
还接受一个 weight
输入,该输入指定采样权重图像的视图。
输入 weight
必须是具有 miplevels
等于 1
、samples
等于 VK_SAMPLE_COUNT_1_BIT
、使用恒等换算创建且使用包括 VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM
的 usage
创建的 2D 或 1D 图像的视图。VkImageViewSampleWeightCreateInfoQCOM 指定了视图的其他参数:filterCenter
、filterSize
和 numPhases
,详见下文。
weight
输入必须使用采样权重图像描述符类型绑定。weight
视图定义一个过滤内核,该内核是视图子资源范围的区域。内核跨越从整数纹素坐标 (0,0) 到 (filterSize.x
-1, filterSize.y
-1) 的区域。视图的子资源具有大于内核的尺寸是有效的,但是具有大于 (filterSize.width
-1, filterSize.height
-1) 的整数坐标的纹素将被权重采样忽略。查询 OpImageQuerySize
、OpImageQuerySizeLod
、OpImageQueryLevels
和 OpImageQuerySamples
为权重图像返回的值是未定义的。
filterCenter
将过滤内核中的整数纹素坐标指定为内核的“中心”。该中心必须在 (0,0) 到 (filterSize.x
-1, filterSize.y
-1) 的范围内。numPhases
描述用于提供亚像素过滤的过滤阶段数。两者将在下面更详细地描述。
权重图像布局
权重图像指定过滤内核权重值。2D 图像视图可用于指定 2D 过滤权重矩阵。对于可分离的过滤器,可以使用 1D 图像视图来指定水平和垂直权重。
2D 不可分离的权重过滤器
使用 VkImageViewSampleWeightCreateInfoQCOM 定义的 2D 图像视图描述了一个权重元素的 2D 矩阵 (filterSize.width
× filterSize.height
),其滤波器中心点位于 filterCenter
。请注意,filterSize
可以小于视图的子资源,但滤波器将始终位于整数纹素坐标 (0,0) 开始的位置。
下图展示了一个 2D 卷积滤波器,其 filterSize
为 (4,3),filterCenter
位于 (1, 1)。
对于 2D 权重滤波器,相位存储为 2D 数组图像的层。视图的子资源范围的宽度和高度必须小于或等于 VkPhysicalDeviceImageProcessingPropertiesQCOM::maxWeightFilterDimension
。这些层以水平相位主序存储。用公式表示,每个滤波器相位的层索引计算如下:
layerIndex(horizPhase,vertPhase,horizPhaseCount) = (vertPhase * horizPhaseCount) + horizPhase
1D 可分离权重滤波器
可分离权重滤波器是一种 2D 滤波器,它可以通过 x 和 y 方向上的两个 1D 滤波器指定,它们的乘积得到 2D 滤波器。以下示例展示了一个 2D 滤波器及其相关的可分离 1D 水平和垂直滤波器。
使用 VkImageViewSampleWeightCreateInfoQCOM 定义且 layerCount
等于 “2” 的 1D 数组图像视图描述了一个可分离的权重滤波器。水平权重在切片 “0” 中指定,垂直权重在切片 “1” 中指定。filterSize
和 filterCenter
指定水平和垂直滤波器的大小和原点。对于许多用例,1D 可分离滤波器可以提供比 2D 滤波器更好的性能。
对于 1D 可分离权重滤波器,相位被排列成具有两层的 1D 数组图像。水平权重存储在第 0 层,垂直权重存储在第 1 层。在 1D 数组图像的每一层中,权重被排列成 4 个一组,然后按相位排列。用公式表示,每一层中每个权重的 1D 纹素偏移量计算如下:
// Let horizontal weights have a weightIndex of [0, filterSize.width - 1]
// Let vertical weights have a weightIndex of [0, filterSize.height - 1]
// Let phaseCount be the number of phases in either the vertical or horizontal direction.
texelOffset(phaseIndex,weightIndex,phaseCount) = (phaseCount * 4 * (weightIndex / 4)) + (phaseIndex * 4) + (weightIndex % 4)
权重采样相位
当使用权重图像采样时,纹理坐标可能与采样图像中的纹素中心不对齐。在这种情况下,可以根据子像素位置调整滤波器权重。这被称为“子像素滤波”,表示滤波器的原点位于纹素中心以外的子像素位置。从概念上讲,这意味着权重滤波器的位置使得滤波器抽头与采样的纹素不能完全对齐。在这种情况下,可能需要修改后的滤波器权重来调整偏离中心的滤波器抽头。与双线性滤波不同,在双线性滤波中,子像素权重由实现计算,子像素权重图像采样要求每个相位的滤波器权重由应用程序预先计算并存储在一个数组中,其中数组的每个切片都是一个“滤波器相位”。该数组由实现根据子像素定位进行索引。应用程序提供的是一个内核数组,而不是单个 2D 滤波器权重内核,每个相位对应一组滤波器权重。
相位的数量受到以下要求的限制,这些要求适用于可分离和不可分离的滤波器
-
垂直方向的相位数,phaseCountvert,必须是 2 的幂(即 1、2、4 等)。
-
水平方向的相位数 phaseCounthoriz,必须等于 phaseCountvert。
-
相位的总数 phaseCountvert × phaseCounthoriz,必须小于或等于 VkPhysicalDeviceImageProcessingPropertiesQCOM::
maxWeightFilterPhases
。
权重采样器参数
权重采样要求 VkSamplerCreateInfo
的 addressModeU
和 addressModeV
必须为 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
或 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER
。如果使用 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER
,则边框颜色必须为 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK
。
权重采样操作
The 2D unnormalized texel coordinates
其中 filterCenter
指定。
Two sets of neighboring integer 2D texel coordinates are generated. The first set is used for selecting texels from the sampled image
where filterSize
.
相位索引
where the number of fraction bits retained is numPhases
Each pair of texel coordinates
If
其中
多个纹素的值与其权重组合在一起,以产生过滤后的值。
当 VkSamplerReductionModeCreateInfo::reductionMode
为 VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE
时,使用上述求和公式。但是,如果缩减模式为 VK_SAMPLER_REDUCTION_MODE_MIN
或 VK_SAMPLER_REDUCTION_MODE_MAX
,则对上述值进行操作,计算具有非零权重的纹素的逐分量最小值或最大值。如果缩减模式为 VK_SAMPLER_REDUCTION_MODE_MIN
或 VK_SAMPLER_REDUCTION_MODE_MAX
,则每个
块匹配
SPIR-V 指令 opImageBlockMatchSAD
和 opImageBlockMatchSSD
指定纹理块匹配操作,其中目标图像内的纹素块或区域与参考图像中大小相同的区域进行比较。这些指令使用两个图像视图:目标视图和参考视图。目标视图和参考视图可以是同一个视图,允许在单个图像内进行两个块的块匹配。
类似于等效的 OpImageFetch
指令,opImageBlockMatchSAD
和 opImageBlockMatchSAD
指定一个 image
和一个整数纹素 coordinate
,用于描述目标块的左下纹素。还有三个额外的输入。reference
和 refCoodinate
指定参考块的左下纹素。blockSize
指定要比较的目标块和参考块的整数宽度和高度,并且必须不大于 VkPhysicalDeviceImageProcessingPropertiesQCOM.maxBlockMatchRegion
。
opImageBlockMatchWindowSAD
和 opImageBlockMatchWindowSAD
采用与相应的非窗口指令相同的输入参数。对于采样器中指定尺寸的二维窗口内的所有像素值执行块匹配比较。
块匹配采样器参数
对于 opImageBlockMatchSAD
和 opImageBlockMatchSSD
,输入 sampler
必须使用 addressModeU
和 addressModeV
创建,这两个值等于 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
,或等于带有 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK
的 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER
。输入 sampler
必须使用等于 VK_TRUE
的 unnormalizedCoordinates
创建。输入 sampler
必须使用等于 VK_COMPONENT_SWIZZLE_IDENTITY
的 components
创建。
对于 opImageBlockMatchWindowSAD
和 opImageBlockMatchWindowSSD
指令,target
采样器必须已在 pNext
链中使用 VkSamplerBlockMatchWindowCreateInfoQCOM 创建。
对于 opImageBlockMatchWindowSAD
、opImageBlockMatchWindowSSD
、opImageBlockMatchGatherSAD
或 opImageBlockMatchGatherSSDinstructions
,输入 sampler
必须使用 addressModeU
和 addressModeV
创建,这两个值等于带有 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK
的 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER
。
忽略其他采样器状态。
块匹配操作
块匹配 SPIR-V 指令 opImageBlockMatchSAD
和 opImageBlockMatchSSD
指定了两组 2D 整数纹素坐标:目标坐标
这些坐标定义了目标块
For the target block, a set of neighboring integer texel coordinates are generated. The neighboring coordinates are combinations of
where blockSize
operand.
类似地,对于参考块,也会生成一组相邻的整数纹素坐标。
参考纹素坐标集
Each pair of texel coordinates
目标纹素值和参考纹素值之间的差异被求和以计算差异度量。opTextureBlockMatchSAD
计算绝对差异之和。
opImageBlockMatchSSD
计算平方差之和。
When VkSamplerReductionModeCreateInfo::reductionMode
is VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE
, the above summation is used. However, if the reduction mode is VK_SAMPLER_REDUCTION_MODE_MIN
or VK_SAMPLER_REDUCTION_MODE_MAX
, the process operates on the above values, computing a component-wise minimum or maximum of
块匹配窗口操作
窗口块匹配 SPIR-V 指令 opImageBlockMatchWindowSAD
和 opImageBlockMatchWindowSSD
指定了两组 2D 整数纹素坐标:目标坐标
The target coordinates are combinations of coordinates from windowExtent
. At each target coordinate, a block matching operation is performed, resulting in a difference metric. The reference coordinate
结果的最小或最大误差在输出的 R 分量中返回。整数窗口坐标 windowCompareMode
选择。
以下伪代码描述了 opImageBlockMatchWindowSAD
的操作。 opImageBlockMatchWindowSSD
的伪代码遵循相同的模式。
vec4 opImageBlockMatchGatherSAD( sampler2D target,
uvec2 targetCoord,
samler2D reference,
uvec2 refCoord,
uvec2 blocksize) {
// Two parameters are sourced from the VkSampler associated with
// `target`:
// compareMode (which can be either `MIN` or `MAX`)
// uvec2 window (which defines the search window)
minSAD = INF;
maxSAD = -INF;
uvec2 minCoord;
uvec2 maxCoord;
for (uint x=0, x<window.width; x++) {
for (uint y=0; y<window.height; y++) {
float SAD = textureBlockMatchSAD(target,
targetCoord + uvec2(x, y),
reference,
refCoord,
blocksize).x;
if (SAD < minSAD) {
minSAD = SAD;
minCoord = uvec2(x,y);
}
if (SAD > maxSAD) {
maxSAD = SAD;
maxCoord = uvec2(x,y);
}
}
}
if (compareMode==MIN) {
return vec4(minSAD, minCoord.x, minCoord.y, 0.0);
} else {
return vec4(maxSAD, maxCoord.x, maxCoord.y, 0.0);
}
}
块匹配收集操作
块匹配 Gather SPIR-V 指令 opImageBlockMatchGatherSAD
和 opImageBlockMatchGatherSSD
指定两组二维整数纹素坐标:目标坐标
These instructions perform the block matching operation 4 times, using integer target coordinates
vec4 opImageBlockMatchGatherSAD(sampler2D target,
uvec2 targetCoord,
samler2D reference,
uvec2 refCoord,
uvec2 blocksize) {
vec4 out;
for (uint x=0, x<4; x++) {
float SAD = textureBlockMatchSAD(target,
targetCoord + uvec2(x, 0),
reference,
refCoord,
blocksize).x;
if (x == 0) {
out.x = SAD;
}
if (x == 1) {
out.y = SAD;
}
if (x == 2) {
out.z = SAD;
}
if (x == 3) {
out.w = SAD;
}
}
return out;
}
盒式滤波器采样
SPIR-V 指令 OpImageBoxFilterQCOM
指定纹理盒式滤波操作,其中计算纹素区域的加权平均值,权重与每个纹素的覆盖率成正比。
除了等效的 OpImageSample*
指令会接受的输入外,OpImageBoxFilterQCOM
还接受一个额外的输入 boxSize
,它指定要平均的区域的宽度和高度(以纹素为单位)。
下图显示了使用 OpImageBoxFilterQCOM
从 8 × 4 纹素二维图像进行采样的示例,其中未标准化的纹理坐标为 (4.125, 2.625),boxSize
为 (2.75, 2.25)。该滤波器将读取 12 个纹素值,并计算基于盒子覆盖的每个纹素部分的权重。
如果 boxSize
的高度和宽度都等于 1.0,则此指令将表现为传统的双线性滤波。 boxSize
参数必须大于或等于 1.0,并且必须不大于 VkPhysicalDeviceImageProcessingPropertiesQCOM.maxBoxFilterBlockSize
。
盒式滤波器采样器参数
输入 sampler
必须使用 addressModeU
和 addressModeV
创建,它们等于 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
,或者 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER
并使用 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK
。
盒式滤波器操作
2D未归一化的纹素坐标
where boxSize
operand.
The filter dimensions
其中 VkPhysicalDeviceLimits
::subTexelPrecisionBits
指定。
A set of neighboring integer texel coordinates are generated. The neighboring coordinates are combinations of
Horizontal weights
多个纹素的值,连同它们的水平和垂直权重,组合起来产生一个盒式滤波值。
当 VkSamplerReductionModeCreateInfo::reductionMode
为 VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE
时,使用上述求和。但是,如果缩减模式是 VK_SAMPLER_REDUCTION_MODE_MIN
或 VK_SAMPLER_REDUCTION_MODE_MAX
,则该过程对上述值进行操作,计算纹素的逐分量最小值或最大值。
图像操作步骤
本章中描述的每个步骤都由图像指令的子集执行
-
纹素输入验证操作、格式转换、纹素替换、转换为 RGBA 和分量混合:由除
OpImageWrite
之外的所有指令执行。 -
深度比较:由
OpImage*Dref
指令执行。 -
所有纹素输出操作:由
OpImageWrite
执行。 -
投影:由所有
OpImage*Proj
指令执行。 -
导数图像操作、立方体贴图操作、缩放因子操作、LOD 操作和图像级别选择以及纹素各向异性滤波:由所有
OpImageSample*
和OpImageSparseSample*
指令执行。 -
(s,t,r,q,a) 到 (u,v,w,a) 转换、环绕和 (u,v,w,a) 到 (i,j,k,l,n) 转换和数组层选择:由所有
OpImageSample
、OpImageSparseSample
和OpImage*Gather
指令执行。 -
纹素收集:由
OpImage*Gather
指令执行。 -
纹素足迹评估:由
OpImageSampleFootprint
指令执行。 -
纹素滤波:由所有
OpImageSample*
和OpImageSparseSample*
指令执行。 -
稀疏驻留:由所有
OpImageSparse*
指令执行。 -
(s,t,r,q,a) 到 (u,v,w,a) 转换、环绕和权重图像采样:由
OpImageWeightedSample*
指令执行。 -
(s,t,r,q,a) 到 (u,v,w,a) 转换、环绕和块匹配:由
opImageBlockMatch*
指令执行。 -
(s,t,r,q,a) 到 (u,v,w,a) 转换、环绕和盒式滤波器采样:由
OpImageBoxFilter*
指令执行。
图像查询指令
图像属性查询
OpImageQuerySize
、OpImageQuerySizeLod
、OpImageQueryLevels
和 OpImageQuerySamples
查询着色器图像操作将访问的图像描述符的属性。如果绑定的描述符为空描述符,则它们返回 0。
OpImageQuerySizeLod
返回由 Level
of
Detail
操作数标识的图像级别的大小。如果该级别在图像中不存在,并且描述符不为空,则返回的值是未定义的。
LOD 查询
OpImageQueryLod
返回在给定图像和坐标的图像操作中将使用的 LOD 参数。如果要访问的描述符是空描述符,则返回 (0,0)。否则,将执行本章中描述的步骤,就像针对 OpImageSampleImplicitLod
一样,直到 缩放因子操作、LOD 操作和图像级别选择。返回值是向量 (λ', dl - levelbase)。这些值可能受限于非常大的、超出范围值的特定于实现的上限和下限。