Convert view space to world space issues

Started by
24 comments, last by Meltac 9 years, 4 months ago

Hi all!

In a 3D game that I'm writing a (post process) pixel shader for I try to transform a view space to a world space coordinate. My HLSL code looks about like this:

float3 world_pos = mul(view_pos,(float3x3)m_WV) + camera_pos

This works, but only for certain view angles and camera positions. E.g. when I look "from south" to the position in question it looks as it should (I mark the position to be transformed on screen as a colored sphere), but when turning the camera more than about 20 degrees, or shifting the camera position so that I will look "from east" the transformation renders completely off.

I must be missing something here, but I don't know what. I've tried normalizing, transposing and some other basic mutations / additions to my code but didn't find any working solution.

Any hints?

Advertisement

I think you need to transform it with inverse of view matrix to undo "view" part.


float3 world_pos = mul(view_pos, ViewInverse);

Maybe you don't even need to do this, why do you need world pos? maybe you can set all to work in world-view space?

This way you can save yourself a lot of inverting which is expensive.


Maybe you don't even need to do this, why do you need world pos? maybe you can set all to work in world-view space?

This way you can save yourself a lot of inverting which is expensive.

Thanks. I need to check whether a certain point in screen space / view space lies between two points from those I got the world space coordinates. It needs to a real "in between" in world space, so I probably can't simply do that all in screen space. Furthermore I need other geometric checks apart from "in between" such as distance-to, on the same line etc. Those checks and calculations can be done pretty straightforward in world-space but would become quite painfully and error-prone in view/screen space.

I searched that forum for inverting a matrix in HLSL but people didn't help much the ones asking for it and just kept saying "don't do that!" - so ignoring those advises against doing it, how WOULD I calculate the inverse of the view matrix (or whatever matrix I need here) in the HLSL shader? And no, transform doesn't do the trick here, I've already tried that.

Oh, you are the guy that makes STALKER mods? smile.png

Can i see the file where m_WV is defined, maybe the view-inverse is provided but under different name.

I have Clear Sky unpacked, and In hmodel.h file i see something that might be it:


uniform half3x4                        m_v2w;

Since STALKER is using "raw" shaders, i think column major is default (unless it is overridden somewhere) so you need to swap matrix-vector for mul op:

//float3 V = mul( VECTOR, MATRIX );
float3 V = mul( MATRIX, VECTOR );

Oh, you are the guy that makes STALKER mods? smile.png

Yes I am rolleyes.gif


Can i see the file where m_WV is defined, maybe the view-inverse is provided but under different name.

Here are the file relevant contents / matrix definitions - I have literally tried them all:


uniform half3x4 m_W;
uniform half3x4 m_V;
uniform half4x4 m_P;
uniform half3x4 m_WV;
uniform half4x4 m_VP;
uniform half4x4 m_WVP;
uniform half4 timers;
uniform half4 fog_plane;
uniform float4 fog_params;
uniform half4 fog_color;
uniform float3 L_sun_color;
uniform half3 L_sun_dir_w;
uniform half3 L_sun_dir_e;
uniform half4 L_hemi_color;
uniform half4 L_ambient;
uniform float3 eye_position;
uniform half3 eye_direction;
uniform half3 eye_normal;
uniform float4 dt_params;

I have Clear Sky unpacked, and In hmodel.h file i see something that might be it:

uniform half3x4 m_v2w;

