c - 在片段着色器中显示格式为 VK_FORMAT_D24_UNORM_S8_UINT 的图像的深度
问题描述
语境
我目前正在尝试显示使用VK_FORMAT_D24_UNORM_S8_UINT
.
如果我正确阅读了文档,这种格式将深度分量存储在 24 位浮点上(值介于0
和之间1
),并将深度存储在无符号 8 位整数上。
Vulkan 设置
我试图做的是首先使用复制此图像vkCmdCopyImage
,并使用以下复制参数“仅提取深度”:
constexpr VkImageAspectFlags source_aspects = VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT;
constexpr VkImageAspectFlags destination_aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
const VkImageCopy COPY_INFORMATION =
{
.srcSubresource =
{
.aspectMask = source_aspects,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1
},
.srcOffset =
{
.x = 0,
.y = 0,
.z = 0
},
.dstSubresource =
{
.aspectMask = destination_aspects,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1
},
.dstOffset =
{
.x = 0,
.y = 0,
.z = 0
},
.extent =
{
.width = WIDTH,
.height = HEIGHT,
.depth = 1
}
};
GLSL 设置
然后我将它传递给片段着色器,如下所示:
#version 450
layout(set = 0, binding = 0) uniform sampler2D depth_sampler;
layout(location = 0) in vec2 screen_quad_position;
layout(location = 0) out vec4 fragment_colour;
void main()
{
float depth = texture(depth_sampler , screen_quad_position).r;
if(depth > 0.9999f)
{
discard;
}
fragment_colour = vec4(vec3((depth)),1);
}
相应的顶点着色器只是一个全屏三角形(因此实际上是一个全屏四边形),正如 Sacha Willems 先生所描述的:
#version 450
layout(location = 0) out vec2 screen_quad_position;
out gl_PerVertex{vec4 gl_Position;};
void main()
{
screen_quad_position = vec2(gl_VertexIndex & 2 , (gl_VertexIndex << 1) & 2);
gl_Position = vec4(screen_quad_position * 2.0f - 1.0f, 0.0f, 1.0f);
}
结果
这确实产生了一个与我正在渲染的形状相对应的输出(带有背面剔除的单一立方体,逆时针三角形顺序):
不要介意边框不对称,我懒得正确截屏。
但我宁愿期待这样的事情:
对问题原因的猜测
我的猜测是 glslfloat
存储在 32 位(如果我没有误解这个页面),但由于深度是 24 位浮点,这完全与显示的值混淆。
最后,问题:
假设我无法更改深度模板图像的格式VK_FORMAT_D24_UNORM_S8_UINT
,那么在片段着色器中使用格式显示图像深度的正确方法是什么?
以更一般的方式,显示此类图像的正确方法是什么(“选择VK_FORMAT_D32_SFLOAT
”的解决方案当然是微不足道的)。
如果我忘记输入任何相关信息,请告诉我。
解决方案
推荐阅读
- delphi - TURLEncoding.Base64.Encode 添加换行符?
- apache-spark - 如何从经过训练的 Spark MLP 模型中提取权重?
- python - 对于向量 v = [2.0, -3.5, 5.1]:求 v 的 L1 范数
- php - 会话开始后运行的 WordPress 中的任何钩子?
- powershell - Out-file , txt 已创建 , 未保存数据
- eclipse - 在 Eclipse 中导入 Maven 项目并将其作为 Java 项目运行的正确方法是什么?
- sql-server - 根据文件夹内容循环 OPENROWSET 语句
- javascript - 可重用的 Alpine.js 组件?
- json - 访问对象的字段
- android - 如何从意图 kotlin 中删除类