Cylindrical UV mapping
up vote
2
down vote
favorite
I'm trying to compute UV coordinates in cylindrical coordinates from a set of vertices from a mesh but it's not wrapping properly.
So here what I have so far. Assuming the variable height
and minY
are already computed outside the for loop.
for (int i = 0; i < mesh.numVertices; ++i)
{
float x = mesh.vertexBuffer[i].pos.x;
float y = mesh.vertexBuffer[i].pos.z;
float v = (mesh.vertexBuffer[i].pos.y - minY) / height; // get the ratio
Vec2 circle = glm::normalize(Vec2(x, y));
x = circle.x;
y = circle.y;
float theta = atan2(y, x); // its range is -pi < theta < pi
theta += PI; // make it such that its 0 < theta < 2pi
float u = theta / TWO_PI; // Get ratio;
mesh.vertexBuffer[i].uv = Vec2(u, v);
}
As you can see, the texture image is not wrapping properly as there's this weird strip on it.
Can anyone tell if my derivation for cylinder is correct?
opengl graphics mapping textures
add a comment |
up vote
2
down vote
favorite
I'm trying to compute UV coordinates in cylindrical coordinates from a set of vertices from a mesh but it's not wrapping properly.
So here what I have so far. Assuming the variable height
and minY
are already computed outside the for loop.
for (int i = 0; i < mesh.numVertices; ++i)
{
float x = mesh.vertexBuffer[i].pos.x;
float y = mesh.vertexBuffer[i].pos.z;
float v = (mesh.vertexBuffer[i].pos.y - minY) / height; // get the ratio
Vec2 circle = glm::normalize(Vec2(x, y));
x = circle.x;
y = circle.y;
float theta = atan2(y, x); // its range is -pi < theta < pi
theta += PI; // make it such that its 0 < theta < 2pi
float u = theta / TWO_PI; // Get ratio;
mesh.vertexBuffer[i].uv = Vec2(u, v);
}
As you can see, the texture image is not wrapping properly as there's this weird strip on it.
Can anyone tell if my derivation for cylinder is correct?
opengl graphics mapping textures
1
This is why you need multiple UVs per vertex. The line where the texture wraps around has U = 1 on one side and U = 0 on the other. Also a simple loop might not work because there is no way to differentiate between the above two cases. Consider processing each triangle instead – you can make use of a triangle's spacial continuity to ensure the same in UV space.
– meowgoesthedog
Nov 21 at 9:25
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I'm trying to compute UV coordinates in cylindrical coordinates from a set of vertices from a mesh but it's not wrapping properly.
So here what I have so far. Assuming the variable height
and minY
are already computed outside the for loop.
for (int i = 0; i < mesh.numVertices; ++i)
{
float x = mesh.vertexBuffer[i].pos.x;
float y = mesh.vertexBuffer[i].pos.z;
float v = (mesh.vertexBuffer[i].pos.y - minY) / height; // get the ratio
Vec2 circle = glm::normalize(Vec2(x, y));
x = circle.x;
y = circle.y;
float theta = atan2(y, x); // its range is -pi < theta < pi
theta += PI; // make it such that its 0 < theta < 2pi
float u = theta / TWO_PI; // Get ratio;
mesh.vertexBuffer[i].uv = Vec2(u, v);
}
As you can see, the texture image is not wrapping properly as there's this weird strip on it.
Can anyone tell if my derivation for cylinder is correct?
opengl graphics mapping textures
I'm trying to compute UV coordinates in cylindrical coordinates from a set of vertices from a mesh but it's not wrapping properly.
So here what I have so far. Assuming the variable height
and minY
are already computed outside the for loop.
for (int i = 0; i < mesh.numVertices; ++i)
{
float x = mesh.vertexBuffer[i].pos.x;
float y = mesh.vertexBuffer[i].pos.z;
float v = (mesh.vertexBuffer[i].pos.y - minY) / height; // get the ratio
Vec2 circle = glm::normalize(Vec2(x, y));
x = circle.x;
y = circle.y;
float theta = atan2(y, x); // its range is -pi < theta < pi
theta += PI; // make it such that its 0 < theta < 2pi
float u = theta / TWO_PI; // Get ratio;
mesh.vertexBuffer[i].uv = Vec2(u, v);
}
As you can see, the texture image is not wrapping properly as there's this weird strip on it.
Can anyone tell if my derivation for cylinder is correct?
opengl graphics mapping textures
opengl graphics mapping textures
edited Nov 21 at 8:59
asked Nov 21 at 8:42
shinichi
285
285
1
This is why you need multiple UVs per vertex. The line where the texture wraps around has U = 1 on one side and U = 0 on the other. Also a simple loop might not work because there is no way to differentiate between the above two cases. Consider processing each triangle instead – you can make use of a triangle's spacial continuity to ensure the same in UV space.
– meowgoesthedog
Nov 21 at 9:25
add a comment |
1
This is why you need multiple UVs per vertex. The line where the texture wraps around has U = 1 on one side and U = 0 on the other. Also a simple loop might not work because there is no way to differentiate between the above two cases. Consider processing each triangle instead – you can make use of a triangle's spacial continuity to ensure the same in UV space.
– meowgoesthedog
Nov 21 at 9:25
1
1
This is why you need multiple UVs per vertex. The line where the texture wraps around has U = 1 on one side and U = 0 on the other. Also a simple loop might not work because there is no way to differentiate between the above two cases. Consider processing each triangle instead – you can make use of a triangle's spacial continuity to ensure the same in UV space.
– meowgoesthedog
Nov 21 at 9:25
This is why you need multiple UVs per vertex. The line where the texture wraps around has U = 1 on one side and U = 0 on the other. Also a simple loop might not work because there is no way to differentiate between the above two cases. Consider processing each triangle instead – you can make use of a triangle's spacial continuity to ensure the same in UV space.
– meowgoesthedog
Nov 21 at 9:25
add a comment |
2 Answers
2
active
oldest
votes
up vote
0
down vote
You have to duplicate the start vertex of each disc and to reuse it at the end of the circumference. The start vertex is associated to the texture coordinate U=0 and at the last vertex has to be associated with the texture coordinate U=1.0.
If you don`t to so you would get a transition from the last point on the circumference to the first point, where the last point has a U coordinate near to 1 and ant the first point a coordinate of 0. This cause that the entire texture is squeezed in this small area (flipped along the y axis). This is the "weird strip" you can see on your image.
Create one vertex at the end of the circumference which is equal the start - focus on <=
:
for (int i = 0; i <= mesh.numVertices; ++i)
{
....
}
I don't think it's quite as simple as that - there is no guarantee that the vertices will be in any cyclic order, and the above approach only works for a single line loop.
– meowgoesthedog
Nov 21 at 10:06
@meowgoesthedog Of course I can't see the indices. The indices would have to be adapted. But the principle is as simple as that. This exactly points out the issue. I did this mistake myself, more than once.
– Rabbid76
Nov 21 at 10:09
I meant that your suggestion of a loop likefor (int i = 0; i <= mesh.numVertices; ++i)
might be misleading for OP; although the intention of the example is clear, handling a real 3D mesh like the vase above is somewhat more complex, especially since OP did not specify that the mesh is divided into simple horizontal discs.
– meowgoesthedog
Nov 21 at 10:14
@meowgoesthedog Yes, I agree. But I tried to point out the issue and to give a hint for a possible solution, based on the code I can see in the question.
– Rabbid76
Nov 21 at 10:22
I found an alternative solution. Thx people.
– shinichi
Nov 22 at 12:51
add a comment |
up vote
0
down vote
The contour where the texture wraps around onto itself represents a UV-space discontinuity. Vertices on it belonging to triangles on one side have U = 0
, and on the other U = 1
:
This raises the need for multiple UVs per vertex (imagine if the red and orange vertices were in the same position). It is common for 3D libraries to use a separate UV buffer, with its own set of indices.
Also, it is insufficient to process each vertex individually – there would be no way to differentiate between the
U = 0
andU = 1
cases.
To resolve this, any vertex must instead be viewed as part of the triangle it belongs to.
e.g. in the figure above:
Yellow: the other vertices are on the "RHS" (theta < PI
) of the discontinuity contour (gray), so the highlighted vertex hasU = 0
.
Red: the other vertices are on the "LHS" (theta > PI
), so the highlighted vertex hasU = 1
.
Blue: crosses the contour, so must either be split along the contour or be discarded as invalid (unless you set up texture tiling which is always a source of grief).
Yellow: represents all other cases, and should be processed in the usual manner.
[Code coming soon]
[hopefully]
Appreciate your input and @Rabbid76's. I did suspect it has to do when the u lies on 1 or 0.
– shinichi
Nov 21 at 17:47
@shinichi if you are still looking for a solution I'll post one as soon as I can
– meowgoesthedog
Nov 21 at 18:23
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
You have to duplicate the start vertex of each disc and to reuse it at the end of the circumference. The start vertex is associated to the texture coordinate U=0 and at the last vertex has to be associated with the texture coordinate U=1.0.
If you don`t to so you would get a transition from the last point on the circumference to the first point, where the last point has a U coordinate near to 1 and ant the first point a coordinate of 0. This cause that the entire texture is squeezed in this small area (flipped along the y axis). This is the "weird strip" you can see on your image.
Create one vertex at the end of the circumference which is equal the start - focus on <=
:
for (int i = 0; i <= mesh.numVertices; ++i)
{
....
}
I don't think it's quite as simple as that - there is no guarantee that the vertices will be in any cyclic order, and the above approach only works for a single line loop.
– meowgoesthedog
Nov 21 at 10:06
@meowgoesthedog Of course I can't see the indices. The indices would have to be adapted. But the principle is as simple as that. This exactly points out the issue. I did this mistake myself, more than once.
– Rabbid76
Nov 21 at 10:09
I meant that your suggestion of a loop likefor (int i = 0; i <= mesh.numVertices; ++i)
might be misleading for OP; although the intention of the example is clear, handling a real 3D mesh like the vase above is somewhat more complex, especially since OP did not specify that the mesh is divided into simple horizontal discs.
– meowgoesthedog
Nov 21 at 10:14
@meowgoesthedog Yes, I agree. But I tried to point out the issue and to give a hint for a possible solution, based on the code I can see in the question.
– Rabbid76
Nov 21 at 10:22
I found an alternative solution. Thx people.
– shinichi
Nov 22 at 12:51
add a comment |
up vote
0
down vote
You have to duplicate the start vertex of each disc and to reuse it at the end of the circumference. The start vertex is associated to the texture coordinate U=0 and at the last vertex has to be associated with the texture coordinate U=1.0.
If you don`t to so you would get a transition from the last point on the circumference to the first point, where the last point has a U coordinate near to 1 and ant the first point a coordinate of 0. This cause that the entire texture is squeezed in this small area (flipped along the y axis). This is the "weird strip" you can see on your image.
Create one vertex at the end of the circumference which is equal the start - focus on <=
:
for (int i = 0; i <= mesh.numVertices; ++i)
{
....
}
I don't think it's quite as simple as that - there is no guarantee that the vertices will be in any cyclic order, and the above approach only works for a single line loop.
– meowgoesthedog
Nov 21 at 10:06
@meowgoesthedog Of course I can't see the indices. The indices would have to be adapted. But the principle is as simple as that. This exactly points out the issue. I did this mistake myself, more than once.
– Rabbid76
Nov 21 at 10:09
I meant that your suggestion of a loop likefor (int i = 0; i <= mesh.numVertices; ++i)
might be misleading for OP; although the intention of the example is clear, handling a real 3D mesh like the vase above is somewhat more complex, especially since OP did not specify that the mesh is divided into simple horizontal discs.
– meowgoesthedog
Nov 21 at 10:14
@meowgoesthedog Yes, I agree. But I tried to point out the issue and to give a hint for a possible solution, based on the code I can see in the question.
– Rabbid76
Nov 21 at 10:22
I found an alternative solution. Thx people.
– shinichi
Nov 22 at 12:51
add a comment |
up vote
0
down vote
up vote
0
down vote
You have to duplicate the start vertex of each disc and to reuse it at the end of the circumference. The start vertex is associated to the texture coordinate U=0 and at the last vertex has to be associated with the texture coordinate U=1.0.
If you don`t to so you would get a transition from the last point on the circumference to the first point, where the last point has a U coordinate near to 1 and ant the first point a coordinate of 0. This cause that the entire texture is squeezed in this small area (flipped along the y axis). This is the "weird strip" you can see on your image.
Create one vertex at the end of the circumference which is equal the start - focus on <=
:
for (int i = 0; i <= mesh.numVertices; ++i)
{
....
}
You have to duplicate the start vertex of each disc and to reuse it at the end of the circumference. The start vertex is associated to the texture coordinate U=0 and at the last vertex has to be associated with the texture coordinate U=1.0.
If you don`t to so you would get a transition from the last point on the circumference to the first point, where the last point has a U coordinate near to 1 and ant the first point a coordinate of 0. This cause that the entire texture is squeezed in this small area (flipped along the y axis). This is the "weird strip" you can see on your image.
Create one vertex at the end of the circumference which is equal the start - focus on <=
:
for (int i = 0; i <= mesh.numVertices; ++i)
{
....
}
answered Nov 21 at 9:46
Rabbid76
30.7k112842
30.7k112842
I don't think it's quite as simple as that - there is no guarantee that the vertices will be in any cyclic order, and the above approach only works for a single line loop.
– meowgoesthedog
Nov 21 at 10:06
@meowgoesthedog Of course I can't see the indices. The indices would have to be adapted. But the principle is as simple as that. This exactly points out the issue. I did this mistake myself, more than once.
– Rabbid76
Nov 21 at 10:09
I meant that your suggestion of a loop likefor (int i = 0; i <= mesh.numVertices; ++i)
might be misleading for OP; although the intention of the example is clear, handling a real 3D mesh like the vase above is somewhat more complex, especially since OP did not specify that the mesh is divided into simple horizontal discs.
– meowgoesthedog
Nov 21 at 10:14
@meowgoesthedog Yes, I agree. But I tried to point out the issue and to give a hint for a possible solution, based on the code I can see in the question.
– Rabbid76
Nov 21 at 10:22
I found an alternative solution. Thx people.
– shinichi
Nov 22 at 12:51
add a comment |
I don't think it's quite as simple as that - there is no guarantee that the vertices will be in any cyclic order, and the above approach only works for a single line loop.
– meowgoesthedog
Nov 21 at 10:06
@meowgoesthedog Of course I can't see the indices. The indices would have to be adapted. But the principle is as simple as that. This exactly points out the issue. I did this mistake myself, more than once.
– Rabbid76
Nov 21 at 10:09
I meant that your suggestion of a loop likefor (int i = 0; i <= mesh.numVertices; ++i)
might be misleading for OP; although the intention of the example is clear, handling a real 3D mesh like the vase above is somewhat more complex, especially since OP did not specify that the mesh is divided into simple horizontal discs.
– meowgoesthedog
Nov 21 at 10:14
@meowgoesthedog Yes, I agree. But I tried to point out the issue and to give a hint for a possible solution, based on the code I can see in the question.
– Rabbid76
Nov 21 at 10:22
I found an alternative solution. Thx people.
– shinichi
Nov 22 at 12:51
I don't think it's quite as simple as that - there is no guarantee that the vertices will be in any cyclic order, and the above approach only works for a single line loop.
– meowgoesthedog
Nov 21 at 10:06
I don't think it's quite as simple as that - there is no guarantee that the vertices will be in any cyclic order, and the above approach only works for a single line loop.
– meowgoesthedog
Nov 21 at 10:06
@meowgoesthedog Of course I can't see the indices. The indices would have to be adapted. But the principle is as simple as that. This exactly points out the issue. I did this mistake myself, more than once.
– Rabbid76
Nov 21 at 10:09
@meowgoesthedog Of course I can't see the indices. The indices would have to be adapted. But the principle is as simple as that. This exactly points out the issue. I did this mistake myself, more than once.
– Rabbid76
Nov 21 at 10:09
I meant that your suggestion of a loop like
for (int i = 0; i <= mesh.numVertices; ++i)
might be misleading for OP; although the intention of the example is clear, handling a real 3D mesh like the vase above is somewhat more complex, especially since OP did not specify that the mesh is divided into simple horizontal discs.– meowgoesthedog
Nov 21 at 10:14
I meant that your suggestion of a loop like
for (int i = 0; i <= mesh.numVertices; ++i)
might be misleading for OP; although the intention of the example is clear, handling a real 3D mesh like the vase above is somewhat more complex, especially since OP did not specify that the mesh is divided into simple horizontal discs.– meowgoesthedog
Nov 21 at 10:14
@meowgoesthedog Yes, I agree. But I tried to point out the issue and to give a hint for a possible solution, based on the code I can see in the question.
– Rabbid76
Nov 21 at 10:22
@meowgoesthedog Yes, I agree. But I tried to point out the issue and to give a hint for a possible solution, based on the code I can see in the question.
– Rabbid76
Nov 21 at 10:22
I found an alternative solution. Thx people.
– shinichi
Nov 22 at 12:51
I found an alternative solution. Thx people.
– shinichi
Nov 22 at 12:51
add a comment |
up vote
0
down vote
The contour where the texture wraps around onto itself represents a UV-space discontinuity. Vertices on it belonging to triangles on one side have U = 0
, and on the other U = 1
:
This raises the need for multiple UVs per vertex (imagine if the red and orange vertices were in the same position). It is common for 3D libraries to use a separate UV buffer, with its own set of indices.
Also, it is insufficient to process each vertex individually – there would be no way to differentiate between the
U = 0
andU = 1
cases.
To resolve this, any vertex must instead be viewed as part of the triangle it belongs to.
e.g. in the figure above:
Yellow: the other vertices are on the "RHS" (theta < PI
) of the discontinuity contour (gray), so the highlighted vertex hasU = 0
.
Red: the other vertices are on the "LHS" (theta > PI
), so the highlighted vertex hasU = 1
.
Blue: crosses the contour, so must either be split along the contour or be discarded as invalid (unless you set up texture tiling which is always a source of grief).
Yellow: represents all other cases, and should be processed in the usual manner.
[Code coming soon]
[hopefully]
Appreciate your input and @Rabbid76's. I did suspect it has to do when the u lies on 1 or 0.
– shinichi
Nov 21 at 17:47
@shinichi if you are still looking for a solution I'll post one as soon as I can
– meowgoesthedog
Nov 21 at 18:23
add a comment |
up vote
0
down vote
The contour where the texture wraps around onto itself represents a UV-space discontinuity. Vertices on it belonging to triangles on one side have U = 0
, and on the other U = 1
:
This raises the need for multiple UVs per vertex (imagine if the red and orange vertices were in the same position). It is common for 3D libraries to use a separate UV buffer, with its own set of indices.
Also, it is insufficient to process each vertex individually – there would be no way to differentiate between the
U = 0
andU = 1
cases.
To resolve this, any vertex must instead be viewed as part of the triangle it belongs to.
e.g. in the figure above:
Yellow: the other vertices are on the "RHS" (theta < PI
) of the discontinuity contour (gray), so the highlighted vertex hasU = 0
.
Red: the other vertices are on the "LHS" (theta > PI
), so the highlighted vertex hasU = 1
.
Blue: crosses the contour, so must either be split along the contour or be discarded as invalid (unless you set up texture tiling which is always a source of grief).
Yellow: represents all other cases, and should be processed in the usual manner.
[Code coming soon]
[hopefully]
Appreciate your input and @Rabbid76's. I did suspect it has to do when the u lies on 1 or 0.
– shinichi
Nov 21 at 17:47
@shinichi if you are still looking for a solution I'll post one as soon as I can
– meowgoesthedog
Nov 21 at 18:23
add a comment |
up vote
0
down vote
up vote
0
down vote
The contour where the texture wraps around onto itself represents a UV-space discontinuity. Vertices on it belonging to triangles on one side have U = 0
, and on the other U = 1
:
This raises the need for multiple UVs per vertex (imagine if the red and orange vertices were in the same position). It is common for 3D libraries to use a separate UV buffer, with its own set of indices.
Also, it is insufficient to process each vertex individually – there would be no way to differentiate between the
U = 0
andU = 1
cases.
To resolve this, any vertex must instead be viewed as part of the triangle it belongs to.
e.g. in the figure above:
Yellow: the other vertices are on the "RHS" (theta < PI
) of the discontinuity contour (gray), so the highlighted vertex hasU = 0
.
Red: the other vertices are on the "LHS" (theta > PI
), so the highlighted vertex hasU = 1
.
Blue: crosses the contour, so must either be split along the contour or be discarded as invalid (unless you set up texture tiling which is always a source of grief).
Yellow: represents all other cases, and should be processed in the usual manner.
[Code coming soon]
[hopefully]
The contour where the texture wraps around onto itself represents a UV-space discontinuity. Vertices on it belonging to triangles on one side have U = 0
, and on the other U = 1
:
This raises the need for multiple UVs per vertex (imagine if the red and orange vertices were in the same position). It is common for 3D libraries to use a separate UV buffer, with its own set of indices.
Also, it is insufficient to process each vertex individually – there would be no way to differentiate between the
U = 0
andU = 1
cases.
To resolve this, any vertex must instead be viewed as part of the triangle it belongs to.
e.g. in the figure above:
Yellow: the other vertices are on the "RHS" (theta < PI
) of the discontinuity contour (gray), so the highlighted vertex hasU = 0
.
Red: the other vertices are on the "LHS" (theta > PI
), so the highlighted vertex hasU = 1
.
Blue: crosses the contour, so must either be split along the contour or be discarded as invalid (unless you set up texture tiling which is always a source of grief).
Yellow: represents all other cases, and should be processed in the usual manner.
[Code coming soon]
[hopefully]
answered Nov 21 at 11:02
meowgoesthedog
8,6033823
8,6033823
Appreciate your input and @Rabbid76's. I did suspect it has to do when the u lies on 1 or 0.
– shinichi
Nov 21 at 17:47
@shinichi if you are still looking for a solution I'll post one as soon as I can
– meowgoesthedog
Nov 21 at 18:23
add a comment |
Appreciate your input and @Rabbid76's. I did suspect it has to do when the u lies on 1 or 0.
– shinichi
Nov 21 at 17:47
@shinichi if you are still looking for a solution I'll post one as soon as I can
– meowgoesthedog
Nov 21 at 18:23
Appreciate your input and @Rabbid76's. I did suspect it has to do when the u lies on 1 or 0.
– shinichi
Nov 21 at 17:47
Appreciate your input and @Rabbid76's. I did suspect it has to do when the u lies on 1 or 0.
– shinichi
Nov 21 at 17:47
@shinichi if you are still looking for a solution I'll post one as soon as I can
– meowgoesthedog
Nov 21 at 18:23
@shinichi if you are still looking for a solution I'll post one as soon as I can
– meowgoesthedog
Nov 21 at 18:23
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408154%2fcylindrical-uv-mapping%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
This is why you need multiple UVs per vertex. The line where the texture wraps around has U = 1 on one side and U = 0 on the other. Also a simple loop might not work because there is no way to differentiate between the above two cases. Consider processing each triangle instead – you can make use of a triangle's spacial continuity to ensure the same in UV space.
– meowgoesthedog
Nov 21 at 9:25