I have trouble getting the correct screen coordinates, so I made this small MWE to replicate the kind of behavior I am seeing in my main project. I use Single Pass Rendering and a Windows Mixed Reality Headset in Unity 3D. I have a shader, which is set to a new material "ppMaterial", which in turn is then used in
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source, destination, ppMaterial);
}
In this MWE, the shader is just supposed to draw circles at the screen edges, so I made this simple shader:
Shader "Custom/ScreenShader" {
Properties {
}
SubShader {
Pass {
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
half4 _MainTex_ST;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float4 screenPos : TEXCOORD1;
};
float getDist(float2 isIn, float2 pos2){
return sqrt((isIn.x - pos2.x)*(isIn.x - pos2.x) + (isIn.y - pos2.y)*(isIn.y - pos2.y));
}
float4 NearBoundary(float2 isIn, v2f i)
{
float2 pos2 = float2(0.5,0.5);
float2 pos3 = float2(0,0.5);
float2 pos4 = float2(0.5,0.0);
float dist2 = getDist(isIn, pos2);
float dist3 = getDist(isIn, pos3);
float dist4 = getDist(isIn, pos4);
if(dist2<0.1){
return float4(0,0.5,0.5,1);
}
if(dist3.x<0.3){
return float4(0.5,0,0.5,1);
}
if(dist4.x<0.3){
return float4(0.5,0,0.5,1);
}
return tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv, _MainTex_ST));
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.screenPos = ComputeScreenPos(o.vertex);
o.uv = v.uv;
return o;
}
half4 frag(v2f i) : SV_Target {
float2 screenPos = i.screenPos;
return NearBoundary(screenPos, i);
}
ENDCG
}
}
}
But this does not work, the dots are not drawn at the center and the borders, respectively, where they should be. How to get the correct screen coordinates in the (0,1)-range for each eye?
Turns out the issue was that the camera giving the coordinates had a targettexture set, which seems to mess the coordinates up. Then, the screenPos had to be set by
screenPos.x -= unity_StereoEyeIndex * 0.5;
screenPos.x *= 2;
Also, inserting
RenderTextureDescriptor d = XRSettings.eyeTextureDesc;
d.width = d.width / 2; // THIS DOES NOT MAKE SENSE
RenderTexture t = new RenderTexture(d);
in the C#-Code as well as setting
uv.y = 1-uv.y
in the shader got me rid of all problems at last.
Posting this for other people having these super weird problems...