Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[SOLVED] Camera screen position shader viewed from other camera

Discussion in 'Shaders' started by Sewf, Jan 18, 2020.

  1. Sewf

    Sewf

    Joined:
    Mar 23, 2018
    Posts:
    3
    [TLDR] Need my shader to cherry pick cameras for screenspace position calculation

    Hey everyone, I am really desperate by now and I hope someone has a solution for me.

    So what I'm making is an App that displayes a box that exists within your phone that is perspectively correct from the angle of your face looking at your screen.
    Basically everything I wanted to do works by now except for the shader that is applied to a plane that is viewed by an orthographic camera for the final output to the phone screen.

    So the setup is the following:

    ArCamera - The device camera to get the position of the face of the user

    FaceCamera - a camera that follows the position of the face and always looks at the box to get the rendertexture I want to apply to the plane from the view of this camera

    OutputCamera - Only looks straight at the plane in a orthographic perspective to get the final output. The screen space position of this camera should not be used to project the texture onto the plane but only look at it 'after is has been applied'.

    PlaneShader - This shader should take the render texture and apply it to the plane but only with the screen space position of the camera that the rendertexture is taken from.

    So my problem is that the screen space position of the shader is calculated for every camera so I can't really get a view of the plane with my OutputCamera. When I do the shader is calculating the screen space position of the outputcamera and I get the view from the FaceCamera applied to the plane.

    I tried a about million bits and pieces of shadercode from the forums by now from people that had a simmilar problem but nothing works.
    The base shader code is from Brackeys for a simple portal setup btw. and it does exactly what it should since you would only ever need the texture to be applied from the view that"s influencing the rendertexture.

    I've attached some pictures to make it more clear.

    The green example is the view of a camera that is exactly like the render texture camera so you can see the plane from the angle that works. So the parts that are not visible from the opening of the box are correctly occluded since the texture is applied to the plane the plane you see here that is exactly where the opening to the box would be.

    The pink example is the view from the OutputCamera that is showing the plane in a fullscreen view and the rendertexture is incorrectly applied to the plane again and simply shows the view that the FaceCamera has currently since the shader is using the screen space position of the OutputCamera when viewed with the OutputCamera.

    I really hope that someone can help me with this! I'm open for each and every suggestion!
    Thank you so much!

    This is the shader applied to the plane:

    Code (CSharp):
    1.  
    2. Shader "Unlit/ScreenCutoutShader"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex ("Texture", 2D) = "white" {}
    7.     }
    8.     SubShader
    9.     {
    10.         Tags{ "Queue" = "Transparent" "IgnoreProjector" =
    11.         "True" "RenderType" = "Transparent" }
    12.  
    13.         Lighting Off
    14.         Cull Back
    15.         ZWrite On
    16.         ZTest Less
    17.        
    18.         Fog{ Mode Off }
    19.  
    20.         Pass
    21.         {
    22.             CGPROGRAM
    23.             #pragma vertex vert
    24.             #pragma fragment frag
    25.            
    26.             #include "UnityCG.cginc"
    27.  
    28.             struct appdata
    29.             {
    30.                 float4 vertex : POSITION;
    31.                 float2 uv : TEXCOORD0;
    32.             };
    33.  
    34.             struct v2f
    35.             {
    36.                 float4 vertex : SV_POSITION;
    37.                 float4 screenPos : TEXCOORD1;
    38.             };
    39.  
    40.             v2f vert (appdata v)
    41.             {
    42.                 v2f o;
    43.  
    44.                 o.vertex = UnityObjectToClipPos(v.vertex);
    45.                 o.screenPos = ComputeScreenPos(o.vertex);
    46.  
    47.                 return o;
    48.             }
    49.            
    50.             sampler2D _MainTex;
    51.  
    52.             fixed4 frag (v2f i) : SV_Target
    53.             {
    54.                 i.screenPos /= i.screenPos.w;
    55.                 fixed4 col = tex2D(_MainTex, float2(i.screenPos.x, i.screenPos.y));
    56.                
    57.                 return col;
    58.             }
    59.             ENDCG
    60.         }
    61.     }
    62. }
    63.  
     

    Attached Files:

  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    I don’t think what you’re asking for is what you want. Getting the “screen space position of another camera” is possible by passing the view projection matrix of that camera to the shader, but it won’t solve the problem you’re having.

    What you should be doing is using the “FaceCamera” as the output camera, and that camera should be using an oblique projection. If you’re just rotating the camera around to aim the correct direction you’re not getting the correct perspective to display on the screen.

    See this article:
    https://medium.com/@michel.brisis/off-axis-projection-in-unity-1572d826541e
     
    Sewf likes this.
  3. Sewf

    Sewf

    Joined:
    Mar 23, 2018
    Posts:
    3
    Oh my god that article is exactly what I want to do! Will try that approach first thing tommorow morning!

    Thank you so much!
     
  4. Sewf

    Sewf

    Joined:
    Mar 23, 2018
    Posts:
    3

    finally got it working! Working like a charm now, thank you so much!