unity分辨率问题,缩小时mesh有洞

Unity resolution problem, mesh has holes when zooming out

我有一个服务器,它使用带有自定义帧缓冲区的 OpenGL 渲染网格。在我的片段着色器中,我将 gl_primitiveID 写入输出变量。之后我调用 glReadPixels 来读出 ID。然后我知道哪些三角形被渲染(因此是可见的)并且我将所有这些三角形发送到在 Unity 上运行的客户端。在这个客户端上,我将顶点和索引数据添加到 GameObject 并且渲染它没有问题。我在 Unity 中得到的渲染结果与在 OpenGL 中得到的完全相同,除非我开始缩小。

以下是使用 Unity 渲染的网格图片:

我的第一个想法是我有不同的分辨率,但事实并非如此。我在服务器和客户端上都有 1920*1080。我在我的服务器上使用来自客户端的相同视图和投影矩阵,所以这也不应该是问题所在。这个错误的原因可能是什么?

如果你需要看我写的一些代码。

这是我的顶点着色器代码:

#version 330 core
layout (location = 0) in vec3 position;

uniform mat4 view;
uniform mat4 projection;

void main()
{
   gl_Position = projection * view * vec4(position, 1.0f);
}

这是我的片段着色器代码:

#version 330 core
layout(location = 0) out int primitiveID;

void main(void)
{ 
   primitiveID = gl_PrimitiveID + 1; // +1 because the first primitive is 0
}

这是我的 getVisibleTriangles 方法:

std::set<int> getVisibleTriangles() {
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glReadPixels(0, 0, SCR_WIDTH, SCR_HEIGHT, GL_RED_INTEGER, GL_INT, &pixels[0]);

    std::set<int> visibleTriangles;
    for (int i = 0; i < pixelsLength; i += 4) {
        int id = * (int*) &pixels[i];
        if (id != 0) {
            visibleTriangles.insert(id-1); // id 0 is NO_PRIMITIVE
        }
    }
    return visibleTriangles;
}

在深入了解此问题的着色器细节之前,您确定问题不在于 Unity 中实现缩小功能的方式吗?这只是一种预感,因为我在较早的项目中看到过它,但是如果缩放 in/out 功能通过实际移动相机来工作,那么当网格表面向外移动时,剪切平面的移动将创建那些 "holes"范围。虽然共享图片中的一些漏洞让我怀疑是不是这种情况,但你永远不知道。

如果这恰好是缩放功能的工作方式,那么您可以通过在缩小时查看编辑器模式来确认这一点。它将显示相机的裁剪平面相对于网格的位置。

天哪,我不敢相信我犯了这么愚蠢的错误。 毕竟分辨率问题。

我没有调用 gl_Viewport(仅在调整 window 大小时)。显然,当使用 glfwCreateWindow 创建 window 时,GLFW 会创建 window,但由于参数只是提示而非硬性约束(如此处所述:glfw reference),因此有可能那些并没有完全实现。由于我已经通过了所需的 1920*1080 大小(这也是我的分辨率),显然绘图区域实际上并没有达到 1920*1080 的大小,因为菜单等也需要一些 space 所以它在服务器上以较低的分辨率(准确地说,它是 1920*1061)呈现,导致客户端丢失三角形。