为什么在这个 Webgl 示例中光线在移动

Why is that the light is moving in this Webgl example

这里是教科书上的 Goraud 插值和 Lambertian 反射模型的例子。

https://jsfiddle.net/zhenghaohe/r73knp0h/6/

然而教科书中有一个愚蠢的错误,在这本书中它说代码应该包含下面这行,而实际上它没有

vec3 light = vec3(uModelViewMatrix * vec4(uLightDirection, 0.0));

奇怪的是这个例子似乎仍然有效。

我知道球体在旋转,因为

mat4.rotate(modelViewMatrix, modelViewMatrix, angle * Math.PI / 180, [0, 1, 0]); 然而,在我看来, 也在随着球体移动。但是在代码中我找不到光线是如何移动的。

谁能告诉我我们也旋转灯的代码?

灯不旋转,它固定在一个静止的位置和方向。这里的问题是你似乎不明白法线是什么以及它在计算机图形学中是如何使用的。

计算机模型是一系列 "vertices" 连接起来形成 "faces"(通常是三角形)。当 "realistic" 光被引入场景时,需要一条额外的信息来确定它应该如何与模型的每个面相互作用,这被称为 "normal." 法线是通常形成的方向向量一条垂直于面的线,但它不一定对您的问题很重要。此法线用于计算光如何与该表面相互作用。

因此您拥有三组数据:顶点、索引(顶点如何组合在一起形成面)和法线(在您的示例中自动计算)。当您开始对模型进行变换(如旋转)但不对变换前计算的法线执行类似变换时,就会出现问题。

让我们想象一下...假设我们有以下金字塔,其中绘制了一条法线来说明问题:

现在当我们开始旋转金字塔,但我们保持法线方向不变时,我们看到法线和面之间的角度开始改变。

为了让事情按预期工作,我们还需要旋转法线,以便相对于面部的角度不会改变。

光线相对于表面法线的角度决定了表面如何被光线遮蔽。当您旋转模型时,法线开始指向 "random" 方向,这会扰乱光计算,看起来好像光在旋转,但事实并非如此。

显然,这是对正在发生的事情的非常淡化的解释,但它应该让您对什么是法线以及为什么还需要对法线应用变换有一个基本的了解。