在webgl中转换法线

use*_*rJS 2 opengl-es coordinate-systems webgl coordinate-transformation

我有2点法线云.在webgl画布上渲染点之前,我需要将PointCloud1转换为与PointCloud2相同的坐标空间,并且我有转换矩阵T,(rot,scale,trans),它完美地适用于这些点.我想对法线做同样的事情.阅读了一些教程后,我尝试了这个:

n'=转置(反向(T))*n

我理解这背后的数学,但有些教程提到我应该只采用T中的上3*3矩阵.我不确定我是否应该做

  1. 乘以3*3 T,n = [abc]或
  2. 乘以4*4 T,n = [abc 0].

如果我使用第二个选项,我会得到n'= [a'b'c'd'].我应该将此向量除以d'以使其均匀吗?

Ret*_*adi 6

既然你说你只使用旋转,平移和缩放,你不需要担心这整个反转置的东西.至少与"缩放"一样长,你的意思是统一缩放.如果使用非均匀缩放,则需要特别考虑正常变换(有关非均匀缩放的背景,请参阅我的答案:非均匀缩放的常规矩阵).

通常,左上3×3子矩阵的逆转置用于变换法线.但在这种情况下,左上角的3x3子矩阵仅包含旋转和缩放.旋转和缩放矩阵的逆转置与原始矩阵相同.所以整个反转置计算都是无操作.

严格来说,均匀缩放矩阵的逆转置与原始矩阵不同.但它仍然是一个统一的缩放矩阵,这意味着唯一的区别是得到的法向量的长度.因为一旦涉及缩放,你必须在转换它们之后重新规范化法线,它仍然没有实际的区别.

无论是为法线明确创建单独的3x3矩阵,还是在使用0分量扩展的法向量上使用常规4x4矩阵,都是首选问题.在数学上,结果完全相同.使用4x4矩阵的优点是不会将额外的3x3矩阵传递到着色器更简单.缺点是它可能效率较低,因为您使用比必要的更大的矩阵执行乘法.

实际上,最好的方法IMHO是将一个单独的3x3普通矩阵传递到着色器,并使其仅包含转换的旋转部分,但包含缩放.这样,您可以跳过在应用变换后通常需要重新规范化法线的步骤,因为纯旋转会使矢量的长度保持不变.

在问题的最后部分:如果使用4x4矩阵,请不要除以结果向量的第4个分量.第四个组件将为零,您不希望除以零...