Transform to NDC, calculate and transform back to worldspace

2.6k views Asked by At

I have a problem moving world coordinates to ndc coordinates than calculate something with it and move it back inside the shader.

The Code looks like that:

vec3 testFunc(vec3 pos, vec3 dir){
    //pos and dir are in worldspace, convert to NDC
    vec4 NDC_dir = MVP * vec4(dir,0);
    vec4 NDC_pos = MVP * vec4(pos,1);
    NDC_dir /= NDC_dir.w;
    NDC_pos /= NDC_pos.w;

    //... do some caclulations => get newPos in NDC 

    //Transform newPos back to worldspace
    vec4 WS_newPos = inverse(MVP) * vec4(newPos,1);
    return WS_newPos.xyz / Ws_newPos.w;
}

What I found when testing is, that while the NDC_dir.x and NDC_dir.y seem to be reasonable, the NDC_dir.w and NDC_dir.z are always almost equal. Therefor when dividing by "w" the z-Value is always about 1. I dont think this is how it should be right? (Same for NDC_pos).

On the other hand, when I transform "pos" to NDC and than transform it back to Worldspace (without any calculations) it seems to get the original Point which actually would mean the transformations are correct.

Can anybody tell me if I am doing something wrong here, and if not, why the z-Value is always 1?

Update: This is a little embarrasing. I had two problems: 1. one was the direction problem @Arne pointed out. The other one was just a scaling problem on my side. I had a really small near clip and a big far clip. And as the value are logarithmic, I just moved in two big steps to realize the z-Value actually really goes from -1 to 1.

1

There are 1 answers

3
Arne On BEST ANSWER

What I found when testing is, that whilte the NDC_dir.x and NDC_dir.y seem to be reasonable, the NDC_dir.w and NDC_dir.z are always almost equal. Therefor when dividing by "w" the z-Value is always about 1. I dont think this is how it should be right? (Same for NDC_pos).

Actually yes, that is how it should be. If your input is formed as {x,y,z,0} then it will be interpreted as a point infinitely far in the direction of {x,y,z}. Therefore the depth component should always be most distant, if visible at all. By the way a point infinitely far away is still translation invariant

But you should know that a point infinitely far away is probably not what you want within NDC.

A vector in 3D space is invariant to translation, it just stays the same vector, because a vector has only a direction, not a position. This is not really possible in the distorted NDC.

If you want to transform a vector, you should better transform two points, and then take the difference in NDC again. But you should know that your result then depends on the position.