[SOLVED] I’m sorry for this in advance… I have a question about uv mapping and normals

I realized that there is this whole huge subject I know -0.125f about… and thought it time I stop being intentionally stupid. So, I start working with custom meshes, seems straightforward enough… I create a box out of 8 vertices assuming I could map the normals like such…



The verts are in this order:

2 3

0 1



6 7

4 5



Of course, the other faces are filled in facing the appropriate way when unshaded.



Next, I want to uv map this… the confusion sets in… I only have 8 verts to work with… I know (or think I know) how to set the normals correctly… buuuut… hmmm??



Anyways, I set something up that I doubt works correctly (I am overly familiar with the coord system on the shader side of things… having trouble translating to this though–0.0,0.0-1.0,1.0–set the appropriate uv coords per vertex) and move on to setting up the normals, like such:



[java]float[] normals = new float[]{

-1, -1, 1,

1, -1, 1,

-1, 1, 1,

1, 1, 1,

-1, -1, -1,

1, -1, -1,

-1, 1, -1,

1, 1, -1

};[/java]



This would have all normals facing in the direction of their corner (outward), which is how I would assume you would set the normal direction if only using 8 vertices. I open up blender and check… yep… the vnormals show this way.



Anyways… long story short. It draws the front side and backside correctly and stretches the rest.



Do I HAVE to use 24 vertices to properly uv map a cube? O.o Or am I just not understanding how to set up the uv coords correctly (which I am confused about to begin with… the whole 8 vertices-if you map the front and back-whats left for the sides, top and bottom… thing)



Help!! Man, sometimes my stupidity catches up with me.



I did do a search on the subject, but didn’t find the answers to the couple questions I have specifically. They are (in no particular order) again:


  1. 24 vertices to properly uv map a cube? Or can I do it with 8?
  2. Is my assumption about the normals, correct? I’m sure there is a way to calculate them, however… I’m a "breaks-things-and-tries-to-fix-them-again-until-I-understand-how-I-broke-it-in-the-first-place-learner so I wanted to see it before I look into the other option.
  3. Is this the first sign of insanity?

The normals will always be a problem if you want it to look flat like a cube. You would definitely need 24 vertexes in that case.



For UV, as long as you want to tile all the way around with every other face a reverse of the previous, then you can still do it with 8. It sounds like your back face has its uv’s flipped. So one face runs “u” 0 - 1 then the next 1 - 0 then the next 0 - 1 and the last 1 - 0 again. So the front and the back both run 0 - 1 from their perspective (ie: if you are facing the side).



And actually, if you want a top and a bottom then they will need their own vertexes. The 8 vertex trick only works for the sides… since all of the top coordinates would have the same “v”… you’d just get the top row of texels stretched over the whole top.



Between normals and everything else, it’s just easier to to have boxes with 24 vertexes.

1 Like

Ok… that was my problem… I flipped the uv coords on the back face and the entire cube mapped properly… however, I assume you mean that 24 vertices are necessary if I want defined edges on the cube? i.e. the shared vertex normals will produce rounded shading?

@t0neg0d said:
Ok.. that was my problem... I flipped the uv coords on the back face and the entire cube mapped properly.... however, I assume you mean that 24 vertices are necessary if I want defined edges on the cube? i.e. the shared vertex normals will produce rounded shading?


You either face them so that some of the faces work (and the others will always be wrong) or you point them at angles... and then your lighting will look rounded. If you want 6 flat faces then you need 6 different face normals... ie: 6 different "faces" with 4 vertexes each.
@pspeed said:
You either face them so that some of the faces work (and the others will always be wrong) or you point them at angles... and then your lighting will look rounded. If you want 6 flat faces then you need 6 different face normals... ie: 6 different "faces" with 4 vertexes each.


