hi,Okan:
I just watched the movie made for Berkeley this year's vicoelastic fluid paper, you did an great
rendering of fluid surface with pixie.
Could you share more detailed information how
did you archieve this with pixie(a tutorial would
be supper:O) ).
The reason for this is that I need a decent
rendering for my own fluid simulator. I'm using
level set implicit function to tracking the fluid
surface like 'those' papers did. when comes to
rendering, i can either use marching cube to
extract the explicit mesh or direct raytracing
the implicit levelset grid field. I prefer the latter
one, since the result should be more accurate,
otherwise why i use levelset at the first place,:O).
Ok, for renderman like renders, currently only
Air has such functionality to directly render a
levelset field by using air's unique dynamic blobby
shaderop: http://www.sitexgraphics.com/html/flood_fluid_simulation.html
Unfortunately, air is not free, and i'm a poor
student can't even afford its education license:O(
It will be great if pixie can do such a job, the
movie you made for the paper convinced me that
pixie can do what renderman can't, the fluid surface
is very high quality.
So what's your approach for the fluid rendering?
thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I know that Pixie supports extended implicit geometry via a dso interface....
You define a dso which exports some named functions and basically returns a signed distance function and gradient at a specified point. It's then ray-traced using a modified newton method, according to Okan. Currently, only ray-tracing of implicit surfaces is supported.
The entry points required (see src/ri/implicitSurface.cpp) are:
init and tinit allocate or destroy global data which is passed to the other two functions.
bmin and bmax, I believe represent the axis-aligned bounding box.
dF is the function derivative.
This interfaces via the RiGeometryV binding. Looking at src/ri/renderer.cpp there also appears to be a 'smoke' geometry type which is pretty interesting (Okan, can you expand?)!
This is what I have gleaned from the code (so it may be slightly inaccurate, Okan will be able to confirm if I'm on the right lines).
Hope this helps until Okan can give a response.
I'm also interested in fluid animation using implicits. It is a very cool piece of functionality to have.
Cheers
George
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
(Hope I got the function derivative right, I did things pretty quickly ;)
Note that the init function sets up the bounding box, and that it is invalid to return 0 for the implicit object's data - so I simply allocate an int, though I could just return 1.
George
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2004-07-26
thanks a lot George, I believe the dso you
mentioned should do the trick, but I thnk dF
has different meanings for implicitEval() and
implicitEvalNormal(), for the first one, i think
it should hold the implicit value of the current
point, for the second one it should hold the
normal, I'm just repeating the name of the
function:O), so i think in your example, for
implicitEval(), you should return the d for dF
instead, and i think the normal for sphere is
right:O). however things will be tricker when
dealing with 3d levelset grid, we need to
interpolate the levelset value(trilinear should
be enough) at the current location, and about
the normal, levelset do have nice property when
comes to calculate normal, however i'm wondering
if pixie can automatically handle the implicit
normal calculation like Air did. After all, accurate
normal calculation is the key, if Okan can share
some thought on that, it will be more than helpful.
yes, also about the smoke geometry, does that
means I can change my fluid sim to a smoke sim
and render with Pixie to get pretty picture?
sounds we are in a wonder land.:O)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm just browsing over the code, but I believe that both dF's are derivatives of the signed distance function - ie. the normal. The function implicitEvalNormal() need not be defined, in which case the dF from implicitEval() is used as the normal. I believe, the function implicitEval() returns the value of the distance function, rather than putting it in dF. I think the reason for this is that you can choose to either supply implicitEval() - for the cases N follows easily from the calculation of F, you can set it here. In the case that N needs special treatment, or is expensive to compute, you'd not set dF in implicitEval() at all, but rather delay the calculation until implicitEvalNormal() is called.
Again, this is somewhat speculation, but looking at the code, the dF's from implicitEvalNormal() and implicitEval() seem to be treated in the manner described above - which would suggest that they represent the same quantity.
Cheers
George
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2004-07-26
hi, George:
maybe you are right, I haven't checked the
pixie source code yet. I just made my rough guess
according to the functions definition.
I think the data pointer in the implicitInit()
and implicitEval() will be a holder for the implicit
field, for levelset grid case, it will hold the levelset
values for all the catesian grid points, then inside
the implicitEval() function we can interpolate the
value at position defined by *point.
I do have a question for that, since for a implicit
field, we only want to render the surface of some
isovalue(say 0.0 isovalue), how do you define this
threshold use the dso function, i couldn't figure this
out by browsing your sphere example, seems your
surface is a sphere with radius 5, but how you let
pixie know that. Or maybe pixie will only render
the 0 isovalue defaultly, so you don't need to
provide a threshold for it, and that's why you
only need to define the normal dF, am i right about
this?
xiao
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You can put whatever you like in the data pointer - in your case that sounds like a good idea.
Currently, I can only see a way to render the F=0 isovalue. I guess it wouldn't be too hard to add arbitrary isovalue support, but oftentimes you wouldn't animate the isovalue... At any rate, you can alter it from within the dso.
To that end, it would be ideal if parameters could be passed into the dso to indicate which field was required (if there were several), the isovalue etc.....
Cheers
George
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2004-07-27
hi, George:
i just tested your dll and rib, it works fine,
but since i'm use VC6.0 on win2000, i have
to change your source a little bit, and complie
it as a .C file, with your original C++ source,
it will report an error when i render the rib,
something like"*.dll missing some function", and
the image is black.
so i teaked the source by following Air's dynamic
blobby shadeop example, bascially just some
macro definition for VC, and complie it as C with
VC's comand line: cl -LD GSHimplicit.C
I think you may want to put this on your tutorial
page for people use VC writing the shadeop. I can
also foward you the C file if you like.
btw, the sphere is perfect, no normal error.:O)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sorry about the late response people, George was right, the forum monitor got turned off somehow.
The discussion above is mainly right. The implicit surface needs to be implemented as a DSO that evaluates the implicit surface at an arbitrary point and returns the value of the signed distance function (actually the function doesn't need to be an exact signed distance function. Our experience shows even a close approximation is fine).
This function is called to initialize the implicit surface. The first parameter is the frame number (input). Your function should fill in the bmin and bmax with the axis aligned bounding box in the object coordinate system of your implicit surface. The return value is a transparent handle that will be passed to the other functions. A return value of NULL indicates an error.
This function should evaluate the implicit surface at P (input) and should return the value of the signed distance function. This function can also fill in the dF (output) with the value of the gradient of the signed distance function at P. time (input) is the time in the shutter interval.
void implicitTini(void *data);
This function is called to delete the implicit surface. This function should perform the cleanup.
If the gradient computation is expensive, then you can supply this function which is only called when a surface intersection is found to compute the gradient of the signed distance function. But this function is optional and the gradient vector returned by "implicitEval" will be used if not supplied.
Some remarks: implicit surfaces can only be raytraced. They are not visible to the scanline renderer which is the default renderer. So you need to explicitly raytrace the scene by:
Hider "raytrace"
Also since there is no parametrization of implicit surfaces, your shaders must only use P and N (and Ng) for surface shading. So no texturemapping.
Okan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2004-08-02
thanks for the reply , Okan:
i have 2 more questions, in the:
Geometry "implicit" "string file" "myimplicit.dll"
I suppose the file parameter pass the file
name to the shadeop, right?, so how can i use
this parameter inside my shadeop, say i wanna
load a file which contains implicit field data,
how do i do it, George's example didn't use it.
second, the frame in the:
void *implicitInit(int frame,float *bmin,float *bmax);
do i need to spcify it in the rib for rendering image
sequeces?
Thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
hi,Okan:
I just watched the movie made for Berkeley this year's vicoelastic fluid paper, you did an great
rendering of fluid surface with pixie.
Could you share more detailed information how
did you archieve this with pixie(a tutorial would
be supper:O) ).
The reason for this is that I need a decent
rendering for my own fluid simulator. I'm using
level set implicit function to tracking the fluid
surface like 'those' papers did. when comes to
rendering, i can either use marching cube to
extract the explicit mesh or direct raytracing
the implicit levelset grid field. I prefer the latter
one, since the result should be more accurate,
otherwise why i use levelset at the first place,:O).
Ok, for renderman like renders, currently only
Air has such functionality to directly render a
levelset field by using air's unique dynamic blobby
shaderop:
http://www.sitexgraphics.com/html/flood_fluid_simulation.html
Unfortunately, air is not free, and i'm a poor
student can't even afford its education license:O(
It will be great if pixie can do such a job, the
movie you made for the paper convinced me that
pixie can do what renderman can't, the fluid surface
is very high quality.
So what's your approach for the fluid rendering?
thanks
I know that Pixie supports extended implicit geometry via a dso interface....
You define a dso which exports some named functions and basically returns a signed distance function and gradient at a specified point. It's then ray-traced using a modified newton method, according to Okan. Currently, only ray-tracing of implicit surfaces is supported.
The entry points required (see src/ri/implicitSurface.cpp) are:
void *implicitInit(int frame,float *bmin,float *bmax);
float implicitEval(float *dF,void *data,const float *point,float rayTime);
void implicitEvalNormal(float *dF,void *data,const float *point,float rayTime);
void implicitTini(void *data);
init and tinit allocate or destroy global data which is passed to the other two functions.
bmin and bmax, I believe represent the axis-aligned bounding box.
dF is the function derivative.
This interfaces via the RiGeometryV binding. Looking at src/ri/renderer.cpp there also appears to be a 'smoke' geometry type which is pretty interesting (Okan, can you expand?)!
This is what I have gleaned from the code (so it may be slightly inaccurate, Okan will be able to confirm if I'm on the right lines).
Hope this helps until Okan can give a response.
I'm also interested in fluid animation using implicits. It is a very cool piece of functionality to have.
Cheers
George
I put up a very brief example at:
http://www.george-graphics.co.uk/pixiewiki/cgi-bin/wiki.pl?UserDSOExamples
(Hope I got the function derivative right, I did things pretty quickly ;)
Note that the init function sets up the bounding box, and that it is invalid to return 0 for the implicit object's data - so I simply allocate an int, though I could just return 1.
George
thanks a lot George, I believe the dso you
mentioned should do the trick, but I thnk dF
has different meanings for implicitEval() and
implicitEvalNormal(), for the first one, i think
it should hold the implicit value of the current
point, for the second one it should hold the
normal, I'm just repeating the name of the
function:O), so i think in your example, for
implicitEval(), you should return the d for dF
instead, and i think the normal for sphere is
right:O). however things will be tricker when
dealing with 3d levelset grid, we need to
interpolate the levelset value(trilinear should
be enough) at the current location, and about
the normal, levelset do have nice property when
comes to calculate normal, however i'm wondering
if pixie can automatically handle the implicit
normal calculation like Air did. After all, accurate
normal calculation is the key, if Okan can share
some thought on that, it will be more than helpful.
yes, also about the smoke geometry, does that
means I can change my fluid sim to a smoke sim
and render with Pixie to get pretty picture?
sounds we are in a wonder land.:O)
I'm just browsing over the code, but I believe that both dF's are derivatives of the signed distance function - ie. the normal. The function implicitEvalNormal() need not be defined, in which case the dF from implicitEval() is used as the normal. I believe, the function implicitEval() returns the value of the distance function, rather than putting it in dF. I think the reason for this is that you can choose to either supply implicitEval() - for the cases N follows easily from the calculation of F, you can set it here. In the case that N needs special treatment, or is expensive to compute, you'd not set dF in implicitEval() at all, but rather delay the calculation until implicitEvalNormal() is called.
Again, this is somewhat speculation, but looking at the code, the dF's from implicitEvalNormal() and implicitEval() seem to be treated in the manner described above - which would suggest that they represent the same quantity.
Cheers
George
hi, George:
maybe you are right, I haven't checked the
pixie source code yet. I just made my rough guess
according to the functions definition.
I think the data pointer in the implicitInit()
and implicitEval() will be a holder for the implicit
field, for levelset grid case, it will hold the levelset
values for all the catesian grid points, then inside
the implicitEval() function we can interpolate the
value at position defined by *point.
I do have a question for that, since for a implicit
field, we only want to render the surface of some
isovalue(say 0.0 isovalue), how do you define this
threshold use the dso function, i couldn't figure this
out by browsing your sphere example, seems your
surface is a sphere with radius 5, but how you let
pixie know that. Or maybe pixie will only render
the 0 isovalue defaultly, so you don't need to
provide a threshold for it, and that's why you
only need to define the normal dF, am i right about
this?
xiao
You can put whatever you like in the data pointer - in your case that sounds like a good idea.
Currently, I can only see a way to render the F=0 isovalue. I guess it wouldn't be too hard to add arbitrary isovalue support, but oftentimes you wouldn't animate the isovalue... At any rate, you can alter it from within the dso.
To that end, it would be ideal if parameters could be passed into the dso to indicate which field was required (if there were several), the isovalue etc.....
Cheers
George
hi, George:
i just tested your dll and rib, it works fine,
but since i'm use VC6.0 on win2000, i have
to change your source a little bit, and complie
it as a .C file, with your original C++ source,
it will report an error when i render the rib,
something like"*.dll missing some function", and
the image is black.
so i teaked the source by following Air's dynamic
blobby shadeop example, bascially just some
macro definition for VC, and complie it as C with
VC's comand line: cl -LD GSHimplicit.C
I think you may want to put this on your tutorial
page for people use VC writing the shadeop. I can
also foward you the C file if you like.
btw, the sphere is perfect, no normal error.:O)
Excellent - do you want to upload that to the Wiki?
Sorry for the long wait - there seems to be some issue with sourceforge not notifying me on all posts....
Okan - did you mention that the same was happening to you? Is there a fix for that?
George
Just discovered that for some reason monitoring this forum was turned off..... Worth a look in my sf.net -> monitoring
Hi, George, check your message. I attached
the code.
Sorry about the late response people, George was right, the forum monitor got turned off somehow.
The discussion above is mainly right. The implicit surface needs to be implemented as a DSO that evaluates the implicit surface at an arbitrary point and returns the value of the signed distance function (actually the function doesn't need to be an exact signed distance function. Our experience shows even a close approximation is fine).
You can instanciate your implicit surface by
Geometry "implicit" "string file" "myimplicit.dll"
The dso myimplicit.dll should implement the following 3 functions:
void *implicitInit(int frame,float *bmin,float *bmax);
This function is called to initialize the implicit surface. The first parameter is the frame number (input). Your function should fill in the bmin and bmax with the axis aligned bounding box in the object coordinate system of your implicit surface. The return value is a transparent handle that will be passed to the other functions. A return value of NULL indicates an error.
float implicitEval(float *dF,void *data,const float *P,float time);
This function should evaluate the implicit surface at P (input) and should return the value of the signed distance function. This function can also fill in the dF (output) with the value of the gradient of the signed distance function at P. time (input) is the time in the shutter interval.
void implicitTini(void *data);
This function is called to delete the implicit surface. This function should perform the cleanup.
Notice that there is another function called
void implicitEvalNormal(float *dF,void *data,const float *P,float time);
If the gradient computation is expensive, then you can supply this function which is only called when a surface intersection is found to compute the gradient of the signed distance function. But this function is optional and the gradient vector returned by "implicitEval" will be used if not supplied.
Some remarks: implicit surfaces can only be raytraced. They are not visible to the scanline renderer which is the default renderer. So you need to explicitly raytrace the scene by:
Hider "raytrace"
Also since there is no parametrization of implicit surfaces, your shaders must only use P and N (and Ng) for surface shading. So no texturemapping.
Okan
thanks for the reply , Okan:
i have 2 more questions, in the:
Geometry "implicit" "string file" "myimplicit.dll"
I suppose the file parameter pass the file
name to the shadeop, right?, so how can i use
this parameter inside my shadeop, say i wanna
load a file which contains implicit field data,
how do i do it, George's example didn't use it.
second, the frame in the:
void *implicitInit(int frame,float *bmin,float *bmax);
do i need to spcify it in the rib for rendering image
sequeces?
Thanks