当我在我的 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/