Yep... I noticed that right after I posted this... from a distance it looked correct at least. 24 vertices it is.
@pspeed said:
You either face them so that some of the faces work (and the others will always be wrong) or you point them at angles... and then your lighting will look rounded. If you want 6 flat faces then you need 6 different face normals... ie: 6 different "faces" with 4 vertexes each.


One final question...

I did get everything working the way I wanted. It uses templates for each face, use pass in start coord & then add the faces of the box you would like... it rebuilds the buffers and looks neat.

My question has little to do with this, but I noticed an odd number of vertices/triangles... so I ran the scene with nothing attached to it aside from:

1 camera
1 ambient light
1 directional light
0 meshes... nothing... notta.

I see some 456 triangle and 912 vertices shown in the stats... what are these from? When I add in whatever mesh I make out of the testMesh class I am screwing around with... the number goes up by the expected # of verts/triangles.
@t0neg0d said:
I see some 456 triangle and 912 vertices shown in the stats… what are these from?

The stats themselves.
each line of text is a mesh with 2 triangles by letter(there is 14 or 15 if i recall)
1 Like
@nehon said:
The stats themselves.
each line of text is a mesh with 2 triangles by letter(there is 14 or 15 if i recall)


*slaps forehead*

Thanks!
@t0neg0d said:
*slaps forehead*

Thanks!


Those are special Heisenberg triangles. :)
1 Like

Ugh… having issues again.



I got the basic boxel thing working reading in a height map… looked cool! So, I though I would move on to grids.



I have everything working fine… until the normals calculation part. I was pretty sure I understood how to calculate these. I have NO clue why this isn’t working though. Here be my understanding (limited as it is):



You have a vector with 8 surrounding vectors:

1 2 3

8 0 4

7 6 5



You determine the normal for each which I thought was:

(v1-v0).cross(v2-v0).normalize();



do this for each pair (v2,v3… v3,v4… etc… oh this does include v8,v1)



Get a sum of the 8 results and I thought you would have the averaged normal.



What am I missing here? My head is starting to hurt >.<



P.S. I’m just doing this because I was interested in knowing how it works. The existing terrain generator is really cool… and there seem to be a million procedural terrain generators already.

What result do you get and why isn’t it right? You should be able to look at the normal vectors and get an idea about what’s wrong with them.

@pspeed said:
What result do you get and why isn't it right? You should be able to look at the normal vectors and get an idea about what's wrong with them.


Let me grab a screen shot. I would have thought so to, but these really don't make much sense... one sec.

OMG… I can’t stop laughing. I actually thought I knew what I was doing… look at that! HAHAHAHAHA

I’m not sure if this is helpful… but here is what the grid looks like as a wireframe:



@t0neg0d said:
You determine the normal for each which I thought was:
(v1-v0).cross(v2-v0).normalize();

I'm not sure this is correct.
From my understanding for smooth shading, the normal of a vertex is the mean of the surrounding faces normals.
To compute a face normal you just take 2 edges of the face an do a cross product.
Also from the look your of mesh, a vertex is surrounded by 5 faces, so that's 6 edges coming from this point

(v0.cross(v1) + v1.cross(v2) + v2.cross(v3) + .....+ v5.cross(v0)) / 6;

Doing this you will compute face normals several times. If you want it faster you should first compute all faces normals and then just compute the mean for each vertex.

Something similar is done in the TangentBinormalGenerator, if you want to have a look. The triangles are gathered and then their data is used for calculation.

Edit : oh i just realized your v1, v2, ... are vertices, I thought they were vectors :p

I wonder what it would look like with the show normals thing.

I don’t understand the coloring on ShowNormals… but here it is!



Uhhh… maybe there’s another step or something. I’ve never used it before. I’ve just seen it in some tests or something.

@nehon @pspeed

Ok… I got it to work correctly. Apparently, I actually did understand what I read correctly. What I was doing wrong (and I still can’t figure out) was, I was trying to exclude the outside border of the grid so I could recalculate the normals including adjacent tiles. I preset the normals vectors to 0,1,0 and just catch index out of bounds exception (this is temporary until I can figure out how to exclude the borders properly) for the time being to verify if what I was doing was even close to correct. I reaaaaalllly appreciate the help with this. Long story short… it produced these results… which looks correct to me:







