javascript - 为什么在这个 Webgl 示例中光线在移动
问题描述
这是教科书中的 Goraud 插值和朗伯反射模型的示例。
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]);
然而,在我看来,光也随着球体移动。但是在代码中我找不到灯光是如何移动的。
有人可以指出我们还旋转灯的代码吗?
解决方案
灯不旋转,它固定在一个静态的位置和方向。这里的问题是您似乎不了解法线是什么以及它在计算机图形学中的使用方式。
计算机模型是一系列连接形成“面”(通常是三角形)的“顶点”。当“真实”光被引入场景时,需要额外的信息来确定它应该如何与模型的每个面进行交互,这称为“法线”。法线是一个方向矢量,通常形成一条垂直于面部的线,但它不一定对您的问题很重要。该法线用于计算光与该表面的交互方式。
因此,您有三组数据:顶点、索引(顶点如何组合在一起形成面)和法线(在您的示例中自动计算)。当您开始对模型进行转换(如旋转)但不对在转换之前计算的法线执行类似的转换时,就会出现问题。
让我们想象一下……假设我们有以下金字塔,其中一个法线被绘制来说明问题:
现在,当我们开始旋转金字塔,但我们保持法线方向不变时,我们会看到法线和面之间的角度开始发生变化。
为了使事情按预期工作,我们还需要旋转法线,以便相对于面部的角度不会改变。
光相对于表面法线的角度决定了表面如何被光着色。当您旋转模型时,法线开始指向“随机”方向,这会干扰灯光计算,看起来好像灯光在旋转,但实际上并非如此。
显然,这是对正在发生的事情的一个非常淡化的解释,但它应该让您基本了解什么是法线以及为什么还需要对它们应用转换。
推荐阅读
- ios - iOS 的 MotionLayout
- multithreading - 队列的实现不是线程安全的
- c - 如何强制 gnu ld 使用 -lc 中的符号覆盖我自己的 libc 副本中的符号?
- java - 来自 TextField 的 SimpleIntegerProperty
- javascript - 为脚本添加仅在 Travis CI 中运行而不是在本地运行的权限
- matlab - 无法实例化派生的 MATLAB 类而不会出错
- node.js - Firebase Web Init 错误文件已存在
- javascript - JS - D3 多线时间序列图
- git - 每次提交都会在 git 中创建一个新的树对象吗?
- keras - 在 Keras 中使用 ModelCheckpoint 时的最大递归深度错误