您的位置:首页 > 编程语言

Vulkan编程指南翻译 第六章 着色器和管线 第5节 第6段 图像采样

2017-03-11 18:48 573 查看
这一节实在太长了,分篇来翻译。

Sampled Images

 

当着色器从图像读数据时,他们可以可以使用两种方式。第一种是原生加载,从图像的指定位置直接读取格式化的或非格式化的数据,第二种是使用采样器对图像采样。采样包括:在图像坐标空间做基础变形或者纹素过滤来光滑图像返回到着色器。

采样器的状态通过一个采样器对象表示,它可像图像或者缓冲区一样被绑定到描述符集合。可调用函数vkCreateSampler()来创建一个采样器对象,其原型如下:

         VkResultvkCreateSampler (

VkDevice                                               device,

const VkSamplerCreateInfo*          pCreateInfo,

const VkAllocationCallbacks*         pAllocator,

VkSampler*                                          pSampler);

将创建采样器的设备通过device传递,采样器剩下的参数通过一个VkSamplerCreateInfo类型数据的指针pCreateInfo传递。一个设备上可以创建的采样器个数的上限取决于与Vulkan实现。可以保证的是至少有4000个。如果你的应用程序有可能创建超过这个数量的采样器,那么你需要检查设备本身支持创建多少个采样器。一个设备可以管理的采样器个数包含在VkPhysicalDeviceLimits类型数据的maxSamplerAllocationCount域,可调用vkGetPhysicalDeviceProperties()函数来获取VkPhysicalDeviceLimits数据。VkSamplerCreateInfo原型如下:

         typedefstruct VkSamplerCreateInfo {

VkStructureType sType;

const void* pNext;

VkSamplerCreateFlags flags;

VkFilter magFilter;

VkFilter minFilter;

VkSamplerMipmapMode mipmapMode;

VkSamplerAddressMode addressModeU;

VkSamplerAddressMode addressModeV;

VkSamplerAddressMode addressModeW;

float mipLodBias;

VkBool32 anisotropyEnable;

float maxAnisotropy;

VkBool32 compareEnable;

VkCompareOp compareOp;

float minLod;

float maxLod;

VkBorderColor borderColor;

VkBool32 unnormalizedCoordinates;

} VkSamplerCreateInfo;

VkSamplerCreateInfo的sType域应置为VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,pNext应置为nullptr。Flags域被保留应置为0。

 

图像过滤

magFilter 和 minFilter域指定了图像在被放大或缩小时将被使用的过滤模式。图像是放大还是缩小是通过比较被计算的相邻像素间采样坐标来决定。如果采样坐标的梯度大于1,那么图像是被缩小的。否则,它是被放大的。magFilter 和 minFilter是VkFilter枚举的成员。VkFilter的成员如下:

• VK_FILTER_NEAREST: When sampling, the nearest texel in the image ischosen and returned

directly to the shader.

• VK_FILTER_LINEAR: A 2 × 2 footprint containing the texelcoordinates is used to produce a

weighted average of four texels, and thisaverage is returned to the shader

 

VK_FILTER_NEAREST模式将使Vulkan在从一张图像采样时简单选择指定坐标临近的纹素。在很多情况下,这就导致blocky喝着带锯齿的图像,导致渲染出来的图像闪烁。VK_FILTER_LINEAR告诉Vulkan当采样时对图像采用线性过滤。

当你正在使用线性过滤来处理图像时,需要获取的采样点也许在1D纹理的两个纹素中间,或者2D纹理的4个纹素中间。Vulkan将从周围的纹素读取数据,然后基于到每个点的距离给予不同的权重计算出结果。这在Figure 6.2中给出了图示,采样点在x,它处于四个纹素A,B,C和D的中间。尽管纹理坐标的整数部分是{u, v},纹理坐标的小数部分是{α, β}。

要获取纹素A、B的线性权重之和,可按照下面的关系来简单的计算

Tu0 = αA + (1 −α) B

这也可以写成

Tu0 = B + α (B−A)

同理,C与D的权重之和通过下面的公式来算

Tu1 = αC + (1 −α) D or

Tu1 = D−α (D−C)

然后,两个临时量Tu0 and Tu1可被结合来算单一一个权重之和,结合β和相似的机制

T = βTu0 + (1 −β) Tu1 or