You can see that the edges of the grid are wrong due to assuming the missing vertices are point directly up. But at least I was able to translate what I read to something usable… which always makes me happy. Currently, I have the directions calculated backwards and I am using negateLocal() because I was lazy and didn’t want to reverse them while testing, but as soon I change that… I’ll post the code snippet in case someone else has this problem.

1 Like

For anyone who is having issues with calculating normals…



This is an EXTREMELY ugly way of calculating vertex normals… but, I’m posting it anyways because it makes the process (just as) EXTREMELY easy to understand. I’m sure once it clicks… you’ll make something purdy out of this.



This is obviously for setting the normals of a deformed grid (terrain tile)

[java] index = 0;

Vector3f v0 = new Vector3f(),

v1 = new Vector3f(),

v2 = new Vector3f(),

v3 = new Vector3f(),

v4 = new Vector3f(),

v5 = new Vector3f(),

v6 = new Vector3f(),

v7 = new Vector3f(),

v8 = new Vector3f(),

r = new Vector3f();

for (int x = 0; x < gridX; x++) {

for (int y = 0; y < gridY; y++) {

// Assume grid normals are facing upward

v1.set(0,1,0);

v2.set(0,1,0);

v3.set(0,1,0);

v4.set(0,1,0);

v5.set(0,1,0);

v6.set(0,1,0);

v7.set(0,1,0);

v8.set(0,1,0);



// Set center vertex

v0.set(tempVertices[x][y]);

// Grab adjacent vertices in a clockwise fashoin

// Here be the EXTREME of the ugllies…

// I couldn’t figure out how to exclude the grid borders properly

// Actually… that’s a lie. I couldn’t figure out the indexing in the normals buffer

try { v1.set(tempVertices[x-1][y-1]); } catch (Exception ex) { }

try { v2.set(tempVertices[x-1][y]); } catch (Exception ex) { }

try { v3.set(tempVertices[x-1][y+1]); } catch (Exception ex) { }

try { v4.set(tempVertices[x][y+1]); } catch (Exception ex) { }

try { v5.set(tempVertices[x+1][y+1]); } catch (Exception ex) { }

try { v6.set(tempVertices[x+1][y]); } catch (Exception ex) { }

try { v7.set(tempVertices[x+1][y-1]); } catch (Exception ex) { }

try { v8.set(tempVertices[x][y-1]); } catch (Exception ex) { }



// Substract the center vertex from each of the adjacent

v1.subtractLocal(v0);

v2.subtractLocal(v0);

v3.subtractLocal(v0);

v4.subtractLocal(v0);

v5.subtractLocal(v0);

v6.subtractLocal(v0);

v7.subtractLocal(v0);

v8.subtractLocal(v0);



// Get the normalized cross product of each vertex

// and it’s clockwise adjacent vertex

Vector3f r1 = v1.cross(v2).normalize();

Vector3f r2 = v2.cross(v3).normalize();

Vector3f r3 = v3.cross(v4).normalize();

Vector3f r4 = v4.cross(v5).normalize();

Vector3f r5 = v5.cross(v6).normalize();

Vector3f r6 = v6.cross(v7).normalize();

Vector3f r7 = v7.cross(v8).normalize();

Vector3f r8 = v8.cross(v1).normalize();



// Get a sum of the results

r.set(r1);

r.addLocal(r2);

r.addLocal(r3);

r.addLocal(r4);

r.addLocal(r5);

r.addLocal(r6);

r.addLocal(r7);

r.addLocal(r8);



// Append it to the normals float buffer

finNormals[index] = r.x;

index++;

finNormals[index] = r.y;

index++;

finNormals[index] = r.z;

index++;

}

}

[/java]

1 Like