Yes that's in my hmodel.h as well but since I'm doing a post-process (i.e. working on a different shading stage) I doubt I could make use of that matrix (but I'll check).


Since STALKER is using "raw" shaders, i think column major is default (unless it is overridden somewhere) so you need to swap matrix-vector for mul op:

//float3 V = mul( VECTOR, MATRIX );
float3 V = mul( MATRIX, VECTOR );

Hmm, that's strange. I've seen lots of code parts in the default stalker shaders where it's done the way I have it - but I'll check as well. Haven't seen any pragma specifying row major so far, though.

Btw, what do you mean by "raw" shaders?

EDIT:

To come back to my initial post, would you say that I get the right results under *some* conditions using the code I've post is purely coincidence or why is that? I just need to make sure that it's me doing something wrong, and not the X-Ray engine providing wrong matrix data.


Here are the file relevant contents / matrix definitions - I have literally tried them all:

... //code snip

Nothing in there suggest what you need. sad.png


Yes that's in my hmodel.h as well but since I'm doing a post-process (i.e. working on a different shading stage) I doubt I could make use of that matrix (but I'll check).

m_v2w name suggest that it is "view to world" matrix, if you look below in same file in hmodel function:

...
half3    nw        = mul( m_v2w, normal );

They take view-space normal (probably from g-buffer i guess) and calculate nw "normal in world-space".

The problem Is m_v2w available/passed in that "shading stage"?


Hmm, that's strange. I've seen lots of code parts in the default stalker shaders where it's done the way I have it - but I'll check as well. Haven't seen any pragma specifying row major so far, though.

Matrices might be passed transposed then this order would work:

float3 V = mul( VECTOR, MATRIX );

You need to check documentation (if any?) to see how they expose/pass their matrices.


Btw, what do you mean by "raw" shaders?

I meant they are not using "Effect framework" in which row-major is default.

Ok, thanks.

I'll check the m_v2w matrix from hmodel, you might be right with that. And yes, I meant that the engine seems to pass that matrix in the geometry and/or lighting phase/stage of the graphics pipeline to the HLSL shaders, but not in the post-processing stage where I do my stuff.


You need to check documentation (if any?)

Hehe, that's one of the best STALKER jokes I've ever heard laugh.png

(there is absolutely NO documentation about the shaders, neither officially nor in-officially - otherwise I wouldn't be here so often)

I'll post my progress when I got a chance to check these things.

Ok, I've tried this yesterday. *Something* worked - but I'm not yet sure about it.

I've replaced my previous view space to world space conversion with this:



float3    world_pos   = mul( m_v2w, view_pos ).xyz + camera_pos

Indeed the engine seems to pass some value for m_v2w after adding it to my HLSL shader code:



uniform float3x4 m_v2w;

However the result is strange. I have this debug code to check whether the transformation is correct:



if (distance(world_pos, check_pos) < 1.0)
   return float4(1,0,0,1);

This is supposed to render a red sphere 1 meter around the spot whose world space coordinate I want to check against (check_pos). That worked well before (when using the code in my initial post), but as mentioned only under specific conditions (within a limited camera position and direction range).

NOW the result is completely different. Instead of rendering a sphere around the check position, regardless of the camera position, the shader renders now a red circle around the player if and only if he is within 1 meter from the check position !?

The good news is that the circle stays there regardless of the camera direction - this wasn't the case before. But how to interpret the new result I don't know. My first thought was that adding the camera position to the transformation formula might not be necessary anymore and cause this output, as the new result is obviously depending on the players / camera position:



float3 world_pos = mul( m_v2w, view_pos ).xyz

But removing that camera_pos part from the code doesn't help either as there will be nothing rendered at all at the check position.

Any ideas???

float3 world_pos = mul( m_v2w, view_pos ).xyz + camera_pos

If the m_v2w is the view-to-world matrix, then you don't need to add the camera_pos since it is already in the matrix.

Cheers!

[edit] I didn't notice that you tried this already.

If the m_v2w is the view-to-world matrix, then you don't need to add the camera_pos since it is already in the matrix.

Yes I have already tried that without success. We suppose that m_v2w is the view-to-world matrix (unfortunately there's no documentation for that engine):


m_v2w name suggest that it is "view to world" matrix, if you look below in same file in hmodel function:

...
half3 nw = mul( m_v2w, normal );

They take view-space normal (probably from g-buffer i guess) and calculate nw "normal in world-space".

So if this assumption should be correct, what could I still be doing wrong?

This topic is closed to new replies.

Advertisement