如何停止位置灯随相机移动
How to stop positional light moving with camera
当我在我的 openGL 项目中旋转 and/or 移动相机时,它几乎就像有一个聚光灯随之移动,但是我已经将我的 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
乘以当前模型视图矩阵。
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
)取决于表面的法向量(N
)和入射光的方向(L
)。它在光照表面上保持不变,与视角无关。
镜面光 (GL_SPECULAR
) 取决于表面法线向量 (N
)、光方向 (L
)。和观察方向 (V
)。当您在场景中移动时,这会导致镜面高光发生变化,因为对光照表面的观察方向会发生变化。
进一步注意,已弃用的 OpenGL 固定功能光照模型中的光照计算是按顶点进行的 (Gouraud Shading). The calculated light is interpolated on the area, between the the corners of the primitives. A modern implementation would be to do the light calculation per fragment (Phong shading)。
Gouraud Shading 会导致天花板上镜面高光的斑点外观,并可能增加意想不到的外观。细分较小和平区的区域可能会改善这一点,但最好的解决方案是切换到 modern OpenGL 编写 Shader 并根据您的需要实施每个片段光模型。
在设置照明位置之前弹出矩阵。因此,您的灯光位置也始终是您设置的位置。然后,您将其他所有内容乘以我假设的视图矩阵。视图矩阵实质上将世界转换为相机的视图。本质上,相机不会移动,世界会围绕相机移动。由于光线未与此视图矩阵相乘,因此您得到的光线似乎保持相对于相机的恒定位置。
当我在我的 openGL 项目中旋转 and/or 移动相机时,它几乎就像有一个聚光灯随之移动,但是我已经将我的 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
乘以当前模型视图矩阵。
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
)取决于表面的法向量(N
)和入射光的方向(L
)。它在光照表面上保持不变,与视角无关。
镜面光 (GL_SPECULAR
) 取决于表面法线向量 (N
)、光方向 (L
)。和观察方向 (V
)。当您在场景中移动时,这会导致镜面高光发生变化,因为对光照表面的观察方向会发生变化。
进一步注意,已弃用的 OpenGL 固定功能光照模型中的光照计算是按顶点进行的 (Gouraud Shading). The calculated light is interpolated on the area, between the the corners of the primitives. A modern implementation would be to do the light calculation per fragment (Phong shading)。 Gouraud Shading 会导致天花板上镜面高光的斑点外观,并可能增加意想不到的外观。细分较小和平区的区域可能会改善这一点,但最好的解决方案是切换到 modern OpenGL 编写 Shader 并根据您的需要实施每个片段光模型。
在设置照明位置之前弹出矩阵。因此,您的灯光位置也始终是您设置的位置。然后,您将其他所有内容乘以我假设的视图矩阵。视图矩阵实质上将世界转换为相机的视图。本质上,相机不会移动,世界会围绕相机移动。由于光线未与此视图矩阵相乘,因此您得到的光线似乎保持相对于相机的恒定位置。