unity分辨率问题,缩小时网格上有孔

时间:2019-04-29 16:32:18

标签: unity3d opengl rendering resolution

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

以下是Unity渲染的网格物体的图片: Normal mesh

Some triangles are missing

我的第一个想法是我有不同的分辨率,但事实并非如此。我在服务器和客户端上都有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;
}

2 个答案:

答案 0 :(得分:3)

我的天哪,我不敢相信我犯了这么愚蠢的错误。 毕竟,这是一个解决问题。

我没有呼叫gl_Viewport(仅在调整窗口大小时)。显然,当使用glfwCreateWindow创建窗口时,GLFW会创建该窗口,但是由于参数仅是提示而不是硬约束(如此处所述:glfw reference),有可能无法完全满足这些要求。由于我已经通过了1920 * 1080的期望尺寸(这也是我的分辨率),显然绘图区域实际上并没有达到1920 * 1080的尺寸,因为菜单等还需要一些空间。因此使用服务器上的分辨率较低(准确地说是1920 * 1061),导致客户端丢失三角形。

答案 1 :(得分:1)

在深入了解此问题的着色器详细信息之前,您确定问题不在于Unity中实现缩小功能的方式吗?自从我在较早的项目中就已经看到过,这只是一种预感,但是如果放大/缩小功能通过实际移动相机而起作用,那么当网格曲面超出范围时,剪切平面的移动将创建这些“孔”。尽管在共享映像中放置了这些孔中的一些使我怀疑情况确实如此,但是您永远都不知道。

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