1

很长一段时间以来,我一直推迟在 OpenTK 中进行的一个项目中修复照明。问题基本上是当我旋转相机时,我正在显示的地形上显示的照明也会旋转。

这是我的 onRenderFrame 代码片段:

protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);

        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

        float dist = (float)Math.Sin(Math.PI / 3) * camZoom;

        Matrix4 view = Matrix4.LookAt(new Vector3(-(float)Math.Cos(camRot) * dist, dist, -(float)Math.Sin(camRot) * dist) + camPos, camPos, new Vector3(0, 1, 0));
        //Note: camPos isn't actually the position of the camera, rather the target of it. The actual camera position is calculated above.


        GL.MatrixMode(MatrixMode.Modelview);

        GL.LoadMatrix(ref view);

        float tx = 50;
        float ty = 20;
        float tz = -15;

        GL.Light(LightName.Light0, LightParameter.Position, new float[] { tx, ty, tz});

        GL.Begin(BeginMode.Lines);
        DrawBox(tx - 2, tx + 2, ty - 2, ty + 2, tz - 2, tz + 2);
        GL.End();

...地形图在这里

我使用我的快速 DrawBox 函数在灯光的位置周围绘制了一个简单的框。它工作正常,我什至实现了一些运动,例如围绕地球的太阳。虽然相机没有移动,但效果很好。但是一旦我转动相机,灯光不再显示它应该有的东西,它似乎已经“移动”了灯光,但实际上并没有移动它(绘制的盒子没有移动,只有灯光的效果)。

4

1 回答 1

1

根据带有 GL_POSITION 参数的 glLight的OpenGL 规范:

GL_POSITION: params 包含四个整数或浮点值,用于指定光在齐次对象坐标中的位置。整数和浮点值都直接映射。整数和浮点值都没有被限制。

当调用 glLight 时,位置由模型视图矩阵转换(就像它是一个点一样),并存储在眼睛坐标中。如果位置的 w 分量为 0,则将光源视为定向光源。漫反射和镜面反射光照计算会考虑光的方向,但不会考虑其实际位置,并且会禁用衰减。否则,漫反射和镜面光照计算基于眼睛坐标中光线的实际位置,并启用衰减。初始位置为 (0, 0, 1, 0);因此,初始光源是定向的,平行于 -z 轴的方向。

你只传递三个花车。我不能确定 OpenTK 使用什么作为第四个 (w) 组件,但我猜它会将任何未指定的参数设为 0,从而使您的光线具有方向性并忽略您给出的位置。我会尝试将 1.0 添加到您传入的数组的末尾,看看是否可以解决问题。

于 2012-04-27T03:47:32.853 回答