gpt4 book ai didi

OpenGL:将 View 空间坐标投影到 NDC,结果似乎超出 [-1,1] 范围

转载 作者:行者123 更新时间:2023-12-04 21:14:55 25 4
gpt4 key购买 nike

我一直在尝试按照 this 的指示实现屏幕空间环境光遮蔽。教程。当我遇到它们时,我一直在解决我的实现问题,但是这个问题让我现在很难过。

我对方法的理解如下。环境遮挡因子由取自与给定片段法线对齐的半球内的样本确定。为了确定样本是否对环境遮挡因子有贡献,我必须根据 View 空间深度纹理(包含在本文图片的左下角)检查样本在 View 空间中的深度。所以我知道要从深度纹理中获取哪些坐标,我必须将样本的坐标从 View 空间转换为标准化的设备坐标(在 [-1,1] 范围内),然后再转换为 [0 ,1],因此深度纹理​​有效地“映射”到视口(viewport)。

下图是我的环境遮挡放置在我的场景上。我知道环境遮挡本身存在一个相当明显的问题(我假设半球的方向不正确),我会及时处理,但目前激起我好奇心的是遮挡的外观被“缩小” ',这表明我从 View 空间样本坐标移动到纹理坐标的操作是不正确的。

enter image description here

由于我缺乏稳定的着色器调试器,我可以做的调试仅限于我可以渲染到屏幕上的内容。下一个图像是使用以下代码创建的,其中 ndcs 是给定样本的标准化设备坐标:

if (ndcs.x > 1.0f || ndcs.y > 1.0f || ndcs.x < -1.0f || ndcs.y < -1.0f)
{
gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
else
{
gl_FragColor = vec4(vec3(1.0f), 1.0f);
}

enter image description here

我希望图像完全是白色的(或者更确切地说,我使用这个着色器的位),但是它似乎表明我正在创建的 NDC 超出了 [-1,1] 范围,我相信一定是不正确的。它也不是屏幕的一致区域,如下图所示,相机非常靠近表面:

enter image description here

我以前从来没有使用过这个程序来获得 NDC,所以我确信我的逻辑一定是有问题的。我已经下载了教程提供的演示代码,但我看不出我的代码有什么不同。我也在网上搜索过(包括在这个网站上),我似乎无法找到与我症状完全相同的人。

这是我的着色器中的相关代码:

垂直着色器:
v_eye_space_position = u_mvpMatrix * a_position;
v_world_space_normal = normalize(u_rotationMatrix * a_normal);
v_eye_space_normal = normalize(u_mvpMatrix * a_normal);
gl_Position = v_eye_space_position;

片段着色器:
// --- SSAO Testing ---
// Convert from the noise texture back to [-1,1] range
// We want the noise texture to tile across the screen.
vec3 kernel_rotation = (texture2D(s_noise, gl_FragCoord.xy * u_noise_scale) * 2.0f - 1.0f).xyz;
vec3 eye_space_tangent = normalize(kernel_rotation - v_eye_space_normal.xyz * dot(kernel_rotation, v_eye_space_normal.xyz));
vec3 eye_space_bitangent = cross(v_eye_space_normal.xyz, eye_space_tangent);
mat3 tbn = mat3(eye_space_tangent, eye_space_bitangent, v_eye_space_normal);

float ambient_occlusion = 0.0f;
const float hemisphere_radius = 0.05f;

for (int i=0; i<16; i++)
{
vec3 kernel_sample = tbn * u_ssao_kernel[i];
kernel_sample = kernel_sample * hemisphere_radius + v_eye_space_position.xyz;

// Project the sample position into screen space.
vec4 offset = vec4(kernel_sample, 1.0f);
offset = u_projection_matrix * offset;
offset.xy /= offset.w;
vec4 ndcs = offset;
offset.xy = 1.0f - (offset.xy * 0.5f + 0.5f);

// Find the depth at this sample point.
float sample_depth = texture2D(s_camera_depth, offset.xy).z;

// Check if the sample point is occluded.
float range_check = 0.0f;

float linear_eye_space_position = (v_eye_space_position.z - u_near_plane)/(u_far_plane - u_near_plane);

// Range check.
if (abs(linear_eye_space_position - sample_depth) < hemisphere_radius)
{
range_check = 1.0f;
}

float linear_kernel_sample_depth = (kernel_sample.z - u_near_plane)/(u_far_plane - u_near_plane);
if (sample_depth <= linear_kernel_sample_depth)
{
ambient_occlusion += 1.0f * range_check;
}
}

// Average and invert the ambient occlusion.
ambient_occlusion = 1.0f - (ambient_occlusion/16.0f);

我已经孤立地查看了每个元素,但看不到它们的问题。
  • 我已经将片段自己的 View 空间位置替换为
    投影(而不是样本的 View 空间位置),我得到
    同样的结果。
  • 投影矩阵是透视矩阵 I
    用于转换模型的顶点(我已经构建了 MVP
    我的顶点着色器中的矩阵,以确保投影矩阵是
    巧妙地到达着色器程序,它是)。
  • 投影操作本身 - 这不是我以前做过的事情,但我读过
    在线文章和有投影问题的人提出的问题
    而且我看不出我做错了什么。

  • 因此,我只能得出结论,我对透视投影的理解一定有一些基本的东西是有缺陷的,但我就是不知道是什么。如果你们中的任何人可以阐明问题或进一步的途径让我检查,我将不胜感激。如果我遗漏了任何有用的信息或我可以澄清的任何信息,请告诉我。

    最佳答案

    从您的顶点着色器:

    v_eye_space_position = u_mvpMatrix * a_position;
    [...]

    pMatrix * a_normal); gl_Position = v_eye_space_position;



    从中可以看出 v_eye_space_position不是顶点的眼睛空间位置而是剪辑空间位置,也需要赋值给 gl_Position .您的矩阵制服的名称也表明这是 ModelView 投影 -矩阵。

    在您的片段着色器中,您基本上再次将投影矩阵的结果相乘(因为您似乎假设它在眼睛空间中)。

    所以正确的代码是:
    v_eye_space_position = u_mvMatrix * a_position;
    [...]
    gl_Position = u_projection_matrix * v_eye_space_position;

    现在,您可以将投影应用于 v_eye_space_position再次在片段着色器中。但我的问题是:为什么还要这样做?如果你想在屏幕空间工作, gl_FragCoord已经在窗口空间中。您只需反转视口(viewport)(和深度范围)变换即可从窗口空间到 NDC。

    关于OpenGL:将 View 空间坐标投影到 NDC,结果似乎超出 [-1,1] 范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26162691/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com