Help with ScreenPositionScaleBias & ScreenUV

Hi,

I am trying to replicate the refraction inside UE4, and in doing so, having to dig inside the source code and figure things out. I am comfortable with programming but only just starting to learn shading development.

There are a couple lines in the source code that confuse me slightly and was wondering if anyone could shed some light.


float2 NDC = (MaterialParameters.ScreenPosition.xy / MaterialParameters.ScreenPosition.w);
float2 ScreenUV = NDC * ResolvedView.ScreenPositionScaleBias.xy + ResolvedView.ScreenPositionScaleBias.wx;

I realize that is common shading formula (position.xy * 0.5 + (0.5, 0.5)) - However, instead of 0.5 it uses ScreenPositionScaleBias.

Can anyone explain why? By using 0.5 we have a mapped screen UV between 0 - 1 and ScreenPositionScaleBias seem to be relative to the size of the window.

Another thing I notice is how the ScreenPositionScreenPositionScaleBias.y is negative. My guess is to make it match with the ScreenPosition node? This may be a basic OpenGL question… But why is this inverted in the first place?

Thanks!!

ScreenPositionScaleBias has view size in xy and position of a view’s corner within render target in zw. y is negative due to projection sign. Could have kept it in original thread though.

Thanks for the response Deathray. I thought I may as well leave that thread to the purpose of recreating the refraction, as this question was more about the programming side of things. I apologize if I’m spamming too much like this.
​​​
Thanks for the info though, I get now what the output represents… However, I would have thought that the purpose of the function is to get the same output as the ScreenPosition node, right?

In order to get the same result I have to do this instead:


float2 NDC = (Parameters.ScreenPosition.xy / Parameters.ScreenPosition.w);
float2 ScreenUV = NDC * float2(0.5,-0.5) + float2(0.5,0.5);
return ScreenUV;

Why use ScreenPositionScaleBias at all?

My guess is that I’m missing something along the way…?

You are missing a possibility of view not occupying the whole output render target.