为什么你使用相机空间而不是模型空间用于法线?

时间:2013-07-06 05:25:29

标签: c++ math opengl

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

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

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

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

2 个答案:

答案 0 :(得分:7)

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

p_view = MV · p_local

由于您通常只有一个模型视图矩阵,因此将这个步骤分成类似

的内容会非常麻烦
p_world = M · p_local
p_view  = V · p_world

为此你需要将MV分开。

由于投影变换传统上是作为一个单独的步骤发生的,因此视图空间是自然的普通低地"基于的照明计算。它只涉及将您的灯光位置从世界转换为视图空间,并且由于灯光位置不是很复杂,因此可以在CPU上进行,并将预转换的灯光位置设置为着色器。

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

答案 1 :(得分:0)

  

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

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

但是,有两个小细节:

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