Menu

about rendering fluid surface

Anonymous
2004-07-26
2004-08-02
  • Anonymous

    Anonymous - 2004-07-26

    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                                           

     
    • George Harker

      George Harker - 2004-07-26

      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

       
    • George Harker

      George Harker - 2004-07-26

      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

       
    • Anonymous

      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)

       
      • George Harker

        George Harker - 2004-07-26

        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

         
    • Anonymous

      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

       
      • George Harker

        George Harker - 2004-07-26

        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

         
    • Anonymous

      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)

       
    • George Harker

      George Harker - 2004-07-29

      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

       
    • George Harker

      George Harker - 2004-07-29

      Just discovered that for some reason monitoring this forum was turned off.....  Worth a look in my sf.net -> monitoring

       
    • Anonymous

      Anonymous - 2004-07-29

      Hi, George, check your message. I attached
      the code.

       
    • Okan Arikan

      Okan Arikan - 2004-07-31

          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

       
    • Anonymous

      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

       

Log in to post a comment.

MongoDB Logo MongoDB