5

所以,我已经在我的 OpenGL 学习任务中获得了基本的光照。

想象一下这个最简单的光照模型。每个顶点都有一个位置、颜色和法线。着色器获取计算为(MV -1 ) T的 ModelViewProjection 矩阵 ( MVP )、Modelview 矩阵 ( MV ) 和法线矩阵 ( N ) ,以及作为制服的LightColorLightDirection。顶点着色器执行光照计算——片段着色器只输出插值的颜色。

现在,在我遇到的关于这个主题的每个教程中,我看到了两件让我困惑的事情。首先,LightDirection已经假设在眼睛坐标中。其次,输出颜色计算为

max(0, dot(LightDirection, N * normal))*LightColor*Color;

我希望LightDirection应该首先反转,也就是说,我认为正确的公式是

max(0, dot(-LightDirection, N * normal))*LightColor*Color;

似乎假设LightDirection实际上是实际光流的向量的倒数。

Q1:这是某种既定惯例,即该模型中的LightDirection被假定为指向无限远光源的矢量,而不是光方向的矢量,或者这不是主要问题,只是碰巧在我遇到的教程是这么假设的?

Q2:如果LightDirection是世界坐标而不是眼睛坐标,应该用法线矩阵还是模型视图矩阵转换为眼睛坐标?

感谢您澄清这些事情!

4

2 回答 2

2

Q1:这是某种既定惯例,即该模型中的 LightDirection 被假定为指向无限远光源的矢量,而不是光方向的矢量,或者这不是主要问题,只是碰巧在我遇到的教程是这么假设的?

在固定函数 OpenGL 中,当提供光的位置时,第 4 个参数确定光是定向的还是位置的。在定向光的情况下,提供的矢量指向(无限远)光源。

在位置光源的情况下,LightDirection 是按每个顶点计算的LightDirection = LightPosition - VertexPosition——为了简单起见,这个计算是在眼睛坐标中完成的

Q2:如果LightDirection是世界坐标而不是眼睛坐标,应该用法线矩阵还是模型视图矩阵转换为眼睛坐标?

glLighti在固定函数 OpenGL 中,通过调用时当前模型视图矩阵提供的光位置被转换。如果光是位置的,它会被通常的模型视图矩阵转换。在定向光的情况下,使用法线矩阵。

于 2011-09-05T15:55:53.067 回答
1

这是某种既定的约定,即该模型中的 LightDirection 被假定为无限远光源的矢量,而不是光方向的矢量,或者这不是主要问题,而且恰好在教程中我偶然发现它是这么假设的?

两者都不。灯的种类很简单。

定向光表示从场景的角度来看无限远的光源。它由矢量方向表示。

位置光表示在场景空间中具有位置的光源。它由矢量位置表示。

这取决于你的着色器的光照模型,它使用什么。事实上,你可以有一个定向光源和几个点光源,它们都会影响同一个模型。由你决定。

您看到的教程只是使用了定向灯。尽管他们可能至少应该提到定向光近似。

如果 LightDirection 是在世界坐标中而不是在眼睛坐标中,是否应该使用法线矩阵或模型视图矩阵将其转换为眼睛坐标?

两者都不。如果光的方向在世界坐标中,那么您也需要将法线放入世界坐标中。在什么空间进行照明并不重要(尽管在剪辑空间或其他非线性后投影空间中进行照明相当困难);重要的是一切都在同一个空间中。

默认的 OpenGL 模型视图矩阵执行它所说的:它从模型空间到视图空间(眼睛空间)。它穿过世界空间,但并不止于此。而默认的 OpenGL 法线矩阵只是模型视图矩阵的反转置。所以他们都不会让你进入世界空间。

In general, you should not do lighting (or anything else on the GPU) in world space, for reasons best explained elsewhere. In order to do lighting in world space, you need to have matrices that transform into world space. My suggestion would be to do it right: put the light direction in eye space, and leave world space to CPU code.

于 2011-09-05T16:42:39.593 回答