- Home /
Calculating a Second Set of Normals
I have meshes imported from Blender 2.59 into Unity 3.42, with the importer's "Normals" option set to "Calculate" and a sharp smoothing angle in order to maintain a boxy lighting effect with seams preserved for sharp edges of objects like cubes and flat buildings.
However, there is sometimes still a need for an additional set of normals. For example, shaders that expand and shrink the vertices by moving them along their normals would need them all totally smoothed. Using the importer's calculated seam-split set of normals for this makes the faces break apart along the seams and each move off in a separate direction, which is not what you want.
I'm not sure if you can calculate smoothed normals on the fly in a vertex shader. It would need the normals of all the faces sharing that vertex to average them out, and I don't know if vertex shaders can act on more than 1 vertex at a time, nor if it would be practical performance-wise. Is that possible?
If not, my guess would be that you'd need to have 2 pre-calculated sets of normals - one with the sharper smoothing angle for correct lighting and the other with a full 180-degree smoothing angle for correct movement with the vertex shader. (And if the former set split vertices along seams, then you'd also need to make sure the normals match for the coincident vertices in the latter.)
So the question is, how can one calculate an additional set of normals like this, procedurally or not, with a different smoothing angle, and where can one store it to feed it to the rendering pipeline? It would be nice if you could just define something like "float3 normal2:NORMAL2;
" in your shader's appdata or declare it in BindChannels{}, but there seems to be only one "normal" channel to bind and one MeshFilter.mesh.normals
available on the scripting side. I could imagine a possible hack in which you store it in MeshFilter.mesh.tangents
or MeshFilter.mesh.colors
(using just the first 3 of the 4 vector components), but then you'd give up their respective functionalities which you might also need. Is there a better way?