Matrix transformations in the VEX function 'fromNDC'

   1088   2   1
User Avatar
Member
45 posts
Joined: Jan. 2016
Online
I was trying to use the VEX function 'fromNDC' inside a snippet wrangle in COPS, but it doesn't seem to provide the same results as when used in a point wrangle in SOPS. The documentation for 'fromNDC' warns that NDC space may not be 'well defined' in every context, so I guess I'm up against that.

I would like to perform the calculation manually in that case, but I'm not exactly sure what transformations are involved. I am trying to convert points from NDC space to camera space. I can see that one part of it is to use the camera matrix like this:

matrix cam_matrix = maketransform(0, 0, cam_position, cam_rotation);
@P *= cam_matrix;

That brings the points in the correct position/rotation in the scene, but there is something missing - I'm not sure if it is a screenspace or clip space or view space or something else transformation which also needs to occur to get the same result as the 'fromNDC' function.

I have attached a project showing the two methods (1) fromNDC, and (2) the incomplete method doing it by hand.

Can anyone help me?

Attachments:
fromNDC.hiplc (202.4 KB)

User Avatar
Member
7796 posts
Joined: Sept. 2011
Online
To go to NDC you need to apply the perspective transform. The camera's matrix doesn't have the perspective matrix, only the positional one. Use the perspective() function to build a perspective matrix. Unfortunately, it doesn't quite use the same parameters as a Houdini camera uses to define the view matrix. The help for the function explains how to convert the values. It also gives an example of using it to build a world to NDC transform.
One odd quirk of perspective transforms is that they are actually four dimensional. The worldtoNDC matrix can't convert a 3d position directly to NDC. Instead, the 3d position is converted to homogeneous coordinates in 4D, and then the perspective is applied in 4D. To get the NDC coordinate, divide the transformed 4d position by its 'w' component, and shift from zero centered to 0.5 centered.
Edited by jsmack - April 19, 2023 17:50:51
User Avatar
Member
117 posts
Joined: Aug. 2017
Offline
make line link to focal in Camera
4 diff wrangle like @jsmack mentioned make lines ,connect with plane.

maybe some errors

s@cam = chs('cam');
@near = ch(sprintf('%s/%s',s@cam,'near'));
@far =  ch(sprintf('%s/%s',s@cam,'near'));
@focal = ch(sprintf('%s/%s',s@cam,'focal'));
@aperture = chf(sprintf('%s/%s',s@cam,'aperture'));
f@resx = float(chi(sprintf('%s/%s',s@cam,'resx')));
f@resy = float(chi(sprintf('%s/%s',s@cam,'resy')));
f@scale = f@resx/f@resy;
@aperturey = @aperture/f@scale;

//nearplane
float x = @near/(@focal/@aperture);
float y = x/f@scale;
float z = sqrt(pow(x,2)+pow(y,2))/2;
float near = sqrt(pow(z,2)+pow(@near,2));

float u = @far/(@focal/@aperture);
float v = u/f@scale;
float w = sqrt(pow(u,2)+pow(v,2))/2;
float far = sqrt(pow(z,2)+pow(@far,2));

setpointattrib(0,'P',1,set(0,0,-near));
setpointattrib(1,'P',2,set(0,0,-far));




@N = set(0,0,1);
v@up = set(0,1,0);
matrix m = maketransform(@N,v@up);
float angle = atan((@aparture/2)/@focal);
float angley= atan((@aparturey/2)/@focal);
vector axis = v@up;
rotate(m,angle,axis);
vector axisy = set(1,0,0);
rotate(m,angle,axisy);
@P *= m;
Edited by cncverkstad - April 20, 2023 03:54:57
Conservation of Momentum
  • Quick Links