#### Archived

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

# Metaballs - Normals

This topic is 5275 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

This is really starting to get interresting. I'll look up your source in a few minutes Hans, it already seems promising.
Here's a few lines I use to calculate the force on my balls (the meta ones):

ForceGrid[ index ] =	MB_SIZE*MB_SIZE/((x-bx1)*(x-bx1) + (y+by1)*(y+by1) + (z-bz1)*(z-bz1)) +	MB_SIZE*MB_SIZE/((x-bx2)*(x-bx2) + (y+by2)*(y+by2) + (z-bz2)*(z-bz2)) +	MB_SIZE*MB_SIZE/((x-bx3)*(x-bx3) + (y+by3)*(y+by3) + (z-bz3)*(z-bz3)) +	MB_SIZE*MB_SIZE/((x-bx4)*(x-bx4) + (y+by4)*(y+by4) + (z-bz4)*(z-bz4));

Edited by - baskuenen on May 25, 2000 3:03:17 PM

##### Share on other sites
So all you''re balls are the same size?
If you want different sized balls, you must do this:

C = center of ball
S = size of ball
V = The vertex who''s normal is to be computed
M = magnitude(V-C)

N = (V-C0)*S0/M0^3 + (V-C1)*S1/M1^3 + (V-C2)*S2/M2^3 + ...

And I calculated my metaballs like:

sqr((x-bx1)*(x-bx1) + (y+by1)*(y+by1) + (z-bz1)*(z-bz1))

but you have only:

(x-bx1)*(x-bx1) + (y+by1)*(y+by1) + (z-bz1)*(z-bz1)

So you''ll need different power that ^3.. I''m not sure what but ^2 felt good when I tested it
Wild quess: maybe now ^1 normalizes the vector and the other ^1 is like (1/2)*2. In the old formula ^1 was normalize and ^2 was (1)*2..
I originally came up with the algo before I even knew what vector is, and I just tested things...

--
MB_SIZE*MB_SIZE
--
But why do you square your balls'' sizes? If you''re going to use that formula above, you shouldn''t sqare the sizes or else you''ll need square root in the formula:

N = (V-C0)*sqr(S0)/M0^2 + (V-C1)*sqr(S1)/M1^2 + (V-C2)*sqr(S2)/M2^2 + ...

-Hans

##### Share on other sites
I''m still looking through the overload of recent info.
Meanwhile I noticed the folowing:

Can''t Sqrt(x)^3 be described as x^2 ?

So after some radical algo optimizations:
N = 1/(V-C0) + 1/(V-C1) + 1/(V-C2) + ...

Am I getting this right?

If you want to use different sizes you get:
N = MB_SIZE/(V-C0) + MB_SIZE/(V-C1) + MB_SIZE/(V-C2) + ...

Please correct me if I''m wrong...

##### Share on other sites
>Can''t Sqrt(x)^3 be described as x^2 ?

No, sqrt(x)=x^(1/2)
And so x^(1/2)^3=x^(3/2)=x^1.5, not x^2
Sqrt(x)^4=x^2.

But since you should use:

N = (V-C0)*S0/M0^2 + (V-C1)*S1/M1^2 + (V-C2)*S2/M2^2 + ...

And M = sqr((x-x0)^2+(y-y0)^2)
M^2=(x-x0)^2+(y-y0)^2 , which is quite fast to calculate and you don''t need sqrt() at all.

(and we''re back at the form that WitchLord suggested earlier)

Whether it is M^2 or M^3 depends on how you calculate the metaballs. (but you, baskuenen, should use M^2 because you don''t use sqr to calculate metaballs'' forces, read my earlier posts)

-Hans

##### Share on other sites
Me = little bit stupid sometimes. You''re right! Optimized my amount of braincells a bit too much...
Good thing there are some sober people around!

But we optimized it!

Optimization is real important in my case, because I''m writing a software rendered runtime 3D animation of the metaballs. It''s still too slow (~20 FPS on PIII-450).

But you made a good point with metaball normal calculation.
- There is a better way -
(Although the "smooth surface normal calculation" topic was getting real interresting!)

