[Sidefx-houdini-list] Hidden interior shader

Andy Nicholas andy at andynicholas.com
Mon Jan 21 14:42:55 EST 2008


Hi Alvin,

Yep, even with subdivisions turned up I still encountered problems and
that was just testing with only a sphere and box. What I found was that
ray trace mode worked in some situations, and metaballs with laser scan
worked in others, but neither worked on its own in all  situations.

Thanks anyway :-)

A


> Hi! Even with the sampling/output divs way up is it still not suitable?
> Or is it the cook time?
>
> Alvin
>
> Andy Nicholas wrote:
>> 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
>>>
>>>
>>
>>
>> _______________________________________________
>> 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