Search - User list
Full Version: Render Curve as Tube with Shader.
Root » Technical Discussion » Render Curve as Tube with Shader.
Jack.N
Hi
I know that we can render curves as tube with using N vector in shader , But I can't remember that !!!
So we don't need for using polywire SOP or similar nodes.
What should I do ?
Thanks
PradeepBarua
You can create “width” attribute on curve, mantra reads it.
Jack.N
PradeepBarua
You can create “width” attribute on curve, mantra reads it.

Yes , I Knooooooooooooooow that :!:

the width attribute is only useful for thickness of the curve when rendering !
BUT
, I wanna Render Curves as Tube , Not just simple FLAT curve and I wanna do that in rendering , not with polywire SOP !!!!
I know we can do that with N and displacement (and maybe frontface) , But I can't remember that :!:
papi
just take the u parameter and recompute the normal

have fun
tamte
you can just plug Hair Normal VOP to N of Surface Model
make sure Do Rounding is on
Jack.N
Really thanks my friends , Yes , Both one worked perfectly and exactly same thing that I want ,But I'm sure I did that before with displacement or frontface (or similar) node (I can't remember that !) , However I can use your methods , they are so simple and thanks again
wlvl
tamte
you can just plug Hair Normal VOP to N of Surface Model
make sure Do Rounding is on


Hi Tomas,

I am using this method works perfectly.
but it makes my extra image passes disappear.

I am binding export some attributes inside the shader. The stop working if I plug in the hairnormal.
Any tips please?

Thanks!
wlvl
I plug in HairnormalVOP inside the shader overriding the parameter and it works!
Cheers
bebe
Hi,

I am following up on this old post about curve rendering as I have a related question.

I rendered a curve with this method (HairNormal plugged into a pianolacquer shader) and a polywired version of the same curve (with the default pianolacquer shader)
And there is a difference in the two renders, the rim light is not present on the curve with HairNormal shader, and the specs are quite different as well.
See renders and hip file attached.

Is there anything I am missing here, or is this the closest I can get to the polywired version?
I was hopping both renders would be the same

Thanks for your help
JH_Engelhardt
The same issue with visually varying results occurred to me at work today. Especially for light coming from the back.
I took the code from the hairnormal node and modified it, wich worked as a fix for me.

My math knowledge is not deep enough to understand this line:
“if ($bow) $Nhair += ($u*2-1) * normalize(dPds);”
Can anyone explain?

Instead of adding to the normal, I rotated it around the tangent:

float angle = asin(u*2-1);
matrix rot = ident();
vector axis = $ht;
rotate(rot, angle , axis);
vector rotateNn = $Nhair * rot;

The result is visually very close to the polywire version. But somehow does not work with classic-shader/principled-shader, as the normal is clamped on the edges (why?). It works with the basic pbr-components though.
Buil my workaround into bebeĀ“s file.
bebe
Thanks for looking into this
And for reminding me to look into the VEX code!

I downloaded your scene with the fix and it works for me with principle and classic shader
But I had to fix something in the code
I got an error in the render view: Reference to undefined variable: u (9, 24)
I changed
float angle = asin(u*2-1);
to
float angle = asin($u*2-1);
and it worked

That said, it does not work with the pbrreflect1 though
I get a Reference to undefined variable: I (1, 27)
A problem with the first line:
vector $ii = normalize(I);
which I don't know how to fix

I tested your fix in Houdini 18.0.287. You?

About the line
if ($bow) $Nhair += ($u*2-1) * normalize(dPds);
Looks like $u is remaped from (0, 1) to (-1, 1) to then multiply dPds
dPds represents the tangent along the parametric coordinate u (let's call it tangentu)
So this lines adds 0*tangentu in the middle: you get N calculated before
And then progressively adds tangentu to N when getting to the edges
I am guessing this line is originally here to fake “rotate” the normal
But if so, then it should also reduce the N while getting to the edges, which this line does not
I think it should be something along:
$Nhair = (1-abs($u*2-1))*Nhair + ($u*2-1) * normalize(dPds);

With this code I get something close to your solution, but not exactly the same
And close to the polywire version, but not exactly the same either!

vector $ii = normalize(I);
vector $ht = normalize(dPdt);
float $u = s;
VOPvector $orth = cross(ht, -ii);
VOPnormal $Nhair = cross(ht, orth);
Nhair = normalize(frontface(Nhair, ii));
Nhair = (1-abs($u*2-1))*normalize(Nhair) + ($u*2-1) * normalize(dPds);
$hairNn = normalize(Nhair);

Your solution, with matrices, seems more academic though

I will submit that to support as a bug/RFE
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB