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

发布于 2024-12-03 12:16:47 字数 950 浏览 1 评论 0原文

因此,我已经在 OpenGL 学习任务中了解了基本光照。

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

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

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

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

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

似乎假设LightDirection strong>实际上是实际光流矢量的反转。

问题 1:此模型中的 LightDirection 被假定为无限远光源的矢量而不是光方向的矢量,这是否是某种既定的约定,或者这不是一个 ?

问题2:如果LightDirection是在世界坐标而不是眼睛坐标中,那么它应该用法线矩阵还是用法线矩阵进行变换 模型视图矩阵到眼睛坐标?

谢谢为了澄清这些事情!

So, I've gotten to basic lighting in my OpenGL learning quest.

Imagine this simplest lighting model. Each vertex has a position, color, and normal. The shader gets the ModelViewProjection matrix (MVP), Modelview matrix(MV) , and Normal matrix (N) which calculated as (MV-1)T, as well as LightColor and LightDirection as uniforms. The vertex shader performs the lighting calculations - the fragment shader just outputs the interpolated colors.

Now, in every tutorial on this subject I have come across I see two things that puzzle me. First, the LightDirection is already assumed to be in eye coordinates. Second, the output color is calculated as

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

I would expect that the LightDirection should be inversed first, that is, the correct formula I would think is

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

It seems that it is assumed that the LightDirection is actually the reverse of the vector of the actual light flow.

Q1: Is this some sort of established convention that the LightDirection in this model is assumed to be the vector to the infinitely far light source rather than the vector of the light direction or is this not a principal matter and it just so happened that in the tutorials I came across it was so assumed?

Q2: If LightDirection is in world coordinates rather than in eye coordinates, should it be transformed with the normal matrix or the modelview matrix to eye coordinates?

Thanks for clarifying these things!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倒带 2024-12-10 12:16:47

Q1:这是某种既定的约定,即该模型中的 LightDirection 被假定为无限远光源的矢量而不是光方向的矢量,或者这不是一个主要问题,而它只是发生了在我遇到的教程中,它是这么假设的?

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

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

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

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

Q1: Is this some sort of established convention that the LightDirection in this model is assumed to be the vector to the infinitely far light source rather than the vector of the light direction or is this not a principal matter and it just so happened that in the tutorials I came across it was so assumed?

In fixed function OpenGL when supplying the position of the light, the 4th parameter determined if the light was directional or positional. In the case of directional light, the vector supplied points towards the (infinitely far away) light source.

In case of a positional light source, LightDirection is computed per vertex as LightDirection = LightPosition - VertexPosition -- for the sake of simplicity this calculation is done in eye coordinates.

Q2: If LightDirection is in world coordinates rather than in eye coordinates, should it be transformed with the normal matrix or the modelview matrix to eye coordinates?

In fixed function OpenGL the light position supplied through glLighti was transformed by the at call time current modelview matrix. If the light was positional, it got transformed by the usual modelview matrix. In case of a directional light, the normal matrix was used.

思念满溢 2024-12-10 12:16:47

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

两者都不。光有很多种。

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

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

这取决于着色器使用的光照模型。事实上,您可以有一个定向光和多个点光源,所有这些都影响同一个模型。由你决定。

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

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

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

默认的 OpenGL 模型视图矩阵顾名思义:它从模型空间到视图空间(眼睛空间)。它穿过世界空间,但并不止于此。默认的 OpenGL 法线矩阵只是模型视图矩阵的逆转置。所以它们都不会带你进入世界空间。

一般来说,您不应该在世界空间中进行光照(或 GPU 上的任何其他操作),原因如下:在其他地方有最好的解释。为了在世界空间中进行照明,您需要具有转换为世界空间的矩阵。我的建议是正确做法:将光线方向放在眼睛空间中,并将世界空间留给 CPU 代码。

Is this some sort of established convention that the LightDirection in this model is assumed to be the vector to the infinitely far light source rather than the vector of the light direction or is this not a principal matter and it just so happened that in the tutorials I came across it was so assumed?

Neither. There are simply multiple kinds of lights.

A directional light represents a light source that, from the perspective of the scene, is infinitely far away. It is represented by a vector direction.

A positional light represents a light source that has a position in the space of the scene. It is represented by a vector position.

It's up to your shader's lighting model as to which it uses. Indeed, you could have a directional light and several point lights, all affecting the same model. It's up to you.

The tutorials you saw simply used directional lights. Though they probably should have at least mentioned the directional light approximation.

If LightDirection is in world coordinates rather than in eye coordinates, should it be transformed with the normal matrix or the modelview matrix to eye coordinates?

Neither. If the light's direction is in world coordinates, then you need to get the normal into world coordinates as well. It doesn't matter what space you do lighting in (though doing it in clip-space or other non-linear post-projective spaces is rather hard); what matters is that everything is in the same space.

The default OpenGL modelview matrix does what it says: it goes from model space to view space (eye space). It passes through world space, but it doesn't stop there. And the default OpenGL normal matrix is just the inverse-transpose of the modelview matrix. So neither of them will get you to world space.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文