[Sidefx-houdini-list] Hidden interior shader

Alvin Yap jtalbain at singnet.com.sg
Mon Jan 21 13:44:32 EST 2008


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