Problem about texture mapping
a42027756 opened this issue · 6 comments
So I tried to accomplish the texture mapping job at the end of Lesson 3, and when I interpolated the uv values, got the color, I get this:
Well, it looks similar to the one in Lesson 3, but slightly different.. This guy's face is not so flat(or smooth?) as the guy in Lesson 3
I want to know if this is a serious problem that if I don't fix it now, it will affect Lessons afterwards and if it is, how can I fix it?
Here's my code:
`void rst::triangle_texture(Vec3f pts[3], Vec2f uvs[3], Vec3f norms[3], float* zbuffer, TGAImage& image, TGAImage& texture, const int& width, float intensity) {
//bounding box
int minx = min(pts[0].x, min(pts[1].x, pts[2].x));
int maxx = max(pts[0].x, max(pts[1].x, pts[2].x));
int miny = min(pts[0].y, min(pts[1].y, pts[2].y));
int maxy = max(pts[0].y, max(pts[1].y, pts[2].y));
for (int i = minx; i <= maxx; ++i) {
for (int j = miny; j <= maxy; ++j) {
Vec3f P(i, j, 0);
Vec2f T(0, 0);
Vec3f N(0, 0, 0);
Vec3f coord = barycentric(pts, P); //returns coord[] containing barycentric coordinates
int w = texture.get_width();
int h = texture.get_height();
//optimization for small black holes (REALLY DISGUSTING)
if (coord.x < -.01 || coord.y < -.01 || coord.z < -.01) continue;
//interpolation
for (int i = 0; i < 3; i++) {
P.z += pts[i].z * coord[i];
T.x += uvs[i].x * coord[i];
//cout << "uv.x : " << T.x << endl;
T.y += uvs[i].y * coord[i];
//cout << "uv.y : " << T.y << endl;
/*N.x += norms[i].x * coord[i];
N.y += norms[i].y * coord[i];
N.z += norms[i].z * coord[i];*/
}
//Texture Sampling
//w *= T.x;
w = (int)(w * T.x);
//cout << "width of the texture: " << w << endl;
h = (int)(h * T.y);
//h *= T.y;
//cout << "height of the texture: " << h << endl;
TGAColor color = texture.get(w, h);
//z-buffering
if (zbuffer[int(P.x + P.y * width)] < P.z) {
zbuffer[int(P.x + P.y * width)] = P.z;
image.set(P.x, P.y, TGAColor(color.r * intensity, color.g * intensity, color.b * intensity));
}`
Please let me know if any other code/information is needed.
it seems that you need to permute your barycentric coordinates, like in this example:
https://github.com/ssloy/tinyrenderer/wiki/Visual-troubleshooting#texturing
it seems that you need to permute your barycentric coordinates, like in this example:
https://github.com/ssloy/tinyrenderer/wiki/Visual-troubleshooting#texturing
Hey, big thanks to you for your reply, but I still don't know understand how this works... I am confused by several problems:
- What does "circular permutation" mean?
- I guess I do have a problem in uv-interpolation. And how is "circular permutation" going to fix that?
this is how I interpolate uvs for now:
Vec3f coord = barycentric(pts, P); //to get barycentric coords
for (int i = 0; i < 3; ++i) {
P.z += pts[i].z * coord[i]; //to interpolate z
T.x += uvs[i].x * coord[i]; //to interpolate uv.x
T.y += uvs[i].y * coord[i]; //to interpolate uv.y
}
Is it that I should not interpolate uvs the way I interpolate z coords?
3. I have run some tests on my barycentric calculations by setting the three vertices in each triangle red, green and blue, and then interpolate the colors. The result looks like this:
Should this indicate that my barycentric interpolation is doing fine?
It would be a great help if I get your reply again!
I think circular permutation means your barycentric coord transforms like this: <a, b, c> -> <b,c,a> -> <c,a,b>.
There exists some correct permutation order that fixes your problem.
Here is my pic for my barycentric coords. You can see the color position is different. I am also using r, g, b orders for my barycentric coords
.
From what I can see, the green and blue positions should be switched. which means you should change your barycentric order a,b,c to a,c,b. R is mapped to a, G is mapped to b, and B is mapped to c. I think you should figure out this problem now. Technically this is not a circular permutation? But another random permutation.
From what I can see, the green and blue positions should be switched. which means you should change your barycentric order a,b,c to a,c,b. R is mapped to a, G is mapped to b, and B is mapped to c. I think you should figure out this problem now. Technically this is not a circular permutation? But another random permutation.
Thank you so much!!! This is exactly where the problem is! By switching the mapping of G and B, it perfectly solves the problem. Never thought that the order of barycentric coordinates would affect anything.
What I did is indeed not a "circular permutation", but changing the order from like(a, b, c) to (a, c, b), which in this case, switched the mapping of Green/Blue color. Hope this can help others who are being through similar situations.
Again, thank you for helping me solve this puzzle that bothered me for a long long time!
Thank you @XiaofanLinUS , did not find time to answer properly.