从规格:
VK_KHR_maintenance1
允许在slink :: VkViewport :: height字段中指定负高度,以将剪辑空间向帧缓冲区空间的y反转。这样,应用程序就可以避免在也针对其他API的着色器中使用gl_Position.y = -gl_Position.y。
我的物理设备支持版本,1.0.42
并且启用了VK_KHR_maintenance1
。当我在VkViewport
结构中执行负高度时,我没有收到任何验证错误/警告。
vkCmdSetViewport(vkContext.commandBuffer, 0, 1, &viewport);
但是,如果我删除了viewport
所有显示为预期的负值,那么我也看不到屏幕上的任何东西,黑色。我还需要做其他任何事情来使用翻转视口VK_KHR_maintenance1 extension
吗?我只是在屏幕上渲染红色四边形,并带有全屏视口。
VkViewport viewport = {};
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = 1024.0f;
viewport.height = -1024.0f;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(vkContext.commandBuffer, 0, 1, &viewport);
顶点着色器:
void main() {
vec4 positions[3] = {
vec4(-1.0, -1.0, 0.0, 1.0),
vec4(3.0, -1.0, 0.0, 1.0),
vec4(-1.0, 3.0, 0.0, 1.0)
};
gl_Position = positions[gl_VertexIndex % 3];
}
片段着色器:
void main() {
outFragColor = vec4(1,0,0,1);
}
只是通过数学。您拥有所有数字,并且规范明确列出了所有数字。
帧缓冲区空间顶点坐标的Y分量的等式为:
Yf = (Py / 2) Yd + Oy
Oy = viewport.y + viewport.height / 2.0
Py = viewport.height
其中Yf
是帧缓冲区空间Y分量,Yd
是NDC空间Y分量。
如果插入正height
数1024,您会得到什么数字?对于Yd
-1,您将获得Yf
0.0。对于Yd
3的a,您得到Yf
2048。
在Vulkan中,“自然”视口变换通过将-1放在viewport.x/y
,将1放在来映射NDC空间viewport.width/height
。请记住:Vulkan的图像具有左上角的原点,正值向下和向右。因此Yf
,0.0的值位于Yf
屏幕顶部,而2048的值位于屏幕底部。因此,三角形(部分)在视口的可见区域中。
鉴于此,当您使用负数时会发生什么height
?数学不变。只是结果。对于Yd
-1,您将获得Yf
0.0,与以前一样。对于Yd
3的a,您得到Yf
-2048。
看起来像什么?好吧,视口的含义没有改变。只是数字。这意味着帧缓冲区图像的可见区域仍在左上方,向下。因此,值-2048在视口上方。
简而言之,负高度会翻转视口。但这会将其翻转到视口原点,而不是屏幕的中心。视口原点位于左上角,向下和向右。因此,翻转它会翻转屏幕上以前可见的所有内容。您现在正在查看屏幕的其他区域,在您的情况下为空白。
如果要翻转视口中心周围的所有内容,则需要调整,viewport.y
以补偿负高度。具体来说,它必须是正高度。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句