对三角形缠绕和变换的困惑

发布于 2024-12-02 02:29:09 字数 3195 浏览 0 评论 0原文

首先,我想为这么长的问题道歉。你不必阅读它。您可以直接跳到问题部分,然后根据需要查找详细信息(我已尝试提供尽可能多的信息,因为根据我的经验,代码太多总比太少好)。所以,...

我对三角形缠绕和变换有点困惑,我以为我理解了。我正在尝试绘制一个立方体,其定义如下:

    const float a = 0.5f; //half of the cube side length
    float positions[nComponents] =
    {
        //front face
        -a, -a, -a,
         a, -a, -a,
         a,  a, -a,

        -a, -a, -a,
         a,  a, -a,
        -a,  a, -a,

        //back face
        -a, -a,  a,
         a,  a,  a,
         a, -a,  a,

        -a, -a,  a,
        -a,  a,  a,
         a,  a,  a,

        //up face
        -a,  a, -a,
         a,  a, -a,
         a,  a,  a,

        -a,  a, -a,
         a,  a,  a,
        -a,  a,  a,

        //down face
        -a, -a, -a,
         a, -a,  a,
         a, -a, -a,

        -a, -a, -a,
        -a, -a,  a,
         a, -a,  a,

         //right face
         a, -a, -a,
         a, -a,  a,
         a,  a,  a,

         a, -a, -a,
         a,  a,  a,
         a,  a, -a,

         //left face
         -a, -a, -a,
         -a,  a,  a,
         -a, -a,  a,

         -a, -a, -a,
         -a,  a, -a,
         -a,  a,  a,
    };

这些是我脸部的假定颜色:

float face_colors[nFaces * dim] =
{
    1,0,0, //front RED
    1,1,1, //back  WHITE
    0,0,1, //up    BLUE
    0,1,1, //down  SKY BLUE
    0,1,0, //right GREEN
    1,1,0, //left  YELLOW
};

正如您从评论中看到的,我使用术语“上”、“下”、“左”、“右”等。这些词的含义是:我们假设我们正在从世界坐标中的位置(例如,(0, 0, -3a))查看立方体。现在,据我了解,我的立方体的正面是逆时针缠绕的(也就是说,如果我们从立方体外部的任何位置观察立方体,并枚举我们看到的三角形中的顶点,我们将得到逆时针缠绕) 。

所以,我需要 1. 启用剔除。 2. 说逆时针方向是正面 3. 剔除背面。这是代码:

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);

我的投影矩阵是透视投影矩阵,而 modelView 矩阵只是一个 LookAt 矩阵。它们作为制服提供给顶点着色器。

ProjectionMatrix = glm::perspective(45.0f, (float)w/h, 0.1f, 100.0f);
glm::vec3 center(0.0f, 0.0f, 0.0f);
glm::vec3 eye(1.0f, 2.0f, -3.0f);
glm::vec3 up(0.0f, 1.0f, 0.0f);
ModelViewMatrix = glm::lookAt(eye, center, up);
glUniformMatrix4fv(locP, 1, false, glm::value_ptr(ProjectionMatrix));
glUniformMatrix4fv(locMV, 1, false, glm::value_ptr(ModelViewMatrix));

我的顶点着色器定义如下:

#version 400
layout(location = 0) in vec4 vVertex;
layout(location = 1) in vec4 vColor;
uniform mat4 P;
uniform mat4 MV;
out vec4 vFragColor;
void main(void)
{
   vFragColor = vColor;
   gl_Position = P * MV * vVertex;
}

我的片段着色器很简单 - 它只是输出插值颜色。

现在...这是我得到的输出:

在此处输入图像描述

如果我更改 glFrontFace(GL_CCW); 更改为 glFrontFace(GL_CW);,或者将 glCullFace(GL_BACK) 更改为glCullFace(GL_FRONT),我得到了预期的(至少比前一个更预期,请参阅第二和第三个问题)渲染:

在此处输入图像描述

我在这里看到三个问题,每个问题都在一个问题中进行了描述:

实际问题:

问题1: 为什么缠绕与我的意图相反?我没有逆时针缠绕正面的顶点吗?
Q2 为什么我的“左”脸和“右”脸交换了位置?左脸应该是黄色,右脸是绿色,而不是相反!我的转变出了什么问题?
Q3 我的变换问题,因为我的眼睛向量的 x 坐标是正数,这意味着我实际上应该看到右侧的一点,而不是右侧的一点左边!

我一起问这些问题是因为我认为它们都是相互关联的,并且可能与我所缺少的一些非常基本的东西有关。非常感谢您花时间澄清这些事情。

First of all, I want to apologize for such a long question. You don't have to read it. You may jump straight to the questions part and then look up for details if needed (I have tried to provide as much information as possible, because in my experience too much code is better than too little). So,...

