Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 最简单光照模型中的光照方向及其变换_Opengl_Glsl_Lighting - Fatal编程技术网

Opengl 最简单光照模型中的光照方向及其变换

Opengl 最简单光照模型中的光照方向及其变换,opengl,glsl,lighting,Opengl,Glsl,Lighting,所以,在我的OpenGL学习任务中,我学习了基本的照明 想象一下这个最简单的照明模型。每个顶点都有一个位置、颜色和法线。着色器获取ModelViewProjection矩阵(MVP)、Modelview矩阵(MV)和法线矩阵(N),计算为(MV-1)T,以及LightColor和LightDirection。顶点着色器执行照明计算-片段着色器仅输出插值颜色 现在,在我遇到的每一个关于这个主题的教程中,我都看到两件让我困惑的事情。首先,光照方向已经假定在眼睛坐标中。其次,输出颜色计算为 max(0

所以,在我的OpenGL学习任务中,我学习了基本的照明

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

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

max(0, dot(LightDirection, N * normal))*LightColor*Color;
我希望光的方向应该先反转,也就是说,我认为正确的公式是

max(0, dot(-LightDirection, N * normal))*LightColor*Color;
似乎假定光的方向实际上与实际光流的矢量相反

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

问题2:如果LightDirection在世界坐标而不是眼睛坐标中,是否应使用法线矩阵或modelview矩阵将其转换为眼睛坐标

谢谢你澄清这些事情

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

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

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

问题2:如果LightDirection在世界坐标而不是眼睛坐标中,是否应使用法线矩阵或modelview矩阵将其转换为眼睛坐标

在固定函数OpenGL中,通过
glLighti
提供的灯光位置由调用时的当前modelview矩阵转换。如果灯光是位置性的,则会通过通常的modelview矩阵进行变换。如果是平行光,则使用法线矩阵

这个模型中的光方向是无限远光源的矢量,而不是光方向的矢量,这是某种既定的惯例吗?或者这不是一个主要问题,只是碰巧在我遇到的教程中是这样假设的

都不是。这里有多种灯光

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

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

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

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

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

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

默认的OpenGL modelview矩阵按照它所说的做:它从一个模型空间转到另一个视图空间(眼睛空间)。它穿过世界空间,但不停在那里。默认的OpenGL法线矩阵只是modelview矩阵的逆转置。所以它们都不能把你带到世界空间


一般来说,由于某些原因,您不应该在世界空间中进行照明(或GPU上的任何其他操作)。为了在世界空间中进行照明,需要将矩阵转换为世界空间。我的建议是:将光线方向放在眼睛空间,将世界空间留给CPU代码。

非常感谢,datenwolf。关于你对问题2的回答:平行光与法线矩阵相乘是因为没有必要与modelview相乘,还是因为与modelview相乘会产生错误的结果?名称“法线矩阵”有点误导。我最好叫“方向变换矩阵”。这就是(M^-1)^T的特殊之处:适用于方向,而不是位置。Lighthouse 3D有一篇关于它的优秀文章@datenwolf在实现光线跟踪器时,我记得使用光线球体相交实现光线椭球相交。如果通过
M
将球体
s
变换为椭球体
e
,而不是进行
r-e
相交,我将光线变换为,
r'=rM⁻CharStyle
和did
r'-s
交叉口。但是
transformRay
函数只有在我应用时才给出正确的输出