Camera Projection and NDC

   20073   13   0
User Avatar
Member
183 posts
Joined: Nov. 2008
Offline
Hi! I have a question on camera projection technique in surface shader. We can easily project texture from current camera, by transforming P to NDC. But what if we need to project from one camera, and render from different. How to transform P to NDC of “projection camera”?. There is a toNDC vex function in houdini help, with this definition:
vector toNDC(string camera_name, vector point)
But this doesn't work. Compile errors : Can't find signature ….. Was this function removed?
So, am i on the right path? I know, i can project from camera in SOPs, but i need shader based approach. Thx!
Aleksei Rusev
Sr. Graphics Tools Engineer @ Nvidia
User Avatar
Member
7709 posts
Joined: July 2005
Online
From http://www.sidefx.com/index.php?option=com_journal&Itemid=213&page=index&journal=default&logfile=ALL&perpage=20&start=20&icon=vop&search=&view=FULL&version=ALL&buildstart=&buildend= [sidefx.com]
Monday, June 6, 2011
Houdini 11.0.768: Change the name of the SOP tondc and fromndc operators to tondcgeo and fromndcgeo. This change will break SOP shaders that used the tondc/fromndc VOPs, but will fix shading context shaders that used the preexisting tondc/fromndc VOPs.
User Avatar
Member
183 posts
Joined: Nov. 2008
Offline
Hi Edward. From what i've discovered, toNDC (string camera, vector pos) doesn't work in shading context. Why is is there such limitation? Thx for reply.
Aleksei Rusev
Sr. Graphics Tools Engineer @ Nvidia
User Avatar
Member
7709 posts
Joined: July 2005
Online
toNDC() is supposed to work in the shading context, as mentioned in the journal entry above. So there is no such limitation.
User Avatar
Member
1002 posts
Joined: July 2005
Offline
The SOP toNDC() function doesn't work within shading contexts because mantra doesn't actually have the information it needs to perform transforms for other cameras. There is currently a single “global” camera in mantra, without any concept of other named cameras.

Andrew
User Avatar
Member
7709 posts
Joined: July 2005
Online
Ah, sorry, I didn't realize that you wanted *arbitrary* cameras.
User Avatar
Member
12428 posts
Joined: July 2005
Online
You're not alone!

Doing arbitrary camera projections in Mantra is harder than it can or should be due to this, and also the narrow bridge of data types one is forced to use in transporting matrices as parameters into VEX, and so this is one motivation behind the following RFEs:

RFE: 47768
Summary:Camera: Output Transform In IFD As Light

For the sake of projections, we often use cameras rather than lights. The unfortunate side effect if that there is no “camera” entity in the IFD to query against using the otransform() vex function.

So in the spirit of the path of least resistance, would it be possible get a rendering property to rather inject cameras as (shaderless) light entities which we could slap on Cameras? This would be the Camera equivalent of the “Output Transform to RIB/IFD” (renderspace) option on Nulls.

Moreover, we've found there is a lack of support for extracting camera projection matrices in VEX, hence an RFE for getting pythonexprs() into VEX so that we can use HOM for some of this. (ID: 47764)
Jason Iversen, Technology Supervisor & FX Pipeline/R+D Lead @ Weta FX
also, http://www.odforce.net [www.odforce.net]
User Avatar
Member
1390 posts
Joined: July 2005
Offline
Stalkerx777
So, am i on the right path? I know, i can project from camera in SOPs, but i need shader based approach. Thx!

I think you can compute camera matrix by yourself and transform P using it (afaik you need camera position, rotation, and focal length/aperture ratio provided to the shader).

It could be this, or something very similar* :


matrix camxform;
camxform= maketrasform(0, 0, cam_pos, cam_rot, {1,1,1}, {0,0,0});
vector ndc= ptransform(“space:world”, P);
ndc *= camxform;
ndc.z = (focal/aperture)/ndc.z
ndc.x = ndc.x / ndc.z;
ndc.y = ndc.y / ndc.z;
ndc *= -1; //?
ndc += {.5, .5, 0};