I''m still implementing...hope it''ll work...

Thanks Hans and all of you guys!

##### Share on other sites
I see that I''m not needed here anymore.

I was inspired by this discussion so I sat down to make my own Metaballs, 2 hours later it was working (I stripped an old program I had for marching cubes). After some tweaking with the numbers I actually managed to get them to look good as well. As of yet the code is totally unoptimized though so the performance is truly poor: 8.7 fps on a Celeron 500 with GeForce. (Impressive isn''t it )

- WitchLord

##### Share on other sites
Did you really think you could get away with it that easy?

We are not done yet! At the moment my surface is smooth, and the phong is shining brightly, but it''s still not right!

This thread is finished when I say so
and only when an image of perfect metaballs is posted!

...

##### Share on other sites
Fine by me

Now that I have gotten my metaballs to run at a steady rate of 105fps with perfect smoothness (at least as perfect as it gets with low detail) I'm willing to give you a hand again.

You might wonder how I managed to optimize from 8.7 fps to 105 fps. Well the biggest change I did was that I no longer compute the field energy if there are no balls in close proximity. This got the fps up to a steady 32 fps (367% increase). The second optimization I made was that I switched to release build, and voila 105 fps (328% increase).

Here's a screenshot of my metaballs:

(Image no longer available)

For the sake of this screenshot I increased the density of the energy field to 64*64*64 from 32*32*32 (lowered fps to 14)

- WitchLord

Edited by - WitchLord on May 25, 2000 11:25:48 PM

Edited by - WitchLord on May 26, 2000 11:45:35 PM

##### Share on other sites
DAMN! that looks good!

Can you post that program?

========================
Game project(s):
www.fiend.cjb.net

##### Share on other sites
I could, if you ask nicely

- WitchLord

##### Share on other sites

Ok, im not gonna crawl... (not until ive seen what the program can do anyways =)

========================
Game project(s):
www.fiend.cjb.net

##### Share on other sites
That was enough for me.

I have uploaded the program with source to my homepage:

projects

I hope you enjoy it.

- WitchLord

##### Share on other sites
Thanx!

========================
Game project(s):
www.fiend.cjb.net

##### Share on other sites
Hey WitchLord or baskuenen, can you tell me where to find a tutorial on marching cubes? I tried to find one once, but all I found was blaahblaah and that it''s a patented algorithm (?).

-Hans

##### Share on other sites
We have given a few pointers in this thread: Metaballs - Where to start?

You may also check the source for my metaballs, it''s really well commented in my own humble opinion.

- WitchLord

##### Share on other sites
Yes, I've done it!
If you look up the previous piece of code I posted, you'll see - with x&z's and + with the y's.
I also saw it: very late . This was my problem with the implementation of the new metaball normals!!!

So I've done it, but still running 20FPS (100% software rendered).

Here's the screenshot:

Here's the demo: 3ddemo_metaballs.zip

(ps: Also improved my homepage a little)

Edited by - baskuenen on May 26, 2000 2:12:07 PM

##### Share on other sites
Here''s another metaball tutorial: http://www.exaflop.org/docs/marchcubes/ind.html

##### Share on other sites
Your metaballs are a whole lot more impressive than mine.

20fps in software mode, I think you should be proud of that. Have you tried the optimizations that I did?

What size do you use for you energy field? In my current version I use 48*48*48.

Could the smooth specular highlights be the result of Phong lighting? I had to turn off specular lighting on my balls because they looked horrible.

- WitchLord

##### Share on other sites
Thanks,

I haven''t optimized the force grid yet. I was thinking about it, but have not come up a solid algo for this...I''m really interrested in your optimizations!

I must admit I''m using a 32*32*32 grid only.

And yes, I managed to implement a fast phong mapping algo. (It''s no OpenGL or DirectX - so you can cheat a little with this)

I like - you like it! You answering all my questions, and I never could answer yours, was starting to bug me.
I always said to myself: If you can do metaballs, you''re really good! Now I can do metaballs, and I feel good. If you can do metaballs like WitchLord or Hans: You''re also a superb programmer! Guru is the name here!

