Hi, I'm trying to make this ( https://github.com/KillianMcCabe/SmoothPortals ) work with virtual reality by making the portal shader take in two render textures, one for each eye. I've managed to get stereoscopic render textures working with this shader: Code (CSharp): Shader "BasicStereoTexture" { Properties { _LeftTex("Left Texture", 2D) = "white" {} _RightTex("Right Texture", 2D) = "white" {} } SubShader { Tags { "RenderType" = "Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct vertexInput { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct vertexOutput { float2 uvLeft : TEXCOORD0; float2 uvRight : TEXCOORD1; float4 vertex : SV_POSITION; }; sampler2D _LeftTex; uniform float4 _LeftTex_ST; sampler2D _RightTex; uniform float4 _RightTex_ST; vertexOutput vert(vertexInput i) { vertexOutput o; //i.vertex.y += sin(i.vertex.x * _Time.y); o.vertex = UnityObjectToClipPos(i.vertex); o.uvLeft = TRANSFORM_TEX(i.uv, _LeftTex); o.uvRight = TRANSFORM_TEX(i.uv, _RightTex); //o.vertex.y += sin(o.vertex.x * _Time.y); return o; } float4 frag(vertexOutput i) : SV_Target { return lerp(tex2D(_LeftTex, i.uvLeft), tex2D(_RightTex, i.uvRight), unity_StereoEyeIndex); } ENDCG } } FallBack "Diffuse" } but the Portal shader uses this in it's frag function: Code (CSharp): fixed4 frag (v2f i) : SV_Target { i.screenPos /= i.screenPos.w; fixed4 col = tex2D(_MainTex, float2(i.screenPos.x, i.screenPos.y)); return col; } So I'm thinking I'd need to do something like this to make this work, except it isn't allowed: Code (CSharp): fixed4 frag (v2f i) : SV_Target { i.screenPos /= i.screenPos.w; fixed4 colL = tex2D(tex2D(_LeftTex, i.uvLeft), float2(i.screenPos.x, i.screenPos.y)); fixed4 colR = tex2D(tex2D(_RightTex, i.uvRight), float2(i.screenPos.x, i.screenPos.y)); return lerp(colL, colR, unity_StereoEyeIndex); } Any clues on how I might be able to achieve this?
Turns out, the actual portal shader is slightly different, but my problem persists: Code (CSharp): Shader "Hidden/PlaneShader" { Properties { _MainTex("Texture", 2D) = "white" {} } SubShader { Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } Lighting Off Cull Back ZWrite On ZTest Less Fog{ Mode Off } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float4 screenPos : TEXCOORD1; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.screenPos = ComputeScreenPos(o.vertex); o.uv = v.uv; return o; } sampler2D _MainTex; fixed4 frag(v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, float2(1 - i.uv.x, 1 - i.uv.y)); return col; } ENDCG } } }
Solved it. You need to do some other changes to the PortalCamera.cs script to make it spawn two cameras, one for each eye, and duplicate the logic for each, but the hardest part is the shader, so here it is: Code (CSharp): Shader "Hidden/PlaneShaderStereo" { Properties { _MainTex("Texture", 2D) = "white" {} _RightTex("Texture", 2D) = "white" {} _LeftTex("Texture", 2D) = "white" {} } SubShader { Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } Lighting Off Cull Back ZWrite On ZTest Less Fog{ Mode Off } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 screenPos : TEXCOORD1; float2 uvLeft : TEXCOORD2; float2 uvRight : TEXCOORD3; float4 vertex : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.screenPos = ComputeScreenPos(o.vertex); o.uv = v.uv; return o; } sampler2D _MainTex; sampler2D _LeftTex; uniform float4 _LeftTex_ST; sampler2D _RightTex; uniform float4 _RightTex_ST; fixed4 frag(v2f i) : SV_Target { fixed4 col = lerp(tex2D(_LeftTex, float2(1 - i.uv.x, 1 - i.uv.y)), tex2D(_RightTex, float2(1 - i.uv.x, 1 - i.uv.y)), unity_StereoEyeIndex); return col; } ENDCG } } }