最简单照明模型中的光方向及其转换

时间:2011-09-05 12:33:56

标签: opengl glsl lighting

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

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

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

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

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

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

似乎假设 LightDirection 实际上与实际光流的矢量相反。

Q1:这是一种既定惯例,假设此模型中的 LightDirection 是无限远光源的矢量,而不是光方向的矢量或者是这不是一个主要问题而且恰好发生在我遇到的教程中,它是如此假设的?

Q2:如果LightDirection是世界坐标而不是眼睛坐标,是否应该使用普通矩阵或模型视图矩阵转换为眼睛坐标?

感谢您澄清这些事情!

2 个答案:

答案 0 :(得分:2)

  

Q1:这是一种既定的惯例,假设这个模型中的LightDirection是无限远光源的矢量而不是光方向的矢量,或者这不是一个主要问题,它就是这样发生的在我遇到的教程中,它是如此假设的?

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

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

  

Q2:如果LightDirection是世界坐标而不是眼睛坐标,是否应该使用普通矩阵或模型视图矩阵转换为眼睛坐标?

在固定功能OpenGL中,通过glLighti提供的灯光位置由at at time current currentviewview矩阵转换。如果光是位置的,它会被通常的模型视图矩阵变换。在定向光的情况下,使用了正常矩阵。

答案 1 :(得分:1)

  

这是某种已建立的约定,假设该模型中的LightDirection是无限远光源的矢量而不是光方向的矢量,或者这不是一个主要问题,它恰好发生在我遇到过的教程是如此假设的?

都不是。只有几种灯。

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

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

这取决于着色器的照明模型。实际上,您可以使用定向灯和几个点光源,这些都会影响同一型号。这取决于你。

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

  

如果LightDirection是世界坐标而不是眼睛坐标,是否应该使用普通矩阵或模型视图矩阵转换为眼睛坐标?

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

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

通常,您不应在世界空间中进行照明(或GPU上的任何其他内容),原因为best explained elsewhere。为了在世界空间中进行照明,您需要将矩阵转换为世界空间。我的建议是做正确的事:将光线方向放在眼睛空间,并将世界空间留给CPU代码。