Monday, November 30, 2009

Seams might be handled!

Without seams handled:
With seams handled:
Now with a 3x3 blur, not position dependent:

Dilated seams

Seams are starting to look better:
I've switched back to GL_NEAREST for the texture filtering and implemented my own dilating filter that uses the max value from the texels in a 3x3 area as the fragment color. I'm not sure if this is correct, but I'll move ahead as if it is.

Seams and roundoff error?

I decided to check some of the texture coordinates for the opposite seam directly and see if they mapped to Frank. Some did, some did not. Then moved around the tex coords that mapped to black around by 1 pixel and found that they started mapping to Frank.

This lead to the realization that I was using GL_NEAREST for the texture filtering and not GL_LINEAR. Switching to GL_LINEAR gives the following:This still isn't what I'd expect to see, but at least I know that my seam finding algorithm is probably working correctly.

Continuing seam problems

I'm continuing to have problems with seams.
In this case, Frank is texture baked as a flat red image. I believe that all of the seams should show up as the same color that was used for Frank, ie, the seams should all be red.

In this case, the fragment shader is set up to discover when the resulting color is black and set the seam color to so darker red so that it is obvious what is missing. It is easy to see that a bunch of the information is not transported across to the matching seam.

It looks to me like the tex coords for grabbing the data from the other side of the seam are wrong or are mapping to black spaces.

Here's my code:

//----------------------------------------------------------------------
// Find seams in the object
//----------------------------------------------------------------------
void OBJModel::findSeams(void)
{
// Seams lie along triangle edges. For each triangle, there are
// three possible seams (v0,v1), (v0,v2) and (v1,v2)
//
// Those lines might be seams if each of the vertices has more than
// one texture coordinate.
for(GLuint tri = 0; tri < _triangles.size(); tri++)
{
// Make a convenient copy of the vertex and texcoord indices
GLuint v[3];
GLuint t[3];

for(int i = 0; i < 3; i++)
{
v[i] = _triangles[tri].vertex(i);
t[i] = _triangles[tri].texCoord(i);
}

Seam sm;

// Find any matching seams for line segment (v0, v1)
sm.v0 = v[0]; sm.v1 = v[1]; sm.t0a = t[0]; sm.t1a = t[1];
findMatchingSeams(sm, tri);

// Find any matching seams for line segment (v0, v2)
sm.v0 = v[0]; sm.v1 = v[2]; sm.t0a = t[0]; sm.t1a = t[2];
findMatchingSeams(sm, tri);

// Find any matching seams for line segment (v1, v2)
sm.v0 = v[1]; sm.v1 = v[2]; sm.t0a = t[1]; sm.t1a = t[2];
findMatchingSeams(sm, tri);
}

cout << "Seams: " << _seams.size() << endl;
cout << "Duplicate vertices: " << _duplicateVertices.size() << endl;
}


//----------------------------------------------------------------------
// Find any matching seams for a line segment
//----------------------------------------------------------------------
void OBJModel::findMatchingSeams(Seam sm0, GLuint noTri)
{
// Both of the vertices need to have more than 1 tex coord
// for this to be a seam
if(numTexCoords(sm0.v0) <= 1 || numTexCoords(sm0.v1 <= 1))
return;

// Find triangles with the same vertex indices
for(GLuint tri = 0; tri < _triangles.size(); tri++)
{
// If this triangle contains these two vertices
if(tri != noTri &&
_triangles[tri].hasVertex(sm0.v0) &&
_triangles[tri].hasVertex(sm0.v1))
{
// Make a copy of the potential seam
Seam sm(sm0);
bool found0 = false;
bool found1 = false;

// Find the tex coords in the matching seam
for(int i = 0; i < 3; i++)
{
// If vertex index 0 matches vertex index i,
// get the texture coord on the other side of the seam
if(sm.v0 == _triangles[tri].vertex(i))
{
found0 = true;
sm.t0b = _triangles[tri].texCoord(i);
}

// If vertex index 1 matches vertex index i,
// get the texture coord on the other side of the seam
if(sm.v1 == _triangles[tri].vertex(i))
{
found1 = true;
sm.t1b = _triangles[tri].texCoord(i);
}
}

// This shouldn't happen and in practice I haven't seen it happen, but
// check anyways
if(!found0 && !found1)
{
cout << "Found a seam but no matching texcoords" << endl;
}

// If the tex coords on the other triangle are exactly the same,
// then this isn't a seam. Removing this check results in an image
// that appears exactly the same as the one above
if(!(sm.t0a == sm.t0b && sm.t1a == sm.t1b))
{
// Add the duplicate vertices
_duplicateVertices.insert(sm.v0);
_duplicateVertices.insert(sm.v1);

// Add this seam to the list
_seams.push_back(sm);
}
}
}
}

Saturday, November 28, 2009

Friday, November 27, 2009

Drawing all triangles in texture space

Here's all the triangles drawn in texture space: Notice that the seams aren't necessarily straight. I've been assuming that the triangles would form a nice seam all the way around the model, but it looks like that isn't true. Do I need to match up vertices between different triangles to make the seams?

Duplicate vertices

Drawing the seams w/ duplicate vertices:
What's up with those duplicate vertices all over the place? They should be on the seams.