View Full Version : Tangents and binormals

Michail Bespalov

03-15-2001, 12:11 AM

Hi.

Is where way to compute tangents and binormals for each pixel from height map and normal map ?

Thanks.

Michail Bespalov

03-18-2001, 07:10 AM

Hi

What's wrong with my question ?

Is it incorrect,bad formulated ?

Thanks.

... or maybe anyone can't answer it? To me, it seems to be quite OK formulated http://www.opengl.org/discussion_boards/ubb/tongue.gif

davepermen

03-18-2001, 07:49 AM

me, i just wait to get an answer for it, too http://www.opengl.org/discussion_boards/ubb/smile.gif cant help you.. but perhaps matt can help you, he said he understand it, but last time he didnt wanted to explain it to me and just refered to the developer page, but this code there is not understandable in any way, so i wait till today http://www.opengl.org/discussion_boards/ubb/frown.gif

IronPeter

03-18-2001, 09:49 AM

Why do you want to do this calculations at per pixel basis?

DFrey

03-18-2001, 11:26 AM

The problem is, for a point in a 2D surface, there are an infinite number of tangent and binormal vectors. A point on a space curve on the otherhand has unique tangent and binormal vectors. So to get the tangent and binormal vectors at a point of a surface, you need some additional constraint. Such as requiring the tangent vector to be in the direction of increasing x or y. Without the additional constraint there is no sensible way to pick a tangent vector (and hence binormal vector since it is derived by the cross product of the tangent and normal).

[This message has been edited by DFrey (edited 03-18-2001).]

davepermen

03-18-2001, 12:25 PM

ok, letz do it simple:

a simple triangle with 2 texturecoordinates and 3 spacecoordinates and 3 normal-coordinates per vertex. now you can calculate the tangent and binormal to do per pixel lighing effects like bumpmapping simple ( you can transform then your lightsource into texturespace to do this )

like it is done in the demos on nvidia/developer

now how to do this? dont understand them how they do this.. and i think this is what michail wants to know too, not?

andreiga

03-18-2001, 04:54 PM

I'm not good in math, but in another NVidia presentation paper they used another way to compute the 3x3 transformation matrix which makes the light vector to be in texture space (they used the position and texture coordinates of the vertex to construct an equations system based on the plane equation formula). But this maybe the same thing, and i don't know very well (as i said before i'm not good in math).

Michail Bespalov

03-18-2001, 11:15 PM

My question is realy bad formulated,sorry.

I want to compute two textures,one for tangent vectors and second for binormals at

preprocessing time.I have only height map and

calculated normal map,no geometry info.

Thanks.

IronPeter

03-19-2001, 01:49 AM

If you have no geometry info, you can not calculate these vectors in eye space. But you can calculate these vectors in local coordinate system as:

B=normalize(1,0,df/dx);

T1=normalize(0,1,df/dy);

N=normalize(T1 cross B);

T=N cross B.

N is normal, T tangent, B - binormal, T1-aux vector.

Overmind

03-19-2001, 10:59 AM

You simply have to take some random vector V that is not the same or the opposite direction of your normal N.

Then a tangent vector is calculated by N x V. So you need no geometric info, only the normals at each point.

With a heightmap you can safely choose your x or y axis as your vector V because the normals of height maps are never in the XY-plane.

davepermen

03-19-2001, 12:35 PM

and how bout textured triangles where you want the tangent and binormal to get texture space? its simple, i know, but i dont get it, sorry..( for landscapes, i got it, too.. there it is some parametric logic, but how to do this for textured things, where i want that for example tangent is in the u, and then the binormal into v direction, and the normal is normal to them http://www.opengl.org/discussion_boards/ubb/smile.gif how to get this? some simple pseudoccode i would like..

davepermen

03-19-2001, 12:46 PM

How to Generate Texture Space?

For each triangle in the model :

Use the x, y, z position and the s, t bump map

texture coordinates

Create plane equations of the form :

Ax + Bs + Ct + D = 0

Ay + Bs + Ct + D = 0

Az + Bs + Ct + D = 0

Solve for the texture gradients dsdx, dsdy, dsdz,

etc.

Generating Texture Space

Now treat the dsdx, dsdy, and dsdz as a 3D vector

representing the S axis < dsdx, dsdy, dsdz >

Do the same to generate the T axis

Now cross the two to generate the SxT axis this

is the Z or up axis of Texture Space, and is

typically close to parallel with the triangles

normal

If your SxT and the triangle normal point in

opposite directions, the artist applied the texture

backwards have the artist fix this, or negate the

SxT axis

These 3 Axes together make up a 3x3

rotation/ scale matrix

dsdx dtdx SxTx

dsdy dtdy SxTy

dsdz dtdz SxTz

Putting an XYZ model- space vector through this 3x3

matrix produces a vector expressed in local

Texture Space

thats what i dont get completely.. anyone?

andreiga

03-19-2001, 05:15 PM

Originally posted by davepermen:

How to Generate Texture Space?

For each triangle in the model :

Use the x, y, z position and the s, t bump map

texture coordinates

Create plane equations of the form :

Ax + Bs + Ct + D = 0

Ay + Bs + Ct + D = 0

Az + Bs + Ct + D = 0

Solve for the texture gradients dsdx, dsdy, dsdz,

etc.

Generating Texture Space

Now treat the dsdx, dsdy, and dsdz as a 3D vector

representing the S axis < dsdx, dsdy, dsdz >

Do the same to generate the T axis

Now cross the two to generate the SxT axis this

is the Z or up axis of Texture Space, and is

typically close to parallel with the triangles

normal

If your SxT and the triangle normal point in

opposite directions, the artist applied the texture

backwards have the artist fix this, or negate the

SxT axis

These 3 Axes together make up a 3x3

rotation/ scale matrix

dsdx dtdx SxTx

dsdy dtdy SxTy

dsdz dtdz SxTz

Putting an XYZ model- space vector through this 3x3

matrix produces a vector expressed in local

Texture Space

thats what i dont get completely.. anyone?

Because i skipped some high-school classes the only thing i don't know is how to solve those texture gradients, but the rest is easy. If you have any ideas please tell me. BTW, which other part didn't you get it?

sualkdimsch

03-20-2001, 04:45 AM

It took me quite a while but I think thats the way to calculate tangent space per !plane! polygon

(BTW the bumpmaping created with this tangenspace looks ok to me)

What you look for basically are three vectors Pv Pu and N. Were Pv points in the 3D (x,y,z) direction of changing v and

Pu in the direction of changing u. Finally N is just the normal of the polygon which is orthogonal to 2D texture space

(the u and v directions).

You start off with a triangle i.e 3 Points with coordinates:

Pi = (xi, yi, zi), (ui, vi) with ui,vi the texture and xi, yi, zi the spatial coordinates of the vertex.

Now start by calculating a bunch of direction vectors namely calculate:

T1 = (v0,u0)-(v1,u1)

T2 = (v0,u0)-(v2,u2)

V1 = P0 - P1

V2 = P0 - P2

Now the Vi Vectors can be represented in terms of Pv and Pu as:

V1 = Pv*T1v + Pu*T1u

V2 = Pv*T2v + Pu*T2u

For instance the x terms are

V1.x = Pv.x*T1v + Pu.x*T1u

V2.x = Pv.x*T2v + Pu.x*T2u

This a simple linear equation system with two equations for two unknowns namely Pv.x and Pu.x.

The Equations for y and z are analogous.

Solve all these for Pv(.xyz) and Pu(.xyz) together with the polygons normal you have

tangent space for your planar polygon.

Hope that helped

davepermen

03-20-2001, 06:46 AM

Ax + Bs + Ct + D = 0

Ay + Bs + Ct + D = 0

Az + Bs + Ct + D = 0

how do i get those equations? isn't D always zero?

or are here the A, B, C, and D always the same values? ( looks like )

then i have 3 equations and 4 variables, sounds like fun http://www.opengl.org/discussion_boards/ubb/smile.gif

ok, when i got them, what are the texture gradients?

what does dsdx means? the vector is [ dsdx, dsdy, dsdz ] in S direction, what is then T? [ dtdx, dtdy, dtdz ]

thats what i want to know.. answer in two steps would be best, first the equation part, then the gradients..

(btw, please use pseudoccode or pseudovertexprogram code, thats what i most understand http://www.opengl.org/discussion_boards/ubb/smile.gif, cause then i do know what you mean ( like dot( v0, v1 ) or cross( v0, v1 ) ), else i'm sitting here with (v0,v1) and, hm.. yeah, is this perhaps a dotproduct? or a cross.. depending on the math book it could be both http://www.opengl.org/discussion_boards/ubb/smile.gif )

davepermen

03-20-2001, 09:00 AM

As noted by

Peercy [21], transforming an object-space vector into tangent space is done by transforming the vector by the 3x3 matrix

formed by the three vectors Tn, Nn, and Bn. So if LOS is the

object space light vector, the light vector in tangent space LTS

computed as

ϊ ϊ ϊ

ϋ

ω

κ κ κ

λ

=

n(z) n(z) n(z)

y) n( y) n( y) n(

n(x) n(x) n(x)

OS TS

N B T

N B T

N B ιT

L L

dont think it can copies that http://www.opengl.org/discussion_boards/ubb/smile.gif

ok, for clearity:

//V0 = Point in Object Space

//V1 = Point in Texture Space

//T = Tangent

//B = Binormal

//N = Normal

V1.x = T.x * V0.x + B.x * V0.y + N.x * V0.z

V1.y = T.y * V0.x + B.y * V0.y + N.y * V0.z

V1.z = T.z * V0.x + B.z * V0.y + N.z * V0.z

//so all i need is the tangent ( binormal = T x N )

[This message has been edited by davepermen (edited 03-20-2001).]

[This message has been edited by davepermen (edited 03-20-2001).]

davepermen

03-20-2001, 12:47 PM

no one knows how to get the vector in object space, wich is in texture space [1,0] and the one wich is in texture space [0,1], these are the two i need, i think ( normalized, of course ), and the noormal

means i have to get ( in u,v,w coordinates )

[1,0,0]

[0,1,0]

[0,0,1] => this i get, its the normal

how bout the others?

I found the code to get the s and t vectors in one of the Nvidia examples (I think from the Dot3 Bumpmapping Vertex Shader Example from their effects browser). The following is the part to get the s and t vectors.

I do not really understand how it works, but maybe some of you can figure this out.

v0, v1 and v2 are the points of the current triangle, punkt is just german for point.

uTex and vTex are the u and v Texture coordinates from each point.

Lars

// x, s, t Kanten berechnen

edge01 = D3DXVECTOR3( v1.punkt.x - v0.punkt.x, v1.uTex - v0.uTex, v1.vTex - v0.vTex );

edge02 = D3DXVECTOR3( v2.punkt.x - v0.punkt.x, v2.uTex - v0.uTex, v2.vTex - v0.vTex );

D3DXVec3Cross(&cp, &edge01, &edge02);

if ( fabs(cp.x) > SMALL_FLOAT )

{

v0.s.x += -cp.y / cp.x;

v0.t.x += -cp.z / cp.x;

v1.s.x += -cp.y / cp.x;

v1.t.x += -cp.z / cp.x;

v2.s.x += -cp.y / cp.x;

v2.t.x += -cp.z / cp.x;

}

// y, s, t

edge01 = D3DXVECTOR3( v1.punkt.y - v0.punkt.y, v1.uTex - v0.uTex, v1.vTex - v0.vTex );

edge02 = D3DXVECTOR3( v2.punkt.y - v0.punkt.y, v2.uTex - v0.uTex, v2.vTex - v0.vTex );

D3DXVec3Cross(&cp, &edge01, &edge02);

if ( fabs(cp.x) > SMALL_FLOAT )

{

v0.s.y += -cp.y / cp.x;

v0.t.y += -cp.z / cp.x;

v1.s.y += -cp.y / cp.x;

v1.t.y += -cp.z / cp.x;

v2.s.y += -cp.y / cp.x;

v2.t.y += -cp.z / cp.x;

}

// z, s, t

edge01 = D3DXVECTOR3( v1.punkt.z - v0.punkt.z, v1.uTex - v0.uTex, v1.vTex - v0.vTex );

edge02 = D3DXVECTOR3( v2.punkt.z - v0.punkt.z, v2.uTex - v0.uTex, v2.vTex - v0.vTex );

D3DXVec3Cross(&cp, &edge01, &edge02);

if ( fabs(cp.x) > SMALL_FLOAT )

{

v0.s.z += -cp.y / cp.x;

v0.t.z += -cp.z / cp.x;

v1.s.z += -cp.y / cp.x;

v1.t.z += -cp.z / cp.x;

v2.s.z += -cp.y / cp.x;

v2.t.z += -cp.z / cp.x;

}

}

davepermen

03-21-2001, 03:33 AM

ok, i have done some calculations today in school ( while history, i'm a bad boy! http://www.opengl.org/discussion_boards/ubb/smile.gif ), and i got this:

struct vec

{

float x,y,z,u,v; //x,y,z modelspace, u,v texturecoordinates

};

vec calcTangentS( vec p0, vec p1, vec p2 )

{

vec v0 = p1 - p0;

vec v1 = p2 - p0;

float t0 = v1.v / ( v0.u * v1.v - v0.v * v1.u );

float t1 = v0.v / ( v0.v * v1.u - v0.u * v1.v );

return t0 * v0 + t1 * v1;

}

and

vec calcTangentS( vec p0, vec p1, vec p2 )

{

vec v0 = p1 - p0;

vec v1 = p2 - p0;

float t0 = v1.u / ( v0.v * v1.u - v0.u * v1.v );

float t1 = v0.u / ( v0.u * v1.v - v0.v * v1.u );

return t0 * v0 + t1 * v1;

}

can someone test if this is true? i dont have my visual c++ yet, so i cant ( and i have no time.. working afternoon, theatre evening, school morning *peng*

btw, a little crieout:

[[--whas zensured after 5 minutes!--]]

[This message has been edited by davepermen (edited 03-21-2001).]

DFrey

03-21-2001, 06:34 AM

Could you clarify what p0, p1 and p2 are?

davepermen

03-21-2001, 10:49 AM

the three points of my trianle, what else?

i didnt called them v0 to v2..

(v0, v1 and v2 are the points of the current triangle, punkt is just german for point.

uTex and vTex are the u and v Texture coordinates from each point.)

sorry.. bad boy dave, bad boy *pansching itself*

(it?!hm..)

DFrey

03-21-2001, 11:17 AM

Ok, the triangle vertices. I didn't know if that's what they were or if those were just three arbitrary points in the tangent plane.

davepermen

03-21-2001, 11:28 AM

and, is it correct or not? does this possibly know someone while i wait for visual c or do i have to try miself later?

its no problem to wait, but its just a question http://www.opengl.org/discussion_boards/ubb/smile.gif

Powered by vBulletin® Version 4.2.2 Copyright © 2016 vBulletin Solutions, Inc. All rights reserved.