在对象空间中是不是正常(从NORMAL语义读取)?

时间:2014-09-01 16:19:10

标签: matrix unity3d shader

将法线从对象空间转换为世界空间时,预定义矩阵_Object2World就像一个魅力:(mul(_Object2World,normal))。旋转和缩放(均匀)通过行和列中的颜色检查元素给出了预期的矩阵,但是为什么有些代码使用法线向左乘以逆矩阵_World2Object进行对象空间转换,这是一个统一版本的东西(I' m使用4.5.2)或法线确实存在于对象空间以外的其他空间中,为什么这两个矩阵不响应非均匀缩放。

1 个答案:

答案 0 :(得分:2)

  

在对象空间中没有法线(从NORMAL语义中读取)

是的。

  

法线确实存在于物体空间以外的其他空间中,并且   为什么这两个矩阵不会对非均匀缩放做出反应。

没有空格是相同的,但在一般情况下(不是统一),非orthogonal matrix不能正确地转换法线。

如果要在一般情况下执行正确的法线变换,则需要使用反向转置矩阵。 (在统一着色器中,这相当于mul(normal,_World2Object)

  

_Object2World就像一个魅力:( mul(_Object2World,normal))。旋转和缩放(均匀)都给出了预期的矩阵   行和列中的颜色检查元素

这有点难以解释(我希望能够正确记住它)。 你可以假设规模始终是统一的因为Unity(至少直到4.x版本。我认为它会在5.x中改变)并不适用于非均匀规模顶点着色器但预先变换网格CPU端。

向着色器提供以下制服:

  • _Object2World:包含包含比例
  • 的世界矩阵
  • unity_Scale:w组件包含统一比例因子的倒数(w = 1/scale
  • _World2Object:包含无比例的逆世界矩阵

为了正常地将法线从物体转换为世界空间,你有3种可能性:

  • 转换缩放的法线float3 worldN = mul((float3x3)_Object2World, SCALED_NORMAL);
  • 如果你在变换后规范化正常情况下你可以避免使用缩放法线(可能这是你的情况,否则AFAIK变换不应该100%正确)
  • 使用逆转置mul(normal,_World2Object)

SCALED_NORMAL以这种方式定义:

#define SCALED_NORMAL (v.normal * unity_Scale.w)