- Home /
Confusion about uv mapping
I've been adapting some example code from a site here on how to create a square grid of meshes:
http://studentgamedev.blogspot.com/2013/08/VoxelTutP2.html
Unfortunately, it creates squares so that the texture draws from the upper left of the square to the lower right, rather than unity style coordinate system of drawing lower left to upper right.
I can change my meshes to they are just one unit up, but I'd rather avoid that if I can. So I tried editing this from his sample code:
newVertices.Add( new Vector3 (x , y , 0 ));
newVertices.Add( new Vector3 (x + gridSquareSize , y , 0 ));
newVertices.Add( new Vector3 (x + gridSquareSize , y - gridSquareSize , 0 ));
newVertices.Add( new Vector3 (x , y - gridSquareSize , 0 ));
newTriangles.Add(squareCount*4);
newTriangles.Add((squareCount*4)+1);
newTriangles.Add((squareCount*4)+3);
newTriangles.Add((squareCount*4)+1);
newTriangles.Add((squareCount*4)+2);
newTriangles.Add((squareCount*4)+3);
newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
newUV.Add(new Vector2 (tUnit*texture.x+tUnit, tUnit*texture.y+tUnit));
newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));
to
newVertices.Add( new Vector3 (x , y , 0 ));
newVertices.Add( new Vector3 (x + gridSquareSize , y , 0 ));
newVertices.Add( new Vector3 (x + gridSquareSize , y + gridSquareSize , 0 ));
newVertices.Add( new Vector3 (x , y + gridSquareSize , 0 ));
newTriangles.Add(squareCount*4);
newTriangles.Add((squareCount*4)+1);
newTriangles.Add((squareCount*4)+3);
newTriangles.Add((squareCount*4)+1);
newTriangles.Add((squareCount*4)+2);
newTriangles.Add((squareCount*4)+3);
newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));
newUV.Add(new Vector2 (tUnit*texture.x+tUnit, tUnit*texture.y));
newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
For each square. But it doesn't seem to work, it just shows a blank screen. I know I should be mapping vertices to texture coordinates, but I cannot figure out how it works. Or maybe I am getting it right, but I don't understand triangles correctly..
Ah wait.. I think I got it... I just found out the triange have to be closkwise :/ So I tried this
newTriangles.Add(squareCount*4 + 3);
newTriangles.Add((squareCount*4)+1);
newTriangles.Add((squareCount*4));
newTriangles.Add((squareCount*4)+3);
newTriangles.Add((squareCount*4)+2);
newTriangles.Add((squareCount*4)+1);
And everything appears to be fine. I think
You might want to double check to see if the normals are generating correctly. It looks like you're reversing the direction of the triangles (clockwise to anti-clockwise) which means your triangles will be facing the wrong way.
Also, when you have this problem solved, please submit an answer for your own question!
Excellent work, but I want to clarify the question. The initial issue was that the UVs were flipped horizontally (lower left should be upper left, lower right should be upper right)? If that was the case, I'm guessing modifying the UVs Y calculation. That should be easy if the uv.y is always going to be a value between 0 and 1 :
1f - (tUnit * texture.y)
1f - (tUnit * texture.y) - tUnit
I'm trying to guess your method. So you switched the vertices horizontally, but then the triangles were wound anti-clockwise facing, so they were not visible. This is the way I'm imagining the vertices are with your edit :
3---2
| \ |
0---1
they were originally
0---1
| / |
3---2
I've done that tutorial, and the uvs are the correct way round (just tested the save from the end of part 3 with a uv test image). Here is my code from that script :
void GenerateSquare( int x, int y, Vector2 tex )
{
newVertices.Add( new Vector3( x , y , 0 ) );
newVertices.Add( new Vector3( x + 1, y , 0 ) );
newVertices.Add( new Vector3( x + 1, y - 1, 0 ) );
newVertices.Add( new Vector3( x , y - 1, 0 ) );
newTriangles.Add( (squareCount * 4) + 0 );
newTriangles.Add( (squareCount * 4) + 1 );
newTriangles.Add( (squareCount * 4) + 3 );
newTriangles.Add( (squareCount * 4) + 1 );
newTriangles.Add( (squareCount * 4) + 2 );
newTriangles.Add( (squareCount * 4) + 3 );
newUV.Add( new Vector2( tUnit * tex.x , tUnit * tex.y + tUnit ) );
newUV.Add( new Vector2( tUnit * tex.x + tUnit, tUnit * tex.y + tUnit ) );
newUV.Add( new Vector2( tUnit * tex.x + tUnit, tUnit * tex.y ) );
newUV.Add( new Vector2( tUnit * tex.x , tUnit * tex.y ) );
squareCount ++;
}
So really not sure what is happening your end. Check the values you have for tUnit, tGrass and tStone.
Of course, VesuvianPrime is absolutely correct about your normal facing direction now. But in future, if the problem is with the UV coordinates, I recommend starting with the UV coordinates and seeing how they should be calculated to your needs.
continued from comments :
Just had another thought about your question! Are you talking about how the uv chunks are defined?
with a texture atlas as a 4 x 4 grid :
GSDR
XXXX
XXXX
XXXX
if you set the Vector2 for tStone, it would be ( 1, 3 ) , and you want to say ( 1, 0 ) ?
Again, that is still a matter of setting the UVs, not moving the vertices, rewinding the triangles, and setting the normals (which is luckily done with the inbuilt RecalculateNormals call).
Again, this is where a diagram/drawing really helps out. Using the original vertex positions and triangle windings :
0---1
| / |
3---2
and also remembering Unity maps uvs from the bottom upwards (crazy, right?!)
uv Y 0 and 1 is 1f - (tUnit * tex.y);
uv Y 3 and 2 is 1f - (tUnit * tex.y) - tUnit;
now if you set the texture atlas positino for tStone to be ( 1, 0 ), now the uvs would be :
newUV.Add( new Vector2( tUnit * tex.x , 1f - (tUnit * tex.y) ) );
newUV.Add( new Vector2( tUnit * tex.x + tUnit, 1f - (tUnit * tex.y) ) );
newUV.Add( new Vector2( tUnit * tex.x + tUnit, 1f - (tUnit * tex.y) - tUnit ) );
newUV.Add( new Vector2( tUnit * tex.x , 1f - (tUnit * tex.y) - tUnit ) );
at least, I hope so (untested...)
Hey all, wow people seem interested in this problem! Okay, I think I might've confused some people: The texture mapping is fine on the website, the problem is that, because he starts the vertices from 0,0 to 1,-1, the actually position of the grid in unity is not what I want.
Like I said, I can fix the whole thing by just shifting my mesh chunks up by one unit, but since I just noticed this problem and my code so far is based off of the meshes being in the right place coordinates, I wanted to see if I could make the example work with vertices that go from 0,0 to 1,1 rather than 0,0 to 1,-1
I will check later tonight when I have access to unity if indeed the squares are reversed. I'm not sure if they are yet because my squares so far were symmetrical lol.
Answer by AlucardJay · Sep 12, 2014 at 01:37 PM
continued from comments :
oh, so if you wanted to just push the vertices upwards, it would be moving everything up 1 on the Y of each vertex :
newVertices.Add( new Vector3( x , y + 1, 0 ) );
newVertices.Add( new Vector3( x + 1, y + 1, 0 ) );
newVertices.Add( new Vector3( x + 1, y, 0 ) );
newVertices.Add( new Vector3( x , y, 0 ) );
Oh I see.. so you're saying the reason I had to muck about with the uvs and tris is because I was adding 1 to the wrong y's. Like I said I'll check it out later tonight.
And thanks :D
Ah, so I checked and the triangles weren't reversed, but this is more sensible, so I will probably use this ins$$anonymous$$d.