Search Unity

Tex2D of a Tex2D?

Discussion in 'Shaders' started by SerializeField, Jul 30, 2019.

  1. SerializeField

    SerializeField

    Joined:
    May 22, 2017
    Posts:
    22
    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):
    1. Shader "BasicStereoTexture"
    2. {
    3.     Properties
    4.     {
    5.         _LeftTex("Left Texture", 2D) = "white" {}
    6.         _RightTex("Right Texture", 2D) = "white" {}
    7.     }
    8.         SubShader
    9.     {
    10.         Tags { "RenderType" = "Opaque" }
    11.  
    12.         Pass
    13.         {
    14.             CGPROGRAM
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.  
    18.             #include "UnityCG.cginc"
    19.  
    20.             struct vertexInput
    21.             {
    22.                 float4 vertex : POSITION;
    23.                 float2 uv : TEXCOORD0;
    24.             };
    25.  
    26.             struct vertexOutput
    27.             {
    28.                 float2 uvLeft : TEXCOORD0;
    29.                 float2 uvRight : TEXCOORD1;
    30.                 float4 vertex : SV_POSITION;
    31.             };
    32.  
    33.             sampler2D _LeftTex;
    34.             uniform float4 _LeftTex_ST;
    35.             sampler2D _RightTex;
    36.             uniform float4 _RightTex_ST;
    37.  
    38.             vertexOutput vert(vertexInput i)
    39.             {
    40.                 vertexOutput o;
    41.                 //i.vertex.y += sin(i.vertex.x * _Time.y);
    42.                 o.vertex = UnityObjectToClipPos(i.vertex);
    43.                 o.uvLeft = TRANSFORM_TEX(i.uv, _LeftTex);
    44.                 o.uvRight = TRANSFORM_TEX(i.uv, _RightTex);
    45.                 //o.vertex.y += sin(o.vertex.x * _Time.y);
    46.  
    47.                 return o;
    48.             }
    49.  
    50.             float4 frag(vertexOutput i) : SV_Target
    51.             {
    52.                 return lerp(tex2D(_LeftTex, i.uvLeft),
    53.                     tex2D(_RightTex, i.uvRight),
    54.                     unity_StereoEyeIndex);
    55.             }
    56.             ENDCG
    57.         }
    58.     }
    59.         FallBack "Diffuse"
    60. }
    but the Portal shader uses this in it's frag function:

    Code (CSharp):
    1. fixed4 frag (v2f i) : SV_Target
    2.             {
    3.                 i.screenPos /= i.screenPos.w;
    4.                 fixed4 col = tex2D(_MainTex, float2(i.screenPos.x, i.screenPos.y));
    5.                
    6.                 return col;
    7.             }
    So I'm thinking I'd need to do something like this to make this work, except it isn't allowed:

    Code (CSharp):
    1. fixed4 frag (v2f i) : SV_Target
    2.             {
    3.                 i.screenPos /= i.screenPos.w;
    4.                 fixed4 colL = tex2D(tex2D(_LeftTex, i.uvLeft), float2(i.screenPos.x, i.screenPos.y));
    5.                 fixed4 colR = tex2D(tex2D(_RightTex, i.uvRight), float2(i.screenPos.x, i.screenPos.y));
    6.                
    7.                 return lerp(colL, colR, unity_StereoEyeIndex);
    8.             }
    Any clues on how I might be able to achieve this?
     
  2. SerializeField

    SerializeField

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

    SerializeField

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