Archived

This topic is now archived and is closed to further replies.

brewski

Which is the fastest way of calcing point normals?

Recommended Posts

I''ve always used this method, but it''s very slow. Adding surfaceNormals of the polys surrounding the vertex, dividing by nrOfPolysSurrounding and normalizing. I set up a lookup-table with indexes to surrounding polys for each vertex.

Share this post


Link to post
Share on other sites
the method you use for calculating normals is well done
in my experience i have found a way of storing information
for a single vertex , normally i use this structure

typedef struct
{
float x,y,z; // coordinate of point in space
float r,g,b,alpha; // color components
float nx,ny,nz; // normal
float t,s; // texture coordintates
};

you compute the normals aas you are doing right now, then
fill the nx,ny,nz values for each relevant point index,
when you need to retrieve the normal just use the index you are using to access the point''s coordinaes in space.

Share this post


Link to post
Share on other sites
set all normals to 0,0,0
for each face, calculate its normal, and add this to the the 3 normals of the 3 vertices building the face

normalize them all..

that way you get them in O(n), and you get them even with having normals more looking to big faces than to small faces (makes more sence if you take a shit of paper)

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
V71-> Thanks for the reply, No appologies needed, gave birth to some new ideas actually.

Davepermen->That''s a faster method than i''ve been using for sure.

Improvement of your method would require a faster calcing of the
surface normal, right?, or is there some other way to do it all?



Share this post


Link to post
Share on other sites
well.. my method uses one crossproduct per face, and one sqrt per vertex (and a lot of additions)

crossproduct can''t be optimized (except you want to code the whole solution in assembler with SSE or 3DNOW instructions)

sqrt _can_ be optimized, and if you say pleaseplease, i''ll post the code for a faster normalization-sqrt (rsq x = 1/sqrt x)

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
Please do. I''d love to see that - and probably others too.
I got source for high or low precision fast fixed point sqrt :

I did''nt write it, it''s written by ''Night Stalker'', from a doc named fpt1, I leeched it from somewhere, can''t remember.
It''s for Watcom compiler though, looks a bit weird:

#pragma aux FixedSqrtLP = \
" xor eax, eax" \
" mov ebx, 40000000h" \
"sqrtLP1: mov edx, ecx" \
" sub edx, ebx" \
" jl sqrtLP2" \
" sub edx, eax" \
" jl sqrtLP2" \
" mov ecx,edx" \
" shr eax, 1" \
" or eax, ebx" \
" shr ebx, 2" \
" jnz sqrtLP1" \
" shl eax, 8" \
" jmp sqrtLP3" \
"sqrtLP2: shr eax, 1" \
" shr ebx, 2" \
" jnz sqrtLP1" \
" shl eax, 8" \
"sqrtLP3: nop" \
parm caller [ecx] \
value [eax] \
modify [eax ebx ecx edx];

#pragma aux FixedSqrtHP = \
" xor eax, eax" \
" mov ebx, 40000000h" \
"sqrtHP1: mov edx, ecx" \
" sub edx, ebx" \
" jb sqrtHP2" \
" sub edx, eax" \
" jb sqrtHP2" \
" mov ecx,edx" \
" shr eax, 1" \
" or eax, ebx" \
" shr ebx, 2" \
" jnz sqrtHP1" \
" jz sqrtHP5" \
"sqrtHP2: shr eax, 1" \
" shr ebx, 2" \
" jnz sqrtHP1" \
"sqrtHP5: mov ebx, 00004000h" \
" shl eax, 16" \
" shl ecx, 16" \
"sqrtHP3: mov edx, ecx" \
" sub edx, ebx" \
" jb sqrtHP4" \
" sub edx, eax" \
" jb sqrtHP4" \
" mov ecx, edx" \
" shr eax, 1" \
" or eax, ebx" \
" shr ebx, 2" \
" jnz sqrtHP3" \
" jmp sqrtHP6" \
"sqrtHP4: shr eax, 1" \
" shr ebx, 2" \
" jnz sqrtHP3" \
"sqrtHP6: nop" \
parm caller [ecx] \
value [eax] \
modify [eax ebx ecx edx];

Share this post


Link to post
Share on other sites
inline float rsq(float x)
{
const float half = 0.5f;
const float one_half = 1.5f;

__asm
{
fld x
fmul half

mov eax, x
mov edx, 05F400000h
shr eax, 1
sub edx, eax
mov x, edx

fmul x
fmul x
fsubr one_half
fmul x
fstp x
}

return x;
}

thats the code for a very fast and quite accurate reverse square root.. usage:

assuming your vec is described with x,y,z

float div = rsq(x*x+y*y+z*z);
x*=div;
y*=div;
z*=div;

works in vc and is quite fast..

if you can use sse-instructions you can even use sse (wich supports a fast rsq as well.. and the rest can be done faster then, too..)

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
quote:
Original post by v71
the method you use for calculating normals is well done
in my experience i have found a way of storing information
for a single vertex , normally i use this structure

typedef struct
{
float x,y,z; // coordinate of point in space
float r,g,b,alpha; // color components
float nx,ny,nz; // normal
float t,s; // texture coordintates
};

you compute the normals aas you are doing right now, then
fill the nx,ny,nz values for each relevant point index,
when you need to retrieve the normal just use the index you are using to access the point''s coordinaes in space.




Is this a typical representation of a 3d vertex in OpenGL? Would it be a good idea to build such a class to so i dont have to use my Vector objects to represent 3d vertices as well?

Share this post


Link to post
Share on other sites
quote:
Original post by endo
Is this a typical representation of a 3d vertex in OpenGL?


It''s just an example of a possible vertex type, i think your better of using different vertex types for specific tasks, to preserve memory.....

Some meshes don''t need an alpha component in their vertices, some don''t even need normals or texture coordinates......


Hope this makes any sense (it''s very late over here)

-Crawl

Share this post


Link to post
Share on other sites