I am a bit confused about triangle winding and transformations, which I thought I understood. I am trying to draw a cube which is defined as follows:

    const float a = 0.5f; //half of the cube side length
    float positions[nComponents] =
    {
        //front face
        -a, -a, -a,
         a, -a, -a,
         a,  a, -a,

        -a, -a, -a,
         a,  a, -a,
        -a,  a, -a,

        //back face
        -a, -a,  a,
         a,  a,  a,
         a, -a,  a,

        -a, -a,  a,
        -a,  a,  a,
         a,  a,  a,

        //up face
        -a,  a, -a,
         a,  a, -a,
         a,  a,  a,

        -a,  a, -a,
         a,  a,  a,
        -a,  a,  a,

        //down face
        -a, -a, -a,
         a, -a,  a,
         a, -a, -a,

        -a, -a, -a,
        -a, -a,  a,
         a, -a,  a,

         //right face
         a, -a, -a,
         a, -a,  a,
         a,  a,  a,

         a, -a, -a,
         a,  a,  a,
         a,  a, -a,

         //left face
         -a, -a, -a,
         -a,  a,  a,
         -a, -a,  a,

         -a, -a, -a,
         -a,  a, -a,
         -a,  a,  a,
    };

And these are the supposed colors of my faces:

float face_colors[nFaces * dim] =
{
    1,0,0, //front RED
    1,1,1, //back  WHITE
    0,0,1, //up    BLUE
    0,1,1, //down  SKY BLUE
    0,1,0, //right GREEN
    1,1,0, //left  YELLOW
};

As you can see from the comments, I use terms up, down, left, right, etc. These words get their meaning if we suppose that we're looking at the cube from the position, say, (0, 0, -3a) in world coordinates. Now, as I understand, the front faces of my cube are wound conter-clockwise (that is, if we look at the cube from any position outside of it, and enumerate the vertices in the triangles we see, we will get counterclockwise winding).

So, I need to 1. Enable culling. 2. Say that counterclockwise is the front face 3. Cull back face. This is the code for that:

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);

My projection matrix is a perspective projection matrix, and the modelView matrix is just a LookAt matrix. They are fed as uniforms to the vertex shader.

ProjectionMatrix = glm::perspective(45.0f, (float)w/h, 0.1f, 100.0f);
glm::vec3 center(0.0f, 0.0f, 0.0f);
glm::vec3 eye(1.0f, 2.0f, -3.0f);
glm::vec3 up(0.0f, 1.0f, 0.0f);
ModelViewMatrix = glm::lookAt(eye, center, up);
glUniformMatrix4fv(locP, 1, false, glm::value_ptr(ProjectionMatrix));
glUniformMatrix4fv(locMV, 1, false, glm::value_ptr(ModelViewMatrix));

My vertex shader is defined as follows:

#version 400
layout(location = 0) in vec4 vVertex;
layout(location = 1) in vec4 vColor;
uniform mat4 P;
uniform mat4 MV;
out vec4 vFragColor;
void main(void)
{
   vFragColor = vColor;
   gl_Position = P * MV * vVertex;
}

My fragment shader is trivial - it just outputs the interpolated color.

Now... here's the output that I get:

enter image description here

If I change glFrontFace(GL_CCW); to glFrontFace(GL_CW);, or alternatively, change glCullFace(GL_BACK) to glCullFace(GL_FRONT), I get the expected (at least more expected than the previous one, see second and third quesions) rendering:

enter image description here

I see three problems here, each described in a question:

ACTUAL QUESTIONS:

Q1: Why is the winding reverse of what I intended? Haven't I wound the vertices counterclockwise for front faces?

Q2 Why have my "left" face and "right" face switched places? The left face was supposed to be yellow and the right one green, not vice-versa! What's wrong with my transformation?

Q3 There is something wrong with my transformation because the x coordinate of my eye vector is positive, which means I should actually see a bit of the right side, not a bit of the left side!

I have asked these questions together because I think they're all connected, and probably with something very basic that I am missing. Thank you very much for taking time to clarify these things.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

握住你手 2024-12-09 02:29:09

默认情况下,OpenGL 采用右手坐标系,即正 Z 轴指向屏幕外。您的立方体顶点位置表明您假设使用左手坐标系。然而,如果您将这些值放入 RHS,那么您的 LHS 逆时针坐标将变为顺时针 (1),一个轴上的面交换位置 (2),并且您假设的眼睛变换将进入相反方向 (3)。

OpenGL by default assumes a right handed coordinate system, i.e. the positive Z axis pointing OUT of the screen. Your cube vertex positions indicate you're assuming a left handed coordinate system. However if you put those values into a RHS then your LHS-counterclockwise coordinates become clockwise (1), faces on one axis swap places(2) and your assumed eye transformations will go into opposite direction(3).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文