片段密度图操作

片段密度图操作概述

当片段在具有片段密度图附件的渲染通道中生成时,其面积由片段所占用的本地帧缓冲区区域的属性决定。帧缓冲区被划分为这些局部区域的统一网格,它们的片段面积属性是通过以下操作从密度图中得出的

获取密度值

每个中心坐标为 (x,y) 的局部帧缓冲区区域都会从片段密度图中获取纹素。

首先,局部帧缓冲区区域中心坐标 (x,y) 会被 VkSubpassFragmentDensityMapOffsetEndInfoQCOM 中指定的值偏移。如果未指定偏移,则使用默认偏移 (0,0)。偏移后的坐标 (x',y') 的计算方式如下

偏移后的坐标 (x',y') 从片段密度图中获取整数坐标处的纹素

\(i = \left\lfloor{\frac{x'}{fragmentDensityTexelSize_{width}}}\right\rfloor\)

\(j = \left\lfloor{\frac{y'}{fragmentDensityTexelSize_{height}}}\right\rfloor\)

其中帧缓冲区中每个区域的大小为

\(fragmentDensityTexelSize'_{width} = {2^{\lceil{\log_2(\frac{framebuffer_{width}}{fragmentDensityMap_{width}})}\rceil}}\)

\(fragmentDensityTexelSize'_{height} = {2^{\lceil{\log_2(\frac{framebuffer_{height}}{fragmentDensityMap_{height}})}\rceil}}\)

此区域受 VkPhysicalDeviceFragmentDensityMapPropertiesEXT 中的限制,因此最终区域大小被钳制

\(fragmentDensityTexelSize_{width} = \mathbin{clamp}(fragmentDensityTexelSize'_{width},minFragmentDensityTexelSize_{width},maxFragmentDensityTexelSize_{width})\)

\(fragmentDensityTexelSize_{height} = \mathbin{clamp}(fragmentDensityTexelSize'_{height},minFragmentDensityTexelSize_{height},maxFragmentDensityTexelSize_{height})\)

当为渲染通道启用了多视图,并且使用大于 1layerCount 创建了片段密度图附件视图时,用于偏移和从片段密度图获取的图层为

否则

接下来将从密度图在 (i,j,layer) 处获取的纹素通过以下操作转换为密度。

组件混合

按照 图像组件混合 中定义的方式,将 VkImageViewCreateInfocomponents 成员应用于获取的纹素。

组件映射

将混合后的纹素的组件映射到密度值

片段面积转换

如果获取的密度不是大于 0.0 的归一化浮点值,则帧缓冲区区域的片段面积是未定义的。否则,该区域获取的片段面积按以下方式得出

片段面积过滤器

可以选择,实现可以(i,j) 周围的实现定义的窗口中获取额外的密度图纹素。纹素遵循标准的转换步骤,直到并包括片段面积转换

实现选择帧缓冲区区域的单个获取的片段面积,并且必须具有在获取的集合的最小最大面积之间的面积。

片段面积钳制

实现可以将获取的片段面积钳制为其支持的面积。钳制的片段面积必须具有小于或等于原始获取值的大小。实现可以为每个帧缓冲区区域更改支持的片段面积集。片段面积 (1,1) 必须始终位于受支持的集合中。

例如,如果获取的片段面积为 (1,4),但实现仅支持 {(1,1),(2,2)} 的面积,它可以选择将面积钳制为 (2,2),因为它与 (1,4) 具有相同的大小。虽然这会在 x 轴上产生质量严格较低的片段,但总体密度得以维持。

钳制的片段面积被分配给相应的帧缓冲区区域。