当我移动或旋转相机时,OpenGL 雾效果会发生变化

Posted

技术标签:

【中文标题】当我移动或旋转相机时,OpenGL 雾效果会发生变化【英文标题】:OpenGL Fog effect changes when I move or rotate the camera 【发布时间】:2014-02-27 08:30:28 【问题描述】:

我想给一个小的 3D 世界添加雾,我试着摆弄参数,但是雾不是均匀的。

我有两个可能相关的问题:

    雾均匀性: 当我用 gluLookAt 移动或旋转我的视点时,雾太重了,整个世界都是灰色的。但是雾的渲染很好的两个角度。 当相机在 Y 轴方向为 45° 或 -135°(相反)时,雾看起来很正常

    以场景原点为中心的雾:

当我的雾正确显示时,它以场景的 (0;0;0) 为中心

这是我用来初始化雾和调用 gluLookAt 的代码

private static final float density = 1f;

private void initFog() 
    float[] vertices = 0.8f, 0.8f, 0.8f, 1f;

    ByteBuffer temp = ByteBuffer.allocateDirect(16);
    temp.order(ByteOrder.nativeOrder());   
    FloatBuffer fogColor = temp.asFloatBuffer(); 
    fogColor.put(vertices);
    GL11.glClearColor(0.8f,0.8f,0.8f,1.0f); 
    GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_LINEAR);
    GL11.glFog(GL11.GL_FOG_COLOR, temp.asFloatBuffer());
    GL11.glFogf(GL11.GL_FOG_DENSITY, density);
    GL11.glHint(GL11.GL_FOG_HINT, GL11.GL_FASTEST);
    GL11.glFogf(GL11.GL_FOG_START, 1f);
    GL11.glFogf(GL11.GL_FOG_END, 10000f);


private void initWindow() 
    try 
        Display.setDisplayMode(new DisplayMode(1600, 900));
        Display.create();
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(60f, 1600f / 900f, 3, 100000);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();
        GL11.glEnable(GL11.GL_FOG);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        initFog();
        initParticles();
     catch (LWJGLException e) 
        Display.destroy();
        System.exit(1);
    

从主循环内的 updatePosition 函数调用 angle 参数是视口在 y 轴上的方向,yCpos 是一个介于 -1 和 1 之间的值,用于向上或向下查看。

    GL11.glLoadIdentity();
    GLU.gluLookAt(xpos, ypos, zpos, xpos + (float)Math.cos(angle), ypos+ yCpos, zpos+ (float)Math.sin(angle), 0, 1, 0);

【问题讨论】:

这听起来很不寻常——线性固定函数雾只是眼睛空间深度和雾范围值(即“结束”和“开始”)的函数。相机的方向不应该影响雾的感知密度 - 平移当然会改变物体的外观,但单独旋转不会改变到相机的距离。你能添加一些屏幕截图吗? 您确定在矩阵模式为GL_MODELVIEW 时应用gluLookAt (...)?雾是将观察变换应用于投影矩阵实际上会产生影响的事情之一。通常,如果您使用恒等 ModelView 矩阵,您可以将相机变换应用于投影矩阵,但如果您这样做,一些事情(雾、顶点照明、透视纹理映射等)会搞砸。跨度> 我有同样的问题,我使用的顺序大致是:glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(...); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(...);(我认为应该没问题) 【参考方案1】:

我用一个巨大的四边形绘制地面,现在我用瓷砖绘制地面,问题不再发生。因此,原因仍然很神秘,但问题已经解决了。

【讨论】:

认为我知道为什么会这样。这似乎与相机背后的顶点有关。也许单个大的四边形/三角形(或其顶点之一)被剪裁,因此搞砸了雾计算中使用的深度插值。 我为这个问题苦苦挣扎了很长时间。使用单个巨大的四边形确实是一个问题,因为它的所有顶点从角度来看都是不可见的。更糟糕的是,问题取决于显卡和驱动程序。使用我的 nvidia 卡,在 ubuntu 下,我在使用免费的 nouveau 驱动程序时遇到了这个问题。但是如果我切换到专有驱动程序,问题就消失了。 仅使用 4 个巨大的四边形,每个中心都有一个顶点,完全解决了问题。 这似乎适用于任何驱动程序。 @LGenzelis,这正是我的情况,OP也面临同样的问题。我有一台带有集成英特尔处理器和 NVidia 卡的笔记本电脑。使用英特尔处理器运行该程序时,我遇到了取决于相机的雾问题。使用 NVidia 卡运行它,fog 的工作与预期一样。

以上是关于当我移动或旋转相机时,OpenGL 雾效果会发生变化的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL:相机和对象

在OpenGL中沿对象后面的方向旋转相机

OpenGL相机旋转怪异

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

第三人称相机 OpenGL

着色器中的 OpenGL 法线变换