(C++) Metaball Scene Node

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Hmm, thats too bad, if the normal information is not present theres not many kinds of shading that can be done. The fact that the vertex colours interpolate smoothly between the triangles even though they're not joined is a good sign, there may be hope yet.

Off the top of my head I guess we can try some methods to calculate the normal inside the vertex shader, for example by passing the center of the ball as a shader constant and normalising the difference between that and the vertex position. An idea for texture mapping could be using the 3D world coords of the vertex, these can also be used to apply some kind of volume normal map, or projecting a cube-normal-map from the center of the ball. Although its hard to imagine how these techniques can be implemented smoothly on more than one ball.

We could also try some screen-space based techniques that work purely on position and depth and are independent of the actual scene geometrical data. For example, you could take a depth map of the balls, then do a post processing pass that extracts world coord information from adjacent depth values and interpolates them ((p1-p2) x (p3-p2)) to get a screen-space normal vector and do some differed shading using that info.

*Goes off to try some stuff out.*
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Nevermind what I said, it was surprisingly easy to whip this up:

Image

Image

Image
Especially specular highlights would be wavy and choppy instead of round and smooth.
Doesn't look that bad to me, so when can we see a moving version of this? :D

I'll try to optimize the algorithm myself, maybe using some SSE intrinsics or something this can be made much faster? I noticed there are some settings for sample adjustment, and there are a few doubles used here and there, so I'll play around with those and see what kind of FPS I get.

Cheers
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Wow, not to downplay your great accomplishment killthesand, but that is great BlindSide. Is that a shader you are running on the metaballs or fixed function? (If a shader, then could be see your refraction shader possibly running on this? :lol: )

killthesand: Haha, you make me want to go out and implement something now. :D
TheQuestion = 2B || !2B
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

And heres the moving version: Click for a cool demo

Its a little slow on my PC (Laptop with AMD Turion), so I'd like to see what the FPS is like on those Intel Quadcores some of you might own. To get them moving I changed a few things: Increased sample width (This made the lighting slightly less attractive, but still tolerable), made the Balls deque public, changed all the f64 to f32, and called "triangulateVolume()" every frame. Ive added an option to set the sample width at start up, so try it out with the optimal value of "0.125" to get better quality if "0.25" performs more than adequately on your machine.
could be see your refraction shader possibly running on this?
Sorry to disappoint but this IS the refraction shader more or less, just modified to not use a normal map (Because thats difficult without proper texcoords) and instead uses the world space normal of the mesh to offset the background. It's easy to notice this if you look at the edges of the spheres in the screenshots I posted, particularly in the last image.

Cheers
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Lekane
Posts: 31
Joined: Thu Jun 01, 2006 7:07 pm

Post by Lekane »

wow, this owns big time!
17 fps on MY celeron + fx5500 pci... yes yes i know, but still!
killthesand
Posts: 42
Joined: Sat Sep 29, 2007 3:33 am
Contact:

Post by killthesand »

That is wonderful! I was hoping someone would take it and fill in where my lack of expertise failed. I was getting 26-29 fps at 0.25 and the specular artifacts aren't too bad. If you take it up to .5 or .75 you clearly start to see the wavy and choppy i was talking about. I still have no clue how to implement UVs. For a surface that constantly changes shape and resolution, that's a tough one to figure out and I haven't found any implementations of UVs on metaballs anywhere online.
BlindSide wrote:if the normal information is not present theres not many kinds of shading that can be done.
The vertex normals shouldn't have been an issue, they are already calculated based from the thresholding of the value function.
BlindSide wrote:Nevermind what I said, it was surprisingly easy to whip this up:
I dug through some other scene nodes to see how to do materials and I got scared. Since there's no UVs, I didn't even try. I guess the next thing I'll work on will be some sort of material/shader project to help me learn this.
BlindSide wrote:An idea for texture mapping could be using the 3D world coords of the vertex...
Yes procedural shaders would be the way to go at this point. 3d noise clouds, x-ray shaders, etc.
BlindSide wrote:screen-space based techniques that work purely on position and depth
I've only seen depth maps use for creating ray cast shadows from spot lights and for doing focal length blurs in post, what else are they capable of?
BlindSide wrote:changed all the f64 to f32
Does the use of 64-bit floats drastically reduce performance? Back in my high school computer science class, we weren't even taught about float, we always used double, so I usually default to that.

Thank you very much for contributing, if anyone should want to use metaballs for some reason, this isn't a bad start. It definitely sounds like a candidate for irrExt.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

