7

我正在学习 OpenGL 图形,并且正在进入阴影。我正在阅读的教程告诉我将法线和光矢量转换为相机空间。为什么是这样?为什么不能只将坐标保存在模型空间中?

对此的后续问题是如何处理模型转换。我无法找到明确的答案。我目前有这个代码:

vec3 normCamSpace = normalize(mat3(V) * normal);"
vec3 dirToLight = (V*vec4(lightPos, 0.0)).xyz;"
float cosTheta = clamp(dot(normCamSpace, dirToLight),0,1);"

V 是视图矩阵或相机矩阵。当模型的位置、旋转和比例发生变化时,我不确定如何移动或编辑灯光。

4

2 回答 2

8

主要原因是,通常您的灯光位置不会在模型空间中给出,而是在世界空间中给出。然而,要使照明有效地工作,所有计算都必须在一个公共空间中进行。在您通常的转换链中,模型局部坐标由模型视图矩阵直接转换到视图空间

p_view = MV · p_local

由于您通常只有一个模型视图矩阵,因此将这个步骤分成类似的东西会很麻烦

p_world = M · p_local
p_view  = V · p_world

为此,您需要将 MV 分开。

由于投影变换传统上是作为一个单独的步骤发生的,因此视图空间是照明计算所基于的自然“共同下层”。它只涉及将您的灯光位置从世界空间转换到视图空间,并且由于灯光位置不是很复杂,这是在 CPU 上完成的,并且预变换的灯光位置作为着色器给出。

请注意,没有什么能阻止您在世界空间中执行照明计算,或对局部空间进行建模。它只需要正确地转换灯光位置。

于 2013-07-06T09:06:46.603 回答
2

我正在学习 OpenGL 图形,并且正在进入阴影。我正在阅读的教程告诉我将法线和光矢量转换为相机空间。为什么是这样?为什么不能只将坐标保存在模型空间中?

实际上,如果你是编写着色器的人,你可以使用任何你想要的坐标空间。IMO 在世界空间中计算光照感觉更“自然”,但那是品味问题。

但是,有两个小细节:

  1. 如果您的对象是蒙皮网格(由骨骼动画的角色模型),您不能“自然地”计算对象空间中的照明。这样的模型将需要世界空间或视图空间。如果您的对象只能平移和旋转(仅限仿射变换),则可以在模型/对象空间中轻松计算光照。我认为一些游戏引擎实际上是这样工作的。
  2. 如果你使用相机空间,你可以在计算镜面高光时减少一个减法。Blinn/phong 镜面反射模型需要矢量到(或来自)眼睛来计算镜面反射因子。在相机空间中,从眼睛到点的向量等于点的位置。这是一个非常小的优化,可能不值得付出努力。
于 2013-07-06T15:29:32.987 回答