Shader "Escape Room Engine/Portal" { Properties { _LeftTex("Left Eye Texture", 2D) = "" {} _RightTex("Right Eye Texture", 2D) = "" {} } SubShader { Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } Pass { // stencil the portal surface to cut it out from the portal frame Stencil { Ref 1 Pass replace } HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_instancing #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct Attributes { float4 positionOS : POSITION; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float4 positionHCS : SV_POSITION; float4 positionScreen : TEXCOORD0; UNITY_VERTEX_OUTPUT_STEREO }; uniform sampler2D _LeftTex, _RightTex; Varyings vert(Attributes IN) { Varyings OUT; UNITY_SETUP_INSTANCE_ID(IN); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); // calculate the screen position which is used to map the portal texture onto the portal OUT.positionScreen = ComputeScreenPos(OUT.positionHCS); return OUT; } half4 frag(Varyings IN) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN); const float2 uv = IN.positionScreen.xy / IN.positionScreen.w; // sample from the correct texture depending on the eye rendered return unity_StereoEyeIndex == 0 ? tex2D(_LeftTex, uv) : tex2D(_RightTex, uv); } ENDHLSL } } }