I'm trying to apply a transform to a 3D object in a STL File (without creating a structured mesh object). Here is how I proceed: I read the normals and faces information one by one in the STL file, apply my transform to each vertex and to the face normal and write back the new computed values in another STL file. The vertex are OK in the generated file but my normals are wrong. It seems that I can't just apply my transform to the normal as I do for the vertice. How is that possible??
我正在尝试将变换应用于STL文件中的3D对象(不创建结构化网格对象)。以下是我的工作方式:我在STL文件中逐个读取法线和面部信息,将我的变换应用于每个顶点和面法线,并在另一个STL文件中写回新的计算值。生成的文件中的顶点是OK,但我的法线错了。似乎我不能像往常一样将变换应用于法线。怎么可能?
5 个解决方案
#1
2
You should look at transforming normals.
你应该看看转换法线。
And actually, Jeff, you're only partly correct. For a vector, you're right. But for a normal, which is a bit different in meaning, you have to transform by the upper 3x3, but inversed, and then transposed.
实际上,杰夫,你只是部分正确。对于矢量,你是对的。但是对于正常意义上的意义而言,你必须通过上部3x3进行变换,但是反转,然后进行转换。
#2
2
You can apply pretty much the same transformation for both but keep these two things in mind:
您可以为两者应用几乎相同的转换,但请记住以下两点:
- Normals are directions, so the position part of a 4x4 matrix shouldn't be applied. To avoid applying it you can either format the vector as Vector(x,y,z,0) before multiplying with the matrix, or use a dedicated TransformVector() function to avoid the instructions that will end up multiplying with zero.
- If the matrix you apply contains a scale, your normal will be scaled as well, meaning that, if you do the typical N.L lighting dot product your result will be brighter or darker than it should be. Usually you'd want to re-normalize after applying the transform, or make sure the transform doesn't de-normalize the normal (which is what the inverse-transpose of the matrix is for.)
法线是方向,因此不应该应用4x4矩阵的位置部分。为了避免应用它,你可以在与矩阵相乘之前将矢量格式化为Vector(x,y,z,0),或者使用专用的TransformVector()函数来避免最终乘以零的指令。
如果您应用的矩阵包含一个刻度,您的法线也会缩放,这意味着,如果您使用典型的N.L光点产品,您的结果将比它应该更亮或更暗。通常,您需要在应用变换后重新规范化,或者确保变换不会对法线进行去标准化(这是矩阵的逆转置。)
#3
1
Transforming a vector is different than transforming a point -- you can't apply the transformation, only the rotations.
变换矢量与变换点不同 - 您不能应用变换,只能应用旋转。
#4
1
Quote Rodrigo Lopez: Normals are directions, so the position part of a 4x4 matrix shouldn't really be applied though renormalization will fix it anyway.
引用Rodrigo Lopez:法线是方向,因此4x4矩阵的位置部分不应该真正应用,尽管重整化将无论如何都会修复它。
renormalization will not fix it: suppose the normal is (1,0,0) then translate it with (-2,0,0) => the normal will be (-1,0,0) which is normalized and is wrong, because the normal should stay the same.
重整化不会修复它:假设法线是(1,0,0)然后将其翻译为(-2,0,0)=>法线将是(-1,0,0),这是标准化的并且是错误的,因为正常应该保持不变。
#5
-1
You need to apply the inverse-transpose of your matrix to the normals, instead of using the original matrix.
您需要将矩阵的反转置应用于法线,而不是使用原始矩阵。
Also, you need to treat w-coordinate of the normal as 0 (not 1 as with points) when transforming it.
此外,在转换时,您需要将法线的w坐标视为0(而不是像点一样)。
#1
2
You should look at transforming normals.
你应该看看转换法线。
And actually, Jeff, you're only partly correct. For a vector, you're right. But for a normal, which is a bit different in meaning, you have to transform by the upper 3x3, but inversed, and then transposed.
实际上,杰夫,你只是部分正确。对于矢量,你是对的。但是对于正常意义上的意义而言,你必须通过上部3x3进行变换,但是反转,然后进行转换。
#2
2
You can apply pretty much the same transformation for both but keep these two things in mind:
您可以为两者应用几乎相同的转换,但请记住以下两点:
- Normals are directions, so the position part of a 4x4 matrix shouldn't be applied. To avoid applying it you can either format the vector as Vector(x,y,z,0) before multiplying with the matrix, or use a dedicated TransformVector() function to avoid the instructions that will end up multiplying with zero.
- If the matrix you apply contains a scale, your normal will be scaled as well, meaning that, if you do the typical N.L lighting dot product your result will be brighter or darker than it should be. Usually you'd want to re-normalize after applying the transform, or make sure the transform doesn't de-normalize the normal (which is what the inverse-transpose of the matrix is for.)
法线是方向,因此不应该应用4x4矩阵的位置部分。为了避免应用它,你可以在与矩阵相乘之前将矢量格式化为Vector(x,y,z,0),或者使用专用的TransformVector()函数来避免最终乘以零的指令。
如果您应用的矩阵包含一个刻度,您的法线也会缩放,这意味着,如果您使用典型的N.L光点产品,您的结果将比它应该更亮或更暗。通常,您需要在应用变换后重新规范化,或者确保变换不会对法线进行去标准化(这是矩阵的逆转置。)
#3
1
Transforming a vector is different than transforming a point -- you can't apply the transformation, only the rotations.
变换矢量与变换点不同 - 您不能应用变换,只能应用旋转。
#4
1
Quote Rodrigo Lopez: Normals are directions, so the position part of a 4x4 matrix shouldn't really be applied though renormalization will fix it anyway.
引用Rodrigo Lopez:法线是方向,因此4x4矩阵的位置部分不应该真正应用,尽管重整化将无论如何都会修复它。
renormalization will not fix it: suppose the normal is (1,0,0) then translate it with (-2,0,0) => the normal will be (-1,0,0) which is normalized and is wrong, because the normal should stay the same.
重整化不会修复它:假设法线是(1,0,0)然后将其翻译为(-2,0,0)=>法线将是(-1,0,0),这是标准化的并且是错误的,因为正常应该保持不变。
#5
-1
You need to apply the inverse-transpose of your matrix to the normals, instead of using the original matrix.
您需要将矩阵的反转置应用于法线,而不是使用原始矩阵。
Also, you need to treat w-coordinate of the normal as 0 (not 1 as with points) when transforming it.
此外,在转换时,您需要将法线的w坐标视为0(而不是像点一样)。