Second option I see, quite funny actually, is to ask Houdini to store this data for us in *.rat file. For this, you can save a single (or many for animated camera) *.rat renders from the camera you're interested in. It could be black image, empty scene, low-res, doesn't matter. Then in your shader, you call teximport():


matrix camxform;
teximport(rat_file, “texture:worldtoNDC”, camxform);

I'm not entirely sure, but I suppose camxform in that case also is your camera projection matrix ready to be used to transfer P into that space.

cheers,
skk.

* - code hardly tested, but I'm sure somebody here will be fast at showing my innocence. Seems like it works in SOPs though, so I was close
User Avatar
Member
678 posts
Joined: July 2005
Offline
SYmek
Stalkerx777
So, am i on the right path? I know, i can project from camera in SOPs, but i need shader based approach. Thx!

I think you can compute camera matrix by yourself and transform P using it (afaik you need camera position, rotation, and focal length/aperture ratio provided to the shader).

It could be this, or something very similar* :


matrix camxform;
camxform= maketrasform(0, 0, cam_pos, cam_rot, {1,1,1}, {0,0,0});
vector ndc= ptransform(“space:world”, P);
ndc *= camxform;
ndc.z = (focal/aperture)/ndc.z
ndc.x = ndc.x / ndc.z;
ndc.y = ndc.y / ndc.z;
ndc *= -1; //?
ndc += {.5, .5, 0};


Second option I see, quite funny actually, is to ask Houdini to store this data for us in *.rat file. For this, you can save a single (or many for animated camera) *.rat renders from the camera you're interested in. It could be black image, empty scene, low-res, doesn't matter. Then in your shader, you call teximport():


matrix camxform;
teximport(rat_file, “texture:worldtoNDC”, camxform);

I'm not entirely sure, but I suppose camxform in that case also is your camera projection matrix ready to be used to transfer P into that space.

cheers,
skk.

* - code hardly tested, but I'm sure somebody here will be fast at showing my innocence. Seems like it works in SOPs though, so I was close

Helpful.
User Avatar
Member
941 posts
Joined: July 2005
Offline
A little more info on the roll-your-own case can be found here [sidefx.com].
Mario Marengo
Senior Developer at Folks VFX [folksvfx.com] in Toronto, Canada.
User Avatar
Member
12428 posts
Joined: July 2005
Online
I really do wish there was some deeper support for camera transforms within Houdini. We at R+H have obviously written our own formulas like the one above, but a good encapsulated camera definition and functions to transform by them are sorely needed.

Currently you're going to account for Window Size, Crops and Pixel Aspect yourself too; all three of these are commonly used in an FX pipeline for oversized camera projections (to account for lens warping) and such.
Jason Iversen, Technology Supervisor & FX Pipeline/R+D Lead @ Weta FX
also, http://www.odforce.net [www.odforce.net]
User Avatar
Member
941 posts
Joined: July 2005
Offline
jason_iversen
I really do wish there was some deeper support for camera transforms within Houdini. We at R+H have obviously written our own formulas like the one above, but a good encapsulated camera definition and functions to transform by them are sorely needed.

Currently you're going to account for Window Size, Crops and Pixel Aspect yourself too; all three of these are commonly used in an FX pipeline for oversized camera projections (to account for lens warping) and such.

Completely agree.
In fact, I would love to not have to look at another NDC matrix ever again.
Mario Marengo
Senior Developer at Folks VFX [folksvfx.com] in Toronto, Canada.
User Avatar
Member
696 posts
Joined: March 2006
Offline
I really hate having to continuously make tools for this
Stephen Tucker
VFXTD
User Avatar
Member
2 posts
Joined: July 2013
Offline
I build a small otl, for this topic.
I hope,this helps someone.

video:
https://vimeo.com/119541167 [vimeo.com]

otl:
https://dl.dropboxusercontent.com/u/34893475/bhfx_CamUvProject_v001.otl [dl.dropboxusercontent.com]
  • Quick Links