Metaballs for VRay

really impressive work Masterbercon !!
your tools are always very useful
And the 3d community really need an alternative to the realflow mesh or blob mesh

thanks a lot

ps: sorry for my english

Transparency and shadows are giving me major headache at the moment.

Reflections and refractions work just fine if nothing is inside the blob but as you can see in the picture, it doesn’t like other objects.

Second problem is shadows, they just don’t really work. There is some shadowing but its “missing” a lot of the blobs and is just buggy.

http://www.niksula.cs.hut.fi/~jylilamm/graphics/Metaballs\_13.jpg

The following questions are mainly for vlado and dimo and other who understand what happens under the hood.

I don’t really understand how the shadow rays differ from normal rays? If normal rays work why don’t shadows?

Should I use the SkipTag thingy somehow? At the moment I just set it but don’t really use it at all.

Now I’m doing following: Searching first intersection from RSRay.p to RSRay.dir direction.

I think the problems might be caused by not taking cmint and cmaxt account, I just return false if the FIRST interscetion found doesn’t match that range. Do those tell the range along the range where I should be searching the intersection?

I could give the entire source code here but its kind a mess so if you can see any obvious errors in what I’m doing it’d be helpfull.

Hi Jerry,

I will give it a shot. I guess Vlado has a deja vue, because those are the same questions I had back then.

make sure that you check: if t is your intersection:
if (t>ray.is.t) return false;
if (t<=ray.cmint) return false;
if (t>=ray.cmaxt) return false;

You have to adjust your step size to the ray direction length. Shadow rays often have a not normalized ray direction length.

Should I use the SkipTag thingy somehow? At the moment I just set it but don’t really use it at all.
// If the origin is near the surface, make sure we get sufficiently away from it to avoid “surface acne”
        if (this==ray.skipTag) {
            do {
                tLeft+=stepsize;
                                dLeft = computeField…

}while (tLeft<t1 && fabsf(dLeft)<1e-3f);

Now I’m doing following: Searching first intersection from RSRay.p to RSRay.dir direction.

I think the problems might be caused by not taking cmint and cmaxt account, I just return false if the FIRST interscetion found doesn’t match that range. Do those tell the range along the range where I should be searching the intersection?
What I did is only look for an intersection between
float t0=ray.cmint;
float t1=ray.cmaxt;
and if
if (t0>ray.is.t) return false;

I could give the entire source code here but its kind a mess so if you can see any obvious errors in what I’m doing it’d be helpfull.
Let me know when you have something to test, I am always interested in speed comparisons :slight_smile:
Dieter

Thanks Dieter!

Unnormalized direction vectors?!? What were they thinking…

Okey now I’ve nailed nearly all problems. There is still problem with Affect Shadows on.

http://www.niksula.cs.hut.fi/~jylilamm/graphics/Metaballs\_14.jpg

It seems the rays never leave the object (they miss one intersection?) so the fog color affects them all the way until they reach the light and get tinted too much.

EDIT:

Okey it seems I was too early to celebrate. How are ray.cmint and ray.cmaxt actually affected by this non-unit direction vector? Does ray.p + ray.dir * ray.cmint always give me the starting location in world space? Should I scale ray.cmint with ray.dir.length()? How should the intersection distance (ray.is.t) be set? Along the not-unit direction vector or along normalized direction vector?

Okey now its finally fully working and I got all the problems fixed.

http://www.niksula.cs.hut.fi/~jylilamm/graphics/Metaballs\_16.jpg

Time to implement some more field algorithms and checkout how motion blur would work out. Then perhaps some more optimizations.

Waw! Awesome!!! :smile:
Can’t wait to try it out

Wow Looks amazing so far.
b

Seems like you found the answer already, but still, during intersection you only work with the (potentially unnormalized) ray that is passed to your primitive.

Best regards,
Vlado

Yeah so you always work with points along the unnormalized direction ray. It took me awhile to understand that when I seek bounding volume intersections along these rays it also returns the intersections in along this ray, I was scaling them with its length which is wrong.

I’m using the IRay and Box classes with the bounding volume which is why I wasn’t quite sure what it was even doing =P

wow. I understad absolutely nothing of this. But i love the results :slight_smile:

keep up the good work!
/k

what are the rendertimes like?

Like dimo said its very fast for opaque stuff, but thats not very useful. For transparent it gets pretty slow.

http://www.niksula.cs.hut.fi/~jylilamm/graphics/Metaballs\_17.jpg

This took 5 minutes to render. Its the worst case scenario where you have 100 000 particles forming thick volume. When tracing rays inside you have to take very small steps all the way to the other side of the volume. There ain’t any way to make it go faster. This scene would probably render in 30 sec if it was using meshed surface instead.

The benifit of using implicit surface is that you can zoom in as close as you want and it keeps smooth. Also it doesn’t require much ram and its slow only when you are rendering it, if it takes just a small portion of the image it doesn’t give any performance hit. If you were to mesh it, you’d have to do it no matter how small the object is. Implicit surface also allows true motion blur which isn’t practical on meshed surface.

Hey dimo or vlado.

How should I make the MovingPrimitive version?

Now I have the same structure as in VRaySphere example where I have 3 classes. The max dummy class, VRay instance class and primitive class.

VRay instance class already inherits the StaticPrimitive, should I change it to DynamicPrimitive or just inherit both StaticPrimitive and MovingPrimitive and do the same for the primitive class? Inheriting both doesn’t actually seem to work since it doesn’t know what to cast them then…

Shoud I have seperate primitive classes for static and moving geometry or can I handle them in the same class (which is what I’d prefer)?

There should be separate classes for the static and moving cases, purely for performance and RAM reasons; you can take a look at the VRayFur example which implements this.

Best regards,
Vlado

You are crazy :wink:

Great stuff - can´t wait to play around…

I don’t know if this is related or not:

Hi Jerry,

what I did for getting motionblur without overcomplicating the code is that I expanded my boxes of the bvh with the start and stop positions.
This way I could reuse most of the code. Since normally particles only travel a short amount in one frame this is good enough I think.

Best regards,
Dieter

From what I understand internally VRay works in 1.0 per frame time, frame 0=0.0, frame 1=1.0, frame 2=2.0 etc. and max works in 0=0, 1=160, 2=320.

Anyway my objects shows up correctly in frame 0 but it disapears in all the other frames (>0). Even if its stationary and MovingBox.b[1] is just pmin/pmax=(0,0,0). I guess it has something to do with time values t[0] and t[1] not matching but neither setting them in VRay time (1.0 and 2.0 or 160 and 320 in frame 1) works. Is there some other times settings that I should update?

Its not calling intersect() even once so the problem isn’t there. It just doesn’t find the object at all.

These values are always relative to the current motion blur interval, so for 1-segmented motion blur they should always be 0.0 and 1.0 respectively.

Best regards,
Vlado

Thanks vlado! Great response time. I guess that ends my questions on this issue.

http://www.niksula.cs.hut.fi/~jylilamm/graphics/Metaballs\_18.jpg
http://www.niksula.cs.hut.fi/~jylilamm/graphics/Metaballs\_19.jpg

Now all the features are working perfectly. All it needs is some heavy optimizations. For example the motion blurred version is pretty slow and there are at least few things I know how to make it faster so there is no point doing any speed tests atm.