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)呈现,导致客户端丢失三角形。
我有一个服务器,它使用带有自定义帧缓冲区的 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)呈现,导致客户端丢失三角形。