[Sidefx-houdini-list] Hidden interior shader

Andy Nicholas andy at andynicholas.com
Mon Jan 21 13:30:46 EST 2008


Nice! Not played with that one before.

Yep, that does it, but after testing it a bit I don't think the quality
will be good enough to work with animated meshes which is what we need it
for. Thanks for the idea though, as I'm sure it'll be useful somewhere
else.

A



> Hmm.... I think an isoOffset SOP could do the trick here too...
>
> zhang xiao wrote:
>> how about use implicit surface generated by metaball for example, you
>> don't
>> need to worry about the boundary detection in this case.
>>
>> On Jan 20, 2008 12:39 PM, Andy Nicholas <andy at andynicholas.com> wrote:
>>
>>
>>> Hi guys,
>>>
>>> First off, apologies for such a long and involved post, but this has
>>> been
>>> driving me nuts for a couple of days now.
>>>
>>> I'm trying to figure out how to create a shader to render numerous
>>> transparent objects made of liquid so that I don't have to worry when
>>> surfaces intersect each other. I.e. that the shader automatically
>>> ignores
>>> interior surfaces and only renders the first and last faces (which are
>>> the
>>> ones that represent the boundary between air and water). So, for
>>> example,
>>> if
>>> you have a small sphere that sits totally enclosed within a larger
>>> sphere,
>>> then you won't see the smaller sphere at all. It's kind of like a
>>> boolean
>>> union operation, but using a shader to achieve the effect.
>>>
>>>
>>> Ideally, I'd like to be able to query the ray history to figure out
>>> whether
>>> I should render the current surface or not, but as far as I know that's
>>> not
>>> possible in VEX? Alternatively, if I could store some sort of user data
>>> in
>>> the current state that shaders further down the line could access, it
>>> would
>>> have the same effect. But again, I don't know if that's possible.
>>>
>>>
>>> So, having given up on that, I opted for an approach that executes a
>>> series
>>> of raycasts after an eye ray hits the surface. Basically it fires a
>>> sequential line of rays (using rayhittest()) until it exits the liquid,
>>> which it figures out by keeping a counter of how many times it has
>>> entered
>>> and exited a surface (based on checking the normal). When it finally
>>> exits,
>>> it calls trace() that will, in theory, give me the final color of
>>> whatever
>>> is behind the surface. I could then combine this with the result of
>>> shading
>>> the front and back faces.
>>>
>>> The problem is that trace() doesn't seem to give me anything
>>> meaningful.
>>> In
>>> fact it appears to call the shader again and return a negative result
>>> for
>>> the first rayhittest() intersection test. Is there some catch or gotcha
>>> with
>>> using trace() inside a surface shader that I don't know about?
>>>
>>> Anyway, in case it helps, the VEX code is pasted in below (with
>>> comments
>>> that explain what's going on). There's no refraction or reflection
>>> built
>>> in
>>> yet, as I wanted to get the basics working before I took it to the next
>>> stage.
>>>
>>> Any ideas, suggestions (or even RTFM's) are gratefully received.
>>>
>>> Thanks a lot :-)
>>>
>>> Andy
>>>
>>>
>>>
>>> - - - -
>>>
>>> I've just got this code inside a VEX Inline Code operator with P and I
>>> being
>>> supplied to it from a Global Variables node. The outputs to the VEX
>>> Inline
>>> Code are just called "out_col" (Vector), "out_opacity" (Vector), and
>>> "out_alpha" (float) and are plugged straight into the output variables.
>>> I've
>>> set the output color to various things along the way for debug
>>> purposes.
>>>
>>>
>>>
>>> //Set some defaults
>>> $out_col={0,0,0};
>>> $out_opacity={1,1,1};
>>> $out_alpha=1;
>>>
>>> vector $phit={0,0,0};
>>> vector $nhit={0,0,0};
>>> vector $curpos={0,0,0};
>>> vector $raydist=$I;
>>> float $maxdist=1000;
>>>
>>> //We need to give rayhittest a maximum length as well as direction to
>>> ray
>>> cast
>>> $raydist = $maxdist * normalize($raydist);
>>>
>>>
>>> float $dist=0.0;
>>> float $dotp=0.0;
>>>
>>> //We have just hit the first surface so we set this to -1.
>>> //When it gets to zero again, we know we have just left the opposing
>>> surface
>>> int $surfcount=-1;
>>>
>>> //Keep a count to make sure we do not infinitely loop
>>> int $count=0;
>>>
>>> $curpos=$P;
>>>
>>> while($surfcount!=0 && $count<50)
>>> {
>>>    $dist = rayhittest($curpos,$raydist,$phit,$nhit,0.0001);
>>>
>>>    if($dist<0.0)
>>>    {
>>>        //Nothing intersected
>>>        $out_col={1,0,0};
>>>        break;
>>>    }
>>>    else
>>>    {
>>>        //Check if we have just entered or exited a surface
>>>        $dotp = dot($I,$nhit);
>>>
>>>        if($dotp>0.0)
>>>        {
>>>            //We have just exited a surface
>>>            $surfcount = $surfcount+1;
>>>            $out_col={0,0,1};
>>>        }
>>>        else
>>>        {
>>>            //We have just entered a surface
>>>            $surfcount = $surfcount-1;
>>>            $out_col={0,1,0};
>>>        }
>>>    }
>>>    $count = $count+1;
>>>
>>>    //Set the new intersection position to be the new ray cast position
>>>    $curpos = $phit;
>>> }
>>>
>>> if($surfcount==0)
>>> {
>>>    //This is the final ray trace when we have exited the final surface
>>>    //It always returns red from the "Nothing intersected" block above
>>>    trace($out_col, $out_opacity, $out_alpha, $phit, $I, 0.0001, 1);
>>>
>>> /*
>>>    //Note: if you replace the single trace() call above with the
>>> following
>>> code:
>>>    //you can see that the position it's ray casting from is correct.
>>>
>>>    //Returns if there's anything beyond where we've just exited the
>>> surface
>>>    $dist = rayhittest($curpos,$raydist,$phit,$nhit,0.0001);
>>>    if($dist<0.0)
>>>    {
>>>        //Nope, nothing
>>>        $out_col={1,1,0};
>>>    }
>>>    else
>>>    {
>>>        //Yep, we've just hit another surface
>>>        $out_col={0,1,1};
>>>    }
>>> */
>>> }
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> Sidefx-houdini-list mailing list
>>> Sidefx-houdini-list at sidefx.com
>>> https://lists.sidefx.com:443/mailman/listinfo/sidefx-houdini-list<https://lists.sidefx.com/mailman/listinfo/sidefx-houdini-list>
>>>
>>>
>>
>>
>>
>>
> _______________________________________________
> Sidefx-houdini-list mailing list
> Sidefx-houdini-list at sidefx.com
> https://lists.sidefx.com:443/mailman/listinfo/sidefx-houdini-list
>





More information about the Sidefx-houdini-list mailing list