f you take it up to .5 or .75 you clearly start to see the wavy and choppy i was talking about.
Well if you take it up to 0.5 choppy specular is the last thing you need to worry about :P , its clearly just from the low resolution, as the problem disappears at your default setting of 0.125.
I guess the next thing I'll work on will be some sort of material/shader project to help me learn this.
I did a tutorial on this kind of effect, check it out here: http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=27054 The main reason why the specular isnt such a big problem in my material is because the lighting is done per-pixel, so it transcends all of the vertex supplied information and works purely on position and normal etc. Look at this comparison on LightHouse3D: http://www.lighthouse3d.com/opengl/glsl ... pointlight (The picture down the bottom).
Does the use of 64-bit floats drastically reduce performance? Back in my high school computer science class, we weren't even taught about float, we always used double, so I usually default to that.
I just figured its common sense that a 32 bit data type would process faster than a 64 bit one, just as 16 bit is usually faster than 32. I think I noticed a gain of one or two FPS just by doing this. I was surprised it didn't affect the precision of the final output much.

I played around with the material some more (And used a proper specular formula this time, the other one is a bit dodgy) and got this:
Image

If you want this kind of effect in the demo just replace BallP.glsl with:

Code: Select all

uniform sampler2D RTTexture;
uniform vec4 TintColour;

varying vec3 WorldView;
varying vec4 GlassPos;
varying vec2 TexCoord;
varying vec3 LightDir, VNormal, Tangent, Binormal;
varying vec4 VCol;

void main()
{
    vec4 projCoord = GlassPos / GlassPos.w;
    projCoord += vec4(1.0);
    projCoord *= 0.5;
    vec2 norTex = TexCoord.xy;

	vec3 Normal = VNormal; 
    vec2 TexOff = Normal.xz * 2.0;
	TexOff -= vec2(1.0,1.0); 
    
    projCoord.xy += (TexOff.xy / 5.0);
    projCoord.xy = clamp(projCoord.xy, 0.001, 0.999);
    
    vec4 refTex = texture2D(RTTexture,projCoord.xy);
    
    
    vec3 ViewDir = normalize(WorldView);
    
    float facing = max(dot(ViewDir, Normal), 0.0);
    float diff = max(dot(LightDir,Normal),0.0);
    vec3 reflect = normalize(diff * Normal - LightDir);
    float spec = dot(reflect, ViewDir) * 4.0;   
    spec = clamp(pow(spec,2.0),0.0,2.0);
 
    gl_FragColor = refTex * VCol * facing;
    gl_FragColor += spec * VCol; 
}
Oh yeah, I modified the code to take advantage of MeshBuffers. I think everyone should use MeshBuffers instead of Vertex/Index arrays as it is exactly the same thing in terms of usage (SMeshBuffer->Vertices and SMeshBuffer->Indices allow you to access and manipulate the vertex and index arrays as you wish) but allow you to utilize VBOs, (and drawing them is easier, just driver->drawMeshBuffer(mb);). Here is the modified version using dynamic vbos (It also has the f64s changed to f32s, so you can change that back if you don't like it):
http://irrlichtirc.g0dsoft.com/BlindSid ... source.zip
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Sylence
Posts: 725
Joined: Sat Mar 03, 2007 9:01 pm
Location: Germany
Contact:

Post by Sylence »

25fps on my AMD 64 x2 4200+ geforce 8800gt.

REALLY nice. Keep up the good work
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Wow, that looks damn good.

Here are some hints on optimization:
f64 and f32 are not necessarily faster or slower, at least not noticeable. However, f64 does take some more memory (which also needs to be copied to registers and back to memory), and takes some additional things regarding precision. But at least not all operations are necessarily slower with f64. If one doesn't need double precision, it's a good idea to explicitly avoid f64 and use f32 to express this.
There are a few things which could be optimized, though, but I guess I'd need to run a profiler to find any important bottlenecks.
A few things to note: Never use 'using namespace' in a header. Doesn't make your code faster, but otherwise namespaces are just useless...
Dividing is expensive. So the colors calculation seems suboptimal. Don't know a better solution, though.
The deque is used far too often, in wrong places, and without pre-allocation: Again example color calculation. Why use a deque, you don't delete from inside the list, better use core::array. Why not preallocating the deque to Balls.size() elements, would save the reallocations in between.
And another performance killer: Missing const& qualifiers for methods like valueFunction. Now, all vector3dfs are copied to the function. Moreover, private performance critical methods can easily be made inline.
Yoran
Site Admin
Posts: 96
Joined: Fri Oct 07, 2005 8:55 am
Location: The Netherlands
Contact:

Post by Yoran »

I am very impressed!
Always liked these demos :)
Post Reply