T = Tu1 + β(Tu1 −Tu0)

这可以拓展到任何维数,尽管在Vulkan中纹理的维数最多只有3。

 

Mipmapping

mipmapMode域指定了当图像被采样时使用多少层mipmaps。其值是VkSamplerMipmapMode枚举的一个成员,枚举成员如下:

• VK_SAMPLER_MIPMAP_MODE_NEAREST: The computed level-of-detail isrounded to the

nearest integer, and that level is used toselect the mipmap level. If sampling from the base

level, then the filtering mode specified inmagFilter is used to sample from that level;

otherwise, the minFilter filter is used.

• VK_SAMPLER_MIPMAP_MODE_LINEAR: The computed level of detail isrounded both up

and down, and the two resulting mipmaplevels are sampled. The two resulting texel values are

then blended and returned to the shader.

 

要从一个图像中选择mipmap,Vulkan将计算纹理中被采样的坐标的导数。关于数学的部分在Vulkan 规范里有讲述。简单来说,被选择的level是纹理坐标维数中导数最大的一个做log2的结果。这个level可以通过采样器或者着色器的参数来调整,或者完全在着色器里指定。不管源是什么,结果可能不是整数。

当mipmap模式是VK_SAMPLER_MIPMAP_MODE_NEAREST,被选择的mipmap level是简单的取其整数部分,然后那单一一层被采样,尽管只是一层图像。当mipmap模式是VK_SAMPLER_MIPMAP_MODE_LINEAR时,采样点从邻近的上一层和下一层取得,使用minFilter域指定的过滤模式,然后这两个采样点依据其权重来合称为一个点,和前面讲述的线性采样相近。

注意,过滤模式只适用于缩小,亦即此过程在mipmap层采样而并不在原图像采样。到纹理坐标导数的log2 比1小时,那么第0层就被使用,所以只有一层能够被采样使用了。这就是放大,使用magFilter指定的过滤模式来从原图像中采样。

VkSamplerCreateInfo中接下来的三个域addressModeU,addressModeV, 和 addressModeW,用来指定纹理坐标系之外采样时选用的变形。可选的模式如下:

 

• VK_SAMPLER_ADDRESS_MODE_REPEAT: As the texture coordinateprogresses from 0.0 to

1.0 and beyond, it is wrapped back to 0.0,effectively using only the fractional part of the

coordinate to sample from the image. Theeffect is to tile the image indefinitely.

• VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: The texture coordinateprogresses

from 0.0 to 1.0 as normal, and then in therange 1.0 to 2.0, the fractional part is subtracted from

1.0 to form a new coordinate moving backtoward 0.0. The effect is to alternately tile the normal

and mirror-image version of a texture.

• VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: Texture coordinates beyond1.0 are

clamped to 1.0, and negative coordinatesare clamped to 0.0. This clamped coordinate is used to

sample from the image. The effect is thatthe texels along the edge of the image are used to fill

any area that would be sampled outside theimage.

• VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: Sampling from the textureoutside

its bounds will result in texels of theborder color, as specified in the borderColor field,

being returned rather than data from theimage.

• VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: This is a hybrid modethat

first applies a single mirroring of thetexture coordinate and then behaves like

VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE.

 

在Figure 6.3展示了每一种应用到图像的采样器寻址模式的效果。在图中,左上角的图像展示了VK_SAMPLER_ADDRESS_MODE_REPEAT寻址模式。你可以看到,在帧之间纹理只是简单的重复。右上角的图像展示VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT模式的结果。每一个重复都会在X或Y方向上镜像。

Figure6.3: Effect of Sampling Modes
 
左下角的图像表示对纹理使用了VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE寻址模式。这里,最后一行或者一列的像素在采样坐标离开纹理范围后被无限重复。最后,右下角的图像展示了VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER模式的结果。这个纹理在创建时使用了黑色的边框,所以,在纹理之外的部分就是空白的,但是Vulkan会从黑色采样。这允许你可以看清原来的纹理。

当过滤模式是VK_FILTER_LINEAR,wrapping或者clamping纹理坐标被应用到每一个在2×2范围内生成的用来产生纹素的坐标。结果就是图像被wrapped时过滤也被应用上了。

