- Home /
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
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); }
Answer by Eric5h5 · Oct 31, 2010 at 06:30 PM
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.
That was right. Same amount of triangles, but many more vertices needed. thanks again Eric5h5!
Answer by Eric5h5 · Oct 31, 2010 at 04:01 PM
Maybe the winding order is backwards for the triangle generation, so it's showing the back side of the polygons?
I changed top order and created holes. I added my code and am not sure I did the uvs right.