从规范中:
VK_KHR_maintenance1 允许在slink::VkViewport::高度字段中指定负高度,以执行剪辑空间到帧缓冲区空间转换的y-反转。这使得应用程序可以避免在着色器中使用gl_Position.y = -gl_Position.y,还可以针对其他API。
我的物理设备支持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);
}
发布于 2017-08-08 14:37:01
算一遍数学。您拥有所有的数字,并且规范显式地列出了所有的数字。
帧缓冲空间顶点坐标的Y分量的方程是:
Yf = (Py / 2) Yd + Oy
Oy = viewport.y + viewport.height / 2.0
Py = viewport.height
其中Yf
是帧缓冲空间Y组件,Yd
是NDC空间Y组件。
如果插入一个正数为1024的height
,你得到的数字是多少?对于-1的Yd
,Yf
为0.0。如果Yd
为3,则Yf
为2048。
在Vulkan,“自然”视口变换通过在viewport.x/y
上放置-1和在viewport.width/height
上放置1来映射NDC-空间。请记住:Vulkan的图像有一个左上角的原点,正值向下和向右。因此,Yf
为0.0在顶部,而Yf
为2048在屏幕底部。因此,三角形(部分)位于视图端口的可见区域。
既然如此,当您使用负height
时会发生什么?数学没有改变,只是结果而已。对于-1的Yd
,Yf
为0.0,与以前一样。如果Yd
为3,则Yf
为-2048。
那是什么样子的?好吧,视点的含义没有改变,只是数字而已。这意味着框架缓冲区图像的可见区域仍然位于左上角,向下移动。因此,-2048的值在视口的上方。
简而言之,一个负高度翻转了视口。但这会在视口原点翻转,而不是在屏幕中心。视口原点位于左上角,向下和右边.因此,翻转它将翻转所有以前在屏幕上可见的东西。您现在正在查看屏幕的另一个区域,在您的情况下,这是空白的。
如果您想要翻转视口中心周围的一切,那么您需要调整viewport.y
以补偿负高度。具体来说,它需要是积极的高度。
https://stackoverflow.com/questions/45570326
复制相似问题