x


how to shade a mesh created in unity

I used the Mesh class to create a curved wall and it worked well as the shape is exactly what I want. However, the shading is off as you cannot tell the top from the side as I can with a basic cube mesh. I use Vertex-Lit shader and the top of the curved wall is completely flat but does not light up on top like the ther meshes. I use a simple direct light straight down and the camera is looking down from above as well. I might be missing something when i created the curved wall, i did call RecalculateNormals and set the uvs although i dont know which effects the shader. The straight wall is lit like I want. Thank you

alt text

alt text

Edit: here is after swapping triangle order in step commented as top 1. Here is my code. I think I have the vertices and triangles but I dont understand the uvs and if I did that right.

var curveMaterial : Material;

function Start() {
CreateCurvedWall(0,0,9,10,0,45,10,0);
}

function CreateCurvedWall( xc : float , zc : float, r1 : float, r2 :float, sa : int, ea : int, ht : int, btm : int) {
var newCurvedWall : GameObject = new GameObject("Curved Wall");
var newMesh : Mesh = new Mesh();
newCurvedWall.AddComponent(MeshFilter);
newCurvedWall.AddComponent(MeshRenderer);
// make vertices
var steps : int = (ea - sa) / 15;
var cnt : int = 0;
var rads : float = 0.0;
var verts : Vector3[] = new Vector3[(steps+1)*4];
var tris : int[] = new int[12+((steps)*24)]; // 4 for ends and 8 per step X 3
for (var i = 0 ; i < (steps + 1); i++) {
    rads = ((i * 15) * Mathf.Deg2Rad);
    verts[cnt] = Vector3(Mathf.Cos(rads)*r1, btm + ht, Mathf.Sin(rads)*r1); cnt++;
    verts[cnt] = Vector3(Mathf.Cos(rads)*r2, btm + ht, Mathf.Sin(rads)*r2); cnt++;
    verts[cnt] = Vector3(Mathf.Cos(rads)*r1, btm, Mathf.Sin(rads)*r1); cnt++;
    verts[cnt] = Vector3(Mathf.Cos(rads)*r2, btm, Mathf.Sin(rads)*r2); cnt++;
}
newMesh.vertices = verts;
// make uvs ?
var uvs : Vector2[] = new Vector2[newMesh.vertices.Length];
for (i = 0 ; i < uvs.Length; i++) {
    uvs[i] = Vector2 (newMesh.vertices[i].x, newMesh.vertices[i].z);
}
newMesh.uv = uvs;
// make triangles
cnt = 0;
tris[cnt] = 0; cnt++; tris[cnt] = 1; cnt++; tris[cnt] = 2; cnt++; //start edge 1 
tris[cnt] = 1; cnt++; tris[cnt] = 3; cnt++; tris[cnt] = 2; cnt++; //start edge 2 
for (i = 0 ; i < (steps); i++) {
    tris[cnt] = i*4; cnt++; tris[cnt] = (i*4)+6; cnt++; tris[cnt] = (i*4)+4; cnt++; //inner 1 
    tris[cnt] = i*4; cnt++; tris[cnt] = (i*4)+2; cnt++; tris[cnt] = (i*4)+6; cnt++; //inner 2
    tris[cnt] = i*4; cnt++; tris[cnt] = (i*4)+4; cnt++; tris[cnt] = (i*4)+5; cnt++; //top 1 
    tris[cnt] = i*4; cnt++; tris[cnt] = (i*4)+5; cnt++; tris[cnt] = (i*4)+1; cnt++; //top 2
    tris[cnt] = (i*4)+1; cnt++; tris[cnt] = (i*4)+5; cnt++; tris[cnt] = (i*4)+7; cnt++; //outer 1 
    tris[cnt] = (i*4)+1; cnt++; tris[cnt] = (i*4)+7; cnt++; tris[cnt] = (i*4)+3; cnt++; //outer 2
    tris[cnt] = (i*4)+2; cnt++; tris[cnt] = (i*4)+7; cnt++; tris[cnt] = (i*4)+6; cnt++; //bottom 1 
    tris[cnt] = (i*4)+2; cnt++; tris[cnt] = (i*4)+3; cnt++; tris[cnt] = (i*4)+7; cnt++; //bottom 2
}
tris[cnt] = (steps*4); cnt++; tris[cnt] = (steps*4)+2; cnt++; tris[cnt] = (steps*4)+1; cnt++; //last edge 1 
tris[cnt] = (steps*4)+2; cnt++; tris[cnt] = (steps*4)+3; cnt++; tris[cnt] = (steps*4)+1; cnt++; //last edge 2
newMesh.triangles = tris;
newMesh.RecalculateNormals();
newCurvedWall.GetComponent(MeshFilter).mesh = newMesh;
if (curveMaterial) newCurvedWall.renderer.material = curveMaterial;
newCurvedWall.AddComponent(MeshCollider);
}
more ▼

asked Oct 31 '10 at 07:28 AM

Twayne gravatar image

Twayne
235 21 22 34

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

After seeing the code, the winding order is fine. You need to split the vertices so that each side has its own set. The way it is now, the lighting is being smoothed over the entire model. You can see a similar effect if you make a cube in a 3D app, then import it into Unity, changing the normals to "Calculate" and using 180 for the smoothing angle.

In order to get hard edges, you need to split vertices. So that particular wall should have 40 vertices (8 top + 8 bottom + 8 left side + 8 right side + 4 front + 4 back) rather than 16. UVs only affect how textures are mapped to vertices, not lighting.

more ▼

answered Oct 31 '10 at 06:30 PM

Eric5h5 gravatar image

Eric5h5
80.3k 42 132 521

That was right. Same amount of triangles, but many more vertices needed. thanks again Eric5h5!

Nov 01 '10 at 04:37 AM Twayne
(comments are locked)
10|3000 characters needed characters left

Maybe the winding order is backwards for the triangle generation, so it's showing the back side of the polygons?

more ▼

answered Oct 31 '10 at 04:01 PM

Eric5h5 gravatar image

Eric5h5
80.3k 42 132 521

I changed top order and created holes. I added my code and am not sure I did the uvs right.

Oct 31 '10 at 05:36 PM Twayne
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1655
x1361

asked: Oct 31 '10 at 07:28 AM

Seen: 782 times

Last Updated: Oct 31 '10 at 05:29 PM