I''m just home - back from the cafe (burph) - Need some liquid now...

##### Share on other sites
Well, I only made a simple optimization, yet the performance was increased by 367%.

What we must recognize here is that the only energy values that are needed are those that are really close to the surface of the balls. In my optimization I don''t compute the values that are too far away from any of the balls. It can maybe be optimized further by not computing the values that are inside the balls as well.

Anyway you can see my optimization in the source code, it is really simple so you shouldn''t have any trouble implementing it in your own code.

- WitchLord

##### Share on other sites
WitchLord:
While looking through your code I noticed it looks simple and clean. Mine still is a bit messy with lots a pointers and stuff.

I''m not re-normalizing the added normals. Is this really needed? It will improve performance a bit.

Is there a precise threshold value for the energy field optimization?

##### Share on other sites
Just for the record: Here''s my metaball vertex normal calculation source:

void __fastcall CalcVertexNormal(PVERTEX pVertex){	float x = pVertex->x;	float y = pVertex->y;	float z = pVertex->z;	float dx1 = (x-tx1);	float dx2 = (x-tx2);	float dx3 = (x-tx3);	float dx4 = (x-tx4);	float dy1 = (y-ty1);	float dy2 = (y-ty2);	float dy3 = (y-ty3);	float dy4 = (y-ty4);	float dz1 = (z-tz1);	float dz2 = (z-tz2);	float dz3 = (z-tz3);	float dz4 = (z-tz4);	float n1 = dx1*dx1 + dy1*dy1 + dz1*dz1;	float n2 = dx2*dx2 + dy2*dy2 + dz2*dz2;	float n3 = dx3*dx3 + dy3*dy3 + dz3*dz3;	float n4 = dx4*dx4 + dy4*dy4 + dz4*dz4;	n1 = MB_SIZE*MB_SIZE / (sqrt(n1) * n1);	n2 = MB_SIZE*MB_SIZE / (sqrt(n2) * n2);	n3 = MB_SIZE*MB_SIZE / (sqrt(n3) * n3);	n4 = MB_SIZE*MB_SIZE / (sqrt(n4) * n4);	pVertex->nx = dx1*n1 + dx2*n2 + dx3*n3 + dx4*n4;	pVertex->ny = dy1*n1 + dy2*n2 + dy3*n3 + dy4*n4;	pVertex->nz = dz1*n1 + dz2*n2 + dz3*n3 + dz4*n4;}

##### Share on other sites
Normalization of the normals are only needed if your lighting code requires it. For both OpenGL and Direct3D the
normals must be unit length, otherwise you''ll get strange lightvalues. If you try normalizing the normals, you''ll see that it doesn''t make a lot of difference to the performance.

I noticed that you have an extra step when computing your normals:

n1 = MB_SIZE*MB_SIZE / (sqrt(n1) * n1);

Is this necessary? Does it give you better appearance of the lighting?

The threshold I use in my optimizations is the distance from the center to the surface if all balls was on the same spot.

- WitchLord

##### Share on other sites
Well I tried adding that step in the normal computations myself and it does look better. I also tried with this:

n1 = MB_SIZE*MB_SIZE / (n1 * n1);

And that does also look right. So which is it? I''ll have to do some testing, I''ll add some user interactivity to my program so that I can do some tests.

- WitchLord

##### Share on other sites
I''m using this extra step for some optimization.
I''m using floating point:
- FDIV costs 17 instructions
- FMUL costs 3 instructions
This is not entirely right, because floating point functions can be interleaved with integer functions, but thats not the case in this function.

If you are going to divide multiple numbers by the same value, it''s better to divide once, and then multiply the rest! If optimized in assembly the FMUL''s clock count could be reduced to 1, and can interleave each other! (the FDIV''s cannot) But that''s all another topic, and you probably knew most of it.

So the extra step is for optimization only.

> The threshold I use in my optimizations is the distance from the center to the surface if all balls was on the same spot.

Good point, that''s the threshold!

Then: If you want the minimal value for a metaball optimization: use the distance from the center to the surface if just one ball.