Jump to content

How to achieve constant line width in screen space?


pencha

Recommended Posts

I want to render, using mantra not wren, and using a non-ortographic camera, lines with a width of say 2 px, no matter how close or far they are from the camera.

I assume the way to go would be an expression that modifies the width attribute of every point (in between the points I don´t really care about "correctness") based on the distance lens and aperture of the camera. Anyone out there has already got something like this working, or a better idea in how to achieve it?

Thanks!

Link to comment
Share on other sites

in vops transform the points of your line into camera space.

use z and some user defined factor to set the width attribute to match the desired width.

Thanks rdg, that´s what I´m doing right now, but I don´t know how to get the correct factor.

It would be hard to cheat as I have lots of lines with VERY different z values (and so the perspective wildly affects the resulting width in the render).

Edited by pencha
Link to comment
Share on other sites

Hi Pencha,

I believe you want to divide your aperture by the distance to camera, and then divide by the focal length.

This will work in X (and y if you are rendering a square image). For Y you need to do the same, but also multiply against the x/y resolution ratio. (And pixel aspect if other than one)

Though, if it's just width, I guess just calculating the X scale will be fine...

good luck!

Link to comment
Share on other sites

Georg's solution is the way to go I think (except you don't need to use VOPs if you don't feel comfortable there). You mention that you already tried it but it didn't work, so I'm thinking maybe you misunderstood some aspect of it.

The relationship between the projected width and the distance from camera (or "depth") is linear, so all you need to correct the foreshortening it is some constant factor of depth. That's it (as Georg mentioned).

One way to get depth into your geometry (without using VOPs) is with the UVTexture SOP, set to "Perspective From camera". In this case, the 'w' component of the uv's that it produces is the depth -- a scaled version of which you can use directly as the curve's "width" attribute.

The only thing to watch out for is the fact that "width" is a point attribute, and so will be interpolated linearly by mantra. This is fine if the thing connecting any 2 points is a straight line, but not if it's a curve. So if you're using NURBs or Bezier curves you'll have to refine or resample them until each segment is close to a straight line.

Here's a test without perspective correction:

post-148-128590994333_thumb.jpg

And here it is with the correction applied:

post-148-128591002925_thumb.jpg

...and the hip file:

camwidth.001.hip

HTH.

  • Like 2
Link to comment
Share on other sites

Thanks again rdg, thanks Jacob and gracias Mario!

Just needed the aclaration that the relationship in this case was linear, problem solved.

I was studying light attenuation in real world photography and then switched to this, overcomplicating things (1/distance squared is the attenuation factor you need to compensate using real-world lights).

ps: Never thought about solving this without VOPS! Nice file

Edit: In case it´s useful for someone, If zooming is needed, dividing Mario´s expression result with the focal length seems to work OK

Edited by pencha
Link to comment
Share on other sites

  • 2 weeks later...

Georg's solution is the way to go I think (except you don't need to use VOPs if you don't feel comfortable there). You mention that you already tried it but it didn't work, so I'm thinking maybe you misunderstood some aspect of it.

The relationship between the projected width and the distance from camera (or "depth") is linear, so all you need to correct the foreshortening it is some constant factor of depth. That's it (as Georg mentioned).

One way to get depth into your geometry (without using VOPs) is with the UVTexture SOP, set to "Perspective From camera". In this case, the 'w' component of the uv's that it produces is the depth -- a scaled version of which you can use directly as the curve's "width" attribute.

The only thing to watch out for is the fact that "width" is a point attribute, and so will be interpolated linearly by mantra. This is fine if the thing connecting any 2 points is a straight line, but not if it's a curve. So if you're using NURBs or Bezier curves you'll have to refine or resample them until each segment is close to a straight line.

Here's a test without perspective correction:

post-148-128590994333_thumb.jpg

And here it is with the correction applied:

post-148-128591002925_thumb.jpg

...and the hip file:

camwidth.001.hip

HTH.

I have to say that is amazing.... so simple... so cool... and so random how I came across from what I searched for.

-inadvertently thanks

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...