Sign in to follow this  
kubow

[C++] Mesh texturing

Recommended Posts

kubow    100
Hi




I all ready go thru some articles about it, but i can find what i'm looking for. I have a texture that i want to map on mesh continually. So when i reach the end of the texture it will map form beginning. By what i read i have programed the object/tangent space matrix TBN from it i get invert matrix. Than i get the hit point from view ray for which i want the color from texture, so i multiple the hit vector with inverted TBN matrix.

What im doing wrong? How should i map the hit point from triangle to texture.

Now what i have :

Computing the TBN for a triangle:


[code]

void Triangl::SetTBN()
{
TTextureMaping *texture = GetMaterial()->getTexNMap();

// Calculate the vectors from the current vertex to the two other vertices in the triangle
vector v2v1 = v[1] - v[0];
vector v3v1 = v[2] - v[0];

// Calculate c2c1_T and c2c1_B
double c2c1_T = texture->GetVec(1).x - texture->GetVec(0).x;
double c2c1_B = texture->GetVec(1).y - texture->GetVec(0).y;

// Calculate c3c1_T and c3c1_B
double c3c1_T = texture->GetVec(2).x - texture->GetVec(0).x;
double c3c1_B = texture->GetVec(2).y - texture->GetVec(0).y;

double fDenominator = c2c1_T * c3c1_B - c3c1_T * c2c1_B;
if (fDenominator == 0.0f)
{
// We won't risk a divide by zero, so set the tangent matrix to the identity matrix
TBNval.mvTBN[0] = vector(1.0f, 0.0f, 0.0f);
TBNval.mvTBN[1] = vector(0.0f, 1.0f, 0.0f);
TBNval.mvTBN[2] = vector(0.0f, 0.0f, 1.0f);
}
else
{
// Calculate the reciprocal value once and for all (to achieve speed)
double fScale1 = 1.0f / fDenominator;

// T and B are calculated just as the equation in the article states
vector T, B, N;
T = vector((c3c1_B * v2v1.x - c2c1_B * v3v1.x) * fScale1,
(c3c1_B * v2v1.y - c2c1_B * v3v1.y) * fScale1,
(c3c1_B * v2v1.z - c2c1_B * v3v1.z) * fScale1);

B = vector((-c3c1_T * v2v1.x + c2c1_T * v3v1.x) * fScale1,
(-c3c1_T * v2v1.y + c2c1_T * v3v1.y) * fScale1,
(-c3c1_T * v2v1.z + c2c1_T * v3v1.z) * fScale1);

// The normal N is calculated as the cross product between T and B
N = T.Cross(B);
TBNval.mvTBN[0] = vector(T.x, B.x, N.x);
TBNval.mvTBN[0] = vector(T.y, B.y, N.y);
TBNval.mvTBN[0] = vector(T.z, B.z, N.z);

// Calculate the reciprocal value once and for all (to achieve speed)
double fScale2 = 1.0f / ((T.x * B.y * N.z - T.z * B.y * N.x) +
(B.x * N.y * T.z - B.z * N.y * T.x) +
(N.x * T.y * B.z - N.z * T.y * B.x));

// Calculate the inverse if the TBN matrix using the formula described in the article.
// We store the basis vectors directly in the provided TBN matrix: pvTBNMatrix
TBNval.invTBN[0].x = B.Cross(N).x * fScale2;
TBNval.invTBN[0].y = -N.Cross(T).x * fScale2;
TBNval.invTBN[0].z = T.Cross(B).x * fScale2;
TBNval.invTBN[0].Normalize();
TBNval.invTBN[1].x = -B.Cross(N).y * fScale2;
TBNval.invTBN[1].y = N.Cross(T).y * fScale2;
TBNval.invTBN[1].z = -T.Cross(B).y * fScale2;
TBNval.invTBN[1].Normalize();

TBNval.invTBN[2].x = B.Cross(N).z * fScale2;
TBNval.invTBN[2].y = -N.Cross(T).z * fScale2;
TBNval.invTBN[2].z = T.Cross(B).z * fScale2;
TBNval.invTBN[2].Normalize();
}
}


[/code]




To get a texture point im multiple it with the inverted TBN matrix :

[code]
Triangl::TBN TBNval = ((Triangl*)prim)->GetTBN();
vector textel;
vector tmT = TBNval.invTBN[0];
vector tmB = TBNval.invTBN[1];
vector tmN = TBNval.invTBN[2];
textel.x = hit.x*tmT.x+hit.y*tmB.x+hit.z*tmN.x;
textel.y = hit.x*tmT.y+hit.y*tmB.y+hit.z*tmN.y;
textel.z = hit.x*tmT.z+hit.y*tmB.z+hit.z*tmN.z;
return tm->GetBIColor(textel.x, textel.y) ;





bmpColor TTextureMaping::GetBIColor(double v, double u) //bilinear interpolation
{
double nas=0.0;
if(texture == NULL){
LastError = -2;
return bmpDarkColor();
}


// I try to stay in the texture size
nas = u/vTex[eBINOR].Length();
u = nas - int(nas);
if(u<0)
u +=1;
nas = v/vTex[eTANG].Length();
v = nas - int(nas);
if(v<0)
v +=1;

int umin = int(PixNumH * u);
int vmin = int(PixNumW * v);
int umax = umin + 1;
int vmax = vmin + 1;
double ucoef = fabs(PixNumH * u - umin);
double vcoef = fabs(PixNumW * v - vmin);

umin = min(max(umin, 0), PixNumH - 1);
umax = min(max(umax, 0), PixNumH - 1);
vmin = min(max(vmin, 0), PixNumW - 1);
vmax = min(max(vmax, 0), PixNumW - 1);

bmpColor cmc1 = texture[umin + PixNumH * vmin];
cmc1 = (1.0f - vcoef) * (1.0f - ucoef)* cmc1;
bmpColor cmc2 = texture[umax + PixNumH * vmin];
cmc2 = (1.0f - vcoef) * ucoef * cmc2;
bmpColor cmc3 = texture[umin + PixNumW * vmax];
cmc3 = vcoef * (1.0f - ucoef) *cmc3;
bmpColor cmc4 = texture[umax + PixNumW * vmax];
cmc4 = vcoef * ucoef * cmc4;

bmpColor output = cmc1+cmc2+cmc3+cmc4;
return output;
}


[/code]




The result with cube: triangle mesh [-5, 5,-5], [-5, -5, -5], [5, -5, -5], [5, 5, -5], [-5, 5,5], [-5, -5, 5], [5, -5, -5], [5, 5, 5] and texture STangent = [5, 0] TTangent = [0, 5] 512x512pix
[img]http://www.stud.fit.vutbr.cz/~xkubis05/RayTracing/TBNoutput_3.png[/img]





Thanks for any suggestion, im new in this and my math is not so great.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this