OpenGL - 每个三角形的像素数不正确



我用Blender创建了一个简单的立方体,并在我的openGL C++代码中使用Ssimp读取它。立方体的 6 个面中的每一个都分为两个三角形。我用不同的颜色给每个三角形着色(蓝色=0,绿色= 0,但红色从一个三角形到另一个三角形是不同的(。

为了可视化立方体,我使用了正射投影。我调用max_vertice立方体中顶点的最大值,fac_max_vertice是我设置为 2 的数字:

glm::mat4 Projection = glm::ortho<float>(-max_vertice* fac_max_vertice,max_vertice* fac_max_vertice,-max_vertice* fac_max_vertice,max_vertice* fac_max_vertice, 0, 2 * max_vertice* fac_max_vertice);

我根据θ和phi的角度(在固定距离上(围绕立方体旋转相机:

distance_camera = maximum value of vertice*fac_max_vertice; // fixed
x_camera = distance_camera * sin(theta) * cos(phi); // phi and theta can vary
y_camera = distance_camera * sin(theta) * sin(phi);
z_camera = distance_camera * cos(theta);
glm::vec3 camera = glm::vec3(x_camera, y_camera, z_camera);                                                                                                                                 
glm::mat4 View = glm::lookAt(camera, glm::vec3(0,0,0), glm::vec3(0,1,0)); 

我使用 glReadPixel 识别每个像素的颜色:

unsigned char *red = (unsigned char *)malloc(3*width_here*height_here*sizeof(unsigned char *));
glReadPixels(0, 0, width_here, height_here, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)(red));

其中width_here和height_here是窗口的宽度和高度(请注意,我称变量为红色,但我查看每个组件为红色,蓝色和绿色(

获得像素的颜色后,我为像素分配其相应的面(具有与像素颜色相同的面(。

然后我计算每张脸的像素数。

当相机放置在人脸正前方时(例如,theta = phi = 0(,人脸的两个三角形的每个人脸的像素数完全相同,这是有道理的。但是,这就是我认为存在错误的地方,当我将相机旋转某个值(例如,phi = 10°(时,两张脸之间的像素数不再相同。不过应该是一样的,因为脸如果平坦,所以从相机看到的像素数对于 2 个三角形是完全相同的。

例如,在附图中,大人脸的 2 个三角形之一的像素数为 21931,但同一大面的另一个三角形的像素数为 21845。同样的错误也发生在低发生率的脸上(也有两个三角形,但颜色彼此接近(:一个三角形为 1105 像素,另一个三角形为 1199 像素。

你知道会发生什么吗?

立方体

有几个因素会导致两个不同的三角形使用不同的像素数进行栅格化:

多重采样

当三角形的边缘不完全出现在像素的边界上,并且启用了多重采样时,生成的像素将包含一个混合值,该值可能不等于给定三角形或任何周围三角形的颜色。因此,计算给定像素颜色的实例必然会导致计数不同。

透视

当您使用透视矩阵作为投影矩阵(而不是正交矩阵(时,不同位置的两个相同三角形将具有不同的大小。三角形通常离屏幕中心越远,它们就越伸展。

取向

两个在数学上相同的三角形将根据它们的位置看到少量的光栅化伪影,尤其是在它们旋转时(它们在您的示例中(。用于确定是否应栅格化特定像素的光栅化器的算法不会对面向不同方向的边进行完全相同的评估。

闭塞

在您的示例中,两个三角形彼此直接相邻。这意味着其中一个三角形将在光栅器中获得优先级。这可能是深度测试、小浮点误差或任何其他因素的结果。它甚至不能保证是确定性的,因为 OpenGL 实现在如何做出这些决策方面允许少量的回旋余地,至少在涉及具有相同深度的片段时;这是Z-Fighting的根本原因。

结论

您的基本假设,即"这两个相同大小的三角形应该具有相同数量的渲染像素"显然是错误的。高度受限的情况(例如,在您的示例中,相机以完全平坦的角度锁定(可能会产生两个具有相同像素数的三角形,但在任何其他情况下,它们都不会。这是现代图形体系结构的自然结果。如果希望两个对象具有完全相同的像素数,则需要切换到基于整数的渲染,或采用一些非常不寻常的做法。我建议你研究一下"复古风格"游戏如何处理以低"有效分辨率"渲染游戏的任务,然后注意其中许多游戏可能显示出许多与你观察到的相同的怪癖。

最新更新