the face normal initial direction works just like the uv winding order yes, but then it may be flipped on top of the winding order. However theres no such thing as a normal facing the wrong way, not really. having a normal upside down is just as valid as having a normal right side up. It does not denote a error per see, its pretty desirable in many cases. Also this simple winding order rule does not really translate all that well to vertex normals which are a different thing and theres plenty of reasons to have them facing differently then any arithmetic says they should be as theres NO real world counterpart for normal interpolation. Its JUST a trick, so unless your model is tied to some underlying arithmetical formula that can be used to derive the correct normal direction then the polygon HAS NO right solution, so the interpretation of right or wrong is just that a guess, based on what the artist was thinking it might or might not be right.
However if you have normals that are mixed, then this is easy to fix whet you do is you take one polygon and define this as right side up, then expand your search to neighborhood faces and check if their topological outside is facing the same way as the other pieces. But dont make this tool, its allready made and its [polygon] normal -> conform.
Heres a old cgfx shader that used to use as a starting point when i evaluate how well the normals behave out:
float4x4 WProj : WorldViewProjection < string UIWidget="none";>;
float3 ColorWhenFacing: Diffuse
<
string UIName = "Color When Facing";
string UIWidget = "Color";
= {0.8f, 0.0f, 0.0f};
float3 ColorWhenNotFacing: Diffuse
<
string UIName = "Color When Not Facing";
string UIWidget = "Color";
= {0.0f, 0.8f, 0.0f};
struct appdata {
float3 Position : POSITION;
float4 Normal : NORMAL0;
};
struct outVertexData {
float4 HPosition : POSITION;
float4 Color : TEXCOORD0;
};
outVertexData bareVS(appdata IN)
{
outVertexData OUT;
float4 Po = float4(IN.Position.xyz, 1.0);
float4 No = float4(IN.Normal.xyz, 0.0);
float4 Os = float4(ColorWhenFacing.xyz, 1.0);
float4 Norm = mul(WProj, No);
if (Norm.z >=0)
Os = float4(ColorWhenNotFacing.xyz, 1.0);
OUT.Color = Os;
OUT.HPosition = mul(WProj, Po);
return OUT;
}
float4 bareFS(outVertexData IN) : COLOR
{
return IN.Color;
}
technique color{
pass p0 {
VertexProgram = compile arbvp1 bareVS();
AlphaTestEnable= false;
BlendEnable= false;
DepthTestEnable = true;
DepthMask = true;
CullFaceEnable = true;
FragmentProgram = compile arbfp1 bareFS();
}
}
Somebody know the reason?
if the uv crosses in on itself then yes that would be interpreted as a negative area, idea is a bit like definite integrals that cross the 0 line.