can a vertex point vector have more than one normal vector?
i have 8 vertex point vector for cube from i am making a cube now problem i can calculate normals for front and back side perfectly but when it comes to left,right,up,bottom side it can't calculate right normals for these side for instance i go for left side normal than front side normal get disturbed because i am using every point for 3 side of cube. so is there any way to have more than one normal vector for one vertex. Note: i can't repeat the vertex point it is requirement for my project.
Answer by Dray · Nov 26, 2017 at 11:57 PM
Short answer: no.
Long answer: If you want proper shading you have to split the vertices and provide four vertices and four normals for each face. Either that or you have to implement a custom shader that uses some other per-vertex information for shading like the uvs or colors.
Another (sloppy) way would be to make the normals be the average of what the real normals would be but that would give you ugly results with the default shaders.
EDIT found this answer searching an image that explains what I mean: https://answers.unity.com/questions/441722/splitting-up-verticies.html
EDIT2 Adding this link to the unity docs surface shader lightning example page: https://docs.unity3d.com/Manual/SL-SurfaceShaderLightingExamples.html
Right, however there are ways to calculate the normal inside the fragment shader using the partial derivative functions as i explained over here. However depending on the hardware those might not be available or they might lower the performance. Also in some edge cases it might not be perfect as it calculates the x and y direction of the surface on the fly.
You're right @Bunny83, that would work aswell, nice example! But that must be impacting the performance a lot right?
I can't imagine that saving a those few vertices and exchanging them for a whole bunch of per-frame-per-vertex vector calculations will be increasing the framerate in any way on any platform or am I wrong?
When it comes to repetitive or recoursive procedures, I always try to get as much data "baked" as I can to move some stress from the CPU over to the RA$$anonymous$$
i am calculating normals by below methods which is giving me average void calculateNormals($$anonymous$$eshInfo m) { // $$anonymous$$eshInfo m = new $$anonymous$$eshInfo();
int triangleCount = m.faceList.Count/3 ;
// print("triangle count: " + triangleCount);
for (int i = 4; i < triangleCount; i++)
{
int normalTriangleIndex = i * 3;
int pointIndexA = m.faceList[normalTriangleIndex];
int pointIndexB = m.faceList[normalTriangleIndex + 1];
int pointIndexC = m.faceList[normalTriangleIndex + 2];
// print("pointindexA: " + pointIndexA);
Vector3 trianlgeNormal = surfaceNormalFromIndices(m, pointIndexA, pointIndexB, pointIndexC);
//vertexNormal.Insert(pointIndexA, trianlgeNormal);
//vertexNormal.Insert(pointIndexB, trianlgeNormal);
//vertexNormal.Insert(pointIndexC, trianlgeNormal);
vertexNormal[pointIndexA] += trianlgeNormal;
vertexNormal[pointIndexB] += trianlgeNormal;
vertexNormal[pointIndexC] += trianlgeNormal;
}
for (int i = 0; i < vertexNormal.Length; i++)
{
vertexNormal[i].Normalize();
//print("new normals: " + vertexNormal[i]);
}
}
Vector3 surfaceNormalFromIndices($$anonymous$$eshInfo m, int indexA, int indexB, int indexC)
{
// $$anonymous$$eshInfo m = new $$anonymous$$eshInfo();
Vector3 pointA = m.pointList[indexA];
Vector3 pointB = m.pointList[indexB];
Vector3 pointC = m.pointList[indexC];
Vector3 sideAB = pointB - pointA;
Vector3 sideAC = pointC - pointA;
return Vector3.Cross(sideAB, sideAC).normalized;
}
and yeah it is giving me ugly results moreover i can't use four vertices for each face. now i have only one option left which is custom shader but i really don't have any idea about that. so please can you little elaborate it for me. thanks
Allright so I can't give you the full shader you are looking for since I simply don't have that but I hope I can give you some directions. If you plan on implementing your own custom shader, you really should understand the general concepts behind shaders.
Basically, a shader is a little program, that runs on the GPU and that is meant to modify the end-result of your rendered scene meaning vertices, pixels, colors etc. There is different shaders for different purposes and there is multiple shader languages out there, bla bla bla.
In the Unity environment, the shader language you want to take a look at is HLSL and for this specific case you can probably implement a so called SurfaceShader.
Suface shaders are a unique thing in unity since they let you mix vertex(~displacement)- and fragment(~pixel)-shaders in one script. Usually those two jobs would be two seperate scripts.
Take a look at this docs article, maybe it helps you writing your desired surface shader: https://docs.unity3d.com/$$anonymous$$anual/SL-SurfaceShaderLightingExamples.html