对于VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER过滤模式,当纹素是从边界采样时(),边界的颜色被替换了而非从图像中读取。被使用的颜色取决于borderColor域的值。这不是一个完整的颜色规范,只是VkBorderColor枚举类型的一个成员,它允许一个小的、预定义的颜色集合可选。它们是:

 

• VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK: Returns floating-pointzeros to the

shader in all channels

• VK_BORDER_COLOR_INT_TRANSPARENT_BLACK: Returns integer zeros to theshader in

all channels

• VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK: Returns floating-point zeros inthe R, G,

and B channels, and floating-point one in A

• VK_BORDER_COLOR_INT_OPAQUE_BLACK: Returns integer zeros in R, G,and B, and

integer one in A

• VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE: Returns floating-point ones tothe shader in

all channels

• VK_BORDER_COLOR_INT_OPAQUE_WHITE: Returns integer ones to theshader in all

Channels

 

VkSamplerCreateInfo的mipLodBias域指定了在被添加到选择mipmap之前计算的level ofdetail 的一个浮点差值。这允许你你把在mipmap链中把level of detail调高或调低,使生成的被过滤的纹理看起来更加锐利或者模糊。

如果你想要使用各向异性过滤,设置anisotropyEnable为VK_TRUE。各向异性过滤的细节是依赖于Vulkan实现的。各向异性管理通常在投影范围内做采样,而不是在固定的2×2范围内。通过在范围内使用更多的采样点来逼近范围内采样。因为采样的个数可能非常大,各向异性过滤可能对性能产生负面影响。同样,在一些极端情况下,投影的范围可能非常大,这会导致影响到很大区域和模糊的过滤效果。为了限制这些效果,你可以对各向异性的范围做剪裁,设置maxAnisotropy在1.0和设备允许的最大值之间。可调用vkGetPhysicalDeviceProperties()并检查VkPhysicalDeviceLimits类型数据的maxSamplerAnisotropy域来获知该最大值。

当采样子用于深度图像时,可以配置来进行比较操作并返回比较的结果而不是存储在图像原生的值。当这种模式启用时,从图像中取出的采样点之间进行比较,结果便是通过采样后数据的分数部分。这可用来实现一个名为spercentage closer filtering, or PCF的技术。要开启这个模式,需设置compareEnable为VK_TRUE,并给compareOp设置比较操作。

compareOp是VkCompareOp枚举的一个成员,该枚举在Vulkan中用于很多地方。如将在第七章“图形管线”中见到,这个枚举会被用于指定深度测试操作。可用的操作和它们在着色器访问深度资源时的语境在Table 6.2中展示。

采样器可被配置来限制在一个带有mipmaps的图像mip levels中一个子集。被限制的mipmap范围通过minLod and maxLod指定,它俩包含了应被采样的最低(最高分辨率)和最高(最低分辨率)的mipmaps。要在整个mipmaps链上做采样,设置minLod to 0.0, 并设置 maxLod为高到不能再进行clamp的level of detail层。

最后,unnormalizedCoordinates是一个标志位,当被设置为VK_TRUE时,表示图像被用于采样的坐标是以原生纹素为单位。而不是从0.0到1.0归一化的值。这允许可从图像里显式的取出纹素。然而,这种模式存在几个限制。当unnormalizedCoordinates是VK_TRUE时,minFilter 和 magFilter必须是相同的,mipmapMode必须是VK_SAMPLER_MIPMAP_MODE_NEAREST,anisotropyEnable必须是VK_FALSE。

当你使用完了采样器,你应该调用vkDestroySampler()销毁它,其原型如下:

        

         voidvkDestroySampler (

VkDevice device,

VkSampler sampler,

const VkAllocationCallbacks* pAllocator);

device是拥有该采样器对象的设备,sampler是需被销毁的采样器对象。如果在创建采样器对象时使用了主机内存分配器,一个兼容的内存分配器也需要通过pAllocator参数传入。否则,pAllocator应置为nullptr。

 

总结

本章覆盖了Vulkan支持的着色语言的基础、SPIR-V,包含了如何Vulkan如何接收SPIR-V着色器module,包含这些着色器的管线如何构造。你看到可如何狗仔计算着色器并用它来创建计算管线,如何分发工作到管线,如何让管线访问资源以产生数据。在接下来的章节里,我们将继续深入管线的概念来创建拥有多阶段的管线对象并使用更多的高级特性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