Help on Normals

Despite you are right, this shouldn’t matter (much) in a (semi-)regular grid.

yup but this is only true until the grid is deformed as a cloth, then it become absolutly not regular, I am sure the shading is ok when all the cloth is flat.

in the exemple below “c” & “b” normals must be divided by two, “a” have twice more influence then c & b

EDIT: note that dividing c & b normals also work when grid is flat

In this way you are right. I wouldn’t however calclulate vertex normals in a grid from the “real” faces, but from 4 pyramid faces formed by the 4 surrounding vertices with the target vertex in the center.

[quote]I wouldn’t however calclulate vertex normals in a grid from the “real” faces, but from 4 pyramid faces formed by the 4 surrounding vertices with the target vertex in the center.
[/quote]
I never thought about this, that could be interresting

The angle technic was the final technic I choosen for 3dzzd smoothgroups because the results was far away better then the others tehcnics I tried ( but it is a little more complex to implement). It give the same result on rendering then 3ds max when dealing with smoothgroups, so this is probably a good choice.

NB: … maybe in some special case (not arbitrary mesh => deformed grid by a math function) computing new normals mathematicaly using the deform equation could be better. I mean if you know the 2d function that deform the flat grid you can mathematicaly compute normal of the “waves” at any points and get a nice normal for each vertex, this could also be very efficient.

Your getFaceNormal is wrong. For half=1 you just switch the c-point, effectively reverting winding order. This way all your normals with half=1 point in the wrong direction.

I’m not sure I got it … what shoud I do instead of c = getPosition(row + 1, col + 1); for half = 1?

You have to switch the other two.


	private Vec3 getFaceNormal(int row, int col, int half)
	{
		Vec3 faceNormal = faceNormals[row][col][half];
		if (faceNormal == null)
		{
			Vec3 a = null;
			Vec3 b = null;
			Vec3 c = null;
			if (half == 0)
			{
				a = getPosition(row + 1, col);
				b = getPosition(row, col + 1);
				c = getPosition(row, col);
			}
			else
			{
				a = getPosition(row, col + 1);
				b = getPosition(row + 1, col);
				c = getPosition(row + 1, col + 1);
			}
			Vec3 v1 = Vec3.subtract(b, a);
			Vec3 v2 = Vec3.subtract(c, a);
			faceNormal = v1.crossProduct(v2).toVersor();
			faceNormals[row][col][half] = faceNormal;
		}
		return faceNormal;
	}

Edit: I overlooked the (half==0), so your getFaceNormal should have been correct too…

I was doing that because I was switching the cross product:

 faceNormal = (half == 0) ? v1.crossProduct(v2).toVersor() : v2
	            .crossProduct(v1).toVersor();

in fact I obtain the same result.

Anyway thank you for have checked my code.

Cool, I was having the same problem without shaders.
Then folks from opengl.org explained that this glitch will always be present unless you use shaders.
Now someone is using shader, but the problem persists.
Hence, the problem is likely to be in the shader :slight_smile: