Wings 3D Development Forum
Anyone else suffer because vertex normals calc wrongly? - Printable Version

+- Wings 3D Development Forum (https://www.wings3d.com/forum)
+-- Forum: Wings 3D (https://www.wings3d.com/forum/forumdisplay.php?fid=1)
+--- Forum: Gripes & Grumbles (https://www.wings3d.com/forum/forumdisplay.php?fid=4)
+--- Thread: Anyone else suffer because vertex normals calc wrongly? (/showthread.php?tid=639)



Anyone else suffer because vertex normals calc wrongly? - ggaliens - 03-27-2014

Anyone else suffer because vertex normals calc wrongly ?

Or is it just me because I work with non-flat faces sometimes ?

The vertex normals appear to be calculated from the face normals which are ill-defined for non-flat faces. But this does not mean that vertex normals should be ill defined ... they should be defined by the edges going out from that vertex ... IMHO.

https://www.youtube.com/watch?v=CwdyeCnyQz4&feature=youtu.be


RE: Anyone else suffer because vertex normals calc wrongly? - ggaliens - 03-28-2014

This MIGHT be better approach for some folks.

Code:
normal(V, #we{}=We) ->
  EL = wings_edge:from_vs([V], We),
  case EL  of
     [_,_] -> normal0(V, We);
     _ -> normal1(V, We)
  end.
        
%% normal(Vertex, We) -> Normal
%%  Calculate the normal for a vertex (based on the normals for all
%%  surrounding faces).
normal0(V, We) ->
    Ns = fold(fun(_, Face, _, A) ->
              [wings_face:normal(Face, We)|A]
          end, [], V, We),
    e3d_vec:norm(e3d_vec:add(Ns)).  
    
    
normal1(V, #we{vp=VPos, es=Etab}=We) ->
    MyAcc = fun(Edge, _, _, A) ->
        #edge{vs=VS,ve=VE}=array:get(Edge,Etab),
        case VS of
            V -> [VE|A];
            _ -> [VS|A]
        end
    end,
    
    Vs = fold(MyAcc, [], V, We),  %% outer verts !
    Len = length(Vs),
    
    MyAcc2 = fun(Idx1, Acc) ->
        Idx2 = (Idx1 + 1) rem Len,
        Pt2 = array:get(lists:nth(Idx2+1,Vs), VPos),
        Pt1 = array:get(lists:nth(Idx1+1,Vs), VPos),
        Pt0 = array:get(V, VPos),
        D1 = e3d_vec:sub(Pt2,Pt0),
        D2 = e3d_vec:sub(Pt1,Pt0),
        Cross0 = e3d_vec:cross(D1, D2),
        Cross = e3d_vec:norm(Cross0),
        [Cross|Acc]
    end,
    
    Ns = lists:foldl(MyAcc2, [], lists:seq(0,Len-1) ),
    N1 = e3d_vec:norm(e3d_vec:add(Ns)),
    N2 = normal0(V,We),
    case  e3d_vec:degrees(N1,N2) > 90.0 of
        true ->  e3d_vec:mul(N1,-1.0);
        false -> N1
    end.



RE: Anyone else suffer because vertex normals calc wrongly? - Arg Arg - 03-28-2014

i was thinking about that.
it sounds interesting!

let me know if i can follow your idea (coz atm iam not able to read the erlang code):

- you calculate the vertex normals by the adjacent edge-normals?

- the result of that should be the same than the standard vertex-normal-per-face
calculation (the smooth vertex normals) with just the difference,
that non-planar n-gons don´t change the vertex normals (coz the sourrounding edges
correct the vertex normal)?
is that right?

if so it is a really good idea, that will improve the shading while modelling!
is that your intention? can i follow you?
perhaps you can tell me more for what it is also good?

ok, you asked if anybody else is suffering from the (so called smooth-vertex) calculation.
so, i have to say if the new calculation don´t change the shading in anyway to the
old vertex-calculation(just drop the non-planar n-gons out of the calculation) it´s good!!!
if the new calculation changing the shading just a little bit in any other way,
it should get a extra-button to call it if needed (CALCULATE VERTEX NORMALS by EDGES) coz
the standard shading is (in practical use) the vertex normal calculation a artist needs.
to create a output that fits perfect to game engines and some render-apps while modelling.

Here you can read some lines from the XNORMAL-Documentation... to prevent artifacts in the
normal-map it has a AVERAGE-NORMAL function. coz some exporters do crazy stuff:

"Using the “smooth normals method” option will calculate each vertex normal using the
normals of the adjacent triangle faces,
which is much better for the normalmap computation and will reduce possible seams.
xNormal can automatically average normals so you won't need to export the normals neither in the high
polygon model neither in the low polygon model.
However, you can export your custom-defined per-vertex normals and use them in xNormal selecting the
option “Use exported normals”, but I don't recommend it unles you are are VERY experienced artist. Also,
exporting vertex normals with your model more disk/memory space will be required.

...and here some lines from the old BLENDER 2.4 doc:

"Technically, in a 3D space, only faces have normals
(the normal of a surface at any point is the vector perpendicular to the plane which is tangential to the surface at that point).
However, it is sometime useful to have normals for vertices, and even edges – the later being interpolated from their two vertex ones.
There are two cases for vertex normals:
If the vertex pertains to one or more faces, its normal is the interpolated value
of all the normals of these faces.
If the vertex does not pertain to any face, its normal is aligned with the line
from the object’s center passing through this vertex."


RE: Anyone else suffer because vertex normals calc wrongly? - ggaliens - 03-29-2014

"- you calculate the vertex normals by the adjacent edge-normals?"

No ... just from the directed edges themselves. They ARE the normals.

I saw some things that alluded to possibility that faces should be triangulated before calculations of vertex normal. But that seems wrong also.

Use the FACE normals ONLY IF the vertex is "isolated" with only two edges. Use all edges as normals (NOT EDGE NORMALS) if the vertex is not isolated. The result is nice.