c++ - 如何停止位置灯随相机移动

标签 c++ opengl lighting opengl-compat

当我在我的 openGL 项目中旋转和/或移动相机时,几乎就像有一个聚光灯随之移动,但是我已经将我的 gl 灯设置为定位并给它一个静态位置。

void Lighting::Display()
{
    glPushMatrix();

    glTranslatef(0.f, yoffset, 0.f); // move to start
    glTranslatef(0.f, ceilHeight * scale[0], 0.f);
    DrawLight();

    glDisable(GL_LIGHTING);

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    // Match colour of sphere to diffuse colour of light
    glColor4fv(specular);
    glTranslatef(0.f, -10.0f * scale[1], 0.f);
    glutSolidSphere(5.0f * scale[0], 25, 25);

    glPopAttrib();
    glPopMatrix();
    // Re-enable lighting after light source has been drawn
    glEnable(GL_LIGHTING);

    // Set properties GL_LIGHT0
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
    //glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0001f);

    GLfloat pos[4] = { 0.f, 950.f, 0.f, 1.f };
    glLightfv(GL_LIGHT0, GL_POSITION, pos);

    // enable GL_LIGHT0 with these defined properties
    glEnable(GL_LIGHT0);
}

我希望有一个单一的光源悬卡在场景的中心,光线从它的位置均匀地向各个方向发射 然而,一道光迹似乎是作为聚光灯发出的。

这是一张展示问题的图片:

如您所见,发出了一条奇怪的光线。

最佳答案

当灯光位置设置为 glLightfv(GL_LIGHT0, GL_POSITION, pos) 时,pos 将乘以当前模型 View 矩阵。

Blinn–Phong reflection model的环境光(Ia)、漫射光(Id)和镜面光(Is)的强度为计算如下:

N  ... norlmal vector 
L  ... light vector (from the vertex position to the light) 
V  ... view vector (from the vertex position to the eye)
sh ... shininess

H     = normalize(V + L)
NdotH = max(dot(N, H), 0.0)

Ia    = 1
Id    = max(dot(N, L), 0.0)
Is    = pow(NdotH, sh)

因此环境光 (GL_AMBIENT) 与任何方向无关。

漫射光 (GL_DIFFUSE) 取决于表面的法 vector (N) 和入射光的方向 (L ).它在光照表面上保持不变,与视角无关。

镜面反射光 (GL_SPECULAR) 取决于表面法 vector (N)、光方向 (L)。和观察方向 (V)。当您在场景中移动时,这会导致镜面高光发生变化,因为对光照表面的观察方向会发生变化。

进一步注意,已弃用的 OpenGL 固定函数光照模型中的光照计算是按顶点 (Gouraud Shading) 进行的。计算出的光被插值到图元角之间的区域上。 现代 实现是按片段 (Phong shading) 进行光计算。 Gouraud Shading 会导致天花板上镜面高光的 Blob 外观,并可能增加意想不到的外观。 segmentation 较小和平区的区域可能会改善这一点,但最好的解决方案是切换到现代 OpenGL 编写一个 Shader 并根据您的需要实现每个片段光模型。

关于c++ - 如何停止位置灯随相机移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56152563/

相关文章:

c++ - 为什么要使用 'glad' 库进行 opengl 初始化?

javascript - 在 HTML5/JavaScript 游戏中使用图 block 创建平滑的光照过渡

opengl - 使用 OpenGL 进行延迟渲染,在表面的光照边界附近经历严重的像素化

c++ - SFINAE - 检测类型 T 是否是具有随机访问运算符且对于给定值类型的指针、数组或容器

JavaScriptCore Hello world 每晚

c++ - 如何使用 Unreal 在 C++ 中解析 JSON 文件中的 Array of Array

java - LWJGL 多重纹理不起作用

c++ - 信号量与互斥量

opengl - 影响 HarfBuzz 的 GLFW 窗口创建选项

旋转相机时的OpenGL照明问题