如何计算切线和副法线? [英] How to calculate Tangent and Binormal?

查看:1482
本文介绍了如何计算切线和副法线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谈起凹凸贴图,高光和这几样东西在OpenGL着色语言(GLSL)

Talking about bump mapping, specular highlight and these kind of things in OpenGL Shading Language (GLSL)

我有:

  • 顶点数组(例如{0.2,0.5,0.1,0.2,0.4,0.5,...})
  • 在法线数组(例如{0.0,0.0,1.0,0.0,1.0,0.0,...})
  • 在世界空间中的一个点光源的位置(例如{0.0,1.0,-5.0})
  • 在世界空间观测者的位置(例如{0.0,0.0,0.0})(假设观众是世界的中心)

现在,我怎么能计算副法线和切线每个顶点?我的意思是,有什么公式来计算Binormals,我有什么根据这些信息使用?而关于切线?

Now, how can I calculate the Binormal and Tangent for each vertex? I mean, what is the formula to calculate the Binormals, what I have to use based on those informations? And about the tangent?

我将构建TBN矩阵,无论如何,所以如果你知道一个公式,构建直接基于这些信息的矩阵将是很好的!

I'll construct the TBN Matrix anyway, so if you know a formula to construct the matrix directly based on those informations will be nice!

呵呵,叶,我有纹理坐标也是如此,如果需要的。 正如我说的是GLSL,将是很好的每个顶点的解决方案,我的意思是,其中一个并不需要在同一时间访问多个顶点信息。

Oh, yeh, I have the texture coordinates too, if needed. And as I'm talking about GLSL, would be nice a per-vertex solution, I mean, one which doesn't need to access more than one vertex information at a time.

----更新-----

---- Update -----

我发现这个解决方案:


vec3 tangent;
vec3 binormal;

vec3 c1 = cross(a_normal, vec3(0.0, 0.0, 1.0));
vec3 c2 = cross(a_normal, vec3(0.0, 1.0, 0.0));

if (length(c1)>length(c2))
{
    tangent = c1;
}
else
{
    tangent = c2;
}

tangent = normalize(tangent);

binormal = cross(v_nglNormal, tangent);
binormal = normalize(binormal);

但我不知道这是否是100%正确的。

But I don't know if it is 100% correct.

推荐答案

相关数据输入到你的问题是纹理坐标。切线和副法线是矢量局部平行于物体的表面。与在正常的映射的情况下,它们要描述正常纹理的局部定向。

The relevant input data to your problem are the texture coordinates. Tangent and Binormal are vectors locally parallel to the object's surface. And in the case of normal mapping they're describing the local orientation of the normal texture.

所以,你必须计算的方向(以模型的空间),其中纹理矢量指向。假设你有一个三角形ABC,纹理坐标HKL。这给了我们向量:

So you have to calculate the direction (in the model's space) in which the texturing vectors point. Say you have a triangle ABC, with texture coordinates HKL. This gives us vectors:

D = B-A
E = C-A

F = K-H
G = L-H

现在我们要在切线空间T,U,即

Now we want to express D and E in terms of tangent space T, U, i.e.

D = F.s * T + F.t * U
E = G.s * T + G.t * U

这是线性方程与6个未知数和6方程的系统,它可以写为

This is a system of linear equations with 6 unknowns and 6 equations, it can be written as

| D.x D.y D.z |   | F.s F.t | | T.x T.y T.z |
|             | = |         | |             |
| E.x E.y E.z |   | G.s G.t | | U.x U.y U.z |

反转的FG基收益率

Inverting the FG matrix yields

| T.x T.y T.z |           1         |  G.t  -F.t | | D.x D.y D.z |
|             | = ----------------- |            | |             |
| U.x U.y U.z |   F.s G.t - F.t G.s | -G.s   F.s | | E.x E.y E.z |

连同正常顶点T和U形成局部空间的基础上,称为正切空间,由矩阵描述

Together with the vertex normal T and U form a local space basis, called the tangent space, described by the matrix

| T.x U.x N.x |
| T.y U.y N.y |
| T.z U.z N.z |

从切线空间转化为物体的空间。做照明计算人们需要的这个倒数。随着锻炼一点点发现:

Transforming from tangent space into object space. To do lighting calculations one needs the inverse of this. With a little bit of exercise one finds:

T' = T - (N·T) N
U' = U - (N·U) N - (T'·U) T'

正火矢量T'和U',称他们为切线和副法线,我们得到了矩阵的对象转化成切空间,我们做了灯光:

Normalizing the vectors T' and U', calling them tangent and binormal we obtain the matrix transforming from object into tangent space, where we do the lighting:

| T'.x T'.y T'.z |
| U'.x U'.y U'.z |
| N.x  N.y  N.z  |

我们保存T'和U'在一起的顶点正常的,因为模型的几何形状的一部分(顶点属性),这样我们就可以使用它们的着色器用于照明计算。 我再说一遍:你不能决定在着色器切线和副法线,你precompute并将其保存为模型的几何结构(就像法线)的一部分

We store T' and U' them together with the vertex normal as a part of the model's geometry (as vertex attributes), so that we can use them in the shader for lighting calculations. I repeat: You don't determine tangent and binormal in the shader, you precompute them and store them as part of the model's geometry (just like normals).

(竖条之间的音符上面都是矩阵,从来没有决定,通常使用,而不是括号内的注释竖线。)

(The notation between the vertical bars above are all matrices, never determinants, which normally use vertical bars instead of brackets in their notation.)

这篇关于如何计算切线和副法线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