OpenGL 的旋转和光照问题

Posted

技术标签:

【中文标题】OpenGL 的旋转和光照问题【英文标题】:OpenGL issue with rotation and lighting 【发布时间】:2012-03-11 22:48:19 【问题描述】:

我正在使用用于 OpenGL 的 OpenTK 和用于 C# ide 的 monodevelop 进行简单的太阳系模拟。进展顺利,我有行星围绕太阳运行,照明正常。当我想倾斜行星的轴时,问题就开始了;无论我在我的方法中放置新的旋转,它都不会明显旋转。一旦它使我的球体的发光面以某种方式围绕它旋转。如果我在使行星绕其轴旋​​转的旋转之前或之后放置旋转,那么行星的顶部会变得奇怪,好像法线被破坏了一样。

public void Display (float time)

    GL.Rotate (axialTilt, tiltAxis);  // This rotation causes the issues, no matter
                                      // where I put it
    GL.PushMatrix ();                 // This push/pop was added later, but it 
                                      // doesn't help
    rotationalPosition += rotationSpeed * time;
    GL.Rotate (rotationalPosition, Vector3.UnitZ);

    planet.Draw ();

    GL.PopMatrix ();

    if (ring != null) 
        ring.Draw ();
    
    if (moons != null) 
        foreach (Orbit o in moons) 
            o.Draw (time);
        
    

这是由以下人员调用的:

public void Draw (float time)

    GL.PushMatrix ();

    GL.Rotate (angle, orientation);            // This will allow an angled axis for
                                               // moons and other planetary orbits.
    orbitPosition += orbitSpeed * time;
    GL.Rotate (orbitPosition, Vector3.UnitZ);

    GL.Translate (orbitDistance, 0, 0);

    GL.Rotate (-orbitPosition, Vector3.UnitZ); // Rotate backward, so rotating around
                                               // the orbit axis doesn't rotate the
                                               // planet.
    orbitingBody.Display (time);

    GL.PopMatrix ();

因此很奇怪。这里应该没有什么会导致法线出现问题,而且倾斜似乎在正确的位置。

【问题讨论】:

您调用GL.Rotate (rotationalPosition, Vector3.UnitZ); 的位置是您想要围绕其轴旋转您的行星的位置,对吗?如果它有一个倾斜的轴,你不应该围绕 z 轴旋转,你应该围绕 z 轴旋转它,该 z 轴由行星轴向倾斜旋转。 然而,你的行星绘图代码看起来确实是不必要的复杂。您可以将行星的极坐标转换为笛卡尔坐标并通过它进行转换。 x = orbitDistance*cos(orbitPosition); y=orbitDistance*sin(orbitPosition); 简化代码可能会帮助您发现问题。 【参考方案1】:

看起来你是先让行星围绕太阳倾斜,然后再旋转。这会使光线来自与您预期不同的方向。

我不确定 planet.Draw() 做了什么,但这是您的代码在概念上应该做的事情。

从单位矩阵开始 (如果你不从单位矩阵开始,你是围绕场景的中心旋转,而不是行星的轴)

围绕它的倾斜轴旋转行星。

将行星相对于太阳的当前位置添加到变换中,以便太阳现在位于场景的原点。 (GL.translate)

围绕太阳旋转行星。

【讨论】:

嗯,这实际上只是对行星的局部倾斜,因为行星有一个倾斜的轴,并且围绕该轴旋转。轨道运行的代码在其他地方并且运行良好。问题是照明会被这种旋转修改,无论我是在行星旋转之前还是之后放置它,但行星并没有明显倾斜。正如我所说,从中心的平移以及轨道运行完美。我得到的效果好像法线被某种方式改变了,而地球没有对旋转做出反应。如果您想查看更多代码,请说出来。 所以当您调用GL.Rotate (axialTilt, tiltAxis) 时,您确定您是从单位矩阵开始的吗?在这种情况下,查看所有涉及矩阵变换的代码以在渲染之前定位您的星球会有所帮助。您所做的任何事情似乎都不太可能改变几何体的法线,当然在您发布的代码中也没有。 奇怪的是,添加第二次轮换似乎会导致所有问题。我还没有尝试改变轨道轴,希望不会产生同样的效果。更新了主帖,这次可能有足够的信息;但基本上它确实从 Planet 的 Display 方法中的身份开始。

以上是关于OpenGL 的旋转和光照问题的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL/GLUT GL_LINES 的光照不正确

✠OpenGL-7-光照

OpenGL ES 光照效果

着色器中的 OpenGL 法线变换

OpenGL中的光照问题

问题理解 OpenGL 中的光照