c++ - 三角法线面检测

标签 c++ c opengl graphics bezier

所以我目前有一个可以动态更改的三角形网格(由贝塞尔曲线制成)。我面临的问题是试图根据相机所在的位置找出实际渲染的三角形。相机总是朝原点 (0,0,0) 看,所以我找到每个三角形的法线并将它与我的相机 vector 进行点积。然后根据结果判断三角形是否“可见”。

以下是我用于计算的代码:

void bezier_plane()
{
    for (int i = 0; i < 20; i++) {
        for (int j = 0; j < 20; j++) {
            grid[i][j].x = 0;
            grid[i][j].y = 0;
            grid[i][j].z = 0;
        }
    }
    //Creates the grid using bezier calculation
    CalcBezier();
    for (int i = 0; i < 19; i++) {
        for (int j = 0; j < 19; j++) {
            Vector p1, p2, p3, normal;
            p1.x = grid[i+1][j+1].x - grid[i][j].x; p1.y = grid[i+1][j+1].y - grid[i][j].y; p1.z = grid[i+1][j+1].z - grid[i][j].z;
            p2.x = grid[i+1][j].x - grid[i][j].x;   p1.y = grid[i+1][j].y - grid[i][j].y; p1.z = grid[i+1][j].z - grid[i][j].z;

            normal = CalcNormal(p2, p1);
            double first = dotproduct(normal, Camera);

            p3.x = grid[i][j+1].x - grid[i][j].x; p3.y = grid[i][j+1].y - grid[i][j].y; p3.z = grid[i][j+1].z - grid[i][j].z;

            normal = CalcNormal(p1, p3);
            double second = dotproduct(normal, Camera);

            if (first < 0 && second < 0) {
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
                glColor3f(0, 1, 0);
                glBegin(GL_TRIANGLE_STRIP);
                    glVertex3f(grid[i][j].x, grid[i][j].y, grid[i][j].z);
                    glVertex3f(grid[i][j+1].x, grid[i][j+1].y, grid[i][j+1].z);
                    glVertex3f(grid[i+1][j].x, grid[i+1][j].y, grid[i+1][j].z);
                    glVertex3f(grid[i+1][j+1].x, grid[i+1][j+1].y, grid[i+1][j+1].z);
                glEnd();
            } else if (first < 0 && second > 0) {
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
                glColor3f(0, 1, 0);
                glBegin(GL_TRIANGLE_STRIP);
                    glVertex3f(grid[i][j].x, grid[i][j].y, grid[i][j].z);
                    glVertex3f(grid[i+1][j].x, grid[i+1][j].y, grid[i+1][j].z);
                    glVertex3f(grid[i+1][j+1].x, grid[i+1][j+1].y, grid[i+1][j+1].z);
                glEnd();
            } else if (first > 0 && second < 0) {
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
                glColor3f(0, 1, 0);
                glBegin(GL_TRIANGLE_STRIP);
                    glVertex3f(grid[i][j].x, grid[i][j].y, grid[i][j].z);
                    glVertex3f(grid[i][j+1].x, grid[i][j+1].y, grid[i][j+1].z);
                    glVertex3f(grid[i+1][j+1].x, grid[i+1][j+1].y, grid[i+1][j+1].z);
                glEnd();
            }
        }
    }
}

这是 CalcNormal:

   Vector CalcNormal(Vector p1, Vector p2)
{
    Vector normal;
    normal.x = (p1.y * p2.z) - (p1.z * p2.y);
    normal.y = (p1.z * p2.x) - (p1.x * p2.z);
    normal.z = (p1.x * p2. y) - (p1.y * p2.x);
    return normal;
}

double dotproduct(Vector normal, Vector Camera)
{
    return (normal.x * Camera.x + normal.y * Camera.y + normal.z + Camera.z);
}

现在,我的代码给出了这个结果。红色圈出的部分不应显示(我相信,后面的三角形)。 result

最佳答案

您测试法线的方法仍然会有视觉伪影,因为面向相机的三角形可能被遮挡。想象一下,如果那个凸起位于最靠近相机的角落。

您还会有部分可见和部分模糊的三角形。

适用于像素级别的解决方案是:

  • glEnable(GL_DEPTH_TEST)
  • 首先实心三角形而不是线框绘制表面
  • 清除帧缓冲区,但深度缓冲区
  • 现在画出整个场景。深度缓冲区将防止绘制模糊的像素

关于c++ - 三角法线面检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16196774/

相关文章:

c++ - 读取 PNG header 的第一个字节时出现奇怪的结果

C++ 重新定义'..' 和之前在这里声明的错误

C 中的 crypt() 函数不起作用

c++ - 在 C 中使用数组

c# - DirectX/SharpDX 中类似 "glReadPixels"的函数

c++ - openGL - 测试映射立方体失败

c++ - isdigit() 总是通过检查

C++ 记住要做的工作(算法)

c - 为什么这个变量等于一个数字和一个字符?

c - OpenGL:移动相机时如何使光线静止?